Left: | ||
Right: |
LEFT | RIGHT |
---|---|
1 #pragma once | 1 #pragma once |
2 | 2 |
3 #include <cstddef> | 3 #include <cstddef> |
4 #include <cstring> | 4 #include <cstring> |
5 #include <algorithm> | 5 #include <algorithm> |
6 | 6 |
7 #include <emscripten.h> | 7 #include <emscripten.h> |
8 | 8 |
9 #include "debug.h" | 9 #include "debug.h" |
10 | 10 |
(...skipping 16 matching lines...) Expand all Loading... | |
27 | 27 |
28 static constexpr size_type FLAGS_MASK = 0xC0000000; | 28 static constexpr size_type FLAGS_MASK = 0xC0000000; |
29 static constexpr size_type LENGTH_MASK = 0x3FFFFFFF; | 29 static constexpr size_type LENGTH_MASK = 0x3FFFFFFF; |
30 | 30 |
31 static constexpr size_type npos = -1; | 31 static constexpr size_type npos = -1; |
32 | 32 |
33 protected: | 33 protected: |
34 value_type* mBuf; | 34 value_type* mBuf; |
35 size_type mLen; | 35 size_type mLen; |
36 | 36 |
37 String(value_type* buf, size_type len, size_type flags) | 37 explicit String(value_type* buf, size_type len, size_type flags) |
38 : mBuf(buf), mLen((len & LENGTH_MASK) | flags) | 38 : mBuf(buf), mLen((len & LENGTH_MASK) | flags) |
39 { | 39 { |
40 } | 40 } |
41 | 41 |
42 ~String() | 42 ~String() |
43 { | 43 { |
44 } | 44 } |
45 | 45 |
46 void reset(value_type* buf, size_type len, size_type flags) | 46 void reset(value_type* buf, size_type len, size_type flags) |
47 { | 47 { |
(...skipping 92 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
140 bool is_invalid() const | 140 bool is_invalid() const |
141 { | 141 { |
142 return (mLen & FLAGS_MASK) == INVALID; | 142 return (mLen & FLAGS_MASK) == INVALID; |
143 } | 143 } |
144 | 144 |
145 bool is_deleted() const | 145 bool is_deleted() const |
146 { | 146 { |
147 return (mLen & FLAGS_MASK) == DELETED; | 147 return (mLen & FLAGS_MASK) == DELETED; |
148 } | 148 } |
149 | 149 |
150 void tolower() | 150 void toLower() |
sergei
2017/01/10 15:58:02
it seems to be consistent it should be to_lower or
Wladimir Palant
2017/03/13 17:42:15
Done.
| |
151 { | 151 { |
152 size_type len = length(); | 152 size_type len = length(); |
153 for (size_type i = 0; i < len; ++i) | 153 for (size_type i = 0; i < len; ++i) |
154 { | 154 { |
155 value_type currChar = mBuf[i]; | 155 value_type currChar = mBuf[i]; |
156 | 156 |
157 // This should be more efficient with a lookup table but I couldn't measur e | 157 // This should be more efficient with a lookup table but I couldn't measur e |
158 // any performance difference. | 158 // any performance difference. |
159 if (currChar >= u'A' && currChar <= u'Z') | 159 if (currChar >= u'A' && currChar <= u'Z') |
160 mBuf[i] = currChar + u'a' - u'A'; | 160 mBuf[i] = currChar + u'a' - u'A'; |
161 else if (currChar >= 128) | 161 else if (currChar >= 128) |
162 { | 162 { |
163 // It seems that calling JS it the easiest solution for lowercasing | 163 // It seems that calling JS is the easiest solution for lowercasing |
sergei
2017/01/10 15:57:54
typo: it -> is
Wladimir Palant
2017/03/13 17:42:20
Done.
| |
164 // Unicode characters. | 164 // Unicode characters. |
165 mBuf[i] = EM_ASM_INT({ | 165 mBuf[i] = EM_ASM_INT({ |
166 return String.fromCharCode($0).toLowerCase().charCodeAt(0); | 166 return String.fromCharCode($0).toLowerCase().charCodeAt(0); |
167 }, currChar); | 167 }, currChar); |
168 } | 168 } |
169 } | 169 } |
170 } | 170 } |
171 }; | 171 }; |
172 | 172 |
173 class DependentString : public String | 173 class DependentString : public String |
174 { | 174 { |
175 public: | 175 public: |
176 DependentString() | 176 explicit DependentString() |
177 : String(nullptr, 0, INVALID) | 177 : String(nullptr, 0, INVALID) |
178 { | 178 { |
179 } | 179 } |
180 | 180 |
181 DependentString(value_type* buf, size_type len) | 181 explicit DependentString(value_type* buf, size_type len) |
182 : String(buf, len, READ_WRITE) | 182 : String(buf, len, READ_WRITE) |
183 { | 183 { |
184 } | 184 } |
185 | 185 |
186 DependentString(const value_type* buf, size_type len) | 186 explicit DependentString(const value_type* buf, size_type len) |
187 : String(const_cast<value_type*>(buf), len, READ_ONLY) | 187 : String(const_cast<value_type*>(buf), len, READ_ONLY) |
188 { | 188 { |
189 } | 189 } |
190 | 190 |
191 explicit DependentString(String& str, size_type pos = 0, size_type len = npos) | 191 explicit DependentString(String& str, size_type pos = 0, size_type len = npos) |
192 : String( | 192 : String( |
193 str.mBuf + std::min(pos, str.length()), | 193 str.mBuf + std::min(pos, str.length()), |
194 std::min(len, str.length() - std::min(pos, str.length())), | 194 std::min(len, str.length() - std::min(pos, str.length())), |
195 str.is_readOnly() ? READ_ONLY : READ_WRITE | 195 str.is_readOnly() ? READ_ONLY : READ_WRITE |
196 ) | 196 ) |
(...skipping 44 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
241 } | 241 } |
242 | 242 |
243 inline void String_assert_readonly(bool readOnly) | 243 inline void String_assert_readonly(bool readOnly) |
244 { | 244 { |
245 assert(!readOnly, u"Writing access to a read-only string"_str); | 245 assert(!readOnly, u"Writing access to a read-only string"_str); |
246 } | 246 } |
247 | 247 |
248 class OwnedString : public String | 248 class OwnedString : public String |
249 { | 249 { |
250 private: | 250 private: |
251 value_type* allocate(size_type len) | 251 void grow(size_type additionalSize) |
252 { | |
253 OwnedString newValue(length() + additionalSize); | |
254 if (length() > 0) | |
255 std::memcpy(newValue.mBuf, mBuf, sizeof(value_type) * length()); | |
256 *this = std::move(newValue); | |
257 } | |
258 | |
259 public: | |
260 explicit OwnedString(size_type len = 0) | |
261 : String(nullptr, len, READ_WRITE) | |
252 { | 262 { |
253 if (len) | 263 if (len) |
254 return new value_type[len]; | 264 { |
265 mBuf = new value_type[length()]; | |
266 annotate_address(mBuf, "String"); | |
267 } | |
255 else | 268 else |
256 return nullptr; | 269 mBuf = nullptr; |
257 } | 270 } |
258 | 271 |
259 void grow(size_type additionalSize) | 272 explicit OwnedString(const String& str) |
260 { | |
261 size_type oldLength = length(); | |
sergei
2017/01/10 15:57:56
It seems it can be simplified to
auto newValue =
Wladimir Palant
2017/03/13 17:42:18
Done.
| |
262 size_type newLength = oldLength + additionalSize; | |
263 value_type* oldBuffer = mBuf; | |
264 | |
265 reset(nullptr, newLength, READ_WRITE); | |
266 newLength = length(); | |
267 mBuf = allocate(newLength); | |
268 annotate_address(mBuf, "String"); | |
269 | |
270 if (oldLength) | |
271 std::memcpy(mBuf, oldBuffer, sizeof(value_type) * oldLength); | |
272 if (oldBuffer) | |
273 delete[] oldBuffer; | |
274 } | |
275 | |
276 public: | |
277 OwnedString(size_type len = 0) | |
278 : String(nullptr, len, READ_WRITE) | |
279 { | |
280 mBuf = allocate(length()); | |
281 annotate_address(mBuf, "String"); | |
282 } | |
283 | |
284 OwnedString(const String& str) | |
285 : OwnedString(str.length()) | 273 : OwnedString(str.length()) |
286 { | 274 { |
287 if (length()) | 275 if (length()) |
288 std::memcpy(mBuf, str.mBuf, sizeof(value_type) * length()); | 276 std::memcpy(mBuf, str.mBuf, sizeof(value_type) * length()); |
289 } | 277 } |
290 | 278 |
291 OwnedString(const OwnedString& str) | 279 OwnedString(const OwnedString& str) |
292 : OwnedString(static_cast<const String&>(str)) | 280 : OwnedString(static_cast<const String&>(str)) |
293 { | 281 { |
294 } | 282 } |
295 | 283 |
296 OwnedString(const value_type* str, size_type len) | 284 explicit OwnedString(const value_type* str, size_type len) |
297 : OwnedString(DependentString(str, len)) | 285 : OwnedString(DependentString(str, len)) |
298 { | 286 { |
299 } | 287 } |
300 | 288 |
301 OwnedString(OwnedString&& str) | 289 explicit OwnedString(OwnedString&& str) |
302 : OwnedString(0) | 290 : OwnedString(0) |
303 { | 291 { |
304 mBuf = str.mBuf; | 292 mBuf = str.mBuf; |
305 mLen = str.mLen; | 293 mLen = str.mLen; |
306 str.mBuf = nullptr; | 294 str.mBuf = nullptr; |
307 str.mLen = READ_WRITE | 0; | 295 str.mLen = READ_WRITE | 0; |
308 } | 296 } |
309 | 297 |
310 ~OwnedString() | 298 ~OwnedString() |
311 { | 299 { |
312 if (mBuf) | 300 if (mBuf) |
313 delete[] mBuf; | 301 delete[] mBuf; |
314 } | 302 } |
315 | 303 |
316 OwnedString& operator=(const String& str) | 304 OwnedString& operator=(const String& str) |
317 { | 305 { |
318 *this = std::move(OwnedString(str)); | 306 *this = std::move(OwnedString(str)); |
319 return *this; | 307 return *this; |
320 } | 308 } |
321 | 309 |
322 OwnedString& operator=(const OwnedString& str) | 310 OwnedString& operator=(const OwnedString& str) |
323 { | 311 { |
324 *this = std::move(OwnedString(str)); | 312 *this = std::move(OwnedString(str)); |
325 return *this; | 313 return *this; |
326 } | 314 } |
327 | 315 |
328 OwnedString& operator=(OwnedString&& str) | 316 OwnedString& operator=(OwnedString&& str) |
sergei
2017/01/10 15:57:52
I don't know how I missed it before but it's incor
Wladimir Palant
2017/03/13 17:42:13
Done.
| |
329 { | 317 { |
330 mBuf = str.mBuf; | 318 std::swap(mBuf, str.mBuf); |
331 mLen = str.mLen; | 319 std::swap(mLen, str.mLen); |
332 str.mBuf = nullptr; | |
333 str.mLen = READ_WRITE | 0; | |
334 return *this; | 320 return *this; |
335 } | 321 } |
336 | 322 |
337 void append(const value_type* source, size_type sourceLen) | 323 void append(const value_type* source, size_type sourceLen) |
338 { | 324 { |
339 if (!sourceLen) | 325 if (!sourceLen) |
340 return; | 326 return; |
341 | 327 |
342 assert(source, u"Null buffer passed to OwnedString.append()"_str); | 328 assert(source, u"Null buffer passed to OwnedString.append()"_str); |
343 size_t oldLength = length(); | 329 size_t oldLength = length(); |
344 grow(sourceLen); | 330 grow(sourceLen); |
345 std::memcpy(mBuf + oldLength, source, sizeof(value_type) * sourceLen); | 331 std::memcpy(mBuf + oldLength, source, sizeof(value_type) * sourceLen); |
346 } | 332 } |
347 | 333 |
348 void append(const String& str) | 334 void append(const String& str) |
349 { | 335 { |
350 append(str.mBuf, str.length()); | 336 append(str.mBuf, str.length()); |
351 } | 337 } |
352 | 338 |
353 void append(value_type c) | 339 void append(value_type c) |
354 { | 340 { |
355 append(&c, 1); | 341 append(&c, 1); |
356 } | 342 } |
357 }; | 343 }; |
LEFT | RIGHT |