1*635a8641SAndroid Build Coastguard Worker // Copyright (c) 2018 The Chromium Authors. All rights reserved.
2*635a8641SAndroid Build Coastguard Worker // Use of this source code is governed by a BSD-style license that can be
3*635a8641SAndroid Build Coastguard Worker // found in the LICENSE file.
4*635a8641SAndroid Build Coastguard Worker
5*635a8641SAndroid Build Coastguard Worker #include "base/strings/utf_string_conversions.h"
6*635a8641SAndroid Build Coastguard Worker
7*635a8641SAndroid Build Coastguard Worker #include <stdint.h>
8*635a8641SAndroid Build Coastguard Worker
9*635a8641SAndroid Build Coastguard Worker #include "base/strings/string_piece.h"
10*635a8641SAndroid Build Coastguard Worker #include "base/strings/string_util.h"
11*635a8641SAndroid Build Coastguard Worker #include "base/strings/utf_string_conversion_utils.h"
12*635a8641SAndroid Build Coastguard Worker #include "base/third_party/icu/icu_utf.h"
13*635a8641SAndroid Build Coastguard Worker #include "build/build_config.h"
14*635a8641SAndroid Build Coastguard Worker
15*635a8641SAndroid Build Coastguard Worker namespace base {
16*635a8641SAndroid Build Coastguard Worker
17*635a8641SAndroid Build Coastguard Worker namespace {
18*635a8641SAndroid Build Coastguard Worker
19*635a8641SAndroid Build Coastguard Worker constexpr int32_t kErrorCodePoint = 0xFFFD;
20*635a8641SAndroid Build Coastguard Worker
21*635a8641SAndroid Build Coastguard Worker // Size coefficient ----------------------------------------------------------
22*635a8641SAndroid Build Coastguard Worker // The maximum number of codeunits in the destination encoding corresponding to
23*635a8641SAndroid Build Coastguard Worker // one codeunit in the source encoding.
24*635a8641SAndroid Build Coastguard Worker
25*635a8641SAndroid Build Coastguard Worker template <typename SrcChar, typename DestChar>
26*635a8641SAndroid Build Coastguard Worker struct SizeCoefficient {
27*635a8641SAndroid Build Coastguard Worker static_assert(sizeof(SrcChar) < sizeof(DestChar),
28*635a8641SAndroid Build Coastguard Worker "Default case: from a smaller encoding to the bigger one");
29*635a8641SAndroid Build Coastguard Worker
30*635a8641SAndroid Build Coastguard Worker // ASCII symbols are encoded by one codeunit in all encodings.
31*635a8641SAndroid Build Coastguard Worker static constexpr int value = 1;
32*635a8641SAndroid Build Coastguard Worker };
33*635a8641SAndroid Build Coastguard Worker
34*635a8641SAndroid Build Coastguard Worker template <>
35*635a8641SAndroid Build Coastguard Worker struct SizeCoefficient<char16, char> {
36*635a8641SAndroid Build Coastguard Worker // One UTF-16 codeunit corresponds to at most 3 codeunits in UTF-8.
37*635a8641SAndroid Build Coastguard Worker static constexpr int value = 3;
38*635a8641SAndroid Build Coastguard Worker };
39*635a8641SAndroid Build Coastguard Worker
40*635a8641SAndroid Build Coastguard Worker #if defined(WCHAR_T_IS_UTF32)
41*635a8641SAndroid Build Coastguard Worker template <>
42*635a8641SAndroid Build Coastguard Worker struct SizeCoefficient<wchar_t, char> {
43*635a8641SAndroid Build Coastguard Worker // UTF-8 uses at most 4 codeunits per character.
44*635a8641SAndroid Build Coastguard Worker static constexpr int value = 4;
45*635a8641SAndroid Build Coastguard Worker };
46*635a8641SAndroid Build Coastguard Worker
47*635a8641SAndroid Build Coastguard Worker template <>
48*635a8641SAndroid Build Coastguard Worker struct SizeCoefficient<wchar_t, char16> {
49*635a8641SAndroid Build Coastguard Worker // UTF-16 uses at most 2 codeunits per character.
50*635a8641SAndroid Build Coastguard Worker static constexpr int value = 2;
51*635a8641SAndroid Build Coastguard Worker };
52*635a8641SAndroid Build Coastguard Worker #endif // defined(WCHAR_T_IS_UTF32)
53*635a8641SAndroid Build Coastguard Worker
54*635a8641SAndroid Build Coastguard Worker template <typename SrcChar, typename DestChar>
55*635a8641SAndroid Build Coastguard Worker constexpr int size_coefficient_v =
56*635a8641SAndroid Build Coastguard Worker SizeCoefficient<std::decay_t<SrcChar>, std::decay_t<DestChar>>::value;
57*635a8641SAndroid Build Coastguard Worker
58*635a8641SAndroid Build Coastguard Worker // UnicodeAppendUnsafe --------------------------------------------------------
59*635a8641SAndroid Build Coastguard Worker // Function overloads that write code_point to the output string. Output string
60*635a8641SAndroid Build Coastguard Worker // has to have enough space for the codepoint.
61*635a8641SAndroid Build Coastguard Worker
UnicodeAppendUnsafe(char * out,int32_t * size,uint32_t code_point)62*635a8641SAndroid Build Coastguard Worker void UnicodeAppendUnsafe(char* out, int32_t* size, uint32_t code_point) {
63*635a8641SAndroid Build Coastguard Worker CBU8_APPEND_UNSAFE(out, *size, code_point);
64*635a8641SAndroid Build Coastguard Worker }
65*635a8641SAndroid Build Coastguard Worker
UnicodeAppendUnsafe(char16 * out,int32_t * size,uint32_t code_point)66*635a8641SAndroid Build Coastguard Worker void UnicodeAppendUnsafe(char16* out, int32_t* size, uint32_t code_point) {
67*635a8641SAndroid Build Coastguard Worker CBU16_APPEND_UNSAFE(out, *size, code_point);
68*635a8641SAndroid Build Coastguard Worker }
69*635a8641SAndroid Build Coastguard Worker
70*635a8641SAndroid Build Coastguard Worker #if defined(WCHAR_T_IS_UTF32)
71*635a8641SAndroid Build Coastguard Worker
UnicodeAppendUnsafe(wchar_t * out,int32_t * size,uint32_t code_point)72*635a8641SAndroid Build Coastguard Worker void UnicodeAppendUnsafe(wchar_t* out, int32_t* size, uint32_t code_point) {
73*635a8641SAndroid Build Coastguard Worker out[(*size)++] = code_point;
74*635a8641SAndroid Build Coastguard Worker }
75*635a8641SAndroid Build Coastguard Worker
76*635a8641SAndroid Build Coastguard Worker #endif // defined(WCHAR_T_IS_UTF32)
77*635a8641SAndroid Build Coastguard Worker
78*635a8641SAndroid Build Coastguard Worker // DoUTFConversion ------------------------------------------------------------
79*635a8641SAndroid Build Coastguard Worker // Main driver of UTFConversion specialized for different Src encodings.
80*635a8641SAndroid Build Coastguard Worker // dest has to have enough room for the converted text.
81*635a8641SAndroid Build Coastguard Worker
82*635a8641SAndroid Build Coastguard Worker template <typename DestChar>
DoUTFConversion(const char * src,int32_t src_len,DestChar * dest,int32_t * dest_len)83*635a8641SAndroid Build Coastguard Worker bool DoUTFConversion(const char* src,
84*635a8641SAndroid Build Coastguard Worker int32_t src_len,
85*635a8641SAndroid Build Coastguard Worker DestChar* dest,
86*635a8641SAndroid Build Coastguard Worker int32_t* dest_len) {
87*635a8641SAndroid Build Coastguard Worker bool success = true;
88*635a8641SAndroid Build Coastguard Worker
89*635a8641SAndroid Build Coastguard Worker for (int32_t i = 0; i < src_len;) {
90*635a8641SAndroid Build Coastguard Worker int32_t code_point;
91*635a8641SAndroid Build Coastguard Worker CBU8_NEXT(src, i, src_len, code_point);
92*635a8641SAndroid Build Coastguard Worker
93*635a8641SAndroid Build Coastguard Worker if (!IsValidCodepoint(code_point)) {
94*635a8641SAndroid Build Coastguard Worker success = false;
95*635a8641SAndroid Build Coastguard Worker code_point = kErrorCodePoint;
96*635a8641SAndroid Build Coastguard Worker }
97*635a8641SAndroid Build Coastguard Worker
98*635a8641SAndroid Build Coastguard Worker UnicodeAppendUnsafe(dest, dest_len, code_point);
99*635a8641SAndroid Build Coastguard Worker }
100*635a8641SAndroid Build Coastguard Worker
101*635a8641SAndroid Build Coastguard Worker return success;
102*635a8641SAndroid Build Coastguard Worker }
103*635a8641SAndroid Build Coastguard Worker
104*635a8641SAndroid Build Coastguard Worker template <typename DestChar>
DoUTFConversion(const char16 * src,int32_t src_len,DestChar * dest,int32_t * dest_len)105*635a8641SAndroid Build Coastguard Worker bool DoUTFConversion(const char16* src,
106*635a8641SAndroid Build Coastguard Worker int32_t src_len,
107*635a8641SAndroid Build Coastguard Worker DestChar* dest,
108*635a8641SAndroid Build Coastguard Worker int32_t* dest_len) {
109*635a8641SAndroid Build Coastguard Worker bool success = true;
110*635a8641SAndroid Build Coastguard Worker
111*635a8641SAndroid Build Coastguard Worker auto ConvertSingleChar = [&success](char16 in) -> int32_t {
112*635a8641SAndroid Build Coastguard Worker if (!CBU16_IS_SINGLE(in) || !IsValidCodepoint(in)) {
113*635a8641SAndroid Build Coastguard Worker success = false;
114*635a8641SAndroid Build Coastguard Worker return kErrorCodePoint;
115*635a8641SAndroid Build Coastguard Worker }
116*635a8641SAndroid Build Coastguard Worker return in;
117*635a8641SAndroid Build Coastguard Worker };
118*635a8641SAndroid Build Coastguard Worker
119*635a8641SAndroid Build Coastguard Worker int32_t i = 0;
120*635a8641SAndroid Build Coastguard Worker
121*635a8641SAndroid Build Coastguard Worker // Always have another symbol in order to avoid checking boundaries in the
122*635a8641SAndroid Build Coastguard Worker // middle of the surrogate pair.
123*635a8641SAndroid Build Coastguard Worker while (i < src_len - 1) {
124*635a8641SAndroid Build Coastguard Worker int32_t code_point;
125*635a8641SAndroid Build Coastguard Worker
126*635a8641SAndroid Build Coastguard Worker if (CBU16_IS_LEAD(src[i]) && CBU16_IS_TRAIL(src[i + 1])) {
127*635a8641SAndroid Build Coastguard Worker code_point = CBU16_GET_SUPPLEMENTARY(src[i], src[i + 1]);
128*635a8641SAndroid Build Coastguard Worker if (!IsValidCodepoint(code_point)) {
129*635a8641SAndroid Build Coastguard Worker code_point = kErrorCodePoint;
130*635a8641SAndroid Build Coastguard Worker success = false;
131*635a8641SAndroid Build Coastguard Worker }
132*635a8641SAndroid Build Coastguard Worker i += 2;
133*635a8641SAndroid Build Coastguard Worker } else {
134*635a8641SAndroid Build Coastguard Worker code_point = ConvertSingleChar(src[i]);
135*635a8641SAndroid Build Coastguard Worker ++i;
136*635a8641SAndroid Build Coastguard Worker }
137*635a8641SAndroid Build Coastguard Worker
138*635a8641SAndroid Build Coastguard Worker UnicodeAppendUnsafe(dest, dest_len, code_point);
139*635a8641SAndroid Build Coastguard Worker }
140*635a8641SAndroid Build Coastguard Worker
141*635a8641SAndroid Build Coastguard Worker if (i < src_len)
142*635a8641SAndroid Build Coastguard Worker UnicodeAppendUnsafe(dest, dest_len, ConvertSingleChar(src[i]));
143*635a8641SAndroid Build Coastguard Worker
144*635a8641SAndroid Build Coastguard Worker return success;
145*635a8641SAndroid Build Coastguard Worker }
146*635a8641SAndroid Build Coastguard Worker
147*635a8641SAndroid Build Coastguard Worker #if defined(WCHAR_T_IS_UTF32)
148*635a8641SAndroid Build Coastguard Worker
149*635a8641SAndroid Build Coastguard Worker template <typename DestChar>
DoUTFConversion(const wchar_t * src,int32_t src_len,DestChar * dest,int32_t * dest_len)150*635a8641SAndroid Build Coastguard Worker bool DoUTFConversion(const wchar_t* src,
151*635a8641SAndroid Build Coastguard Worker int32_t src_len,
152*635a8641SAndroid Build Coastguard Worker DestChar* dest,
153*635a8641SAndroid Build Coastguard Worker int32_t* dest_len) {
154*635a8641SAndroid Build Coastguard Worker bool success = true;
155*635a8641SAndroid Build Coastguard Worker
156*635a8641SAndroid Build Coastguard Worker for (int32_t i = 0; i < src_len; ++i) {
157*635a8641SAndroid Build Coastguard Worker int32_t code_point = src[i];
158*635a8641SAndroid Build Coastguard Worker
159*635a8641SAndroid Build Coastguard Worker if (!IsValidCodepoint(code_point)) {
160*635a8641SAndroid Build Coastguard Worker success = false;
161*635a8641SAndroid Build Coastguard Worker code_point = kErrorCodePoint;
162*635a8641SAndroid Build Coastguard Worker }
163*635a8641SAndroid Build Coastguard Worker
164*635a8641SAndroid Build Coastguard Worker UnicodeAppendUnsafe(dest, dest_len, code_point);
165*635a8641SAndroid Build Coastguard Worker }
166*635a8641SAndroid Build Coastguard Worker
167*635a8641SAndroid Build Coastguard Worker return success;
168*635a8641SAndroid Build Coastguard Worker }
169*635a8641SAndroid Build Coastguard Worker
170*635a8641SAndroid Build Coastguard Worker #endif // defined(WCHAR_T_IS_UTF32)
171*635a8641SAndroid Build Coastguard Worker
172*635a8641SAndroid Build Coastguard Worker // UTFConversion --------------------------------------------------------------
173*635a8641SAndroid Build Coastguard Worker // Function template for generating all UTF conversions.
174*635a8641SAndroid Build Coastguard Worker
175*635a8641SAndroid Build Coastguard Worker template <typename InputString, typename DestString>
UTFConversion(const InputString & src_str,DestString * dest_str)176*635a8641SAndroid Build Coastguard Worker bool UTFConversion(const InputString& src_str, DestString* dest_str) {
177*635a8641SAndroid Build Coastguard Worker if (IsStringASCII(src_str)) {
178*635a8641SAndroid Build Coastguard Worker dest_str->assign(src_str.begin(), src_str.end());
179*635a8641SAndroid Build Coastguard Worker return true;
180*635a8641SAndroid Build Coastguard Worker }
181*635a8641SAndroid Build Coastguard Worker
182*635a8641SAndroid Build Coastguard Worker dest_str->resize(src_str.length() *
183*635a8641SAndroid Build Coastguard Worker size_coefficient_v<typename InputString::value_type,
184*635a8641SAndroid Build Coastguard Worker typename DestString::value_type>);
185*635a8641SAndroid Build Coastguard Worker
186*635a8641SAndroid Build Coastguard Worker // Empty string is ASCII => it OK to call operator[].
187*635a8641SAndroid Build Coastguard Worker auto* dest = &(*dest_str)[0];
188*635a8641SAndroid Build Coastguard Worker
189*635a8641SAndroid Build Coastguard Worker // ICU requires 32 bit numbers.
190*635a8641SAndroid Build Coastguard Worker int32_t src_len32 = static_cast<int32_t>(src_str.length());
191*635a8641SAndroid Build Coastguard Worker int32_t dest_len32 = 0;
192*635a8641SAndroid Build Coastguard Worker
193*635a8641SAndroid Build Coastguard Worker bool res = DoUTFConversion(src_str.data(), src_len32, dest, &dest_len32);
194*635a8641SAndroid Build Coastguard Worker
195*635a8641SAndroid Build Coastguard Worker dest_str->resize(dest_len32);
196*635a8641SAndroid Build Coastguard Worker dest_str->shrink_to_fit();
197*635a8641SAndroid Build Coastguard Worker
198*635a8641SAndroid Build Coastguard Worker return res;
199*635a8641SAndroid Build Coastguard Worker }
200*635a8641SAndroid Build Coastguard Worker
201*635a8641SAndroid Build Coastguard Worker } // namespace
202*635a8641SAndroid Build Coastguard Worker
203*635a8641SAndroid Build Coastguard Worker // UTF16 <-> UTF8 --------------------------------------------------------------
204*635a8641SAndroid Build Coastguard Worker
UTF8ToUTF16(const char * src,size_t src_len,string16 * output)205*635a8641SAndroid Build Coastguard Worker bool UTF8ToUTF16(const char* src, size_t src_len, string16* output) {
206*635a8641SAndroid Build Coastguard Worker return UTFConversion(StringPiece(src, src_len), output);
207*635a8641SAndroid Build Coastguard Worker }
208*635a8641SAndroid Build Coastguard Worker
UTF8ToUTF16(StringPiece utf8)209*635a8641SAndroid Build Coastguard Worker string16 UTF8ToUTF16(StringPiece utf8) {
210*635a8641SAndroid Build Coastguard Worker string16 ret;
211*635a8641SAndroid Build Coastguard Worker // Ignore the success flag of this call, it will do the best it can for
212*635a8641SAndroid Build Coastguard Worker // invalid input, which is what we want here.
213*635a8641SAndroid Build Coastguard Worker UTF8ToUTF16(utf8.data(), utf8.size(), &ret);
214*635a8641SAndroid Build Coastguard Worker return ret;
215*635a8641SAndroid Build Coastguard Worker }
216*635a8641SAndroid Build Coastguard Worker
UTF16ToUTF8(const char16 * src,size_t src_len,std::string * output)217*635a8641SAndroid Build Coastguard Worker bool UTF16ToUTF8(const char16* src, size_t src_len, std::string* output) {
218*635a8641SAndroid Build Coastguard Worker return UTFConversion(StringPiece16(src, src_len), output);
219*635a8641SAndroid Build Coastguard Worker }
220*635a8641SAndroid Build Coastguard Worker
UTF16ToUTF8(StringPiece16 utf16)221*635a8641SAndroid Build Coastguard Worker std::string UTF16ToUTF8(StringPiece16 utf16) {
222*635a8641SAndroid Build Coastguard Worker std::string ret;
223*635a8641SAndroid Build Coastguard Worker // Ignore the success flag of this call, it will do the best it can for
224*635a8641SAndroid Build Coastguard Worker // invalid input, which is what we want here.
225*635a8641SAndroid Build Coastguard Worker UTF16ToUTF8(utf16.data(), utf16.length(), &ret);
226*635a8641SAndroid Build Coastguard Worker return ret;
227*635a8641SAndroid Build Coastguard Worker }
228*635a8641SAndroid Build Coastguard Worker
229*635a8641SAndroid Build Coastguard Worker // UTF-16 <-> Wide -------------------------------------------------------------
230*635a8641SAndroid Build Coastguard Worker
231*635a8641SAndroid Build Coastguard Worker #if defined(WCHAR_T_IS_UTF16)
232*635a8641SAndroid Build Coastguard Worker // When wide == UTF-16 the conversions are a NOP.
233*635a8641SAndroid Build Coastguard Worker
WideToUTF16(const wchar_t * src,size_t src_len,string16 * output)234*635a8641SAndroid Build Coastguard Worker bool WideToUTF16(const wchar_t* src, size_t src_len, string16* output) {
235*635a8641SAndroid Build Coastguard Worker output->assign(src, src_len);
236*635a8641SAndroid Build Coastguard Worker return true;
237*635a8641SAndroid Build Coastguard Worker }
238*635a8641SAndroid Build Coastguard Worker
WideToUTF16(WStringPiece wide)239*635a8641SAndroid Build Coastguard Worker string16 WideToUTF16(WStringPiece wide) {
240*635a8641SAndroid Build Coastguard Worker return wide.as_string();
241*635a8641SAndroid Build Coastguard Worker }
242*635a8641SAndroid Build Coastguard Worker
UTF16ToWide(const char16 * src,size_t src_len,std::wstring * output)243*635a8641SAndroid Build Coastguard Worker bool UTF16ToWide(const char16* src, size_t src_len, std::wstring* output) {
244*635a8641SAndroid Build Coastguard Worker output->assign(src, src_len);
245*635a8641SAndroid Build Coastguard Worker return true;
246*635a8641SAndroid Build Coastguard Worker }
247*635a8641SAndroid Build Coastguard Worker
UTF16ToWide(StringPiece16 utf16)248*635a8641SAndroid Build Coastguard Worker std::wstring UTF16ToWide(StringPiece16 utf16) {
249*635a8641SAndroid Build Coastguard Worker return utf16.as_string();
250*635a8641SAndroid Build Coastguard Worker }
251*635a8641SAndroid Build Coastguard Worker
252*635a8641SAndroid Build Coastguard Worker #elif defined(WCHAR_T_IS_UTF32)
253*635a8641SAndroid Build Coastguard Worker
WideToUTF16(const wchar_t * src,size_t src_len,string16 * output)254*635a8641SAndroid Build Coastguard Worker bool WideToUTF16(const wchar_t* src, size_t src_len, string16* output) {
255*635a8641SAndroid Build Coastguard Worker return UTFConversion(base::WStringPiece(src, src_len), output);
256*635a8641SAndroid Build Coastguard Worker }
257*635a8641SAndroid Build Coastguard Worker
WideToUTF16(WStringPiece wide)258*635a8641SAndroid Build Coastguard Worker string16 WideToUTF16(WStringPiece wide) {
259*635a8641SAndroid Build Coastguard Worker string16 ret;
260*635a8641SAndroid Build Coastguard Worker // Ignore the success flag of this call, it will do the best it can for
261*635a8641SAndroid Build Coastguard Worker // invalid input, which is what we want here.
262*635a8641SAndroid Build Coastguard Worker WideToUTF16(wide.data(), wide.length(), &ret);
263*635a8641SAndroid Build Coastguard Worker return ret;
264*635a8641SAndroid Build Coastguard Worker }
265*635a8641SAndroid Build Coastguard Worker
UTF16ToWide(const char16 * src,size_t src_len,std::wstring * output)266*635a8641SAndroid Build Coastguard Worker bool UTF16ToWide(const char16* src, size_t src_len, std::wstring* output) {
267*635a8641SAndroid Build Coastguard Worker return UTFConversion(StringPiece16(src, src_len), output);
268*635a8641SAndroid Build Coastguard Worker }
269*635a8641SAndroid Build Coastguard Worker
UTF16ToWide(StringPiece16 utf16)270*635a8641SAndroid Build Coastguard Worker std::wstring UTF16ToWide(StringPiece16 utf16) {
271*635a8641SAndroid Build Coastguard Worker std::wstring ret;
272*635a8641SAndroid Build Coastguard Worker // Ignore the success flag of this call, it will do the best it can for
273*635a8641SAndroid Build Coastguard Worker // invalid input, which is what we want here.
274*635a8641SAndroid Build Coastguard Worker UTF16ToWide(utf16.data(), utf16.length(), &ret);
275*635a8641SAndroid Build Coastguard Worker return ret;
276*635a8641SAndroid Build Coastguard Worker }
277*635a8641SAndroid Build Coastguard Worker
278*635a8641SAndroid Build Coastguard Worker #endif // defined(WCHAR_T_IS_UTF32)
279*635a8641SAndroid Build Coastguard Worker
280*635a8641SAndroid Build Coastguard Worker // UTF-8 <-> Wide --------------------------------------------------------------
281*635a8641SAndroid Build Coastguard Worker
282*635a8641SAndroid Build Coastguard Worker // UTF8ToWide is the same code, regardless of whether wide is 16 or 32 bits
283*635a8641SAndroid Build Coastguard Worker
UTF8ToWide(const char * src,size_t src_len,std::wstring * output)284*635a8641SAndroid Build Coastguard Worker bool UTF8ToWide(const char* src, size_t src_len, std::wstring* output) {
285*635a8641SAndroid Build Coastguard Worker return UTFConversion(StringPiece(src, src_len), output);
286*635a8641SAndroid Build Coastguard Worker }
287*635a8641SAndroid Build Coastguard Worker
UTF8ToWide(StringPiece utf8)288*635a8641SAndroid Build Coastguard Worker std::wstring UTF8ToWide(StringPiece utf8) {
289*635a8641SAndroid Build Coastguard Worker std::wstring ret;
290*635a8641SAndroid Build Coastguard Worker // Ignore the success flag of this call, it will do the best it can for
291*635a8641SAndroid Build Coastguard Worker // invalid input, which is what we want here.
292*635a8641SAndroid Build Coastguard Worker UTF8ToWide(utf8.data(), utf8.length(), &ret);
293*635a8641SAndroid Build Coastguard Worker return ret;
294*635a8641SAndroid Build Coastguard Worker }
295*635a8641SAndroid Build Coastguard Worker
296*635a8641SAndroid Build Coastguard Worker #if defined(WCHAR_T_IS_UTF16)
297*635a8641SAndroid Build Coastguard Worker // Easy case since we can use the "utf" versions we already wrote above.
298*635a8641SAndroid Build Coastguard Worker
WideToUTF8(const wchar_t * src,size_t src_len,std::string * output)299*635a8641SAndroid Build Coastguard Worker bool WideToUTF8(const wchar_t* src, size_t src_len, std::string* output) {
300*635a8641SAndroid Build Coastguard Worker return UTF16ToUTF8(src, src_len, output);
301*635a8641SAndroid Build Coastguard Worker }
302*635a8641SAndroid Build Coastguard Worker
WideToUTF8(WStringPiece wide)303*635a8641SAndroid Build Coastguard Worker std::string WideToUTF8(WStringPiece wide) {
304*635a8641SAndroid Build Coastguard Worker return UTF16ToUTF8(wide);
305*635a8641SAndroid Build Coastguard Worker }
306*635a8641SAndroid Build Coastguard Worker
307*635a8641SAndroid Build Coastguard Worker #elif defined(WCHAR_T_IS_UTF32)
308*635a8641SAndroid Build Coastguard Worker
WideToUTF8(const wchar_t * src,size_t src_len,std::string * output)309*635a8641SAndroid Build Coastguard Worker bool WideToUTF8(const wchar_t* src, size_t src_len, std::string* output) {
310*635a8641SAndroid Build Coastguard Worker return UTFConversion(WStringPiece(src, src_len), output);
311*635a8641SAndroid Build Coastguard Worker }
312*635a8641SAndroid Build Coastguard Worker
WideToUTF8(WStringPiece wide)313*635a8641SAndroid Build Coastguard Worker std::string WideToUTF8(WStringPiece wide) {
314*635a8641SAndroid Build Coastguard Worker std::string ret;
315*635a8641SAndroid Build Coastguard Worker // Ignore the success flag of this call, it will do the best it can for
316*635a8641SAndroid Build Coastguard Worker // invalid input, which is what we want here.
317*635a8641SAndroid Build Coastguard Worker WideToUTF8(wide.data(), wide.length(), &ret);
318*635a8641SAndroid Build Coastguard Worker return ret;
319*635a8641SAndroid Build Coastguard Worker }
320*635a8641SAndroid Build Coastguard Worker
321*635a8641SAndroid Build Coastguard Worker #endif // defined(WCHAR_T_IS_UTF32)
322*635a8641SAndroid Build Coastguard Worker
ASCIIToUTF16(StringPiece ascii)323*635a8641SAndroid Build Coastguard Worker string16 ASCIIToUTF16(StringPiece ascii) {
324*635a8641SAndroid Build Coastguard Worker DCHECK(IsStringASCII(ascii)) << ascii;
325*635a8641SAndroid Build Coastguard Worker return string16(ascii.begin(), ascii.end());
326*635a8641SAndroid Build Coastguard Worker }
327*635a8641SAndroid Build Coastguard Worker
UTF16ToASCII(StringPiece16 utf16)328*635a8641SAndroid Build Coastguard Worker std::string UTF16ToASCII(StringPiece16 utf16) {
329*635a8641SAndroid Build Coastguard Worker DCHECK(IsStringASCII(utf16)) << UTF16ToUTF8(utf16);
330*635a8641SAndroid Build Coastguard Worker return std::string(utf16.begin(), utf16.end());
331*635a8641SAndroid Build Coastguard Worker }
332*635a8641SAndroid Build Coastguard Worker
333*635a8641SAndroid Build Coastguard Worker } // namespace base
334