Rietveld Code Review Tool
Help | Bug tracker | Discussion group | Source code

Side by Side Diff: compiled/String.h

Issue 29333474: Issue 4125 - [emscripten] Convert filter classes to C++ (Closed)
Patch Set: Addressed comments, made String class slightly more sane, slightly cleaned up bindings.cpp Created Feb. 2, 2016, 5:48 p.m.
Left:
Right:
Use n/p to move between diff chunks; N/P to move between comments.
Jump to:
View unified diff | Download patch
« no previous file with comments | « compiled/RegExpFilter.cpp ('k') | compiled/StringMap.h » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
(Empty)
1 #ifndef ADBLOCK_PLUS_STRING_H
2 #define ADBLOCK_PLUS_STRING_H
3
4 #include <cstddef>
5 #include <cstring>
6 #include <algorithm>
7
8 #include "debug.h"
9
10 inline void String_assert_readonly(bool readOnly);
11
12 class String
13 {
14 public:
15 typedef char16_t value_type;
16 typedef size_t size_type;
17
18 // Type flags, stored in the top 2 bits of the mLen member
19 static constexpr size_type OWNBUFFER = 0xC0000000;
20 static constexpr size_type INVALID = 0x80000000;
21 static constexpr size_type DELETED = 0x40000000;
22 static constexpr size_type DEPENDENT = 0x00000000;
23
24 // Read-only flag (for debug asserts only)
25 static constexpr size_type READ_ONLY = 0x20000000;
26 static constexpr size_type READ_WRITE = 0x00000000;
27
28 static constexpr size_type FLAGS_MASK = 0xE0000000;
29 static constexpr size_type LENGTH_MASK = 0x1FFFFFFF;
30
31 static constexpr size_type npos = -1;
32
33 private:
34 value_type* mBuf;
35 size_type mLen;
36
37 value_type* allocate(size_type len)
38 {
39 if (len)
40 return new value_type[len];
41 else
42 return nullptr;
43 }
44
45 void resize(size_type newLength, bool copy)
46 {
47 bool owningOldBuffer = owns_buffer();
48 size_type oldLength = length();
49 value_type* oldBuffer = mBuf;
50
51 newLength &= LENGTH_MASK;
52 mBuf = allocate(newLength);
53 annotate_address(mBuf, "String");
54 mLen = OWNBUFFER | READ_WRITE | newLength;
55
56 if (copy && oldLength)
57 memcpy(mBuf, oldBuffer, sizeof(value_type) * std::min(oldLength, newLength ));
58 if (owningOldBuffer)
59 delete[] oldBuffer;
60 }
61
62 public:
63 String() : mBuf(nullptr), mLen(INVALID) {}
64
65 String(size_type len)
66 : mBuf(allocate(len & LENGTH_MASK)),
67 mLen(OWNBUFFER | READ_WRITE | (len & LENGTH_MASK))
68 {
69 annotate_address(mBuf, "String");
70 }
71
72 String(value_type* buf, size_type len)
73 : mBuf(buf), mLen(DEPENDENT | READ_WRITE | (buf ? len & LENGTH_MASK: 0))
74 {
75 }
76
77 String(const value_type* buf, size_type len)
78 : mBuf(const_cast<value_type*>(buf)),
79 mLen(DEPENDENT | READ_ONLY | (buf ? len & LENGTH_MASK: 0))
80 {
81 }
82
83 String(String& str, size_type pos = 0, size_type len = npos)
84 : mBuf(str.mBuf + std::min(pos, str.length())),
85 mLen(DEPENDENT | READ_WRITE | std::min(len, str.length() - (mBuf - str.m Buf)))
86 {
87 }
88
89 String(const String& str, size_type pos = 0, size_type len = npos)
90 : mBuf(str.mBuf + std::min(pos, str.length())),
91 mLen(DEPENDENT | READ_ONLY | std::min(len, str.length() - (mBuf - str.mB uf)))
92 {
93 }
94
95 String(String&& str)
96 {
97 *this = std::move(str);
98 }
99
100 String(const char* source, size_type len)
101 : String(len)
102 {
103 for (size_type i = 0; i < len; i++)
104 mBuf[i] = source[i];
105 }
106
107 String& operator=(const String& str)
108 {
109 reset(str);
110 return *this;
111 }
112
113 String& operator=(String& str)
114 {
115 reset(str);
116 return *this;
117 }
118
119 String& operator=(String&& str)
120 {
121 mBuf = str.mBuf;
122 mLen = str.mLen;
123 str.mBuf = nullptr;
124 str.mLen = INVALID;
125 return *this;
126 }
127
128 ~String()
129 {
130 if (owns_buffer())
131 delete[] mBuf;
132 }
133
134 void reset(value_type* buf, size_type len)
135 {
136 mBuf = buf;
137 mLen = (DEPENDENT | READ_WRITE | (buf ? len & LENGTH_MASK: 0));
138 }
139
140 void reset(const value_type* buf, size_type len)
141 {
142 mBuf = const_cast<value_type*>(buf);
143 mLen = (DEPENDENT | READ_ONLY | (buf ? len & LENGTH_MASK: 0));
144 }
145
146 void reset(String& str, size_type pos = 0, size_type len = npos)
147 {
148 pos = std::min(pos, str.length());
149 len = std::min(len, str.length() - pos);
150 reset(str.mBuf + pos, len);
151 }
152
153 void reset(const String& str, size_type pos = 0, size_type len = npos)
154 {
155 pos = std::min(pos, str.length());
156 len = std::min(len, str.length() - pos);
157 reset(const_cast<const value_type*>(str.mBuf + pos), len);
158 }
159
160 size_type length() const
161 {
162 return mLen & LENGTH_MASK;
163 }
164
165 bool empty() const
166 {
167 return !(mLen & LENGTH_MASK);
168 }
169
170 const value_type* data() const
171 {
172 return mBuf;
173 }
174
175 value_type* data()
176 {
177 String_assert_readonly(mLen & READ_ONLY);
178 return mBuf;
179 }
180
181 const value_type& operator[](size_type pos) const
182 {
183 return mBuf[pos];
184 }
185
186 value_type& operator[](size_type pos)
187 {
188 String_assert_readonly(mLen & READ_ONLY);
189 return mBuf[pos];
190 }
191
192 bool equals(const String& other) const
193 {
194 if (length() != other.length())
195 return false;
196
197 return memcmp(mBuf, other.mBuf, sizeof(value_type) * length()) == 0;
198 }
199
200 size_type find(value_type c, size_type pos = 0) const
201 {
202 for (size_type i = pos; i < length(); ++i)
203 if (mBuf[i] == c)
204 return i;
205 return npos;
206 }
207
208 size_type find(const String& str, size_type pos = 0) const
209 {
210 if (!str.length())
211 return pos;
212
213 if (length() - pos < str.length())
214 return npos;
215
216 for (; pos < length() - str.length(); ++pos)
217 {
218 if (mBuf[pos] == str[0] &&
219 memcmp(mBuf + pos, str.mBuf, sizeof(value_type) * str.length()) == 0)
220 {
221 return pos;
222 }
223 }
224
225 return npos;
226 }
227
228 size_type rfind(value_type c, size_type pos = npos) const
229 {
230 if (length() == 0)
231 return npos;
232
233 if (pos == npos)
234 pos = length() - 1;
235
236 for (int i = pos; i >= 0; --i)
237 if (mBuf[i] == c)
238 return i;
239 return npos;
240 }
241
242 void append(const value_type* source, size_type sourceLen)
243 {
244 if (!sourceLen)
245 return;
246
247 size_t oldLength = length();
248 resize(oldLength + sourceLen, true);
249 memcpy(mBuf + oldLength, source, sizeof(value_type) * sourceLen);
250 }
251
252 void append(const String& str)
253 {
254 append(str.mBuf, str.length());
255 }
256
257 void append(value_type c)
258 {
259 append(&c, 1);
260 }
261
262 bool owns_buffer() const
263 {
264 return mBuf && (mLen & FLAGS_MASK) == OWNBUFFER;
265 }
266
267 String& ensure_own_buffer()
268 {
269 size_type len = length();
270 if (len && !owns_buffer())
271 resize(len, true);
272 return *this;
273 }
274
275 bool is_dependent() const
276 {
277 return (mLen & FLAGS_MASK) == DEPENDENT;
278 }
279
280 bool is_invalid() const
281 {
282 return (mLen & FLAGS_MASK) == INVALID;
283 }
284
285 bool is_deleted() const
286 {
287 return (mLen & FLAGS_MASK) == DELETED;
288 }
289 };
290
291 inline String operator "" _str(const String::value_type* str,
292 String::size_type len)
293 {
294 return String(const_cast<String::value_type*>(str), len);
295 }
296
297 inline void String_assert_readonly(bool readOnly)
298 {
299 assert(!readOnly, u"Writing access to a read-only string"_str);
300 }
301
302 #endif
OLDNEW
« no previous file with comments | « compiled/RegExpFilter.cpp ('k') | compiled/StringMap.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld