• 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_STRING8_H
18 #define ANDROID_STRING8_H
19 
20 #include <iostream>
21 
22 #include <utils/Errors.h>
23 #include <utils/Unicode.h>
24 #include <utils/TypeHelpers.h>
25 
26 #include <string.h> // for strcmp
27 #include <stdarg.h>
28 
29 #if __has_include(<string>)
30 #include <string>
31 #define HAS_STRING
32 #endif
33 
34 #if __has_include(<string_view>)
35 #include <string_view>
36 #define HAS_STRING_VIEW
37 #endif
38 
39 #if __cplusplus >= 202002L
40 #include <compare>
41 #endif
42 
43 // ---------------------------------------------------------------------------
44 
45 namespace android {
46 
47 class String16;
48 
49 // DO NOT USE: please use std::string
50 
51 //! This is a string holding UTF-8 characters. Does not allow the value more
52 // than 0x10FFFF, which is not valid unicode codepoint.
53 class String8
54 {
55 public:
56                                 String8();
57                                 String8(const String8& o);
58     explicit                    String8(const char* o);
59     explicit                    String8(const char* o, size_t numChars);
60 
61     explicit                    String8(const String16& o);
62     explicit                    String8(const char16_t* o);
63     explicit                    String8(const char16_t* o, size_t numChars);
64     explicit                    String8(const char32_t* o);
65     explicit                    String8(const char32_t* o, size_t numChars);
66                                 ~String8();
67 
68     static String8              format(const char* fmt, ...) __attribute__((format (printf, 1, 2)));
69     static String8              formatV(const char* fmt, va_list args);
70 
71     inline  const char*         c_str() const;
72 
73     inline  size_t              size() const;
74     inline  size_t              bytes() const;
75     inline  bool                empty() const;
76 
77             size_t              length() const;
78 
79             void                clear();
80 
81             void                setTo(const String8& other);
82             status_t            setTo(const char* other);
83             status_t            setTo(const char* other, size_t numChars);
84             status_t            setTo(const char16_t* other, size_t numChars);
85             status_t            setTo(const char32_t* other,
86                                       size_t length);
87 
88             status_t            append(const String8& other);
89             status_t            append(const char* other);
90             status_t            append(const char* other, size_t numChars);
91 
92             status_t            appendFormat(const char* fmt, ...)
93                     __attribute__((format (printf, 2, 3)));
94             status_t            appendFormatV(const char* fmt, va_list args);
95 
96     inline  String8&            operator=(const String8& other);
97     inline  String8&            operator=(const char* other);
98 
99     inline  String8&            operator+=(const String8& other);
100     inline  String8             operator+(const String8& other) const;
101 
102     inline  String8&            operator+=(const char* other);
103     inline  String8             operator+(const char* other) const;
104 
105     inline  int                 compare(const String8& other) const;
106 
107     inline  bool                operator<(const String8& other) const;
108     inline  bool                operator<=(const String8& other) const;
109     inline  bool                operator==(const String8& other) const;
110     inline  bool                operator!=(const String8& other) const;
111     inline  bool                operator>=(const String8& other) const;
112     inline  bool                operator>(const String8& other) const;
113 #if __cplusplus >= 202002L
114     inline std::strong_ordering operator<=>(const String8& other) const;
115 #endif
116 
117     inline  bool                operator<(const char* other) const;
118     inline  bool                operator<=(const char* other) const;
119     inline  bool                operator==(const char* other) const;
120     inline  bool                operator!=(const char* other) const;
121     inline  bool                operator>=(const char* other) const;
122     inline  bool                operator>(const char* other) const;
123 #if __cplusplus >= 202002L
124     inline std::strong_ordering operator<=>(const char* other) const;
125 #endif
126 
127     inline                      operator const char*() const;
128 
129 #ifdef HAS_STRING_VIEW
130     inline explicit             operator std::string_view() const;
131 #endif
132 
133             char*               lockBuffer(size_t size);
134             void                unlockBuffer();
135             status_t            unlockBuffer(size_t size);
136 
137             // return the index of the first byte of other in this at or after
138             // start, or -1 if not found
139             ssize_t             find(const char* other, size_t start = 0) const;
140     inline  ssize_t             find(const String8& other, size_t start = 0) const;
141 
142             // return true if this string contains the specified substring
143     inline  bool                contains(const char* other) const;
144     inline  bool                contains(const String8& other) const;
145 
146             // removes all occurrence of the specified substring
147             // returns true if any were found and removed
148             bool                removeAll(const char* other);
149     inline  bool                removeAll(const String8& other);
150 
151             void                toLower();
152 
153 private:
154             String8 getPathDir(void) const;
155             String8 getPathExtension(void) const;
156 
157             status_t            real_append(const char* other, size_t numChars);
158 
159             const char* mString;
160 
161 // These symbols are for potential backward compatibility with prebuilts. To be removed.
162 #ifdef ENABLE_STRING8_OBSOLETE_METHODS
163 public:
164 #else
165 private:
166 #endif
167     inline  const char*         string() const;
168     inline  bool                isEmpty() const;
169 };
170 
171 // String8 can be trivially moved using memcpy() because moving does not
172 // require any change to the underlying SharedBuffer contents or reference count.
173 ANDROID_TRIVIAL_MOVE_TRAIT(String8)
174 
175 static inline std::ostream& operator<<(std::ostream& os, const String8& str) {
176     os << str.c_str();
177     return os;
178 }
179 
180 // ---------------------------------------------------------------------------
181 // No user servicable parts below.
182 
compare_type(const String8 & lhs,const String8 & rhs)183 inline int compare_type(const String8& lhs, const String8& rhs)
184 {
185     return lhs.compare(rhs);
186 }
187 
strictly_order_type(const String8 & lhs,const String8 & rhs)188 inline int strictly_order_type(const String8& lhs, const String8& rhs)
189 {
190     return compare_type(lhs, rhs) < 0;
191 }
192 
c_str()193 inline const char* String8::c_str() const
194 {
195     return mString;
196 }
string()197 inline const char* String8::string() const
198 {
199     return mString;
200 }
201 
size()202 inline size_t String8::size() const
203 {
204     return length();
205 }
206 
empty()207 inline bool String8::empty() const
208 {
209     return length() == 0;
210 }
211 
isEmpty()212 inline bool String8::isEmpty() const
213 {
214     return length() == 0;
215 }
216 
bytes()217 inline size_t String8::bytes() const
218 {
219     return length();
220 }
221 
find(const String8 & other,size_t start)222 inline ssize_t String8::find(const String8& other, size_t start) const
223 {
224     return find(other.c_str(), start);
225 }
226 
contains(const char * other)227 inline bool String8::contains(const char* other) const
228 {
229     return find(other) >= 0;
230 }
231 
contains(const String8 & other)232 inline bool String8::contains(const String8& other) const
233 {
234     return contains(other.c_str());
235 }
236 
removeAll(const String8 & other)237 inline bool String8::removeAll(const String8& other)
238 {
239     return removeAll(other.c_str());
240 }
241 
242 inline String8& String8::operator=(const String8& other)
243 {
244     setTo(other);
245     return *this;
246 }
247 
248 inline String8& String8::operator=(const char* other)
249 {
250     setTo(other);
251     return *this;
252 }
253 
254 inline String8& String8::operator+=(const String8& other)
255 {
256     append(other);
257     return *this;
258 }
259 
260 inline String8 String8::operator+(const String8& other) const
261 {
262     String8 tmp(*this);
263     tmp += other;
264     return tmp;
265 }
266 
267 inline String8& String8::operator+=(const char* other)
268 {
269     append(other);
270     return *this;
271 }
272 
273 inline String8 String8::operator+(const char* other) const
274 {
275     String8 tmp(*this);
276     tmp += other;
277     return tmp;
278 }
279 
compare(const String8 & other)280 inline int String8::compare(const String8& other) const
281 {
282     return strcmp(mString, other.mString);
283 }
284 
285 inline bool String8::operator<(const String8& other) const
286 {
287     return strcmp(mString, other.mString) < 0;
288 }
289 
290 inline bool String8::operator<=(const String8& other) const
291 {
292     return strcmp(mString, other.mString) <= 0;
293 }
294 
295 inline bool String8::operator==(const String8& other) const
296 {
297     return strcmp(mString, other.mString) == 0;
298 }
299 
300 inline bool String8::operator!=(const String8& other) const
301 {
302     return strcmp(mString, other.mString) != 0;
303 }
304 
305 inline bool String8::operator>=(const String8& other) const
306 {
307     return strcmp(mString, other.mString) >= 0;
308 }
309 
310 inline bool String8::operator>(const String8& other) const
311 {
312     return strcmp(mString, other.mString) > 0;
313 }
314 
315 #if __cplusplus >= 202002L
316 inline std::strong_ordering String8::operator<=>(const String8& other) const {
317     int result = strcmp(mString, other.mString);
318     if (result == 0) {
319         return std::strong_ordering::equal;
320     } else if (result < 0) {
321         return std::strong_ordering::less;
322     } else {
323         return std::strong_ordering::greater;
324     }
325 }
326 #endif
327 
328 inline bool String8::operator<(const char* other) const
329 {
330     return strcmp(mString, other) < 0;
331 }
332 
333 inline bool String8::operator<=(const char* other) const
334 {
335     return strcmp(mString, other) <= 0;
336 }
337 
338 inline bool String8::operator==(const char* other) const
339 {
340     return strcmp(mString, other) == 0;
341 }
342 
343 inline bool String8::operator!=(const char* other) const
344 {
345     return strcmp(mString, other) != 0;
346 }
347 
348 inline bool String8::operator>=(const char* other) const
349 {
350     return strcmp(mString, other) >= 0;
351 }
352 
353 inline bool String8::operator>(const char* other) const
354 {
355     return strcmp(mString, other) > 0;
356 }
357 
358 #if __cplusplus >= 202002L
359 inline std::strong_ordering String8::operator<=>(const char* other) const {
360     int result = strcmp(mString, other);
361     if (result == 0) {
362         return std::strong_ordering::equal;
363     } else if (result < 0) {
364         return std::strong_ordering::less;
365     } else {
366         return std::strong_ordering::greater;
367     }
368 }
369 #endif
370 
371 inline String8::operator const char*() const
372 {
373     return mString;
374 }
375 
376 #ifdef HAS_STRING_VIEW
string_view()377 inline String8::operator std::string_view() const
378 {
379     return {mString, length()};
380 }
381 #endif
382 
383 }  // namespace android
384 
385 // ---------------------------------------------------------------------------
386 
387 #undef HAS_STRING
388 #undef HAS_STRING_VIEW
389 
390 #endif // ANDROID_STRING8_H
391