1 // Copyright (c) 2012 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
5 #include "base/strings/sys_string_conversions.h"
9 #include "base/strings/string_piece.h"
10 #include "base/utf_string_conversions.h"
14 std::string
SysWideToUTF8(const std::wstring
& wide
) {
15 // In theory this should be using the system-provided conversion rather
16 // than our ICU, but this will do for now.
17 return WideToUTF8(wide
);
19 std::wstring
SysUTF8ToWide(const StringPiece
& utf8
) {
20 // In theory this should be using the system-provided conversion rather
21 // than our ICU, but this will do for now.
23 UTF8ToWide(utf8
.data(), utf8
.size(), &out
);
27 #if defined(OS_CHROMEOS) || defined(OS_ANDROID)
28 // TODO(port): Consider reverting the OS_ANDROID when we have wcrtomb()
29 // support and a better understanding of what calls these routines.
31 // ChromeOS always runs in UTF-8 locale.
32 std::string
SysWideToNativeMB(const std::wstring
& wide
) {
33 return WideToUTF8(wide
);
36 std::wstring
SysNativeMBToWide(const StringPiece
& native_mb
) {
37 return SysUTF8ToWide(native_mb
);
42 std::string
SysWideToNativeMB(const std::wstring
& wide
) {
45 // Calculate the number of multi-byte characters. We walk through the string
46 // without writing the output, counting the number of multi-byte characters.
47 size_t num_out_chars
= 0;
48 memset(&ps
, 0, sizeof(ps
));
49 for (size_t i
= 0; i
< wide
.size(); ++i
) {
50 const wchar_t src
= wide
[i
];
51 // Use a temp buffer since calling wcrtomb with an output of NULL does not
52 // calculate the output length.
54 // Skip NULLs to avoid wcrtomb's special handling of them.
55 size_t res
= src
? wcrtomb(buf
, src
, &ps
) : 0;
57 // Handle any errors and return an empty string.
58 case static_cast<size_t>(-1):
62 // We hit an embedded null byte, keep going.
71 if (num_out_chars
== 0)
75 out
.resize(num_out_chars
);
77 // We walk the input string again, with |i| tracking the index of the
78 // wide input, and |j| tracking the multi-byte output.
79 memset(&ps
, 0, sizeof(ps
));
80 for (size_t i
= 0, j
= 0; i
< wide
.size(); ++i
) {
81 const wchar_t src
= wide
[i
];
82 // We don't want wcrtomb to do its funkiness for embedded NULLs.
83 size_t res
= src
? wcrtomb(&out
[j
], src
, &ps
) : 0;
85 // Handle any errors and return an empty string.
86 case static_cast<size_t>(-1):
90 // We hit an embedded null byte, keep going.
91 ++j
; // Output is already zeroed.
102 std::wstring
SysNativeMBToWide(const StringPiece
& native_mb
) {
105 // Calculate the number of wide characters. We walk through the string
106 // without writing the output, counting the number of wide characters.
107 size_t num_out_chars
= 0;
108 memset(&ps
, 0, sizeof(ps
));
109 for (size_t i
= 0; i
< native_mb
.size(); ) {
110 const char* src
= native_mb
.data() + i
;
111 size_t res
= mbrtowc(NULL
, src
, native_mb
.size() - i
, &ps
);
113 // Handle any errors and return an empty string.
114 case static_cast<size_t>(-2):
115 case static_cast<size_t>(-1):
116 return std::wstring();
119 // We hit an embedded null byte, keep going.
120 i
+= 1; // Fall through.
128 if (num_out_chars
== 0)
129 return std::wstring();
132 out
.resize(num_out_chars
);
134 memset(&ps
, 0, sizeof(ps
)); // Clear the shift state.
135 // We walk the input string again, with |i| tracking the index of the
136 // multi-byte input, and |j| tracking the wide output.
137 for (size_t i
= 0, j
= 0; i
< native_mb
.size(); ++j
) {
138 const char* src
= native_mb
.data() + i
;
139 wchar_t* dst
= &out
[j
];
140 size_t res
= mbrtowc(dst
, src
, native_mb
.size() - i
, &ps
);
142 // Handle any errors and return an empty string.
143 case static_cast<size_t>(-2):
144 case static_cast<size_t>(-1):
145 return std::wstring();
148 i
+= 1; // Skip null byte.
159 #endif // OS_CHROMEOS