Skia
2D Graphics Library
SkString.h
Go to the documentation of this file.
1 /*
2  * Copyright 2006 The Android Open Source Project
3  *
4  * Use of this source code is governed by a BSD-style license that can be
5  * found in the LICENSE file.
6  */
7 
8 #ifndef SkString_DEFINED
9 #define SkString_DEFINED
10 
11 #include "include/core/SkRefCnt.h"
12 #include "include/core/SkScalar.h"
13 #include "include/core/SkTypes.h"
14 #include "include/private/SkMalloc.h"
15 #include "include/private/SkTArray.h"
16 #include "include/private/SkTo.h"
17 
18 #include <stdarg.h>
19 #include <string.h>
20 #include <atomic>
21 #include <string>
22 
23 /* Some helper functions for C strings */
24 static inline bool SkStrStartsWith(const char string[], const char prefixStr[]) {
25  SkASSERT(string);
26  SkASSERT(prefixStr);
27  return !strncmp(string, prefixStr, strlen(prefixStr));
28 }
29 static inline bool SkStrStartsWith(const char string[], const char prefixChar) {
30  SkASSERT(string);
31  return (prefixChar == *string);
32 }
33 
34 bool SkStrEndsWith(const char string[], const char suffixStr[]);
35 bool SkStrEndsWith(const char string[], const char suffixChar);
36 
37 int SkStrStartsWithOneOf(const char string[], const char prefixes[]);
38 
39 static inline int SkStrFind(const char string[], const char substring[]) {
40  const char *first = strstr(string, substring);
41  if (nullptr == first) return -1;
42  return SkToInt(first - &string[0]);
43 }
44 
45 static inline int SkStrFindLastOf(const char string[], const char subchar) {
46  const char* last = strrchr(string, subchar);
47  if (nullptr == last) return -1;
48  return SkToInt(last - &string[0]);
49 }
50 
51 static inline bool SkStrContains(const char string[], const char substring[]) {
52  SkASSERT(string);
53  SkASSERT(substring);
54  return (-1 != SkStrFind(string, substring));
55 }
56 static inline bool SkStrContains(const char string[], const char subchar) {
57  SkASSERT(string);
58  char tmp[2];
59  tmp[0] = subchar;
60  tmp[1] = '\0';
61  return (-1 != SkStrFind(string, tmp));
62 }
63 
64 /*
65  * The SkStrAppend... methods will write into the provided buffer, assuming it is large enough.
66  * Each method has an associated const (e.g. kSkStrAppendU32_MaxSize) which will be the largest
67  * value needed for that method's buffer.
68  *
69  * char storage[kSkStrAppendU32_MaxSize];
70  * SkStrAppendU32(storage, value);
71  *
72  * Note : none of the SkStrAppend... methods write a terminating 0 to their buffers. Instead,
73  * the methods return the ptr to the end of the written part of the buffer. This can be used
74  * to compute the length, and/or know where to write a 0 if that is desired.
75  *
76  * char storage[kSkStrAppendU32_MaxSize + 1];
77  * char* stop = SkStrAppendU32(storage, value);
78  * size_t len = stop - storage;
79  * *stop = 0; // valid, since storage was 1 byte larger than the max.
80  */
81 
82 static constexpr int kSkStrAppendU32_MaxSize = 10;
83 char* SkStrAppendU32(char buffer[], uint32_t);
84 static constexpr int kSkStrAppendU64_MaxSize = 20;
85 char* SkStrAppendU64(char buffer[], uint64_t, int minDigits);
86 
88 char* SkStrAppendS32(char buffer[], int32_t);
90 char* SkStrAppendS64(char buffer[], int64_t, int minDigits);
91 
99 static constexpr int kSkStrAppendScalar_MaxSize = 15;
100 
108 char* SkStrAppendScalar(char buffer[], SkScalar);
109 
117 public:
119  explicit SkString(size_t len);
120  explicit SkString(const char text[]);
121  SkString(const char text[], size_t len);
124  explicit SkString(const std::string&);
126 
127  bool isEmpty() const { return 0 == fRec->fLength; }
128  size_t size() const { return (size_t) fRec->fLength; }
129  const char* c_str() const { return fRec->data(); }
130  char operator[](size_t n) const { return this->c_str()[n]; }
131 
132  bool equals(const SkString&) const;
133  bool equals(const char text[]) const;
134  bool equals(const char text[], size_t len) const;
135 
136  bool startsWith(const char prefixStr[]) const {
137  return SkStrStartsWith(fRec->data(), prefixStr);
138  }
139  bool startsWith(const char prefixChar) const {
140  return SkStrStartsWith(fRec->data(), prefixChar);
141  }
142  bool endsWith(const char suffixStr[]) const {
143  return SkStrEndsWith(fRec->data(), suffixStr);
144  }
145  bool endsWith(const char suffixChar) const {
146  return SkStrEndsWith(fRec->data(), suffixChar);
147  }
148  bool contains(const char substring[]) const {
149  return SkStrContains(fRec->data(), substring);
150  }
151  bool contains(const char subchar) const {
152  return SkStrContains(fRec->data(), subchar);
153  }
154  int find(const char substring[]) const {
155  return SkStrFind(fRec->data(), substring);
156  }
157  int findLastOf(const char subchar) const {
158  return SkStrFindLastOf(fRec->data(), subchar);
159  }
160 
161  friend bool operator==(const SkString& a, const SkString& b) {
162  return a.equals(b);
163  }
164  friend bool operator!=(const SkString& a, const SkString& b) {
165  return !a.equals(b);
166  }
167 
168  // these methods edit the string
169 
172  SkString& operator=(const char text[]);
173 
174  char* writable_str();
175  char& operator[](size_t n) { return this->writable_str()[n]; }
176 
177  void reset();
181  void resize(size_t len);
182  void set(const SkString& src) { *this = src; }
183  void set(const char text[]);
184  void set(const char text[], size_t len);
185 
186  void insert(size_t offset, const SkString& src) { this->insert(offset, src.c_str(), src.size()); }
187  void insert(size_t offset, const char text[]);
188  void insert(size_t offset, const char text[], size_t len);
189  void insertUnichar(size_t offset, SkUnichar);
190  void insertS32(size_t offset, int32_t value);
191  void insertS64(size_t offset, int64_t value, int minDigits = 0);
192  void insertU32(size_t offset, uint32_t value);
193  void insertU64(size_t offset, uint64_t value, int minDigits = 0);
194  void insertHex(size_t offset, uint32_t value, int minDigits = 0);
195  void insertScalar(size_t offset, SkScalar);
196 
197  void append(const SkString& str) { this->insert((size_t)-1, str); }
198  void append(const char text[]) { this->insert((size_t)-1, text); }
199  void append(const char text[], size_t len) { this->insert((size_t)-1, text, len); }
200  void appendUnichar(SkUnichar uni) { this->insertUnichar((size_t)-1, uni); }
201  void appendS32(int32_t value) { this->insertS32((size_t)-1, value); }
202  void appendS64(int64_t value, int minDigits = 0) { this->insertS64((size_t)-1, value, minDigits); }
203  void appendU32(uint32_t value) { this->insertU32((size_t)-1, value); }
204  void appendU64(uint64_t value, int minDigits = 0) { this->insertU64((size_t)-1, value, minDigits); }
205  void appendHex(uint32_t value, int minDigits = 0) { this->insertHex((size_t)-1, value, minDigits); }
206  void appendScalar(SkScalar value) { this->insertScalar((size_t)-1, value); }
207 
208  void prepend(const SkString& str) { this->insert(0, str); }
209  void prepend(const char text[]) { this->insert(0, text); }
210  void prepend(const char text[], size_t len) { this->insert(0, text, len); }
211  void prependUnichar(SkUnichar uni) { this->insertUnichar(0, uni); }
212  void prependS32(int32_t value) { this->insertS32(0, value); }
213  void prependS64(int32_t value, int minDigits = 0) { this->insertS64(0, value, minDigits); }
214  void prependHex(uint32_t value, int minDigits = 0) { this->insertHex(0, value, minDigits); }
215  void prependScalar(SkScalar value) { this->insertScalar((size_t)-1, value); }
216 
217  void printf(const char format[], ...) SK_PRINTF_LIKE(2, 3);
218  void printVAList(const char format[], va_list);
219  void appendf(const char format[], ...) SK_PRINTF_LIKE(2, 3);
220  void appendVAList(const char format[], va_list);
221  void prependf(const char format[], ...) SK_PRINTF_LIKE(2, 3);
222  void prependVAList(const char format[], va_list);
223 
224  void remove(size_t offset, size_t length);
225 
226  SkString& operator+=(const SkString& s) { this->append(s); return *this; }
227  SkString& operator+=(const char text[]) { this->append(text); return *this; }
228  SkString& operator+=(const char c) { this->append(&c, 1); return *this; }
229 
234  void swap(SkString& other);
235 
236 private:
237  struct Rec {
238  public:
239  constexpr Rec(uint32_t len, int32_t refCnt) : fLength(len), fRefCnt(refCnt) {}
240  static sk_sp<Rec> Make(const char text[], size_t len);
241  char* data() { return &fBeginningOfData; }
242  const char* data() const { return &fBeginningOfData; }
243  void ref() const;
244  void unref() const;
245  bool unique() const;
246 
247  uint32_t fLength; // logically size_t, but we want it to stay 32 bits
248  mutable std::atomic<int32_t> fRefCnt;
249  char fBeginningOfData = '\0';
250 
251  private:
252  // Ensure the unsized delete is called.
253  void operator delete(void* p) { ::operator delete(p); }
254  };
255  sk_sp<Rec> fRec;
256 
257 #ifdef SK_DEBUG
258  const SkString& validate() const;
259 #else
260  const SkString& validate() const { return *this; }
261 #endif
262 
263  static const Rec gEmptyRec;
264 };
265 
267 SkString SkStringPrintf(const char* format, ...) SK_PRINTF_LIKE(1, 2);
270 static inline SkString SkStringPrintf() { return SkString(); }
271 
272 static inline void swap(SkString& a, SkString& b) {
273  a.swap(b);
274 }
275 
277  // Strictly return all results. If the input is ",," and the separator is ',' this will return
278  // an array of three empty strings.
280 
281  // Only nonempty results will be added to the results. Multiple separators will be
282  // coalesced. Separators at the beginning and end of the input will be ignored. If the input is
283  // ",," and the separator is ',', this will return an empty vector.
285 };
286 
287 // Split str on any characters in delimiters into out. (Think, strtok with a sane API.)
288 void SkStrSplit(const char* str, const char* delimiters, SkStrSplitMode splitMode,
289  SkTArray<SkString>* out);
290 inline void SkStrSplit(const char* str, const char* delimiters, SkTArray<SkString>* out) {
291  SkStrSplit(str, delimiters, kCoalesce_SkStrSplitMode, out);
292 }
293 
294 #endif
kSkStrAppendU32_MaxSize
static constexpr int kSkStrAppendU32_MaxSize
Definition: SkString.h:82
SkString::writable_str
char * writable_str()
SkString::endsWith
bool endsWith(const char suffixStr[]) const
Definition: SkString.h:142
SkString::prepend
void prepend(const char text[])
Definition: SkString.h:209
SkString::equals
bool equals(const char text[], size_t len) const
SkString::appendHex
void appendHex(uint32_t value, int minDigits=0)
Definition: SkString.h:205
SkStrFind
static int SkStrFind(const char string[], const char substring[])
Definition: SkString.h:39
SkString::operator=
SkString & operator=(const SkString &)
SkString::insert
void insert(size_t offset, const char text[], size_t len)
SkTypes.h
SkString::set
void set(const char text[])
SkString::set
void set(const SkString &src)
Definition: SkString.h:182
SkString::contains
bool contains(const char subchar) const
Definition: SkString.h:151
SkString::insertS32
void insertS32(size_t offset, int32_t value)
SkStrStartsWith
static bool SkStrStartsWith(const char string[], const char prefixStr[])
Definition: SkString.h:24
kCoalesce_SkStrSplitMode
@ kCoalesce_SkStrSplitMode
Definition: SkString.h:284
SkString::printf
void printf(const char format[],...) SK_PRINTF_LIKE(2
SkString::~SkString
~SkString()
SkString::insertUnichar
void insertUnichar(size_t offset, SkUnichar)
kSkStrAppendS64_MaxSize
static constexpr int kSkStrAppendS64_MaxSize
Definition: SkString.h:89
SkString::contains
bool contains(const char substring[]) const
Definition: SkString.h:148
swap
static void swap(SkString &a, SkString &b)
Definition: SkString.h:272
SkString::append
void append(const char text[], size_t len)
Definition: SkString.h:199
SkStrEndsWith
bool SkStrEndsWith(const char string[], const char suffixStr[])
SK_PRINTF_LIKE
#define SK_PRINTF_LIKE(A, B)
Definition: SkTypes.h:375
SkString::operator==
friend bool operator==(const SkString &a, const SkString &b)
Definition: SkString.h:161
SkRefCnt.h
SkStrContains
static bool SkStrContains(const char string[], const char substring[])
Definition: SkString.h:51
SkString::operator[]
char & operator[](size_t n)
Definition: SkString.h:175
SkString::findLastOf
int findLastOf(const char subchar) const
Definition: SkString.h:157
SkStrAppendU32
char * SkStrAppendU32(char buffer[], uint32_t)
SkString::insertU32
void insertU32(size_t offset, uint32_t value)
SkScalar.h
SkString::operator+=
SkString & operator+=(const char c)
Definition: SkString.h:228
sk_sp< Rec >
SkString::append
void append(const SkString &str)
Definition: SkString.h:197
kStrict_SkStrSplitMode
@ kStrict_SkStrSplitMode
Definition: SkString.h:279
SkString::prependScalar
void prependScalar(SkScalar value)
Definition: SkString.h:215
SkString::operator[]
char operator[](size_t n) const
Definition: SkString.h:130
SkString::size
size_t size() const
Definition: SkString.h:128
SkString::appendS32
void appendS32(int32_t value)
Definition: SkString.h:201
SkString::SkString
SkString(const std::string &)
SK_API
#define SK_API
Definition: SkTypes.h:181
SkASSERT
#define SkASSERT(cond)
Definition: SkTypes.h:460
SkString::SkString
SkString(const char text[], size_t len)
SkStrAppendS32
char * SkStrAppendS32(char buffer[], int32_t)
SkString::appendScalar
void appendScalar(SkScalar value)
Definition: SkString.h:206
SkString::SkString
SkString(SkString &&)
SkStrFindLastOf
static int SkStrFindLastOf(const char string[], const char subchar)
Definition: SkString.h:45
SkString::insert
void insert(size_t offset, const char text[])
SkString::appendS64
void appendS64(int64_t value, int minDigits=0)
Definition: SkString.h:202
SkString::insert
void insert(size_t offset, const SkString &src)
Definition: SkString.h:186
SkStrStartsWithOneOf
int SkStrStartsWithOneOf(const char string[], const char prefixes[])
SkStrAppendScalar
char * SkStrAppendScalar(char buffer[], SkScalar)
Write the scalar in decimal format into buffer, and return a pointer to the next char after the last ...
SkString::swap
void swap(SkString &other)
Swap contents between this and other.
SkString::insertU64
void insertU64(size_t offset, uint64_t value, int minDigits=0)
SkScalar
float SkScalar
Definition: SkScalar.h:16
SkString::SkString
SkString(const SkString &)
kSkStrAppendScalar_MaxSize
static constexpr int kSkStrAppendScalar_MaxSize
Floats have at most 8 significant digits, so we limit our g to that.
Definition: SkString.h:99
SkUnichar
int32_t SkUnichar
32 bit integer to hold a unicode value
Definition: SkTypes.h:552
kSkStrAppendU64_MaxSize
static constexpr int kSkStrAppendU64_MaxSize
Definition: SkString.h:84
SkStrSplit
void SkStrSplit(const char *str, const char *delimiters, SkStrSplitMode splitMode, SkTArray< SkString > *out)
SkString::operator=
SkString & operator=(SkString &&)
SkString::SkString
SkString(const char text[])
SkString::resize
void resize(size_t len)
String contents are preserved on resize.
SkString::isEmpty
bool isEmpty() const
Definition: SkString.h:127
SkString::prependS64
void prependS64(int32_t value, int minDigits=0)
Definition: SkString.h:213
SkString::insertHex
void insertHex(size_t offset, uint32_t value, int minDigits=0)
SkStringPrintf
SkString SkStringPrintf(const char *format,...) SK_PRINTF_LIKE(1
Creates a new string and writes into it using a printf()-style format.
SkStrAppendU64
char * SkStrAppendU64(char buffer[], uint64_t, int minDigits)
SkString::prependUnichar
void prependUnichar(SkUnichar uni)
Definition: SkString.h:211
SkStrAppendS64
char * SkStrAppendS64(char buffer[], int64_t, int minDigits)
SkString::set
void set(const char text[], size_t len)
SkString::insertScalar
void insertScalar(size_t offset, SkScalar)
SkString::SkString
SkString(size_t len)
SkString::c_str
const char * c_str() const
Definition: SkString.h:129
SkString::startsWith
bool startsWith(const char prefixChar) const
Definition: SkString.h:139
SkString
Definition: SkString.h:116
SkBlurDrawLooper::Make
sk_sp< SkDrawLooper > SK_API Make(SkColor4f color, SkColorSpace *cs, SkScalar sigma, SkScalar dx, SkScalar dy)
SkString::endsWith
bool endsWith(const char suffixChar) const
Definition: SkString.h:145
SkString::equals
bool equals(const char text[]) const
SkString::operator=
SkString & operator=(const char text[])
SkString::startsWith
bool startsWith(const char prefixStr[]) const
Definition: SkString.h:136
SkString::find
int find(const char substring[]) const
Definition: SkString.h:154
SkString::prepend
void prepend(const char text[], size_t len)
Definition: SkString.h:210
SkString::prepend
void prepend(const SkString &str)
Definition: SkString.h:208
kSkStrAppendS32_MaxSize
static constexpr int kSkStrAppendS32_MaxSize
Definition: SkString.h:87
SkStrSplitMode
SkStrSplitMode
Definition: SkString.h:276
SkString::appendU32
void appendU32(uint32_t value)
Definition: SkString.h:203
SkString::operator!=
friend bool operator!=(const SkString &a, const SkString &b)
Definition: SkString.h:164
SkString::equals
bool equals(const SkString &) const
SkString::prependHex
void prependHex(uint32_t value, int minDigits=0)
Definition: SkString.h:214
SkString::prependS32
void prependS32(int32_t value)
Definition: SkString.h:212
SkString::operator+=
SkString & operator+=(const char text[])
Definition: SkString.h:227
SkString::reset
void reset()
SkString::appendUnichar
void appendUnichar(SkUnichar uni)
Definition: SkString.h:200
SkString::append
void append(const char text[])
Definition: SkString.h:198
SkString::SkString
SkString()
SkString::insertS64
void insertS64(size_t offset, int64_t value, int minDigits=0)
SkString::appendU64
void appendU64(uint64_t value, int minDigits=0)
Definition: SkString.h:204