Home | History | Annotate | Download | only in core
      1 
      2 /*
      3  * Copyright 2006 The Android Open Source Project
      4  *
      5  * Use of this source code is governed by a BSD-style license that can be
      6  * found in the LICENSE file.
      7  */
      8 
      9 
     10 #ifndef SkString_DEFINED
     11 #define SkString_DEFINED
     12 
     13 #include "SkScalar.h"
     14 
     15 /*  Some helper functions for C strings
     16 */
     17 
     18 bool SkStrStartsWith(const char string[], const char prefix[]);
     19 bool SkStrEndsWith(const char string[], const char suffix[]);
     20 int SkStrStartsWithOneOf(const char string[], const char prefixes[]);
     21 
     22 #define SkStrAppendS32_MaxSize  11
     23 char*   SkStrAppendS32(char buffer[], int32_t);
     24 #define SkStrAppendS64_MaxSize  20
     25 char*   SkStrAppendS64(char buffer[], int64_t, int minDigits);
     26 
     27 /**
     28  *  Floats have at most 8 significant digits, so we limit our %g to that.
     29  *  However, the total string could be 15 characters: -1.2345678e-005
     30  *
     31  *  In theory we should only expect up to 2 digits for the exponent, but on
     32  *  some platforms we have seen 3 (as in the example above).
     33  */
     34 #define SkStrAppendScalar_MaxSize  15
     35 
     36 /**
     37  *  Write the scaler in decimal format into buffer, and return a pointer to
     38  *  the next char after the last one written. Note: a terminating 0 is not
     39  *  written into buffer, which must be at least SkStrAppendScalar_MaxSize.
     40  *  Thus if the caller wants to add a 0 at the end, buffer must be at least
     41  *  SkStrAppendScalar_MaxSize + 1 bytes large.
     42  */
     43 #ifdef SK_SCALAR_IS_FLOAT
     44     #define SkStrAppendScalar SkStrAppendFloat
     45 #else
     46     #define SkStrAppendScalar SkStrAppendFixed
     47 #endif
     48 
     49 #ifdef SK_CAN_USE_FLOAT
     50 char* SkStrAppendFloat(char buffer[], float);
     51 #endif
     52 char* SkStrAppendFixed(char buffer[], SkFixed);
     53 
     54 /** \class SkString
     55 
     56     Light weight class for managing strings. Uses reference
     57     counting to make string assignments and copies very fast
     58     with no extra RAM cost. Assumes UTF8 encoding.
     59 */
     60 class SkString {
     61 public:
     62                 SkString();
     63     explicit    SkString(size_t len);
     64     explicit    SkString(const char text[]);
     65                 SkString(const char text[], size_t len);
     66                 SkString(const SkString&);
     67                 ~SkString();
     68 
     69     bool        isEmpty() const { return 0 == fRec->fLength; }
     70     size_t      size() const { return (size_t) fRec->fLength; }
     71     const char* c_str() const { return fRec->data(); }
     72     char operator[](size_t n) const { return this->c_str()[n]; }
     73 
     74     bool equals(const SkString&) const;
     75     bool equals(const char text[]) const;
     76     bool equals(const char text[], size_t len) const;
     77 
     78     bool startsWith(const char prefix[]) const {
     79         return SkStrStartsWith(fRec->data(), prefix);
     80     }
     81     bool endsWith(const char suffix[]) const {
     82         return SkStrEndsWith(fRec->data(), suffix);
     83     }
     84 
     85     friend bool operator==(const SkString& a, const SkString& b) {
     86         return a.equals(b);
     87     }
     88     friend bool operator!=(const SkString& a, const SkString& b) {
     89         return !a.equals(b);
     90     }
     91 
     92     // these methods edit the string
     93 
     94     SkString& operator=(const SkString&);
     95     SkString& operator=(const char text[]);
     96 
     97     char* writable_str();
     98     char& operator[](size_t n) { return this->writable_str()[n]; }
     99 
    100     void reset();
    101     void resize(size_t len) { this->set(NULL, len); }
    102     void set(const SkString& src) { *this = src; }
    103     void set(const char text[]);
    104     void set(const char text[], size_t len);
    105     void setUTF16(const uint16_t[]);
    106     void setUTF16(const uint16_t[], size_t len);
    107 
    108     void insert(size_t offset, const SkString& src) { this->insert(offset, src.c_str(), src.size()); }
    109     void insert(size_t offset, const char text[]);
    110     void insert(size_t offset, const char text[], size_t len);
    111     void insertUnichar(size_t offset, SkUnichar);
    112     void insertS32(size_t offset, int32_t value);
    113     void insertS64(size_t offset, int64_t value, int minDigits = 0);
    114     void insertHex(size_t offset, uint32_t value, int minDigits = 0);
    115     void insertScalar(size_t offset, SkScalar);
    116 
    117     void append(const SkString& str) { this->insert((size_t)-1, str); }
    118     void append(const char text[]) { this->insert((size_t)-1, text); }
    119     void append(const char text[], size_t len) { this->insert((size_t)-1, text, len); }
    120     void appendUnichar(SkUnichar uni) { this->insertUnichar((size_t)-1, uni); }
    121     void appendS32(int32_t value) { this->insertS32((size_t)-1, value); }
    122     void appendS64(int64_t value, int minDigits = 0) { this->insertS64((size_t)-1, value, minDigits); }
    123     void appendHex(uint32_t value, int minDigits = 0) { this->insertHex((size_t)-1, value, minDigits); }
    124     void appendScalar(SkScalar value) { this->insertScalar((size_t)-1, value); }
    125 
    126     void prepend(const SkString& str) { this->insert(0, str); }
    127     void prepend(const char text[]) { this->insert(0, text); }
    128     void prepend(const char text[], size_t len) { this->insert(0, text, len); }
    129     void prependUnichar(SkUnichar uni) { this->insertUnichar(0, uni); }
    130     void prependS32(int32_t value) { this->insertS32(0, value); }
    131     void prependS64(int32_t value, int minDigits = 0) { this->insertS64(0, value, minDigits); }
    132     void prependHex(uint32_t value, int minDigits = 0) { this->insertHex(0, value, minDigits); }
    133     void prependScalar(SkScalar value) { this->insertScalar((size_t)-1, value); }
    134 
    135     void printf(const char format[], ...);
    136     void appendf(const char format[], ...);
    137     void prependf(const char format[], ...);
    138 
    139     void remove(size_t offset, size_t length);
    140 
    141     SkString& operator+=(const SkString& s) { this->append(s); return *this; }
    142     SkString& operator+=(const char text[]) { this->append(text); return *this; }
    143     SkString& operator+=(const char c) { this->append(&c, 1); return *this; }
    144 
    145     /**
    146      *  Swap contents between this and other. This function is guaranteed
    147      *  to never fail or throw.
    148      */
    149     void swap(SkString& other);
    150 
    151 private:
    152     struct Rec {
    153     public:
    154         size_t      fLength;
    155         int32_t     fRefCnt;
    156         char        fBeginningOfData;
    157 
    158         char* data() { return &fBeginningOfData; }
    159         const char* data() const { return &fBeginningOfData; }
    160     };
    161     Rec* fRec;
    162 
    163 #ifdef SK_DEBUG
    164     const char* fStr;
    165     void validate() const;
    166 #else
    167     void validate() const {}
    168 #endif
    169 
    170     static const Rec gEmptyRec;
    171     static Rec* AllocRec(const char text[], size_t len);
    172     static Rec* RefRec(Rec*);
    173 };
    174 
    175 class SkAutoUCS2 {
    176 public:
    177     SkAutoUCS2(const char utf8[]);
    178     ~SkAutoUCS2();
    179 
    180     /** This returns the number of ucs2 characters
    181     */
    182     int count() const { return fCount; }
    183 
    184     /** This returns a null terminated ucs2 string
    185     */
    186     const uint16_t* getUCS2() const { return fUCS2; }
    187 
    188 private:
    189     int         fCount;
    190     uint16_t*   fUCS2;
    191 };
    192 
    193 /// Creates a new string and writes into it using a printf()-style format.
    194 SkString SkStringPrintf(const char* format, ...);
    195 
    196 #endif
    197