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 :
69 : bool isEmpty() const { return 0 == fRec->fLength; }
70 0 : size_t size() const { return (size_t) fRec->fLength; }
71 0 : 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 :
78 : bool startsWith(const char prefix[]) const {
79 : return SkStrStartsWith(fRec->data(), prefix);
80 : }
81 0 : bool endsWith(const char suffix[]) const {
82 0 : 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();
101 0 : void resize(size_t len) { this->set(NULL, len); }
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 :
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 :
117 : void append(const SkString& str) { this->insert((size_t)-1, str); }
118 0 : void append(const char text[]) { this->insert((size_t)-1, text); }
119 0 : void append(const char text[], size_t len) { this->insert((size_t)-1, text, len); }
120 : void appendUnichar(SkUnichar uni) { this->insertUnichar((size_t)-1, uni); }
121 0 : void appendS32(int32_t value) { this->insertS32((size_t)-1, value); }
122 0 : void appendS64(int64_t value, int minDigits = 0) { this->insertS64((size_t)-1, value, minDigits); }
123 0 : void appendHex(uint32_t value, int minDigits = 0) { this->insertHex((size_t)-1, value, minDigits); }
124 0 : void appendScalar(SkScalar value) { this->insertScalar((size_t)-1, value); }
125 :
126 : void prepend(const SkString& str) { this->insert(0, str); }
127 : void prepend(const char text[]) { this->insert(0, text); }
128 0 : void prepend(const char text[], size_t len) { this->insert(0, text, len); }
129 : void prependUnichar(SkUnichar uni) { this->insertUnichar(0, uni); }
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); }
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 :
158 0 : char* data() { return &fBeginningOfData; }
159 0 : 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
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 : */
182 : int count() const { return fCount; }
183 :
184 : /** This returns a null terminated ucs2 string
185 : */
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
|