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