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 <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 = NULL) 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);
    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      */
    227     String8 appendPathCopy(const char* leaf) const
    228                                              { String8 p(*this); p.appendPath(leaf); return p; }
    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.
    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 
    259 inline int strictly_order_type(const String8& lhs, const String8& rhs)
    260 {
    261     return compare_type(lhs, rhs) < 0;
    262 }
    263 
    264 inline const String8 String8::empty() {
    265     return String8();
    266 }
    267 
    268 inline const char* String8::c_str() const
    269 {
    270     return mString;
    271 }
    272 inline const char* String8::string() const
    273 {
    274     return mString;
    275 }
    276 
    277 inline std::string String8::std_string(const String8& str)
    278 {
    279     return std::string(str.string());
    280 }
    281 
    282 inline size_t String8::size() const
    283 {
    284     return length();
    285 }
    286 
    287 inline bool String8::isEmpty() const
    288 {
    289     return length() == 0;
    290 }
    291 
    292 inline size_t String8::bytes() const
    293 {
    294     return length();
    295 }
    296 
    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 
    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