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