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