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