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