blob: 3ef56a3cfa8faa5106e4ff7a5004c8dbce93a103 [file] [log] [blame]
The Android Open Source Projectcbb10112009-03-03 19:31:44 -08001/*
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
Steven Moreland7a57b8a2020-02-10 14:18:45 -080020#include <iostream>
21#include <string>
Samuel Tan9ac4e002016-02-16 14:20:05 -080022
The Android Open Source Projectcbb10112009-03-03 19:31:44 -080023#include <utils/Errors.h>
Samuel Tan9ac4e002016-02-16 14:20:05 -080024#include <utils/String8.h>
Jeff Brown9a0a76d2012-03-16 14:45:49 -070025#include <utils/TypeHelpers.h>
The Android Open Source Projectcbb10112009-03-03 19:31:44 -080026
27// ---------------------------------------------------------------------------
28
The Android Open Source Projectcbb10112009-03-03 19:31:44 -080029namespace android {
30
Kenny Root9a2d83e2009-12-04 09:38:48 -080031// ---------------------------------------------------------------------------
32
Vic Yang9fb93ed2019-09-05 13:18:27 -070033template <size_t N>
34class StaticString16;
35
Steven Morelandb8f152d2017-12-18 16:14:13 -080036// DO NOT USE: please use std::u16string
37
The Android Open Source Projectcbb10112009-03-03 19:31:44 -080038//! This is a string holding UTF-16 characters.
39class String16
40{
41public:
42 String16();
43 String16(const String16& o);
Jooyung Han98b396e2021-06-27 03:30:42 +090044 String16(String16&& o) noexcept;
The Android Open Source Projectcbb10112009-03-03 19:31:44 -080045 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();
Samuel Tanf9d16ef2016-02-16 15:17:10 -080055
The Android Open Source Projectcbb10112009-03-03 19:31:44 -080056 inline const char16_t* string() const;
Samuel Tanf9d16ef2016-02-16 15:17:10 -080057
Steven Moreland2aac3352017-03-10 22:31:08 -080058private:
Samuel Tan9ac4e002016-02-16 14:20:05 -080059 static inline std::string std_string(const String16& str);
Steven Moreland2aac3352017-03-10 22:31:08 -080060public:
Sergio Girod2529f22015-09-23 16:22:59 +010061 size_t size() const;
The Android Open Source Projectcbb10112009-03-03 19:31:44 -080062 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);
Samuel Tanf9d16ef2016-02-16 15:17:10 -080068
The Android Open Source Projectcbb10112009-03-03 19:31:44 -080069 status_t append(const String16& other);
70 status_t append(const char16_t* other, size_t len);
Samuel Tanf9d16ef2016-02-16 15:17:10 -080071
The Android Open Source Projectcbb10112009-03-03 19:31:44 -080072 inline String16& operator=(const String16& other);
Jooyung Han98b396e2021-06-27 03:30:42 +090073 String16& operator=(String16&& other) noexcept;
Samuel Tanf9d16ef2016-02-16 15:17:10 -080074
The Android Open Source Projectcbb10112009-03-03 19:31:44 -080075 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;
Samuel Tanf9d16ef2016-02-16 15:17:10 -080087
Michael Wright5bacef32016-05-09 14:43:31 +010088 bool contains(const char16_t* chrs) const;
89
The Android Open Source Projectcbb10112009-03-03 19:31:44 -080090 status_t replaceAll(char16_t replaceThis,
91 char16_t withThis);
92
The Android Open Source Projectcbb10112009-03-03 19:31:44 -080093 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;
Samuel Tanf9d16ef2016-02-16 15:17:10 -0800101
The Android Open Source Projectcbb10112009-03-03 19:31:44 -0800102 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;
Samuel Tanf9d16ef2016-02-16 15:17:10 -0800108
The Android Open Source Projectcbb10112009-03-03 19:31:44 -0800109 inline operator const char16_t*() const;
Samuel Tanf9d16ef2016-02-16 15:17:10 -0800110
Vic Yang9fb93ed2019-09-05 13:18:27 -0700111 // 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
142protected:
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!");
155 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>
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>
176 explicit constexpr String16(const StaticData<N>& s) : mString(s.data) {}
The Android Open Source Projectcbb10112009-03-03 19:31:44 -0800177};
178
Jeff Brown9a0a76d2012-03-16 14:45:49 -0700179// String16 can be trivially moved using memcpy() because moving does not
180// require any change to the underlying SharedBuffer contents or reference count.
181ANDROID_TRIVIAL_MOVE_TRAIT(String16)
182
Steven Moreland7a57b8a2020-02-10 14:18:45 -0800183static inline std::ostream& operator<<(std::ostream& os, const String16& str) {
Steven Morelandb1d31612020-02-25 17:59:34 -0800184 os << String8(str);
Steven Moreland7a57b8a2020-02-10 14:18:45 -0800185 return os;
186}
187
The Android Open Source Projectcbb10112009-03-03 19:31:44 -0800188// ---------------------------------------------------------------------------
Vic Yang9fb93ed2019-09-05 13:18:27 -0700189
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 */
203template <size_t N>
204class StaticString16 : public String16 {
205public:
206 constexpr StaticString16(const char16_t (&s)[N]) : String16(mData), mData(makeStaticData(s)) {}
207
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
217private:
218 const StaticData<N> mData;
219};
220
221template <typename F>
222StaticString16(const F&)->StaticString16<sizeof(F) / sizeof(char16_t)>;
223
224// ---------------------------------------------------------------------------
The Android Open Source Projectcbb10112009-03-03 19:31:44 -0800225// No user servicable parts below.
226
227inline int compare_type(const String16& lhs, const String16& rhs)
228{
229 return lhs.compare(rhs);
230}
231
232inline int strictly_order_type(const String16& lhs, const String16& rhs)
233{
234 return compare_type(lhs, rhs) < 0;
235}
236
237inline const char16_t* String16::string() const
238{
239 return mString;
240}
241
Samuel Tan9ac4e002016-02-16 14:20:05 -0800242inline std::string String16::std_string(const String16& str)
243{
244 return std::string(String8(str).string());
245}
246
The Android Open Source Projectcbb10112009-03-03 19:31:44 -0800247inline String16& String16::operator=(const String16& other)
248{
249 setTo(other);
250 return *this;
251}
252
253inline String16& String16::operator+=(const String16& other)
254{
255 append(other);
256 return *this;
257}
258
259inline String16 String16::operator+(const String16& other) const
260{
Josiah Gaskin9ee3fc42011-08-16 15:16:04 -0700261 String16 tmp(*this);
The Android Open Source Projectcbb10112009-03-03 19:31:44 -0800262 tmp += other;
263 return tmp;
264}
265
266inline int String16::compare(const String16& other) const
267{
268 return strzcmp16(mString, size(), other.mString, other.size());
269}
270
271inline bool String16::operator<(const String16& other) const
272{
273 return strzcmp16(mString, size(), other.mString, other.size()) < 0;
274}
275
276inline bool String16::operator<=(const String16& other) const
277{
278 return strzcmp16(mString, size(), other.mString, other.size()) <= 0;
279}
280
281inline bool String16::operator==(const String16& other) const
282{
Brad Fitzpatrick9d589aa2010-10-20 17:06:28 -0700283 return strzcmp16(mString, size(), other.mString, other.size()) == 0;
The Android Open Source Projectcbb10112009-03-03 19:31:44 -0800284}
285
286inline bool String16::operator!=(const String16& other) const
287{
288 return strzcmp16(mString, size(), other.mString, other.size()) != 0;
289}
290
291inline bool String16::operator>=(const String16& other) const
292{
293 return strzcmp16(mString, size(), other.mString, other.size()) >= 0;
294}
295
296inline bool String16::operator>(const String16& other) const
297{
298 return strzcmp16(mString, size(), other.mString, other.size()) > 0;
299}
300
301inline bool String16::operator<(const char16_t* other) const
302{
303 return strcmp16(mString, other) < 0;
304}
305
306inline bool String16::operator<=(const char16_t* other) const
307{
308 return strcmp16(mString, other) <= 0;
309}
310
311inline bool String16::operator==(const char16_t* other) const
312{
313 return strcmp16(mString, other) == 0;
314}
315
316inline bool String16::operator!=(const char16_t* other) const
317{
318 return strcmp16(mString, other) != 0;
319}
320
321inline bool String16::operator>=(const char16_t* other) const
322{
323 return strcmp16(mString, other) >= 0;
324}
325
326inline bool String16::operator>(const char16_t* other) const
327{
328 return strcmp16(mString, other) > 0;
329}
330
331inline String16::operator const char16_t*() const
332{
333 return mString;
334}
335
Pirama Arumuga Nainareab48ce2018-04-10 14:31:29 -0700336} // namespace android
The Android Open Source Projectcbb10112009-03-03 19:31:44 -0800337
338// ---------------------------------------------------------------------------
339
340#endif // ANDROID_STRING16_H