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