LMMS
Loading...
Searching...
No Matches
CharPointer_UTF8.h
Go to the documentation of this file.
1/*
2 ==============================================================================
3
4 This file is part of the Water library.
5 Copyright (c) 2016 ROLI Ltd.
6 Copyright (C) 2017 Filipe Coelho <falktx@falktx.com>
7
8 Permission is granted to use this software under the terms of the ISC license
9 http://www.isc.org/downloads/software-support-policy/isc-license/
10
11 Permission to use, copy, modify, and/or distribute this software for any
12 purpose with or without fee is hereby granted, provided that the above
13 copyright notice and this permission notice appear in all copies.
14
15 THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH REGARD
16 TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND
17 FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT,
18 OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF
19 USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
20 TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE
21 OF THIS SOFTWARE.
22
23 ==============================================================================
24*/
25
26#ifndef WATER_CHARPOINTER_UTF8_H_INCLUDED
27#define WATER_CHARPOINTER_UTF8_H_INCLUDED
28
29#include "CharacterFunctions.h"
30#include "../memory/Atomic.h"
31
32#include "CarlaUtils.hpp"
33
34namespace water {
35
36class String;
37
38//==============================================================================
45{
46public:
47 typedef char CharType;
48
49 inline explicit CharPointer_UTF8 (const CharType* const rawPointer) noexcept
50 : data (const_cast<CharType*> (rawPointer))
51 {
52 }
53
55 : data (other.data)
56 {
57 }
58
60 {
61 data = other.data;
62 return *this;
63 }
64
65 inline CharPointer_UTF8& operator= (const CharType* text) noexcept
66 {
67 data = const_cast<CharType*> (text);
68 return *this;
69 }
70
72 inline bool operator== (CharPointer_UTF8 other) const noexcept { return data == other.data; }
73 inline bool operator!= (CharPointer_UTF8 other) const noexcept { return data != other.data; }
74 inline bool operator<= (CharPointer_UTF8 other) const noexcept { return data <= other.data; }
75 inline bool operator< (CharPointer_UTF8 other) const noexcept { return data < other.data; }
76 inline bool operator>= (CharPointer_UTF8 other) const noexcept { return data >= other.data; }
77 inline bool operator> (CharPointer_UTF8 other) const noexcept { return data > other.data; }
78
80 inline CharType* getAddress() const noexcept { return data; }
81
83 inline operator const CharType*() const noexcept { return data; }
84
86 inline bool isEmpty() const noexcept { return *data == 0; }
87
90 {
91 const signed char byte = (signed char) *data;
92
93 if (byte >= 0)
94 return (water_uchar) (uint8) byte;
95
96 uint32 n = (uint32) (uint8) byte;
97 uint32 mask = 0x7f;
98 uint32 bit = 0x40;
99 int numExtraValues = 0;
100
101 while ((n & bit) != 0 && bit > 0x8)
102 {
103 mask >>= 1;
104 ++numExtraValues;
105 bit >>= 1;
106 }
107
108 n &= mask;
109
110 for (int i = 1; i <= numExtraValues; ++i)
111 {
112 const uint32 nextByte = (uint32) (uint8) data[i];
113
114 if ((nextByte & 0xc0) != 0x80)
115 break;
116
117 n <<= 6;
118 n |= (nextByte & 0x3f);
119 }
120
121 return (water_uchar) n;
122 }
123
126 {
127 wassert (*data != 0); // trying to advance past the end of the string?
128 const signed char n = (signed char) *data++;
129
130 if (n < 0)
131 {
132 water_uchar bit = 0x40;
133
134 while ((static_cast<unsigned char>(n) & bit) != 0 && bit > 0x8)
135 {
136 ++data;
137 bit >>= 1;
138 }
139 }
140
141 return *this;
142 }
143
146 {
147 int count = 0;
148
149 while ((*--data & 0xc0) == 0x80 && ++count < 4)
150 {}
151
152 return *this;
153 }
154
158 {
159 const signed char byte = (signed char) *data++;
160
161 if (byte >= 0)
162 return (water_uchar) (uint8) byte;
163
164 uint32 n = (uint32) (uint8) byte;
165 uint32 mask = 0x7f;
166 uint32 bit = 0x40;
167 int numExtraValues = 0;
168
169 while ((n & bit) != 0 && bit > 0x8)
170 {
171 mask >>= 1;
172 ++numExtraValues;
173 bit >>= 1;
174 }
175
176 n &= mask;
177
178 while (--numExtraValues >= 0)
179 {
180 const uint32 nextByte = (uint32) (uint8) *data;
181
182 if ((nextByte & 0xc0) != 0x80)
183 break;
184
185 ++data;
186 n <<= 6;
187 n |= (nextByte & 0x3f);
188 }
189
190 return (water_uchar) n;
191 }
192
195 {
196 CharPointer_UTF8 temp (*this);
197 ++*this;
198 return temp;
199 }
200
202 void operator+= (int numToSkip) noexcept
203 {
204 if (numToSkip < 0)
205 {
206 while (++numToSkip <= 0)
207 --*this;
208 }
209 else
210 {
211 while (--numToSkip >= 0)
212 ++*this;
213 }
214 }
215
217 void operator-= (int numToSkip) noexcept
218 {
219 operator+= (-numToSkip);
220 }
221
223 water_uchar operator[] (int characterIndex) const noexcept
224 {
225 CharPointer_UTF8 p (*this);
226 p += characterIndex;
227 return *p;
228 }
229
231 CharPointer_UTF8 operator+ (int numToSkip) const noexcept
232 {
233 CharPointer_UTF8 p (*this);
234 p += numToSkip;
235 return p;
236 }
237
239 CharPointer_UTF8 operator- (int numToSkip) const noexcept
240 {
241 CharPointer_UTF8 p (*this);
242 p += -numToSkip;
243 return p;
244 }
245
248 {
249 const CharType* d = data;
250 size_t count = 0;
251
252 for (;;)
253 {
254 const uint32 n = (uint32) (uint8) *d++;
255
256 if ((n & 0x80) != 0)
257 {
258 while ((*d & 0xc0) == 0x80)
259 ++d;
260 }
261 else if (n == 0)
262 break;
263
264 ++count;
265 }
266
267 return count;
268 }
269
271 size_t lengthUpTo (const size_t maxCharsToCount) const noexcept
272 {
273 return CharacterFunctions::lengthUpTo (*this, maxCharsToCount);
274 }
275
277 size_t lengthUpTo (const CharPointer_UTF8 end) const noexcept
278 {
279 return CharacterFunctions::lengthUpTo (*this, end);
280 }
281
286 {
287 wassert (data != nullptr);
288 return strlen (data) + 1;
289 }
290
294 static size_t getBytesRequiredFor (const water_uchar charToWrite) noexcept
295 {
296 size_t num = 1;
297 const uint32 c = (uint32) charToWrite;
298
299 if (c >= 0x80)
300 {
301 ++num;
302 if (c >= 0x800)
303 {
304 ++num;
305 if (c >= 0x10000)
306 ++num;
307 }
308 }
309
310 return num;
311 }
312
317 template <class CharPointer>
318 static size_t getBytesRequiredFor (CharPointer text) noexcept
319 {
320 size_t count = 0;
321
322 while (water_uchar n = text.getAndAdvance())
324
325 return count;
326 }
327
333
335 void write (const water_uchar charToWrite) noexcept
336 {
337 const uint32 c = (uint32) charToWrite;
338
339 if (c >= 0x80)
340 {
341 int numExtraBytes = 1;
342 if (c >= 0x800)
343 {
344 ++numExtraBytes;
345 if (c >= 0x10000)
346 ++numExtraBytes;
347 }
348
349 *data++ = (CharType) ((uint32) (0xff << (7 - numExtraBytes)) | (c >> (numExtraBytes * 6)));
350
351 while (--numExtraBytes >= 0)
352 *data++ = (CharType) (0x80 | (0x3f & (c >> (numExtraBytes * 6))));
353 }
354 else
355 {
356 *data++ = (CharType) c;
357 }
358 }
359
362 {
363 *data = 0;
364 }
365
367 template <typename CharPointer>
368 void writeAll (const CharPointer src) noexcept
369 {
370 CharacterFunctions::copyAll (*this, src);
371 }
372
374 void writeAll (const CharPointer_UTF8 src) noexcept
375 {
376 const CharType* s = src.data;
377
378 while ((*data = *s) != 0)
379 {
380 ++data;
381 ++s;
382 }
383 }
384
389 template <typename CharPointer>
390 size_t writeWithDestByteLimit (const CharPointer src, const size_t maxDestBytes) noexcept
391 {
392 return CharacterFunctions::copyWithDestByteLimit (*this, src, maxDestBytes);
393 }
394
399 template <typename CharPointer>
400 void writeWithCharLimit (const CharPointer src, const int maxChars) noexcept
401 {
402 CharacterFunctions::copyWithCharLimit (*this, src, maxChars);
403 }
404
406 template <typename CharPointer>
407 int compare (const CharPointer other) const noexcept
408 {
409 return CharacterFunctions::compare (*this, other);
410 }
411
413 template <typename CharPointer>
414 int compareUpTo (const CharPointer other, const int maxChars) const noexcept
415 {
416 return CharacterFunctions::compareUpTo (*this, other, maxChars);
417 }
418
420 template <typename CharPointer>
421 int compareIgnoreCase (const CharPointer other) const noexcept
422 {
423 return CharacterFunctions::compareIgnoreCase (*this, other);
424 }
425
427 int compareIgnoreCase (const CharPointer_UTF8 other) const noexcept
428 {
429 return CharacterFunctions::compareIgnoreCase (*this, other);
430 }
431
433 template <typename CharPointer>
434 int compareIgnoreCaseUpTo (const CharPointer other, const int maxChars) const noexcept
435 {
436 return CharacterFunctions::compareIgnoreCaseUpTo (*this, other, maxChars);
437 }
438
440 template <typename CharPointer>
441 int indexOf (const CharPointer stringToFind) const noexcept
442 {
443 return CharacterFunctions::indexOf (*this, stringToFind);
444 }
445
447 int indexOf (const water_uchar charToFind) const noexcept
448 {
449 return CharacterFunctions::indexOfChar (*this, charToFind);
450 }
451
453 int indexOf (const water_uchar charToFind, const bool ignoreCase) const noexcept
454 {
455 return ignoreCase ? CharacterFunctions::indexOfCharIgnoreCase (*this, charToFind)
456 : CharacterFunctions::indexOfChar (*this, charToFind);
457 }
458
460 bool isWhitespace() const noexcept { const CharType c = *data; return c == ' ' || (c <= 13 && c >= 9); }
462 bool isDigit() const noexcept { const CharType c = *data; return c >= '0' && c <= '9'; }
464 bool isLetter() const noexcept { return CharacterFunctions::isLetter (operator*()) != 0; }
468 bool isUpperCase() const noexcept { return CharacterFunctions::isUpperCase (operator*()) != 0; }
470 bool isLowerCase() const noexcept { return CharacterFunctions::isLowerCase (operator*()) != 0; }
471
476
478 int getIntValue32() const noexcept { return atoi (data); }
479
482 {
483 return atoll (data);
484 #if 0
486 #endif
487 }
488
491
494
496 static bool canRepresent (water_uchar character) noexcept
497 {
498 return ((unsigned int) character) < (unsigned int) 0x10ffff;
499 }
500
502 static bool isValidString (const CharType* dataToTest, int maxBytesToRead)
503 {
504 while (--maxBytesToRead >= 0 && *dataToTest != 0)
505 {
506 const signed char byte = (signed char) *dataToTest++;
507
508 if (byte < 0)
509 {
510 int bit = 0x40;
511 int numExtraValues = 0;
512
513 while ((byte & bit) != 0)
514 {
515 if (bit < 8)
516 return false;
517
518 ++numExtraValues;
519 bit >>= 1;
520
521 if (bit == 8 && (numExtraValues > maxBytesToRead
522 || *CharPointer_UTF8 (dataToTest - 1) > 0x10ffff))
523 return false;
524 }
525
526 if (numExtraValues == 0)
527 return false;
528
529 maxBytesToRead -= numExtraValues;
530 if (maxBytesToRead < 0)
531 return false;
532
533 while (--numExtraValues >= 0)
534 if ((*dataToTest++ & 0xc0) != 0x80)
535 return false;
536 }
537 }
538
539 return true;
540 }
541
543 enum
544 {
548 };
549
553 static bool isByteOrderMark (const void* possibleByteOrder) noexcept
554 {
555 wassert (possibleByteOrder != nullptr);
556 const uint8* const c = static_cast<const uint8*> (possibleByteOrder);
557
558 return c[0] == (uint8) byteOrderMark1
559 && c[1] == (uint8) byteOrderMark2
560 && c[2] == (uint8) byteOrderMark3;
561 }
562
563private:
565
566 friend class String;
567};
568
569}
570
571#endif // WATER_CHARPOINTER_UTF8_H_INCLUDED
#define noexcept
Definition DistrhoDefines.h:72
static const unsigned long mask[]
Definition bitwise.c:31
#define byte
Definition blargg_source.h:87
CharPointer_UTF8(const CharType *const rawPointer) noexcept
Definition CharPointer_UTF8.h:49
static size_t getBytesRequiredFor(CharPointer text) noexcept
Definition CharPointer_UTF8.h:318
bool isWhitespace() const noexcept
Definition CharPointer_UTF8.h:460
size_t writeWithDestByteLimit(const CharPointer src, const size_t maxDestBytes) noexcept
Definition CharPointer_UTF8.h:390
int64 getIntValue64() const noexcept
Definition CharPointer_UTF8.h:481
void operator-=(int numToSkip) noexcept
Definition CharPointer_UTF8.h:217
bool operator!=(CharPointer_UTF8 other) const noexcept
Definition CharPointer_UTF8.h:73
int compareIgnoreCaseUpTo(const CharPointer other, const int maxChars) const noexcept
Definition CharPointer_UTF8.h:434
CharType * data
Definition CharPointer_UTF8.h:564
CharType * getAddress() const noexcept
Definition CharPointer_UTF8.h:80
bool operator<=(CharPointer_UTF8 other) const noexcept
Definition CharPointer_UTF8.h:74
size_t length() const noexcept
Definition CharPointer_UTF8.h:247
CharPointer_UTF8 & operator=(CharPointer_UTF8 other) noexcept
Definition CharPointer_UTF8.h:59
CharPointer_UTF8(const CharType *const rawPointer) noexcept
Definition CharPointer_UTF8.h:49
bool operator==(CharPointer_UTF8 other) const noexcept
Definition CharPointer_UTF8.h:72
size_t sizeInBytes() const noexcept
Definition CharPointer_UTF8.h:285
bool isUpperCase() const noexcept
Definition CharPointer_UTF8.h:468
bool operator>=(CharPointer_UTF8 other) const noexcept
Definition CharPointer_UTF8.h:76
void writeNull() const noexcept
Definition CharPointer_UTF8.h:361
int compareIgnoreCase(const CharPointer other) const noexcept
Definition CharPointer_UTF8.h:421
int indexOf(const water_uchar charToFind) const noexcept
Definition CharPointer_UTF8.h:447
water_uchar operator[](int characterIndex) const noexcept
Definition CharPointer_UTF8.h:223
bool isLowerCase() const noexcept
Definition CharPointer_UTF8.h:470
int indexOf(const water_uchar charToFind, const bool ignoreCase) const noexcept
Definition CharPointer_UTF8.h:453
bool isLetter() const noexcept
Definition CharPointer_UTF8.h:464
bool isDigit() const noexcept
Definition CharPointer_UTF8.h:462
CharPointer_UTF8 & operator++() noexcept
Definition CharPointer_UTF8.h:125
water_uchar operator*() const noexcept
Definition CharPointer_UTF8.h:89
double getDoubleValue() const noexcept
Definition CharPointer_UTF8.h:490
CharPointer_UTF8 operator-(int numToSkip) const noexcept
Definition CharPointer_UTF8.h:239
friend class String
Definition CharPointer_UTF8.h:566
static bool isValidString(const CharType *dataToTest, int maxBytesToRead)
Definition CharPointer_UTF8.h:502
void operator+=(int numToSkip) noexcept
Definition CharPointer_UTF8.h:202
bool isEmpty() const noexcept
Definition CharPointer_UTF8.h:86
static bool isByteOrderMark(const void *possibleByteOrder) noexcept
Definition CharPointer_UTF8.h:553
CharPointer_UTF8 findEndOfWhitespace() const noexcept
Definition CharPointer_UTF8.h:493
CharPointer_UTF8 findTerminatingNull() const noexcept
Definition CharPointer_UTF8.h:329
bool isLetterOrDigit() const noexcept
Definition CharPointer_UTF8.h:466
bool operator>(CharPointer_UTF8 other) const noexcept
Definition CharPointer_UTF8.h:77
water_uchar toUpperCase() const noexcept
Definition CharPointer_UTF8.h:473
size_t lengthUpTo(const size_t maxCharsToCount) const noexcept
Definition CharPointer_UTF8.h:271
@ byteOrderMark2
Definition CharPointer_UTF8.h:546
@ byteOrderMark1
Definition CharPointer_UTF8.h:545
@ byteOrderMark3
Definition CharPointer_UTF8.h:547
int indexOf(const CharPointer stringToFind) const noexcept
Definition CharPointer_UTF8.h:441
int compare(const CharPointer other) const noexcept
Definition CharPointer_UTF8.h:407
int compareUpTo(const CharPointer other, const int maxChars) const noexcept
Definition CharPointer_UTF8.h:414
static size_t getBytesRequiredFor(const water_uchar charToWrite) noexcept
Definition CharPointer_UTF8.h:294
int compareIgnoreCase(const CharPointer_UTF8 other) const noexcept
Definition CharPointer_UTF8.h:427
int getIntValue32() const noexcept
Definition CharPointer_UTF8.h:478
void writeAll(const CharPointer src) noexcept
Definition CharPointer_UTF8.h:368
static bool canRepresent(water_uchar character) noexcept
Definition CharPointer_UTF8.h:496
CharPointer_UTF8 operator+(int numToSkip) const noexcept
Definition CharPointer_UTF8.h:231
void write(const water_uchar charToWrite) noexcept
Definition CharPointer_UTF8.h:335
char CharType
Definition CharPointer_UTF8.h:47
void writeWithCharLimit(const CharPointer src, const int maxChars) noexcept
Definition CharPointer_UTF8.h:400
CharPointer_UTF8(const CharPointer_UTF8 &other) noexcept
Definition CharPointer_UTF8.h:54
size_t lengthUpTo(const CharPointer_UTF8 end) const noexcept
Definition CharPointer_UTF8.h:277
CharPointer_UTF8 & operator--() noexcept
Definition CharPointer_UTF8.h:145
void writeAll(const CharPointer_UTF8 src) noexcept
Definition CharPointer_UTF8.h:374
water_uchar getAndAdvance() noexcept
Definition CharPointer_UTF8.h:157
water_uchar toLowerCase() const noexcept
Definition CharPointer_UTF8.h:475
bool operator<(CharPointer_UTF8 other) const noexcept
Definition CharPointer_UTF8.h:75
static water_uchar toUpperCase(water_uchar character) noexcept
Definition CharacterFunctions.cpp:34
static int compareUpTo(CharPointerType1 s1, CharPointerType2 s2, int maxChars) noexcept
Definition CharacterFunctions.h:396
static bool isLetterOrDigit(char character) noexcept
Definition CharacterFunctions.cpp:94
static int indexOf(CharPointerType1 textToSearch, const CharPointerType2 substringToLookFor) noexcept
Definition CharacterFunctions.h:458
static bool isLetter(char character) noexcept
Definition CharacterFunctions.cpp:83
static int compareIgnoreCase(water_uchar char1, water_uchar char2) noexcept
Definition CharacterFunctions.h:413
static int compareIgnoreCaseUpTo(CharPointerType1 s1, CharPointerType2 s2, int maxChars) noexcept
Definition CharacterFunctions.h:438
static double getDoubleValue(CharPointerType text) noexcept
Definition CharacterFunctions.h:236
static water_uchar toLowerCase(water_uchar character) noexcept
Definition CharacterFunctions.cpp:39
static int indexOfChar(Type text, const water_uchar charToFind) noexcept
Definition CharacterFunctions.h:535
static bool isLowerCase(water_uchar character) noexcept
Definition CharacterFunctions.cpp:53
static int compare(water_uchar char1, water_uchar char2) noexcept
Definition CharacterFunctions.h:368
static bool isUpperCase(water_uchar character) noexcept
Definition CharacterFunctions.cpp:44
static void copyAll(DestCharPointerType &dest, SrcCharPointerType src) noexcept
Definition CharacterFunctions.h:315
static int indexOfCharIgnoreCase(Type text, water_uchar charToFind) noexcept
Definition CharacterFunctions.h:555
static void copyWithCharLimit(DestCharPointerType &dest, SrcCharPointerType src, int maxChars) noexcept
Definition CharacterFunctions.h:353
static Type findEndOfWhitespace(Type text) noexcept
Definition CharacterFunctions.h:577
static size_t lengthUpTo(CharPointerType text, const size_t maxCharsToCount) noexcept
Definition CharacterFunctions.h:290
static size_t copyWithDestByteLimit(DestCharPointerType &dest, SrcCharPointerType src, size_t maxBytesToWrite) noexcept
Definition CharacterFunctions.h:326
static IntType getIntValue(const CharPointerType text) noexcept
Definition CharacterFunctions.h:244
Definition String.h:48
unsigned d
Definition inflate.c:940
register unsigned i
Definition inflate.c:1575
unsigned s
Definition inflate.c:1555
#define wassert(expression)
Definition AudioSampleBuffer.h:33
unsigned int uint32
Definition water.h:98
long long int64
Definition water.h:100
unsigned char uint8
Definition water.h:90
uint32 water_uchar
Definition CharacterFunctions.h:38
const char * text
Definition swell-functions.h:167
int n
Definition crypt.c:458
uch * p
Definition crypt.c:594
return c
Definition crypt.c:175
typedef int(UZ_EXP MsgFn)()
_WDL_CSTRING_PREFIX void INT_PTR count
Definition wdlcstring.h:263
#define const
Definition zconf.h:137