openshot-audio  0.1.2
juce_CharPointer_UTF8.h
Go to the documentation of this file.
1 /*
2  ==============================================================================
3 
4  This file is part of the juce_core module of the JUCE library.
5  Copyright (c) 2015 - ROLI Ltd.
6 
7  Permission to use, copy, modify, and/or distribute this software for any purpose with
8  or without fee is hereby granted, provided that the above copyright notice and this
9  permission notice appear in all copies.
10 
11  THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH REGARD
12  TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. IN
13  NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL
14  DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER
15  IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
16  CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
17 
18  ------------------------------------------------------------------------------
19 
20  NOTE! This permissive ISC license applies ONLY to files within the juce_core module!
21  All other JUCE modules are covered by a dual GPL/commercial license, so if you are
22  using any other modules, be sure to check that you also comply with their license.
23 
24  For more details, visit www.juce.com
25 
26  ==============================================================================
27 */
28 
29 #ifndef JUCE_CHARPOINTER_UTF8_H_INCLUDED
30 #define JUCE_CHARPOINTER_UTF8_H_INCLUDED
31 
32 //==============================================================================
39 {
40 public:
41  typedef char CharType;
42 
43  inline explicit CharPointer_UTF8 (const CharType* const rawPointer) noexcept
44  : data (const_cast <CharType*> (rawPointer))
45  {
46  }
47 
49  : data (other.data)
50  {
51  }
52 
54  {
55  data = other.data;
56  return *this;
57  }
58 
59  inline CharPointer_UTF8 operator= (const CharType* text) noexcept
60  {
61  data = const_cast <CharType*> (text);
62  return *this;
63  }
64 
66  inline bool operator== (CharPointer_UTF8 other) const noexcept { return data == other.data; }
67  inline bool operator!= (CharPointer_UTF8 other) const noexcept { return data != other.data; }
68  inline bool operator<= (CharPointer_UTF8 other) const noexcept { return data <= other.data; }
69  inline bool operator< (CharPointer_UTF8 other) const noexcept { return data < other.data; }
70  inline bool operator>= (CharPointer_UTF8 other) const noexcept { return data >= other.data; }
71  inline bool operator> (CharPointer_UTF8 other) const noexcept { return data > other.data; }
72 
74  inline CharType* getAddress() const noexcept { return data; }
75 
77  inline operator const CharType*() const noexcept { return data; }
78 
80  inline bool isEmpty() const noexcept { return *data == 0; }
81 
84  {
85  const signed char byte = (signed char) *data;
86 
87  if (byte >= 0)
88  return (juce_wchar) (uint8) byte;
89 
90  uint32 n = (uint32) (uint8) byte;
91  uint32 mask = 0x7f;
92  uint32 bit = 0x40;
93  size_t numExtraValues = 0;
94 
95  while ((n & bit) != 0 && bit > 0x10)
96  {
97  mask >>= 1;
98  ++numExtraValues;
99  bit >>= 1;
100  }
101 
102  n &= mask;
103 
104  for (size_t i = 1; i <= numExtraValues; ++i)
105  {
106  const uint8 nextByte = (uint8) data [i];
107 
108  if ((nextByte & 0xc0) != 0x80)
109  break;
110 
111  n <<= 6;
112  n |= (nextByte & 0x3f);
113  }
114 
115  return (juce_wchar) n;
116  }
117 
120  {
121  jassert (*data != 0); // trying to advance past the end of the string?
122  const signed char n = (signed char) *data++;
123 
124  if (n < 0)
125  {
126  juce_wchar bit = 0x40;
127 
128  while ((n & bit) != 0 && bit > 0x8)
129  {
130  ++data;
131  bit >>= 1;
132  }
133  }
134 
135  return *this;
136  }
137 
140  {
141  int count = 0;
142 
143  while ((*--data & 0xc0) == 0x80 && ++count < 4)
144  {}
145 
146  return *this;
147  }
148 
152  {
153  const signed char byte = (signed char) *data++;
154 
155  if (byte >= 0)
156  return (juce_wchar) (uint8) byte;
157 
158  uint32 n = (uint32) (uint8) byte;
159  uint32 mask = 0x7f;
160  uint32 bit = 0x40;
161  int numExtraValues = 0;
162 
163  while ((n & bit) != 0 && bit > 0x8)
164  {
165  mask >>= 1;
166  ++numExtraValues;
167  bit >>= 1;
168  }
169 
170  n &= mask;
171 
172  while (--numExtraValues >= 0)
173  {
174  const uint32 nextByte = (uint32) (uint8) *data;
175 
176  if ((nextByte & 0xc0) != 0x80)
177  break;
178 
179  ++data;
180  n <<= 6;
181  n |= (nextByte & 0x3f);
182  }
183 
184  return (juce_wchar) n;
185  }
186 
189  {
190  CharPointer_UTF8 temp (*this);
191  ++*this;
192  return temp;
193  }
194 
196  void operator+= (int numToSkip) noexcept
197  {
198  if (numToSkip < 0)
199  {
200  while (++numToSkip <= 0)
201  --*this;
202  }
203  else
204  {
205  while (--numToSkip >= 0)
206  ++*this;
207  }
208  }
209 
211  void operator-= (int numToSkip) noexcept
212  {
213  operator+= (-numToSkip);
214  }
215 
217  juce_wchar operator[] (int characterIndex) const noexcept
218  {
219  CharPointer_UTF8 p (*this);
220  p += characterIndex;
221  return *p;
222  }
223 
225  CharPointer_UTF8 operator+ (int numToSkip) const noexcept
226  {
227  CharPointer_UTF8 p (*this);
228  p += numToSkip;
229  return p;
230  }
231 
233  CharPointer_UTF8 operator- (int numToSkip) const noexcept
234  {
235  CharPointer_UTF8 p (*this);
236  p += -numToSkip;
237  return p;
238  }
239 
241  size_t length() const noexcept
242  {
243  const CharType* d = data;
244  size_t count = 0;
245 
246  for (;;)
247  {
248  const uint32 n = (uint32) (uint8) *d++;
249 
250  if ((n & 0x80) != 0)
251  {
252  while ((*d & 0xc0) == 0x80)
253  ++d;
254  }
255  else if (n == 0)
256  break;
257 
258  ++count;
259  }
260 
261  return count;
262  }
263 
265  size_t lengthUpTo (const size_t maxCharsToCount) const noexcept
266  {
267  return CharacterFunctions::lengthUpTo (*this, maxCharsToCount);
268  }
269 
271  size_t lengthUpTo (const CharPointer_UTF8 end) const noexcept
272  {
273  return CharacterFunctions::lengthUpTo (*this, end);
274  }
275 
279  size_t sizeInBytes() const noexcept
280  {
281  jassert (data != nullptr);
282  return strlen (data) + 1;
283  }
284 
288  static size_t getBytesRequiredFor (const juce_wchar charToWrite) noexcept
289  {
290  size_t num = 1;
291  const uint32 c = (uint32) charToWrite;
292 
293  if (c >= 0x80)
294  {
295  ++num;
296  if (c >= 0x800)
297  {
298  ++num;
299  if (c >= 0x10000)
300  ++num;
301  }
302  }
303 
304  return num;
305  }
306 
311  template <class CharPointer>
312  static size_t getBytesRequiredFor (CharPointer text) noexcept
313  {
314  size_t count = 0;
315  juce_wchar n;
316 
317  while ((n = text.getAndAdvance()) != 0)
318  count += getBytesRequiredFor (n);
319 
320  return count;
321  }
322 
325  {
326  return CharPointer_UTF8 (data + strlen (data));
327  }
328 
330  void write (const juce_wchar charToWrite) noexcept
331  {
332  const uint32 c = (uint32) charToWrite;
333 
334  if (c >= 0x80)
335  {
336  int numExtraBytes = 1;
337  if (c >= 0x800)
338  {
339  ++numExtraBytes;
340  if (c >= 0x10000)
341  ++numExtraBytes;
342  }
343 
344  *data++ = (CharType) ((uint32) (0xff << (7 - numExtraBytes)) | (c >> (numExtraBytes * 6)));
345 
346  while (--numExtraBytes >= 0)
347  *data++ = (CharType) (0x80 | (0x3f & (c >> (numExtraBytes * 6))));
348  }
349  else
350  {
351  *data++ = (CharType) c;
352  }
353  }
354 
356  inline void writeNull() const noexcept
357  {
358  *data = 0;
359  }
360 
362  template <typename CharPointer>
363  void writeAll (const CharPointer src) noexcept
364  {
365  CharacterFunctions::copyAll (*this, src);
366  }
367 
370  {
371  const CharType* s = src.data;
372 
373  while ((*data = *s) != 0)
374  {
375  ++data;
376  ++s;
377  }
378  }
379 
384  template <typename CharPointer>
385  size_t writeWithDestByteLimit (const CharPointer src, const size_t maxDestBytes) noexcept
386  {
387  return CharacterFunctions::copyWithDestByteLimit (*this, src, maxDestBytes);
388  }
389 
394  template <typename CharPointer>
395  void writeWithCharLimit (const CharPointer src, const int maxChars) noexcept
396  {
397  CharacterFunctions::copyWithCharLimit (*this, src, maxChars);
398  }
399 
401  template <typename CharPointer>
402  int compare (const CharPointer other) const noexcept
403  {
404  return CharacterFunctions::compare (*this, other);
405  }
406 
408  template <typename CharPointer>
409  int compareUpTo (const CharPointer other, const int maxChars) const noexcept
410  {
411  return CharacterFunctions::compareUpTo (*this, other, maxChars);
412  }
413 
415  template <typename CharPointer>
416  int compareIgnoreCase (const CharPointer other) const noexcept
417  {
418  return CharacterFunctions::compareIgnoreCase (*this, other);
419  }
420 
423  {
424  #if JUCE_MSVC
425  return stricmp (data, other.data);
426  #elif JUCE_MINGW
427  return CharacterFunctions::compareIgnoreCase (*this, other);
428  #else
429  return strcasecmp (data, other.data);
430  #endif
431  }
432 
434  template <typename CharPointer>
435  int compareIgnoreCaseUpTo (const CharPointer other, const int maxChars) const noexcept
436  {
437  return CharacterFunctions::compareIgnoreCaseUpTo (*this, other, maxChars);
438  }
439 
441  template <typename CharPointer>
442  int indexOf (const CharPointer stringToFind) const noexcept
443  {
444  return CharacterFunctions::indexOf (*this, stringToFind);
445  }
446 
448  int indexOf (const juce_wchar charToFind) const noexcept
449  {
450  return CharacterFunctions::indexOfChar (*this, charToFind);
451  }
452 
454  int indexOf (const juce_wchar charToFind, const bool ignoreCase) const noexcept
455  {
456  return ignoreCase ? CharacterFunctions::indexOfCharIgnoreCase (*this, charToFind)
457  : CharacterFunctions::indexOfChar (*this, charToFind);
458  }
459 
461  bool isWhitespace() const noexcept { const CharType c = *data; return c == ' ' || (c <= 13 && c >= 9); }
463  bool isDigit() const noexcept { const CharType c = *data; return c >= '0' && c <= '9'; }
465  bool isLetter() const noexcept { return CharacterFunctions::isLetter (operator*()) != 0; }
467  bool isLetterOrDigit() const noexcept { return CharacterFunctions::isLetterOrDigit (operator*()) != 0; }
469  bool isUpperCase() const noexcept { return CharacterFunctions::isUpperCase (operator*()) != 0; }
471  bool isLowerCase() const noexcept { return CharacterFunctions::isLowerCase (operator*()) != 0; }
472 
477 
479  int getIntValue32() const noexcept { return atoi (data); }
480 
483  {
484  #if JUCE_LINUX || JUCE_ANDROID || JUCE_MINGW
485  return atoll (data);
486  #elif JUCE_WINDOWS
487  return _atoi64 (data);
488  #else
489  return CharacterFunctions::getIntValue <int64, CharPointer_UTF8> (*this);
490  #endif
491  }
492 
494  double getDoubleValue() const noexcept { return CharacterFunctions::getDoubleValue (*this); }
495 
498 
500  static bool canRepresent (juce_wchar character) noexcept
501  {
502  return ((unsigned int) character) < (unsigned int) 0x10ffff;
503  }
504 
506  static bool isValidString (const CharType* dataToTest, int maxBytesToRead)
507  {
508  while (--maxBytesToRead >= 0 && *dataToTest != 0)
509  {
510  const signed char byte = (signed char) *dataToTest++;
511 
512  if (byte < 0)
513  {
514  int bit = 0x40;
515  int numExtraValues = 0;
516 
517  while ((byte & bit) != 0)
518  {
519  if (bit < 8)
520  return false;
521 
522  ++numExtraValues;
523  bit >>= 1;
524 
525  if (bit == 8 && (numExtraValues > maxBytesToRead
526  || *CharPointer_UTF8 (dataToTest - 1) > 0x10ffff))
527  return false;
528  }
529 
530  maxBytesToRead -= numExtraValues;
531  if (maxBytesToRead < 0)
532  return false;
533 
534  while (--numExtraValues >= 0)
535  if ((*dataToTest++ & 0xc0) != 0x80)
536  return false;
537  }
538  }
539 
540  return true;
541  }
542 
545  {
546  return CharPointer_UTF8 (reinterpret_cast <Atomic<CharType*>&> (data).exchange (newValue.data));
547  }
548 
550  enum
551  {
555  };
556 
560  static bool isByteOrderMark (const void* possibleByteOrder) noexcept
561  {
562  jassert (possibleByteOrder != nullptr);
563  const uint8* const c = static_cast<const uint8*> (possibleByteOrder);
564 
565  return c[0] == (uint8) byteOrderMark1
566  && c[1] == (uint8) byteOrderMark2
567  && c[2] == (uint8) byteOrderMark3;
568  }
569 
570 private:
571  CharType* data;
572 };
573 
574 #endif // JUCE_CHARPOINTER_UTF8_H_INCLUDED
CharPointer_UTF8 operator=(CharPointer_UTF8 other) noexcept
Definition: juce_CharPointer_UTF8.h:53
bool operator<=(CharPointer_UTF8 other) const noexcept
Definition: juce_CharPointer_UTF8.h:68
Definition: juce_CharPointer_UTF8.h:554
bool isLowerCase() const noexcept
Definition: juce_CharPointer_UTF8.h:471
int getIntValue32() const noexcept
Definition: juce_CharPointer_UTF8.h:479
static size_t lengthUpTo(CharPointerType text, const size_t maxCharsToCount) noexcept
Definition: juce_CharacterFunctions.h:307
juce_wchar operator[](int characterIndex) const noexcept
Definition: juce_CharPointer_UTF8.h:217
CharPointer_UTF8(const CharPointer_UTF8 &other) noexcept
Definition: juce_CharPointer_UTF8.h:48
CharPointer_UTF8(const CharType *const rawPointer) noexcept
Definition: juce_CharPointer_UTF8.h:43
CharPointer_UTF8 findEndOfWhitespace() const noexcept
Definition: juce_CharPointer_UTF8.h:497
#define noexcept
Definition: juce_CompilerSupport.h:141
juce_wchar operator*() const noexcept
Definition: juce_CharPointer_UTF8.h:83
Definition: juce_Atomic.h:41
static juce_wchar toLowerCase(juce_wchar character) noexcept
Definition: juce_CharacterFunctions.cpp:40
static int compare(CharPointerType1 s1, CharPointerType2 s2) noexcept
Definition: juce_CharacterFunctions.h:393
static Type findEndOfWhitespace(Type text) noexcept
Definition: juce_CharacterFunctions.h:586
static bool canRepresent(juce_wchar character) noexcept
Definition: juce_CharPointer_UTF8.h:500
static size_t getBytesRequiredFor(CharPointer text) noexcept
Definition: juce_CharPointer_UTF8.h:312
static double getDoubleValue(CharPointerType text) noexcept
Definition: juce_CharacterFunctions.h:253
Definition: juce_CharPointer_UTF8.h:38
char CharType
Definition: juce_CharPointer_UTF8.h:41
int indexOf(const CharPointer stringToFind) const noexcept
Definition: juce_CharPointer_UTF8.h:442
size_t sizeInBytes() const noexcept
Definition: juce_CharPointer_UTF8.h:279
static bool isLetterOrDigit(char character) noexcept
Definition: juce_CharacterFunctions.cpp:99
static juce_wchar toUpperCase(juce_wchar character) noexcept
Definition: juce_CharacterFunctions.cpp:35
void write(const juce_wchar charToWrite) noexcept
Definition: juce_CharPointer_UTF8.h:330
bool isUpperCase() const noexcept
Definition: juce_CharPointer_UTF8.h:469
static bool isLetter(char character) noexcept
Definition: juce_CharacterFunctions.cpp:88
static int indexOf(CharPointerType1 textToSearch, const CharPointerType2 substringToLookFor) noexcept
Definition: juce_CharacterFunctions.h:467
static void copyAll(DestCharPointerType &dest, SrcCharPointerType src) noexcept
Definition: juce_CharacterFunctions.h:332
static size_t copyWithDestByteLimit(DestCharPointerType &dest, SrcCharPointerType src, size_t maxBytesToWrite) noexcept
Definition: juce_CharacterFunctions.h:350
bool isEmpty() const noexcept
Definition: juce_CharPointer_UTF8.h:80
juce_wchar toLowerCase() const noexcept
Definition: juce_CharPointer_UTF8.h:476
int compareUpTo(const CharPointer other, const int maxChars) const noexcept
Definition: juce_CharPointer_UTF8.h:409
void writeAll(const CharPointer_UTF8 src) noexcept
Definition: juce_CharPointer_UTF8.h:369
bool operator>(CharPointer_UTF8 other) const noexcept
Definition: juce_CharPointer_UTF8.h:71
Definition: juce_CharPointer_UTF8.h:553
bool isDigit() const noexcept
Definition: juce_CharPointer_UTF8.h:463
size_t lengthUpTo(const CharPointer_UTF8 end) const noexcept
Definition: juce_CharPointer_UTF8.h:271
void writeWithCharLimit(const CharPointer src, const int maxChars) noexcept
Definition: juce_CharPointer_UTF8.h:395
unsigned int uint32
Definition: juce_MathsFunctions.h:51
static void copyWithCharLimit(DestCharPointerType &dest, SrcCharPointerType src, int maxChars) noexcept
Definition: juce_CharacterFunctions.h:377
juce_wchar toUpperCase() const noexcept
Definition: juce_CharPointer_UTF8.h:474
static int compareIgnoreCase(CharPointerType1 s1, CharPointerType2 s2) noexcept
Definition: juce_CharacterFunctions.h:427
size_t writeWithDestByteLimit(const CharPointer src, const size_t maxDestBytes) noexcept
Definition: juce_CharPointer_UTF8.h:385
void writeNull() const noexcept
Definition: juce_CharPointer_UTF8.h:356
long long int64
Definition: juce_MathsFunctions.h:60
bool operator==(CharPointer_UTF8 other) const noexcept
Definition: juce_CharPointer_UTF8.h:66
bool operator!=(CharPointer_UTF8 other) const noexcept
Definition: juce_CharPointer_UTF8.h:67
CharPointer_UTF8 findTerminatingNull() const noexcept
Definition: juce_CharPointer_UTF8.h:324
int compareIgnoreCaseUpTo(const CharPointer other, const int maxChars) const noexcept
Definition: juce_CharPointer_UTF8.h:435
static int indexOfChar(Type text, const juce_wchar charToFind) noexcept
Definition: juce_CharacterFunctions.h:544
CharPointer_UTF8 operator--() noexcept
Definition: juce_CharPointer_UTF8.h:139
int64 getIntValue64() const noexcept
Definition: juce_CharPointer_UTF8.h:482
bool isWhitespace() const noexcept
Definition: juce_CharPointer_UTF8.h:461
Definition: juce_CharPointer_UTF8.h:552
bool isLetter() const noexcept
Definition: juce_CharPointer_UTF8.h:465
bool operator>=(CharPointer_UTF8 other) const noexcept
Definition: juce_CharPointer_UTF8.h:70
#define jassert(a)
Definition: juce_PlatformDefs.h:146
void writeAll(const CharPointer src) noexcept
Definition: juce_CharPointer_UTF8.h:363
static int compareUpTo(CharPointerType1 s1, CharPointerType2 s2, int maxChars) noexcept
Definition: juce_CharacterFunctions.h:410
int indexOf(const juce_wchar charToFind) const noexcept
Definition: juce_CharPointer_UTF8.h:448
static int indexOfCharIgnoreCase(Type text, juce_wchar charToFind) noexcept
Definition: juce_CharacterFunctions.h:564
static bool isLowerCase(juce_wchar character) noexcept
Definition: juce_CharacterFunctions.cpp:54
CharPointer_UTF8 atomicSwap(const CharPointer_UTF8 newValue)
Definition: juce_CharPointer_UTF8.h:544
bool isLetterOrDigit() const noexcept
Definition: juce_CharPointer_UTF8.h:467
static bool isValidString(const CharType *dataToTest, int maxBytesToRead)
Definition: juce_CharPointer_UTF8.h:506
int compare(const CharPointer other) const noexcept
Definition: juce_CharPointer_UTF8.h:402
int compareIgnoreCase(const CharPointer_UTF8 other) const noexcept
Definition: juce_CharPointer_UTF8.h:422
double getDoubleValue() const noexcept
Definition: juce_CharPointer_UTF8.h:494
static bool isUpperCase(juce_wchar character) noexcept
Definition: juce_CharacterFunctions.cpp:45
static int compareIgnoreCaseUpTo(CharPointerType1 s1, CharPointerType2 s2, int maxChars) noexcept
Definition: juce_CharacterFunctions.h:446
static bool isByteOrderMark(const void *possibleByteOrder) noexcept
Definition: juce_CharPointer_UTF8.h:560
static size_t getBytesRequiredFor(const juce_wchar charToWrite) noexcept
Definition: juce_CharPointer_UTF8.h:288
CharPointer_UTF8 & operator++() noexcept
Definition: juce_CharPointer_UTF8.h:119
juce_wchar getAndAdvance() noexcept
Definition: juce_CharPointer_UTF8.h:151
CharPointer_UTF8 operator-(int numToSkip) const noexcept
Definition: juce_CharPointer_UTF8.h:233
CharPointer_UTF8 operator+(int numToSkip) const noexcept
Definition: juce_CharPointer_UTF8.h:225
CharType * getAddress() const noexcept
Definition: juce_CharPointer_UTF8.h:74
unsigned char uint8
Definition: juce_MathsFunctions.h:43
size_t lengthUpTo(const size_t maxCharsToCount) const noexcept
Definition: juce_CharPointer_UTF8.h:265
void operator-=(int numToSkip) noexcept
Definition: juce_CharPointer_UTF8.h:211
void operator+=(int numToSkip) noexcept
Definition: juce_CharPointer_UTF8.h:196
wchar_t juce_wchar
Definition: juce_CharacterFunctions.h:49
int indexOf(const juce_wchar charToFind, const bool ignoreCase) const noexcept
Definition: juce_CharPointer_UTF8.h:454
size_t length() const noexcept
Definition: juce_CharPointer_UTF8.h:241
bool operator<(CharPointer_UTF8 other) const noexcept
Definition: juce_CharPointer_UTF8.h:69
int compareIgnoreCase(const CharPointer other) const noexcept
Definition: juce_CharPointer_UTF8.h:416