• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 // Copyright (C) 2015 The Android Open Source Project
2 //
3 // Licensed under the Apache License, Version 2.0 (the "License");
4 // you may not use this file except in compliance with the License.
5 // You may obtain a copy of the License at
6 //
7 // http://www.apache.org/licenses/LICENSE-2.0
8 //
9 // Unless required by applicable law or agreed to in writing, software
10 // distributed under the License is distributed on an "AS IS" BASIS,
11 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 // See the License for the specific language governing permissions and
13 // limitations under the License.
14 
15 #pragma once
16 
17 #ifndef _WIN32
18 // this file is just empty on non-Win32
19 #else  // _WIN32
20 
21 #include "aemu/base/Compiler.h"
22 
23 #include <string>
24 
25 #include <wchar.h>
26 
27 namespace android {
28 namespace base {
29 
30 // Helper class used to model a Windows Unicode string, which stores
31 // text and file paths as a zero-terminated array of UTF-16 code points
32 // (at least since Windows Vista, before that the encoding was slightly
33 // different).
34 //
35 // This is very intentionally *not* a general purpose class. It should only
36 // be used to simplify conversions between the Win32 Unicode API and the
37 // rest of android::base which uses UTF-8 for all Unicode text.
38 class Win32UnicodeString {
39 public:
40     // Default constructor.
41     Win32UnicodeString();
42 
43     // Initialize a new instance from UTF-8 text at |str| of |len| bytes.
44     // This doesn't try to validate the input, i.e. on error, the instance's
45     // content is undefined.
46     Win32UnicodeString(const char* str, size_t len);
47 
48     // Initialize a new instance from an existing string instance |str|.
49     explicit Win32UnicodeString(const char* str);
50     explicit Win32UnicodeString(const std::string& str);
51 
52     // Initialize by reserving enough room for a string of |size| UTF-16
53     // codepoints.
54     explicit Win32UnicodeString(size_t size);
55 
56     // Initialize from a zero-terminated wchar_t array.
57     explicit Win32UnicodeString(const wchar_t* str);
58 
59     // Copy-constructor.
60     Win32UnicodeString(const Win32UnicodeString& other);
61 
62     // Destructor.
63     ~Win32UnicodeString();
64 
65     // Assignment operators.
66     Win32UnicodeString& operator=(const Win32UnicodeString& other);
67     Win32UnicodeString& operator=(const wchar_t* str);
68 
69     // Return pointer to first wchar_t in the string.
c_str()70     const wchar_t* c_str() const { return mStr ? mStr : L""; }
71 
72     // Return pointer to writable wchar_t array. This can never be NULL
73     // but no more than size() items should be accessed.
74     wchar_t* data();
75 
76     // Return size of the string, this is the number of UTF-16 code points
77     // stored by the string, which may be larger than the number of actual
78     // Unicode characters in it.
size()79     size_t size() const { return mSize; }
80 
81     // Convert to a string instance holding the corresponding UTF-8 text.
82     std::string toString() const;
83 
84     // Return n-th character from string.
85     wchar_t operator[](size_t index) const { return mStr[index]; }
86 
87     // Reset content from UTF-8 text at |str| or |len| bytes.
88     void reset(const char* str, size_t len);
89 
90     // Reset content from UTF-8 text at |str|.
91     void reset(const char* str);
92 
93     // Resize array.
94     void resize(size_t newSize);
95 
96     // Append at the end of a Win32UnicodeString.
97     void append(const wchar_t* other);
98     void append(const wchar_t* other, size_t len);
99     void append(const Win32UnicodeString& other);
100 
101     // Release the Unicode string array to the caller.
102     wchar_t* release();
103 
104     // Directly convert a Unicode string to UTF-8 text and back.
105     // |len| - input length. if set to -1, means the input is null-terminated
106     static std::string convertToUtf8(const wchar_t* str, int len = -1);
107 
108     ////////////////////////////////////////////////////////////////////////////
109     // Be careful when crossing this line. The following functions work with
110     // raw buffers of static length, and are much harder to use correctly.
111     // You've been warned
112     ////////////////////////////////////////////////////////////////////////////
113 
114     // Calculate the needed buffer size (in characters) to convert the |str|
115     // parameter either to or from UTF8
116     // |len| - size of the input. -1 means it is 0-terminated
117     // Return value is either the size of the buffer needed to convert the whole
118     // input of size |len|, or, if |len| is -1, the size needed to convert a
119     // zero-terminated string, including the terminator character, or negative -
120     // if the size can't be calculated
121     static int calcUtf8BufferLength(const wchar_t* str, int len = -1);
122     static int calcUtf16BufferLength(const char* str, int len = -1);
123 
124     // The following two functions convert |str| into the output buffer, instead
125     // of dynamically allocated class object.
126     // |str| - source string to convert, must be not null
127     // |len| - length of the source string, in chars; must be positive or -1.
128     //  -1 means 'the input is zero-terminated'. In that case output has to
129     //  be large enough to hold a zero character as well.
130     // |outStr| - the output buffer, must be not null
131     // |outLen| - the output buffer length, in chars; must be large enough to
132     //  hold the converted string. One can calculate the required length using
133     //  one of the getUtf<*>BufferLength() functions
134     //
135     // Returns a number of bytes written into the |outBuf|, or -1 on failure
136     //
137     // Note: you can't get the reason of the failure from this function call:
138     //  it could be bad input parameter (e.g. null buffer), too short output,
139     //  bad characters in the input string, even OS failure. So make sure
140     //  you do the call to getUtf<*>BufferLength() and all parameters are
141     //  correct - if you need to know the exact reason and not just "can't" one.
142     static int convertToUtf8(char* outStr, int outLen,
143                               const wchar_t* str, int len = -1);
144     static int convertFromUtf8(wchar_t* outStr, int outLen,
145                                 const char* str, int len = -1);
146 
147 private:
148     wchar_t* mStr;
149     size_t mSize;
150 };
151 
152 }  // namespace base
153 }  // namespace android
154 
155 #endif  // _WIN32
156