• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (C) 2005 The Android Open Source Project
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  *      http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16 
17 #ifndef ANDROID_STRING16_H
18 #define ANDROID_STRING16_H
19 
20 #include <iostream>
21 #include <string>
22 
23 #include <utils/Errors.h>
24 #include <utils/String8.h>
25 #include <utils/TypeHelpers.h>
26 
27 // ---------------------------------------------------------------------------
28 
29 namespace android {
30 
31 // ---------------------------------------------------------------------------
32 
33 template <size_t N>
34 class StaticString16;
35 
36 // DO NOT USE: please use std::u16string
37 
38 //! This is a string holding UTF-16 characters.
39 class String16
40 {
41 public:
42                                 String16();
43                                 String16(const String16& o);
44                                 String16(String16&& o) noexcept;
45                                 String16(const String16& o,
46                                          size_t len,
47                                          size_t begin=0);
48     explicit                    String16(const char16_t* o);
49     explicit                    String16(const char16_t* o, size_t len);
50     explicit                    String16(const String8& o);
51     explicit                    String16(const char* o);
52     explicit                    String16(const char* o, size_t len);
53 
54                                 ~String16();
55 
56     inline  const char16_t*     string() const;
57 
58 private:
59     static inline std::string   std_string(const String16& str);
60 public:
61             size_t              size() const;
62             void                setTo(const String16& other);
63             status_t            setTo(const char16_t* other);
64             status_t            setTo(const char16_t* other, size_t len);
65             status_t            setTo(const String16& other,
66                                       size_t len,
67                                       size_t begin=0);
68 
69             status_t            append(const String16& other);
70             status_t            append(const char16_t* other, size_t len);
71 
72     inline  String16&           operator=(const String16& other);
73             String16&           operator=(String16&& other) noexcept;
74 
75     inline  String16&           operator+=(const String16& other);
76     inline  String16            operator+(const String16& other) const;
77 
78             status_t            insert(size_t pos, const char16_t* chrs);
79             status_t            insert(size_t pos,
80                                        const char16_t* chrs, size_t len);
81 
82             ssize_t             findFirst(char16_t c) const;
83             ssize_t             findLast(char16_t c) const;
84 
85             bool                startsWith(const String16& prefix) const;
86             bool                startsWith(const char16_t* prefix) const;
87 
88             bool                contains(const char16_t* chrs) const;
89 
90             status_t            replaceAll(char16_t replaceThis,
91                                            char16_t withThis);
92 
93     inline  int                 compare(const String16& other) const;
94 
95     inline  bool                operator<(const String16& other) const;
96     inline  bool                operator<=(const String16& other) const;
97     inline  bool                operator==(const String16& other) const;
98     inline  bool                operator!=(const String16& other) const;
99     inline  bool                operator>=(const String16& other) const;
100     inline  bool                operator>(const String16& other) const;
101 
102     inline  bool                operator<(const char16_t* other) const;
103     inline  bool                operator<=(const char16_t* other) const;
104     inline  bool                operator==(const char16_t* other) const;
105     inline  bool                operator!=(const char16_t* other) const;
106     inline  bool                operator>=(const char16_t* other) const;
107     inline  bool                operator>(const char16_t* other) const;
108 
109     inline                      operator const char16_t*() const;
110 
111     // Static and non-static String16 behave the same for the users, so
112     // this method isn't of much use for the users. It is public for testing.
113             bool                isStaticString() const;
114 
115   private:
116     /*
117      * A flag indicating the type of underlying buffer.
118      */
119     static constexpr uint32_t kIsSharedBufferAllocated = 0x80000000;
120 
121     /*
122      * alloc() returns void* so that SharedBuffer class is not exposed.
123      */
124     static void* alloc(size_t size);
125     static char16_t* allocFromUTF8(const char* u8str, size_t u8len);
126     static char16_t* allocFromUTF16(const char16_t* u16str, size_t u16len);
127 
128     /*
129      * edit() and editResize() return void* so that SharedBuffer class
130      * is not exposed.
131      */
132     void* edit();
133     void* editResize(size_t new_size);
134 
135     void acquire();
136     void release();
137 
138     size_t staticStringSize() const;
139 
140     const char16_t* mString;
141 
142 protected:
143     /*
144      * Data structure used to allocate static storage for static String16.
145      *
146      * Note that this data structure and SharedBuffer are used interchangably
147      * as the underlying data structure for a String16.  Therefore, the layout
148      * of this data structure must match the part in SharedBuffer that is
149      * visible to String16.
150      */
151     template <size_t N>
152     struct StaticData {
153         // The high bit of 'size' is used as a flag.
154         static_assert(N - 1 < kIsSharedBufferAllocated, "StaticString16 too long!");
StaticDataStaticData155         constexpr StaticData() : size(N - 1), data{0} {}
156         const uint32_t size;
157         char16_t data[N];
158 
159         constexpr StaticData(const StaticData<N>&) = default;
160     };
161 
162     /*
163      * Helper function for constructing a StaticData object.
164      */
165     template <size_t N>
makeStaticData(const char16_t (& s)[N])166     static constexpr const StaticData<N> makeStaticData(const char16_t (&s)[N]) {
167         StaticData<N> r;
168         // The 'size' field is at the same location where mClientMetadata would
169         // be for a SharedBuffer.  We do NOT set kIsSharedBufferAllocated flag
170         // here.
171         for (size_t i = 0; i < N - 1; ++i) r.data[i] = s[i];
172         return r;
173     }
174 
175     template <size_t N>
String16(const StaticData<N> & s)176     explicit constexpr String16(const StaticData<N>& s) : mString(s.data) {}
177 };
178 
179 // String16 can be trivially moved using memcpy() because moving does not
180 // require any change to the underlying SharedBuffer contents or reference count.
181 ANDROID_TRIVIAL_MOVE_TRAIT(String16)
182 
183 static inline std::ostream& operator<<(std::ostream& os, const String16& str) {
184     os << String8(str);
185     return os;
186 }
187 
188 // ---------------------------------------------------------------------------
189 
190 /*
191  * A StaticString16 object is a specialized String16 object.  Instead of holding
192  * the string data in a ref counted SharedBuffer object, it holds data in a
193  * buffer within StaticString16 itself.  Note that this buffer is NOT ref
194  * counted and is assumed to be available for as long as there is at least a
195  * String16 object using it.  Therefore, one must be extra careful to NEVER
196  * assign a StaticString16 to a String16 that outlives the StaticString16
197  * object.
198  *
199  * THE SAFEST APPROACH IS TO USE StaticString16 ONLY AS GLOBAL VARIABLES.
200  *
201  * A StaticString16 SHOULD NEVER APPEAR IN APIs.  USE String16 INSTEAD.
202  */
203 template <size_t N>
204 class StaticString16 : public String16 {
205 public:
StaticString16(const char16_t (& s)[N])206     constexpr StaticString16(const char16_t (&s)[N]) : String16(mData), mData(makeStaticData(s)) {}
207 
StaticString16(const StaticString16<N> & other)208     constexpr StaticString16(const StaticString16<N>& other)
209         : String16(mData), mData(other.mData) {}
210 
211     constexpr StaticString16(const StaticString16<N>&&) = delete;
212 
213     // There is no reason why one would want to 'new' a StaticString16.  Delete
214     // it to discourage misuse.
215     static void* operator new(std::size_t) = delete;
216 
217 private:
218     const StaticData<N> mData;
219 };
220 
221 template <typename F>
222 StaticString16(const F&)->StaticString16<sizeof(F) / sizeof(char16_t)>;
223 
224 // ---------------------------------------------------------------------------
225 // No user servicable parts below.
226 
compare_type(const String16 & lhs,const String16 & rhs)227 inline int compare_type(const String16& lhs, const String16& rhs)
228 {
229     return lhs.compare(rhs);
230 }
231 
strictly_order_type(const String16 & lhs,const String16 & rhs)232 inline int strictly_order_type(const String16& lhs, const String16& rhs)
233 {
234     return compare_type(lhs, rhs) < 0;
235 }
236 
string()237 inline const char16_t* String16::string() const
238 {
239     return mString;
240 }
241 
std_string(const String16 & str)242 inline std::string String16::std_string(const String16& str)
243 {
244     return std::string(String8(str).string());
245 }
246 
247 inline String16& String16::operator=(const String16& other)
248 {
249     setTo(other);
250     return *this;
251 }
252 
253 inline String16& String16::operator+=(const String16& other)
254 {
255     append(other);
256     return *this;
257 }
258 
259 inline String16 String16::operator+(const String16& other) const
260 {
261     String16 tmp(*this);
262     tmp += other;
263     return tmp;
264 }
265 
compare(const String16 & other)266 inline int String16::compare(const String16& other) const
267 {
268     return strzcmp16(mString, size(), other.mString, other.size());
269 }
270 
271 inline bool String16::operator<(const String16& other) const
272 {
273     return strzcmp16(mString, size(), other.mString, other.size()) < 0;
274 }
275 
276 inline bool String16::operator<=(const String16& other) const
277 {
278     return strzcmp16(mString, size(), other.mString, other.size()) <= 0;
279 }
280 
281 inline bool String16::operator==(const String16& other) const
282 {
283     return strzcmp16(mString, size(), other.mString, other.size()) == 0;
284 }
285 
286 inline bool String16::operator!=(const String16& other) const
287 {
288     return strzcmp16(mString, size(), other.mString, other.size()) != 0;
289 }
290 
291 inline bool String16::operator>=(const String16& other) const
292 {
293     return strzcmp16(mString, size(), other.mString, other.size()) >= 0;
294 }
295 
296 inline bool String16::operator>(const String16& other) const
297 {
298     return strzcmp16(mString, size(), other.mString, other.size()) > 0;
299 }
300 
301 inline bool String16::operator<(const char16_t* other) const
302 {
303     return strcmp16(mString, other) < 0;
304 }
305 
306 inline bool String16::operator<=(const char16_t* other) const
307 {
308     return strcmp16(mString, other) <= 0;
309 }
310 
311 inline bool String16::operator==(const char16_t* other) const
312 {
313     return strcmp16(mString, other) == 0;
314 }
315 
316 inline bool String16::operator!=(const char16_t* other) const
317 {
318     return strcmp16(mString, other) != 0;
319 }
320 
321 inline bool String16::operator>=(const char16_t* other) const
322 {
323     return strcmp16(mString, other) >= 0;
324 }
325 
326 inline bool String16::operator>(const char16_t* other) const
327 {
328     return strcmp16(mString, other) > 0;
329 }
330 
331 inline String16::operator const char16_t*() const
332 {
333     return mString;
334 }
335 
336 }  // namespace android
337 
338 // ---------------------------------------------------------------------------
339 
340 #endif // ANDROID_STRING16_H
341