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