• 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 <string> // for std::string
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 // ---------------------------------------------------------------------------
30 
31 namespace android {
32 
33 class String16;
34 
35 // DO NOT USE: please use std::string
36 
37 //! This is a string holding UTF-8 characters. Does not allow the value more
38 // than 0x10FFFF, which is not valid unicode codepoint.
39 class String8
40 {
41 public:
42     /* use String8(StaticLinkage) if you're statically linking against
43      * libutils and declaring an empty static String8, e.g.:
44      *
45      *   static String8 sAStaticEmptyString(String8::kEmptyString);
46      *   static String8 sAnotherStaticEmptyString(sAStaticEmptyString);
47      */
48     enum StaticLinkage { kEmptyString };
49 
50                                 String8();
51     explicit                    String8(StaticLinkage);
52                                 String8(const String8& o);
53     explicit                    String8(const char* o);
54     explicit                    String8(const char* o, size_t numChars);
55 
56     explicit                    String8(const String16& o);
57     explicit                    String8(const char16_t* o);
58     explicit                    String8(const char16_t* o, size_t numChars);
59     explicit                    String8(const char32_t* o);
60     explicit                    String8(const char32_t* o, size_t numChars);
61                                 ~String8();
62 
63     static inline const String8 empty();
64 
65     static String8              format(const char* fmt, ...) __attribute__((format (printf, 1, 2)));
66     static String8              formatV(const char* fmt, va_list args);
67 
68     inline  const char*         c_str() const;
69     inline  const char*         string() const;
70 
71 private:
72     static inline std::string   std_string(const String8& str);
73 public:
74 
75     inline  size_t              size() const;
76     inline  size_t              bytes() const;
77     inline  bool                isEmpty() const;
78 
79             size_t              length() const;
80 
81             void                clear();
82 
83             void                setTo(const String8& other);
84             status_t            setTo(const char* other);
85             status_t            setTo(const char* other, size_t numChars);
86             status_t            setTo(const char16_t* other, size_t numChars);
87             status_t            setTo(const char32_t* other,
88                                       size_t length);
89 
90             status_t            append(const String8& other);
91             status_t            append(const char* other);
92             status_t            append(const char* other, size_t numChars);
93 
94             status_t            appendFormat(const char* fmt, ...)
95                     __attribute__((format (printf, 2, 3)));
96             status_t            appendFormatV(const char* fmt, va_list args);
97 
98             // Note that this function takes O(N) time to calculate the value.
99             // No cache value is stored.
100             size_t              getUtf32Length() const;
101             int32_t             getUtf32At(size_t index,
102                                            size_t *next_index) const;
103             void                getUtf32(char32_t* dst) const;
104 
105     inline  String8&            operator=(const String8& other);
106     inline  String8&            operator=(const char* other);
107 
108     inline  String8&            operator+=(const String8& other);
109     inline  String8             operator+(const String8& other) const;
110 
111     inline  String8&            operator+=(const char* other);
112     inline  String8             operator+(const char* other) const;
113 
114     inline  int                 compare(const String8& other) const;
115 
116     inline  bool                operator<(const String8& other) const;
117     inline  bool                operator<=(const String8& other) const;
118     inline  bool                operator==(const String8& other) const;
119     inline  bool                operator!=(const String8& other) const;
120     inline  bool                operator>=(const String8& other) const;
121     inline  bool                operator>(const String8& other) const;
122 
123     inline  bool                operator<(const char* other) const;
124     inline  bool                operator<=(const char* other) const;
125     inline  bool                operator==(const char* other) const;
126     inline  bool                operator!=(const char* other) const;
127     inline  bool                operator>=(const char* other) const;
128     inline  bool                operator>(const char* other) const;
129 
130     inline                      operator const char*() const;
131 
132             char*               lockBuffer(size_t size);
133             void                unlockBuffer();
134             status_t            unlockBuffer(size_t size);
135 
136             // return the index of the first byte of other in this at or after
137             // start, or -1 if not found
138             ssize_t             find(const char* other, size_t start = 0) const;
139 
140             // return true if this string contains the specified substring
141     inline  bool                contains(const char* other) const;
142 
143             // removes all occurrence of the specified substring
144             // returns true if any were found and removed
145             bool                removeAll(const char* other);
146 
147             void                toLower();
148             void                toLower(size_t start, size_t numChars);
149             void                toUpper();
150             void                toUpper(size_t start, size_t numChars);
151 
152 
153     /*
154      * These methods operate on the string as if it were a path name.
155      */
156 
157     /*
158      * Set the filename field to a specific value.
159      *
160      * Normalizes the filename, removing a trailing '/' if present.
161      */
162     void setPathName(const char* name);
163     void setPathName(const char* name, size_t numChars);
164 
165     /*
166      * Get just the filename component.
167      *
168      * "/tmp/foo/bar.c" --> "bar.c"
169      */
170     String8 getPathLeaf(void) const;
171 
172     /*
173      * Remove the last (file name) component, leaving just the directory
174      * name.
175      *
176      * "/tmp/foo/bar.c" --> "/tmp/foo"
177      * "/tmp" --> "" // ????? shouldn't this be "/" ???? XXX
178      * "bar.c" --> ""
179      */
180     String8 getPathDir(void) const;
181 
182     /*
183      * Retrieve the front (root dir) component.  Optionally also return the
184      * remaining components.
185      *
186      * "/tmp/foo/bar.c" --> "tmp" (remain = "foo/bar.c")
187      * "/tmp" --> "tmp" (remain = "")
188      * "bar.c" --> "bar.c" (remain = "")
189      */
190     String8 walkPath(String8* outRemains = nullptr) const;
191 
192     /*
193      * Return the filename extension.  This is the last '.' and any number
194      * of characters that follow it.  The '.' is included in case we
195      * decide to expand our definition of what constitutes an extension.
196      *
197      * "/tmp/foo/bar.c" --> ".c"
198      * "/tmp" --> ""
199      * "/tmp/foo.bar/baz" --> ""
200      * "foo.jpeg" --> ".jpeg"
201      * "foo." --> ""
202      */
203     String8 getPathExtension(void) const;
204 
205     /*
206      * Return the path without the extension.  Rules for what constitutes
207      * an extension are described in the comment for getPathExtension().
208      *
209      * "/tmp/foo/bar.c" --> "/tmp/foo/bar"
210      */
211     String8 getBasePath(void) const;
212 
213     /*
214      * Add a component to the pathname.  We guarantee that there is
215      * exactly one path separator between the old path and the new.
216      * If there is no existing name, we just copy the new name in.
217      *
218      * If leaf is a fully qualified path (i.e. starts with '/', it
219      * replaces whatever was there before.
220      */
221     String8& appendPath(const char* leaf);
appendPath(const String8 & leaf)222     String8& appendPath(const String8& leaf)  { return appendPath(leaf.string()); }
223 
224     /*
225      * Like appendPath(), but does not affect this string.  Returns a new one instead.
226      */
appendPathCopy(const char * leaf)227     String8 appendPathCopy(const char* leaf) const
228                                              { String8 p(*this); p.appendPath(leaf); return p; }
appendPathCopy(const String8 & leaf)229     String8 appendPathCopy(const String8& leaf) const { return appendPathCopy(leaf.string()); }
230 
231     /*
232      * Converts all separators in this string to /, the default path separator.
233      *
234      * If the default OS separator is backslash, this converts all
235      * backslashes to slashes, in-place. Otherwise it does nothing.
236      * Returns self.
237      */
238     String8& convertToResPath();
239 
240 private:
241             status_t            real_append(const char* other, size_t numChars);
242             char*               find_extension(void) const;
243 
244             const char* mString;
245 };
246 
247 // String8 can be trivially moved using memcpy() because moving does not
248 // require any change to the underlying SharedBuffer contents or reference count.
ANDROID_TRIVIAL_MOVE_TRAIT(String8)249 ANDROID_TRIVIAL_MOVE_TRAIT(String8)
250 
251 // ---------------------------------------------------------------------------
252 // No user servicable parts below.
253 
254 inline int compare_type(const String8& lhs, const String8& rhs)
255 {
256     return lhs.compare(rhs);
257 }
258 
strictly_order_type(const String8 & lhs,const String8 & rhs)259 inline int strictly_order_type(const String8& lhs, const String8& rhs)
260 {
261     return compare_type(lhs, rhs) < 0;
262 }
263 
empty()264 inline const String8 String8::empty() {
265     return String8();
266 }
267 
c_str()268 inline const char* String8::c_str() const
269 {
270     return mString;
271 }
string()272 inline const char* String8::string() const
273 {
274     return mString;
275 }
276 
std_string(const String8 & str)277 inline std::string String8::std_string(const String8& str)
278 {
279     return std::string(str.string());
280 }
281 
size()282 inline size_t String8::size() const
283 {
284     return length();
285 }
286 
isEmpty()287 inline bool String8::isEmpty() const
288 {
289     return length() == 0;
290 }
291 
bytes()292 inline size_t String8::bytes() const
293 {
294     return length();
295 }
296 
contains(const char * other)297 inline bool String8::contains(const char* other) const
298 {
299     return find(other) >= 0;
300 }
301 
302 inline String8& String8::operator=(const String8& other)
303 {
304     setTo(other);
305     return *this;
306 }
307 
308 inline String8& String8::operator=(const char* other)
309 {
310     setTo(other);
311     return *this;
312 }
313 
314 inline String8& String8::operator+=(const String8& other)
315 {
316     append(other);
317     return *this;
318 }
319 
320 inline String8 String8::operator+(const String8& other) const
321 {
322     String8 tmp(*this);
323     tmp += other;
324     return tmp;
325 }
326 
327 inline String8& String8::operator+=(const char* other)
328 {
329     append(other);
330     return *this;
331 }
332 
333 inline String8 String8::operator+(const char* other) const
334 {
335     String8 tmp(*this);
336     tmp += other;
337     return tmp;
338 }
339 
compare(const String8 & other)340 inline int String8::compare(const String8& other) const
341 {
342     return strcmp(mString, other.mString);
343 }
344 
345 inline bool String8::operator<(const String8& other) const
346 {
347     return strcmp(mString, other.mString) < 0;
348 }
349 
350 inline bool String8::operator<=(const String8& other) const
351 {
352     return strcmp(mString, other.mString) <= 0;
353 }
354 
355 inline bool String8::operator==(const String8& other) const
356 {
357     return strcmp(mString, other.mString) == 0;
358 }
359 
360 inline bool String8::operator!=(const String8& other) const
361 {
362     return strcmp(mString, other.mString) != 0;
363 }
364 
365 inline bool String8::operator>=(const String8& other) const
366 {
367     return strcmp(mString, other.mString) >= 0;
368 }
369 
370 inline bool String8::operator>(const String8& other) const
371 {
372     return strcmp(mString, other.mString) > 0;
373 }
374 
375 inline bool String8::operator<(const char* other) const
376 {
377     return strcmp(mString, other) < 0;
378 }
379 
380 inline bool String8::operator<=(const char* other) const
381 {
382     return strcmp(mString, other) <= 0;
383 }
384 
385 inline bool String8::operator==(const char* other) const
386 {
387     return strcmp(mString, other) == 0;
388 }
389 
390 inline bool String8::operator!=(const char* other) const
391 {
392     return strcmp(mString, other) != 0;
393 }
394 
395 inline bool String8::operator>=(const char* other) const
396 {
397     return strcmp(mString, other) >= 0;
398 }
399 
400 inline bool String8::operator>(const char* other) const
401 {
402     return strcmp(mString, other) > 0;
403 }
404 
405 inline String8::operator const char*() const
406 {
407     return mString;
408 }
409 
410 }  // namespace android
411 
412 // ---------------------------------------------------------------------------
413 
414 #endif // ANDROID_STRING8_H
415