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