• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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