Skia
2DGraphicsLibrary
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Pages
SkString.h
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 "../private/SkTArray.h"
14 #include "SkScalar.h"
15 
16 #include <stdarg.h>
17 
18 /* Some helper functions for C strings
19 */
20 
21 static bool SkStrStartsWith(const char string[], const char prefixStr[]) {
22  SkASSERT(string);
23  SkASSERT(prefixStr);
24  return !strncmp(string, prefixStr, strlen(prefixStr));
25 }
26 static bool SkStrStartsWith(const char string[], const char prefixChar) {
27  SkASSERT(string);
28  return (prefixChar == *string);
29 }
30 
31 bool SkStrEndsWith(const char string[], const char suffixStr[]);
32 bool SkStrEndsWith(const char string[], const char suffixChar);
33 
34 int SkStrStartsWithOneOf(const char string[], const char prefixes[]);
35 
36 static int SkStrFind(const char string[], const char substring[]) {
37  const char *first = strstr(string, substring);
38  if (NULL == first) return -1;
39  return SkToInt(first - &string[0]);
40 }
41 
42 static int SkStrFindLastOf(const char string[], const char subchar) {
43  const char* last = strrchr(string, subchar);
44  if (NULL == last) return -1;
45  return SkToInt(last - &string[0]);
46 }
47 
48 static bool SkStrContains(const char string[], const char substring[]) {
49  SkASSERT(string);
50  SkASSERT(substring);
51  return (-1 != SkStrFind(string, substring));
52 }
53 static bool SkStrContains(const char string[], const char subchar) {
54  SkASSERT(string);
55  char tmp[2];
56  tmp[0] = subchar;
57  tmp[1] = '\0';
58  return (-1 != SkStrFind(string, tmp));
59 }
60 
61 static inline char *SkStrDup(const char string[]) {
62  char *ret = (char *) sk_malloc_throw(strlen(string)+1);
63  memcpy(ret,string,strlen(string)+1);
64  return ret;
65 }
66 
67 /*
68  * The SkStrAppend... methods will write into the provided buffer, assuming it is large enough.
69  * Each method has an associated const (e.g. SkStrAppendU32_MaxSize) which will be the largest
70  * value needed for that method's buffer.
71  *
72  * char storage[SkStrAppendU32_MaxSize];
73  * SkStrAppendU32(storage, value);
74  *
75  * Note : none of the SkStrAppend... methods write a terminating 0 to their buffers. Instead,
76  * the methods return the ptr to the end of the written part of the buffer. This can be used
77  * to compute the length, and/or know where to write a 0 if that is desired.
78  *
79  * char storage[SkStrAppendU32_MaxSize + 1];
80  * char* stop = SkStrAppendU32(storage, value);
81  * size_t len = stop - storage;
82  * *stop = 0; // valid, since storage was 1 byte larger than the max.
83  */
84 
85 #define SkStrAppendU32_MaxSize 10
86 char* SkStrAppendU32(char buffer[], uint32_t);
87 #define SkStrAppendU64_MaxSize 20
88 char* SkStrAppendU64(char buffer[], uint64_t, int minDigits);
89 
90 #define SkStrAppendS32_MaxSize (SkStrAppendU32_MaxSize + 1)
91 char* SkStrAppendS32(char buffer[], int32_t);
92 #define SkStrAppendS64_MaxSize (SkStrAppendU64_MaxSize + 1)
93 char* SkStrAppendS64(char buffer[], int64_t, int minDigits);
94 
102 #define SkStrAppendScalar_MaxSize 15
103 
111 #define SkStrAppendScalar SkStrAppendFloat
112 
113 char* SkStrAppendFloat(char buffer[], float);
114 
121 class SK_API SkString {
122 public:
123  SkString();
124  explicit SkString(size_t len);
125  explicit SkString(const char text[]);
126  SkString(const char text[], size_t len);
127  SkString(const SkString&);
128  SkString(SkString&&);
129  ~SkString();
130 
131  bool isEmpty() const { return 0 == fRec->fLength; }
132  size_t size() const { return (size_t) fRec->fLength; }
133  const char* c_str() const { return fRec->data(); }
134  char operator[](size_t n) const { return this->c_str()[n]; }
135 
136  bool equals(const SkString&) const;
137  bool equals(const char text[]) const;
138  bool equals(const char text[], size_t len) const;
139 
140  bool startsWith(const char prefixStr[]) const {
141  return SkStrStartsWith(fRec->data(), prefixStr);
142  }
143  bool startsWith(const char prefixChar) const {
144  return SkStrStartsWith(fRec->data(), prefixChar);
145  }
146  bool endsWith(const char suffixStr[]) const {
147  return SkStrEndsWith(fRec->data(), suffixStr);
148  }
149  bool endsWith(const char suffixChar) const {
150  return SkStrEndsWith(fRec->data(), suffixChar);
151  }
152  bool contains(const char substring[]) const {
153  return SkStrContains(fRec->data(), substring);
154  }
155  bool contains(const char subchar) const {
156  return SkStrContains(fRec->data(), subchar);
157  }
158  int find(const char substring[]) const {
159  return SkStrFind(fRec->data(), substring);
160  }
161  int findLastOf(const char subchar) const {
162  return SkStrFindLastOf(fRec->data(), subchar);
163  }
164 
165  friend bool operator==(const SkString& a, const SkString& b) {
166  return a.equals(b);
167  }
168  friend bool operator!=(const SkString& a, const SkString& b) {
169  return !a.equals(b);
170  }
171 
172  // these methods edit the string
173 
174  SkString& operator=(const SkString&);
175  SkString& operator=(SkString&&);
176  SkString& operator=(const char text[]);
177 
178  char* writable_str();
179  char& operator[](size_t n) { return this->writable_str()[n]; }
180 
181  void reset();
183  void resize(size_t len) { this->set(NULL, len); }
184  void set(const SkString& src) { *this = src; }
185  void set(const char text[]);
186  void set(const char text[], size_t len);
187  void setUTF16(const uint16_t[]);
188  void setUTF16(const uint16_t[], size_t len);
189 
190  void insert(size_t offset, const SkString& src) { this->insert(offset, src.c_str(), src.size()); }
191  void insert(size_t offset, const char text[]);
192  void insert(size_t offset, const char text[], size_t len);
193  void insertUnichar(size_t offset, SkUnichar);
194  void insertS32(size_t offset, int32_t value);
195  void insertS64(size_t offset, int64_t value, int minDigits = 0);
196  void insertU32(size_t offset, uint32_t value);
197  void insertU64(size_t offset, uint64_t value, int minDigits = 0);
198  void insertHex(size_t offset, uint32_t value, int minDigits = 0);
199  void insertScalar(size_t offset, SkScalar);
200 
201  void append(const SkString& str) { this->insert((size_t)-1, str); }
202  void append(const char text[]) { this->insert((size_t)-1, text); }
203  void append(const char text[], size_t len) { this->insert((size_t)-1, text, len); }
204  void appendUnichar(SkUnichar uni) { this->insertUnichar((size_t)-1, uni); }
205  void appendS32(int32_t value) { this->insertS32((size_t)-1, value); }
206  void appendS64(int64_t value, int minDigits = 0) { this->insertS64((size_t)-1, value, minDigits); }
207  void appendU32(uint32_t value) { this->insertU32((size_t)-1, value); }
208  void appendU64(uint64_t value, int minDigits = 0) { this->insertU64((size_t)-1, value, minDigits); }
209  void appendHex(uint32_t value, int minDigits = 0) { this->insertHex((size_t)-1, value, minDigits); }
210  void appendScalar(SkScalar value) { this->insertScalar((size_t)-1, value); }
211 
212  void prepend(const SkString& str) { this->insert(0, str); }
213  void prepend(const char text[]) { this->insert(0, text); }
214  void prepend(const char text[], size_t len) { this->insert(0, text, len); }
215  void prependUnichar(SkUnichar uni) { this->insertUnichar(0, uni); }
216  void prependS32(int32_t value) { this->insertS32(0, value); }
217  void prependS64(int32_t value, int minDigits = 0) { this->insertS64(0, value, minDigits); }
218  void prependHex(uint32_t value, int minDigits = 0) { this->insertHex(0, value, minDigits); }
219  void prependScalar(SkScalar value) { this->insertScalar((size_t)-1, value); }
220 
221  void printf(const char format[], ...) SK_PRINTF_LIKE(2, 3);
222  void appendf(const char format[], ...) SK_PRINTF_LIKE(2, 3);
223  void appendVAList(const char format[], va_list);
224  void prependf(const char format[], ...) SK_PRINTF_LIKE(2, 3);
225  void prependVAList(const char format[], va_list);
226 
227  void remove(size_t offset, size_t length);
228 
229  SkString& operator+=(const SkString& s) { this->append(s); return *this; }
230  SkString& operator+=(const char text[]) { this->append(text); return *this; }
231  SkString& operator+=(const char c) { this->append(&c, 1); return *this; }
232 
237  void swap(SkString& other);
238 
239 private:
240  struct Rec {
241  public:
242  uint32_t fLength; // logically size_t, but we want it to stay 32bits
243  int32_t fRefCnt;
244  char fBeginningOfData;
245 
246  char* data() { return &fBeginningOfData; }
247  const char* data() const { return &fBeginningOfData; }
248  };
249  Rec* fRec;
250 
251 #ifdef SK_DEBUG
252  void validate() const;
253 #else
254  void validate() const {}
255 #endif
256 
257  static const Rec gEmptyRec;
258  static Rec* AllocRec(const char text[], size_t len);
259  static Rec* RefRec(Rec*);
260 };
261 
263 SkString SkStringPrintf(const char* format, ...);
264 
265 // Specialized to take advantage of SkString's fast swap path. The unspecialized function is
266 // declared in SkTypes.h and called by SkTSort.
267 template <> inline void SkTSwap(SkString& a, SkString& b) {
268  a.swap(b);
269 }
270 
271 enum SkStrSplitMode {
272  // Strictly return all results. If the input is ",," and the separator is ',' this will return
273  // an array of three empty strings.
274  kStrict_SkStrSplitMode,
275 
276  // Only nonempty results will be added to the results. Multiple separators will be
277  // coalesced. Separators at the beginning and end of the input will be ignored. If the input is
278  // ",," and the separator is ',', this will return an empty vector.
279  kCoalesce_SkStrSplitMode
280 };
281 
282 // Split str on any characters in delimiters into out. (Think, strtok with a sane API.)
283 void SkStrSplit(const char* str, const char* delimiters, SkStrSplitMode splitMode,
284  SkTArray<SkString>* out);
285 inline void SkStrSplit(const char* str, const char* delimiters, SkTArray<SkString>* out) {
286  SkStrSplit(str, delimiters, kCoalesce_SkStrSplitMode, out);
287 }
288 
289 #endif
Definition: SkString.h:240
void swap(SkString &other)
Swap contents between this and other.
int32_t SkUnichar
32 bit integer to hold a unicode value
Definition: SkTypes.h:295
void resize(size_t len)
Destructive resize, does not preserve contents.
Definition: SkString.h:183
Light weight class for managing strings.
Definition: SkString.h:121