OpenShot Library | libopenshot-audio  0.1.9
juce_CharacterFunctions.h
1 
2 /** @weakgroup juce_core-text
3  * @{
4  */
5 /*
6  ==============================================================================
7 
8  This file is part of the JUCE library.
9  Copyright (c) 2017 - ROLI Ltd.
10 
11  JUCE is an open source library subject to commercial or open-source
12  licensing.
13 
14  The code included in this file is provided under the terms of the ISC license
15  http://www.isc.org/downloads/software-support-policy/isc-license. Permission
16  To use, copy, modify, and/or distribute this software for any purpose with or
17  without fee is hereby granted provided that the above copyright notice and
18  this permission notice appear in all copies.
19 
20  JUCE IS PROVIDED "AS IS" WITHOUT ANY WARRANTY, AND ALL WARRANTIES, WHETHER
21  EXPRESSED OR IMPLIED, INCLUDING MERCHANTABILITY AND FITNESS FOR PURPOSE, ARE
22  DISCLAIMED.
23 
24  ==============================================================================
25 */
26 
27 namespace juce
28 {
29 
30 //==============================================================================
31 #if JUCE_WINDOWS && ! DOXYGEN
32  #define JUCE_NATIVE_WCHAR_IS_UTF8 0
33  #define JUCE_NATIVE_WCHAR_IS_UTF16 1
34  #define JUCE_NATIVE_WCHAR_IS_UTF32 0
35 #else
36  /** This macro will be set to 1 if the compiler's native wchar_t is an 8-bit type. */
37  #define JUCE_NATIVE_WCHAR_IS_UTF8 0
38  /** This macro will be set to 1 if the compiler's native wchar_t is a 16-bit type. */
39  #define JUCE_NATIVE_WCHAR_IS_UTF16 0
40  /** This macro will be set to 1 if the compiler's native wchar_t is a 32-bit type. */
41  #define JUCE_NATIVE_WCHAR_IS_UTF32 1
42 #endif
43 
44 #if JUCE_NATIVE_WCHAR_IS_UTF32 || DOXYGEN
45  /** A platform-independent 32-bit unicode character type. */
46  using juce_wchar = wchar_t;
47 #else
48  using juce_wchar = uint32;
49 #endif
50 
51 #ifndef DOXYGEN
52  /** This macro is deprecated, but preserved for compatibility with old code. */
53  #define JUCE_T(stringLiteral) (L##stringLiteral)
54 #endif
55 
56 #if JUCE_DEFINE_T_MACRO
57  /** The 'T' macro is an alternative for using the "L" prefix in front of a string literal.
58 
59  This macro is deprecated, but available for compatibility with old code if you set
60  JUCE_DEFINE_T_MACRO = 1. The fastest, most portable and best way to write your string
61  literals is as standard char strings, using escaped utf-8 character sequences for extended
62  characters, rather than trying to store them as wide-char strings.
63  */
64  #define T(stringLiteral) JUCE_T(stringLiteral)
65 #endif
66 
67 #if ! DOXYGEN
68 
69 //==============================================================================
70 // GNU libstdc++ does not have std::make_unsigned
71 namespace internal
72 {
73  template <typename Type> struct make_unsigned { using type = Type; };
74  template <> struct make_unsigned<signed char> { using type = unsigned char; };
75  template <> struct make_unsigned<char> { using type = unsigned char; };
76  template <> struct make_unsigned<short> { using type = unsigned short; };
77  template <> struct make_unsigned<int> { using type = unsigned int; };
78  template <> struct make_unsigned<long> { using type = unsigned long; };
79  template <> struct make_unsigned<long long> { using type = unsigned long long; };
80 }
81 
82 #endif
83 
84 //==============================================================================
85 /**
86  A collection of functions for manipulating characters and character strings.
87 
88  Most of these methods are designed for internal use by the String and CharPointer
89  classes, but some of them may be useful to call directly.
90 
91  @see String, CharPointer_UTF8, CharPointer_UTF16, CharPointer_UTF32
92 
93  @tags{Core}
94 */
96 {
97 public:
98  //==============================================================================
99  /** Converts a character to upper-case. */
100  static juce_wchar toUpperCase (juce_wchar character) noexcept;
101  /** Converts a character to lower-case. */
102  static juce_wchar toLowerCase (juce_wchar character) noexcept;
103 
104  /** Checks whether a unicode character is upper-case. */
105  static bool isUpperCase (juce_wchar character) noexcept;
106  /** Checks whether a unicode character is lower-case. */
107  static bool isLowerCase (juce_wchar character) noexcept;
108 
109  /** Checks whether a character is whitespace. */
110  static bool isWhitespace (char character) noexcept;
111  /** Checks whether a character is whitespace. */
112  static bool isWhitespace (juce_wchar character) noexcept;
113 
114  /** Checks whether a character is a digit. */
115  static bool isDigit (char character) noexcept;
116  /** Checks whether a character is a digit. */
117  static bool isDigit (juce_wchar character) noexcept;
118 
119  /** Checks whether a character is alphabetic. */
120  static bool isLetter (char character) noexcept;
121  /** Checks whether a character is alphabetic. */
122  static bool isLetter (juce_wchar character) noexcept;
123 
124  /** Checks whether a character is alphabetic or numeric. */
125  static bool isLetterOrDigit (char character) noexcept;
126  /** Checks whether a character is alphabetic or numeric. */
127  static bool isLetterOrDigit (juce_wchar character) noexcept;
128 
129  /** Checks whether a character is a printable character, i.e. alphabetic, numeric,
130  a punctuation character or a space.
131  */
132  static bool isPrintable (char character) noexcept;
133 
134  /** Checks whether a character is a printable character, i.e. alphabetic, numeric,
135  a punctuation character or a space.
136  */
137  static bool isPrintable (juce_wchar character) noexcept;
138 
139  /** Returns 0 to 16 for '0' to 'F", or -1 for characters that aren't a legal hex digit. */
140  static int getHexDigitValue (juce_wchar digit) noexcept;
141 
142  /** Converts a byte of Windows 1252 codepage to unicode. */
143  static juce_wchar getUnicodeCharFromWindows1252Codepage (uint8 windows1252Char) noexcept;
144 
145  //==============================================================================
146  /** Parses a character string to read a floating-point number.
147  Note that this will advance the pointer that is passed in, leaving it at
148  the end of the number.
149  */
150  template <typename CharPointerType>
151  static double readDoubleValue (CharPointerType& text) noexcept
152  {
153  #if JUCE_MINGW
154  bool isNegative = false;
155  #else
156  JUCE_CONSTEXPR const int maxSignificantDigits = 17 + 1; // An additional digit for rounding
157  JUCE_CONSTEXPR const int bufferSize = maxSignificantDigits + 7 + 1; // -.E-XXX and a trailing null-terminator
158  char buffer[bufferSize] = {};
159  char* currentCharacter = &(buffer[0]);
160  #endif
161 
162  text = text.findEndOfWhitespace();
163  auto c = *text;
164 
165  switch (c)
166  {
167  case '-':
168  #if JUCE_MINGW
169  isNegative = true;
170  #else
171  *currentCharacter++ = '-';
172  #endif
173  // Fall-through..
174  case '+':
175  c = *++text;
176  }
177 
178  switch (c)
179  {
180  case 'n':
181  case 'N':
182  if ((text[1] == 'a' || text[1] == 'A') && (text[2] == 'n' || text[2] == 'N'))
183  return std::numeric_limits<double>::quiet_NaN();
184  break;
185 
186  case 'i':
187  case 'I':
188  if ((text[1] == 'n' || text[1] == 'N') && (text[2] == 'f' || text[2] == 'F'))
189  return std::numeric_limits<double>::infinity();
190  break;
191  }
192 
193  #if JUCE_MINGW
194  // MinGW does not have access to the locale functions required for strtold, so we parse the doubles
195  // ourselves. There are some edge cases where the least significant digit will be wrong!
196  double result[3] = { 0 }, accumulator[2] = { 0 };
197  int exponentAdjustment[2] = { 0 }, exponentAccumulator[2] = { -1, -1 };
198  int exponent = 0, decPointIndex = 0, digit = 0;
199  int lastDigit = 0, numSignificantDigits = 0;
200  bool digitsFound = false;
201  JUCE_CONSTEXPR const int maxSignificantDigits = 17 + 1;
202 
203  for (;;)
204  {
205  if (text.isDigit())
206  {
207  lastDigit = digit;
208  digit = (int) text.getAndAdvance() - '0';
209  digitsFound = true;
210 
211  if (decPointIndex != 0)
212  exponentAdjustment[1]++;
213 
214  if (numSignificantDigits == 0 && digit == 0)
215  continue;
216 
217  if (++numSignificantDigits > maxSignificantDigits)
218  {
219  if (digit > 5)
220  ++accumulator [decPointIndex];
221  else if (digit == 5 && (lastDigit & 1) != 0)
222  ++accumulator [decPointIndex];
223 
224  if (decPointIndex > 0)
225  exponentAdjustment[1]--;
226  else
227  exponentAdjustment[0]++;
228 
229  while (text.isDigit())
230  {
231  ++text;
232  if (decPointIndex == 0)
233  exponentAdjustment[0]++;
234  }
235  }
236  else
237  {
238  const auto maxAccumulatorValue = (double) ((std::numeric_limits<unsigned int>::max() - 9) / 10);
239  if (accumulator [decPointIndex] > maxAccumulatorValue)
240  {
241  result [decPointIndex] = mulexp10 (result [decPointIndex], exponentAccumulator [decPointIndex])
242  + accumulator [decPointIndex];
243  accumulator [decPointIndex] = 0;
244  exponentAccumulator [decPointIndex] = 0;
245  }
246 
247  accumulator [decPointIndex] = accumulator[decPointIndex] * 10 + digit;
248  exponentAccumulator [decPointIndex]++;
249  }
250  }
251  else if (decPointIndex == 0 && *text == '.')
252  {
253  ++text;
254  decPointIndex = 1;
255 
256  if (numSignificantDigits > maxSignificantDigits)
257  {
258  while (text.isDigit())
259  ++text;
260  break;
261  }
262  }
263  else
264  {
265  break;
266  }
267  }
268 
269  result[0] = mulexp10 (result[0], exponentAccumulator[0]) + accumulator[0];
270 
271  if (decPointIndex != 0)
272  result[1] = mulexp10 (result[1], exponentAccumulator[1]) + accumulator[1];
273 
274  c = *text;
275  if ((c == 'e' || c == 'E') && digitsFound)
276  {
277  auto negativeExponent = false;
278 
279  switch (*++text)
280  {
281  case '-': negativeExponent = true; // fall-through..
282  case '+': ++text;
283  }
284 
285  while (text.isDigit())
286  exponent = (exponent * 10) + ((int) text.getAndAdvance() - '0');
287 
288  if (negativeExponent)
289  exponent = -exponent;
290  }
291 
292  auto r = mulexp10 (result[0], exponent + exponentAdjustment[0]);
293  if (decPointIndex != 0)
294  r += mulexp10 (result[1], exponent - exponentAdjustment[1]);
295 
296  return isNegative ? -r : r;
297 
298  #else // ! JUCE_MINGW
299 
300  int numSigFigs = 0;
301  bool decimalPointFound = false;
302  int extraExponent = 0;
303 
304  for (;;)
305  {
306  if (text.isDigit())
307  {
308  auto digit = (int) text.getAndAdvance() - '0';
309 
310  if (decimalPointFound)
311  {
312  if (numSigFigs >= maxSignificantDigits)
313  continue;
314  }
315  else
316  {
317  if (numSigFigs >= maxSignificantDigits)
318  {
319  ++extraExponent;
320  continue;
321  }
322 
323  if (numSigFigs == 0 && digit == 0)
324  continue;
325  }
326 
327  *currentCharacter++ = (char) ('0' + (char) digit);
328  numSigFigs++;
329  }
330  else if ((! decimalPointFound) && *text == '.')
331  {
332  ++text;
333  *currentCharacter++ = '.';
334  decimalPointFound = true;
335  }
336  else
337  {
338  break;
339  }
340  }
341 
342  c = *text;
343 
344  auto writeExponentDigits = [](int exponent, char* destination)
345  {
346  auto exponentDivisor = 100;
347 
348  while (exponentDivisor > 1)
349  {
350  auto digit = exponent / exponentDivisor;
351  *destination++ = (char) ('0' + (char) digit);
352  exponent -= digit * exponentDivisor;
353  exponentDivisor /= 10;
354  }
355 
356  *destination++ = (char) ('0' + (char) exponent);
357  };
358 
359  if ((c == 'e' || c == 'E') && numSigFigs > 0)
360  {
361  *currentCharacter++ = 'e';
362  bool parsedExponentIsPositive = true;
363 
364  switch (*++text)
365  {
366  case '-': parsedExponentIsPositive = false; // Fall-through..
367  case '+': ++text;
368  }
369 
370  int exponent = 0;
371 
372  while (text.isDigit())
373  {
374  auto digit = (int) text.getAndAdvance() - '0';
375 
376  if (digit != 0 || exponent != 0)
377  exponent = (exponent * 10) + digit;
378  }
379 
380  exponent = extraExponent + (parsedExponentIsPositive ? exponent : -exponent);
381 
382  if (exponent < 0)
383  *currentCharacter++ = '-';
384 
385  exponent = std::abs (exponent);
386 
387  if (exponent > std::numeric_limits<double>::max_exponent10)
388  return std::numeric_limits<double>::quiet_NaN();
389 
390  writeExponentDigits (exponent, currentCharacter);
391  }
392  else if (extraExponent > 0)
393  {
394  *currentCharacter++ = 'e';
395  writeExponentDigits (extraExponent, currentCharacter);
396  }
397 
398  #if JUCE_WINDOWS
399  static _locale_t locale = _create_locale (LC_ALL, "C");
400  return _strtod_l (&buffer[0], nullptr, locale);
401  #else
402  static locale_t locale = newlocale (LC_ALL_MASK, "C", nullptr);
403  #if JUCE_ANDROID
404  return (double) strtold_l (&buffer[0], nullptr, locale);
405  #else
406  return strtod_l (&buffer[0], nullptr, locale);
407  #endif
408  #endif
409 
410  #endif // JUCE_MINGW
411  }
412 
413  /** Parses a character string, to read a floating-point value. */
414  template <typename CharPointerType>
415  static double getDoubleValue (CharPointerType text) noexcept
416  {
417  return readDoubleValue (text);
418  }
419 
420  //==============================================================================
421  /** Parses a character string, to read an integer value. */
422  template <typename IntType, typename CharPointerType>
423  static IntType getIntValue (const CharPointerType text) noexcept
424  {
425  using UIntType = typename internal::make_unsigned<IntType>::type;
426 
427  UIntType v = 0;
428  auto s = text.findEndOfWhitespace();
429  const bool isNeg = *s == '-';
430 
431  if (isNeg)
432  ++s;
433 
434  for (;;)
435  {
436  auto c = s.getAndAdvance();
437 
438  if (c >= '0' && c <= '9')
439  v = v * 10 + (UIntType) (c - '0');
440  else
441  break;
442  }
443 
444  return isNeg ? - (IntType) v : (IntType) v;
445  }
446 
447  /** Parses a character string, to read a hexadecimal value. */
448  template <typename ResultType>
449  struct HexParser
450  {
451  template <typename CharPointerType>
452  static ResultType parse (CharPointerType t) noexcept
453  {
454  ResultType result = 0;
455 
456  while (! t.isEmpty())
457  {
458  auto hexValue = CharacterFunctions::getHexDigitValue (t.getAndAdvance());
459 
460  if (hexValue >= 0)
461  result = (result << 4) | hexValue;
462  }
463 
464  return result;
465  }
466  };
467 
468  //==============================================================================
469  /** Counts the number of characters in a given string, stopping if the count exceeds
470  a specified limit. */
471  template <typename CharPointerType>
472  static size_t lengthUpTo (CharPointerType text, const size_t maxCharsToCount) noexcept
473  {
474  size_t len = 0;
475 
476  while (len < maxCharsToCount && text.getAndAdvance() != 0)
477  ++len;
478 
479  return len;
480  }
481 
482  /** Counts the number of characters in a given string, stopping if the count exceeds
483  a specified end-pointer. */
484  template <typename CharPointerType>
485  static size_t lengthUpTo (CharPointerType start, const CharPointerType end) noexcept
486  {
487  size_t len = 0;
488 
489  while (start < end && start.getAndAdvance() != 0)
490  ++len;
491 
492  return len;
493  }
494 
495  /** Copies null-terminated characters from one string to another. */
496  template <typename DestCharPointerType, typename SrcCharPointerType>
497  static void copyAll (DestCharPointerType& dest, SrcCharPointerType src) noexcept
498  {
499  while (auto c = src.getAndAdvance())
500  dest.write (c);
501 
502  dest.writeNull();
503  }
504 
505  /** Copies characters from one string to another, up to a null terminator
506  or a given byte size limit. */
507  template <typename DestCharPointerType, typename SrcCharPointerType>
508  static size_t copyWithDestByteLimit (DestCharPointerType& dest, SrcCharPointerType src, size_t maxBytesToWrite) noexcept
509  {
510  auto startAddress = dest.getAddress();
511  auto maxBytes = (ssize_t) maxBytesToWrite;
512  maxBytes -= sizeof (typename DestCharPointerType::CharType); // (allow for a terminating null)
513 
514  for (;;)
515  {
516  auto c = src.getAndAdvance();
517  auto bytesNeeded = DestCharPointerType::getBytesRequiredFor (c);
518  maxBytes -= bytesNeeded;
519 
520  if (c == 0 || maxBytes < 0)
521  break;
522 
523  dest.write (c);
524  }
525 
526  dest.writeNull();
527 
528  return (size_t) getAddressDifference (dest.getAddress(), startAddress)
529  + sizeof (typename DestCharPointerType::CharType);
530  }
531 
532  /** Copies characters from one string to another, up to a null terminator
533  or a given maximum number of characters. */
534  template <typename DestCharPointerType, typename SrcCharPointerType>
535  static void copyWithCharLimit (DestCharPointerType& dest, SrcCharPointerType src, int maxChars) noexcept
536  {
537  while (--maxChars > 0)
538  {
539  auto c = src.getAndAdvance();
540 
541  if (c == 0)
542  break;
543 
544  dest.write (c);
545  }
546 
547  dest.writeNull();
548  }
549 
550  /** Compares two characters. */
551  static inline int compare (juce_wchar char1, juce_wchar char2) noexcept
552  {
553  if (auto diff = static_cast<int> (char1) - static_cast<int> (char2))
554  return diff < 0 ? -1 : 1;
555 
556  return 0;
557  }
558 
559  /** Compares two null-terminated character strings. */
560  template <typename CharPointerType1, typename CharPointerType2>
561  static int compare (CharPointerType1 s1, CharPointerType2 s2) noexcept
562  {
563  for (;;)
564  {
565  auto c1 = s1.getAndAdvance();
566 
567  if (auto diff = compare (c1, s2.getAndAdvance()))
568  return diff;
569 
570  if (c1 == 0)
571  break;
572  }
573 
574  return 0;
575  }
576 
577  /** Compares two null-terminated character strings, up to a given number of characters. */
578  template <typename CharPointerType1, typename CharPointerType2>
579  static int compareUpTo (CharPointerType1 s1, CharPointerType2 s2, int maxChars) noexcept
580  {
581  while (--maxChars >= 0)
582  {
583  auto c1 = s1.getAndAdvance();
584 
585  if (auto diff = compare (c1, s2.getAndAdvance()))
586  return diff;
587 
588  if (c1 == 0)
589  break;
590  }
591 
592  return 0;
593  }
594 
595  /** Compares two characters, using a case-independant match. */
596  static inline int compareIgnoreCase (juce_wchar char1, juce_wchar char2) noexcept
597  {
598  return char1 != char2 ? compare (toUpperCase (char1), toUpperCase (char2)) : 0;
599  }
600 
601  /** Compares two null-terminated character strings, using a case-independant match. */
602  template <typename CharPointerType1, typename CharPointerType2>
603  static int compareIgnoreCase (CharPointerType1 s1, CharPointerType2 s2) noexcept
604  {
605  for (;;)
606  {
607  auto c1 = s1.getAndAdvance();
608 
609  if (auto diff = compareIgnoreCase (c1, s2.getAndAdvance()))
610  return diff;
611 
612  if (c1 == 0)
613  break;
614  }
615 
616  return 0;
617  }
618 
619  /** Compares two null-terminated character strings, using a case-independent match. */
620  template <typename CharPointerType1, typename CharPointerType2>
621  static int compareIgnoreCaseUpTo (CharPointerType1 s1, CharPointerType2 s2, int maxChars) noexcept
622  {
623  while (--maxChars >= 0)
624  {
625  auto c1 = s1.getAndAdvance();
626 
627  if (auto diff = compareIgnoreCase (c1, s2.getAndAdvance()))
628  return diff;
629 
630  if (c1 == 0)
631  break;
632  }
633 
634  return 0;
635  }
636 
637  /** Finds the character index of a given substring in another string.
638  Returns -1 if the substring is not found.
639  */
640  template <typename CharPointerType1, typename CharPointerType2>
641  static int indexOf (CharPointerType1 textToSearch, const CharPointerType2 substringToLookFor) noexcept
642  {
643  int index = 0;
644  auto substringLength = (int) substringToLookFor.length();
645 
646  for (;;)
647  {
648  if (textToSearch.compareUpTo (substringToLookFor, substringLength) == 0)
649  return index;
650 
651  if (textToSearch.getAndAdvance() == 0)
652  return -1;
653 
654  ++index;
655  }
656  }
657 
658  /** Returns a pointer to the first occurrence of a substring in a string.
659  If the substring is not found, this will return a pointer to the string's
660  null terminator.
661  */
662  template <typename CharPointerType1, typename CharPointerType2>
663  static CharPointerType1 find (CharPointerType1 textToSearch, const CharPointerType2 substringToLookFor) noexcept
664  {
665  auto substringLength = (int) substringToLookFor.length();
666 
667  while (textToSearch.compareUpTo (substringToLookFor, substringLength) != 0
668  && ! textToSearch.isEmpty())
669  ++textToSearch;
670 
671  return textToSearch;
672  }
673 
674  /** Returns a pointer to the first occurrence of a substring in a string.
675  If the substring is not found, this will return a pointer to the string's
676  null terminator.
677  */
678  template <typename CharPointerType>
679  static CharPointerType find (CharPointerType textToSearch, const juce_wchar charToLookFor) noexcept
680  {
681  for (;; ++textToSearch)
682  {
683  auto c = *textToSearch;
684 
685  if (c == charToLookFor || c == 0)
686  break;
687  }
688 
689  return textToSearch;
690  }
691 
692  /** Finds the character index of a given substring in another string, using
693  a case-independent match.
694  Returns -1 if the substring is not found.
695  */
696  template <typename CharPointerType1, typename CharPointerType2>
697  static int indexOfIgnoreCase (CharPointerType1 haystack, const CharPointerType2 needle) noexcept
698  {
699  int index = 0;
700  auto needleLength = (int) needle.length();
701 
702  for (;;)
703  {
704  if (haystack.compareIgnoreCaseUpTo (needle, needleLength) == 0)
705  return index;
706 
707  if (haystack.getAndAdvance() == 0)
708  return -1;
709 
710  ++index;
711  }
712  }
713 
714  /** Finds the character index of a given character in another string.
715  Returns -1 if the character is not found.
716  */
717  template <typename Type>
718  static int indexOfChar (Type text, const juce_wchar charToFind) noexcept
719  {
720  int i = 0;
721 
722  while (! text.isEmpty())
723  {
724  if (text.getAndAdvance() == charToFind)
725  return i;
726 
727  ++i;
728  }
729 
730  return -1;
731  }
732 
733  /** Finds the character index of a given character in another string, using
734  a case-independent match.
735  Returns -1 if the character is not found.
736  */
737  template <typename Type>
738  static int indexOfCharIgnoreCase (Type text, juce_wchar charToFind) noexcept
739  {
740  charToFind = CharacterFunctions::toLowerCase (charToFind);
741  int i = 0;
742 
743  while (! text.isEmpty())
744  {
745  if (text.toLowerCase() == charToFind)
746  return i;
747 
748  ++text;
749  ++i;
750  }
751 
752  return -1;
753  }
754 
755  /** Returns a pointer to the first non-whitespace character in a string.
756  If the string contains only whitespace, this will return a pointer
757  to its null terminator.
758  */
759  template <typename Type>
760  static Type findEndOfWhitespace (Type text) noexcept
761  {
762  while (text.isWhitespace())
763  ++text;
764 
765  return text;
766  }
767 
768  /** Returns a pointer to the first character in the string which is found in
769  the breakCharacters string.
770  */
771  template <typename Type, typename BreakType>
772  static Type findEndOfToken (Type text, BreakType breakCharacters, Type quoteCharacters)
773  {
774  juce_wchar currentQuoteChar = 0;
775 
776  while (! text.isEmpty())
777  {
778  auto c = text.getAndAdvance();
779 
780  if (currentQuoteChar == 0 && breakCharacters.indexOf (c) >= 0)
781  {
782  --text;
783  break;
784  }
785 
786  if (quoteCharacters.indexOf (c) >= 0)
787  {
788  if (currentQuoteChar == 0)
789  currentQuoteChar = c;
790  else if (currentQuoteChar == c)
791  currentQuoteChar = 0;
792  }
793  }
794 
795  return text;
796  }
797 
798 private:
799  static double mulexp10 (double value, int exponent) noexcept;
800 };
801 
802 } // namespace juce
803 
804 /** @}*/
static double getDoubleValue(CharPointerType text) noexcept
Parses a character string, to read a floating-point value.
#define JUCE_API
This macro is added to all JUCE public class declarations.
static Type findEndOfToken(Type text, BreakType breakCharacters, Type quoteCharacters)
Returns a pointer to the first character in the string which is found in the breakCharacters string...
A collection of functions for manipulating characters and character strings.
static size_t lengthUpTo(CharPointerType start, const CharPointerType end) noexcept
Counts the number of characters in a given string, stopping if the count exceeds a specified end-poin...
static int indexOfCharIgnoreCase(Type text, juce_wchar charToFind) noexcept
Finds the character index of a given character in another string, using a case-independent match...
static void copyAll(DestCharPointerType &dest, SrcCharPointerType src) noexcept
Copies null-terminated characters from one string to another.
static int compareIgnoreCase(juce_wchar char1, juce_wchar char2) noexcept
Compares two characters, using a case-independant match.
static double readDoubleValue(CharPointerType &text) noexcept
Parses a character string to read a floating-point number.
static Type findEndOfWhitespace(Type text) noexcept
Returns a pointer to the first non-whitespace character in a string.
static int compare(CharPointerType1 s1, CharPointerType2 s2) noexcept
Compares two null-terminated character strings.
static IntType getIntValue(const CharPointerType text) noexcept
Parses a character string, to read an integer value.
static int indexOfChar(Type text, const juce_wchar charToFind) noexcept
Finds the character index of a given character in another string.
static int compareIgnoreCaseUpTo(CharPointerType1 s1, CharPointerType2 s2, int maxChars) noexcept
Compares two null-terminated character strings, using a case-independent match.
static CharPointerType1 find(CharPointerType1 textToSearch, const CharPointerType2 substringToLookFor) noexcept
Returns a pointer to the first occurrence of a substring in a string.
static size_t lengthUpTo(CharPointerType text, const size_t maxCharsToCount) noexcept
Counts the number of characters in a given string, stopping if the count exceeds a specified limit...
static CharPointerType find(CharPointerType textToSearch, const juce_wchar charToLookFor) noexcept
Returns a pointer to the first occurrence of a substring in a string.
static size_t copyWithDestByteLimit(DestCharPointerType &dest, SrcCharPointerType src, size_t maxBytesToWrite) noexcept
Copies characters from one string to another, up to a null terminator or a given byte size limit...
static int getHexDigitValue(juce_wchar digit) noexcept
Returns 0 to 16 for &#39;0&#39; to &#39;F", or -1 for characters that aren&#39;t a legal hex digit.
static juce_wchar toLowerCase(juce_wchar character) noexcept
Converts a character to lower-case.
static int compareIgnoreCase(CharPointerType1 s1, CharPointerType2 s2) noexcept
Compares two null-terminated character strings, using a case-independant match.
static int indexOf(CharPointerType1 textToSearch, const CharPointerType2 substringToLookFor) noexcept
Finds the character index of a given substring in another string.
Parses a character string, to read a hexadecimal value.
static int compareUpTo(CharPointerType1 s1, CharPointerType2 s2, int maxChars) noexcept
Compares two null-terminated character strings, up to a given number of characters.
static int indexOfIgnoreCase(CharPointerType1 haystack, const CharPointerType2 needle) noexcept
Finds the character index of a given substring in another string, using a case-independent match...
static void copyWithCharLimit(DestCharPointerType &dest, SrcCharPointerType src, int maxChars) noexcept
Copies characters from one string to another, up to a null terminator or a given maximum number of ch...
static int compare(juce_wchar char1, juce_wchar char2) noexcept
Compares two characters.