openshot-audio  0.1.2
juce_CharacterFunctions.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_CHARACTERFUNCTIONS_H_INCLUDED
30 #define JUCE_CHARACTERFUNCTIONS_H_INCLUDED
31 
32 
33 //==============================================================================
34 #if JUCE_WINDOWS && ! DOXYGEN
35  #define JUCE_NATIVE_WCHAR_IS_UTF8 0
36  #define JUCE_NATIVE_WCHAR_IS_UTF16 1
37  #define JUCE_NATIVE_WCHAR_IS_UTF32 0
38 #else
39 
40  #define JUCE_NATIVE_WCHAR_IS_UTF8 0
41 
42  #define JUCE_NATIVE_WCHAR_IS_UTF16 0
43 
44  #define JUCE_NATIVE_WCHAR_IS_UTF32 1
45 #endif
46 
47 #if JUCE_NATIVE_WCHAR_IS_UTF32 || DOXYGEN
48 
49  typedef wchar_t juce_wchar;
50 #else
51  typedef uint32 juce_wchar;
52 #endif
53 
54 #ifndef DOXYGEN
55 
56  #define JUCE_T(stringLiteral) (L##stringLiteral)
57 #endif
58 
59 #if JUCE_DEFINE_T_MACRO
60 
67  #define T(stringLiteral) JUCE_T(stringLiteral)
68 #endif
69 
70 //==============================================================================
80 {
81 public:
82  //==============================================================================
84  static juce_wchar toUpperCase (juce_wchar character) noexcept;
86  static juce_wchar toLowerCase (juce_wchar character) noexcept;
87 
89  static bool isUpperCase (juce_wchar character) noexcept;
91  static bool isLowerCase (juce_wchar character) noexcept;
92 
94  static bool isWhitespace (char character) noexcept;
96  static bool isWhitespace (juce_wchar character) noexcept;
97 
99  static bool isDigit (char character) noexcept;
101  static bool isDigit (juce_wchar character) noexcept;
102 
104  static bool isLetter (char character) noexcept;
106  static bool isLetter (juce_wchar character) noexcept;
107 
109  static bool isLetterOrDigit (char character) noexcept;
111  static bool isLetterOrDigit (juce_wchar character) noexcept;
112 
114  static int getHexDigitValue (juce_wchar digit) noexcept;
115 
116  //==============================================================================
121  template <typename CharPointerType>
122  static double readDoubleValue (CharPointerType& text) noexcept
123  {
124  double result[3] = { 0 }, accumulator[2] = { 0 };
125  int exponentAdjustment[2] = { 0 }, exponentAccumulator[2] = { -1, -1 };
126  int exponent = 0, decPointIndex = 0, digit = 0;
127  int lastDigit = 0, numSignificantDigits = 0;
128  bool isNegative = false, digitsFound = false;
129  const int maxSignificantDigits = 15 + 2;
130 
131  text = text.findEndOfWhitespace();
132  juce_wchar c = *text;
133 
134  switch (c)
135  {
136  case '-': isNegative = true; // fall-through..
137  case '+': c = *++text;
138  }
139 
140  switch (c)
141  {
142  case 'n':
143  case 'N':
144  if ((text[1] == 'a' || text[1] == 'A') && (text[2] == 'n' || text[2] == 'N'))
145  return std::numeric_limits<double>::quiet_NaN();
146  break;
147 
148  case 'i':
149  case 'I':
150  if ((text[1] == 'n' || text[1] == 'N') && (text[2] == 'f' || text[2] == 'F'))
151  return std::numeric_limits<double>::infinity();
152  break;
153  }
154 
155  for (;;)
156  {
157  if (text.isDigit())
158  {
159  lastDigit = digit;
160  digit = (int) text.getAndAdvance() - '0';
161  digitsFound = true;
162 
163  if (decPointIndex != 0)
164  exponentAdjustment[1]++;
165 
166  if (numSignificantDigits == 0 && digit == 0)
167  continue;
168 
169  if (++numSignificantDigits > maxSignificantDigits)
170  {
171  if (digit > 5)
172  ++accumulator [decPointIndex];
173  else if (digit == 5 && (lastDigit & 1) != 0)
174  ++accumulator [decPointIndex];
175 
176  if (decPointIndex > 0)
177  exponentAdjustment[1]--;
178  else
179  exponentAdjustment[0]++;
180 
181  while (text.isDigit())
182  {
183  ++text;
184  if (decPointIndex == 0)
185  exponentAdjustment[0]++;
186  }
187  }
188  else
189  {
190  const double maxAccumulatorValue = (double) ((std::numeric_limits<unsigned int>::max() - 9) / 10);
191  if (accumulator [decPointIndex] > maxAccumulatorValue)
192  {
193  result [decPointIndex] = mulexp10 (result [decPointIndex], exponentAccumulator [decPointIndex])
194  + accumulator [decPointIndex];
195  accumulator [decPointIndex] = 0;
196  exponentAccumulator [decPointIndex] = 0;
197  }
198 
199  accumulator [decPointIndex] = accumulator[decPointIndex] * 10 + digit;
200  exponentAccumulator [decPointIndex]++;
201  }
202  }
203  else if (decPointIndex == 0 && *text == '.')
204  {
205  ++text;
206  decPointIndex = 1;
207 
208  if (numSignificantDigits > maxSignificantDigits)
209  {
210  while (text.isDigit())
211  ++text;
212  break;
213  }
214  }
215  else
216  {
217  break;
218  }
219  }
220 
221  result[0] = mulexp10 (result[0], exponentAccumulator[0]) + accumulator[0];
222 
223  if (decPointIndex != 0)
224  result[1] = mulexp10 (result[1], exponentAccumulator[1]) + accumulator[1];
225 
226  c = *text;
227  if ((c == 'e' || c == 'E') && digitsFound)
228  {
229  bool negativeExponent = false;
230 
231  switch (*++text)
232  {
233  case '-': negativeExponent = true; // fall-through..
234  case '+': ++text;
235  }
236 
237  while (text.isDigit())
238  exponent = (exponent * 10) + ((int) text.getAndAdvance() - '0');
239 
240  if (negativeExponent)
241  exponent = -exponent;
242  }
243 
244  double r = mulexp10 (result[0], exponent + exponentAdjustment[0]);
245  if (decPointIndex != 0)
246  r += mulexp10 (result[1], exponent - exponentAdjustment[1]);
247 
248  return isNegative ? -r : r;
249  }
250 
252  template <typename CharPointerType>
253  static double getDoubleValue (CharPointerType text) noexcept
254  {
255  return readDoubleValue (text);
256  }
257 
258  //==============================================================================
260  template <typename IntType, typename CharPointerType>
261  static IntType getIntValue (const CharPointerType text) noexcept
262  {
263  IntType v = 0;
264  CharPointerType s (text.findEndOfWhitespace());
265 
266  const bool isNeg = *s == '-';
267  if (isNeg)
268  ++s;
269 
270  for (;;)
271  {
272  const juce_wchar c = s.getAndAdvance();
273 
274  if (c >= '0' && c <= '9')
275  v = v * 10 + (IntType) (c - '0');
276  else
277  break;
278  }
279 
280  return isNeg ? -v : v;
281  }
282 
283  template <typename ResultType>
284  struct HexParser
285  {
286  template <typename CharPointerType>
287  static ResultType parse (CharPointerType t) noexcept
288  {
289  ResultType result = 0;
290 
291  while (! t.isEmpty())
292  {
293  const int hexValue = CharacterFunctions::getHexDigitValue (t.getAndAdvance());
294 
295  if (hexValue >= 0)
296  result = (result << 4) | hexValue;
297  }
298 
299  return result;
300  }
301  };
302 
303  //==============================================================================
306  template <typename CharPointerType>
307  static size_t lengthUpTo (CharPointerType text, const size_t maxCharsToCount) noexcept
308  {
309  size_t len = 0;
310 
311  while (len < maxCharsToCount && text.getAndAdvance() != 0)
312  ++len;
313 
314  return len;
315  }
316 
319  template <typename CharPointerType>
320  static size_t lengthUpTo (CharPointerType start, const CharPointerType end) noexcept
321  {
322  size_t len = 0;
323 
324  while (start < end && start.getAndAdvance() != 0)
325  ++len;
326 
327  return len;
328  }
329 
331  template <typename DestCharPointerType, typename SrcCharPointerType>
332  static void copyAll (DestCharPointerType& dest, SrcCharPointerType src) noexcept
333  {
334  for (;;)
335  {
336  const juce_wchar c = src.getAndAdvance();
337 
338  if (c == 0)
339  break;
340 
341  dest.write (c);
342  }
343 
344  dest.writeNull();
345  }
346 
349  template <typename DestCharPointerType, typename SrcCharPointerType>
350  static size_t copyWithDestByteLimit (DestCharPointerType& dest, SrcCharPointerType src, size_t maxBytesToWrite) noexcept
351  {
352  typename DestCharPointerType::CharType const* const startAddress = dest.getAddress();
353  ssize_t maxBytes = (ssize_t) maxBytesToWrite;
354  maxBytes -= sizeof (typename DestCharPointerType::CharType); // (allow for a terminating null)
355 
356  for (;;)
357  {
358  const juce_wchar c = src.getAndAdvance();
359  const size_t bytesNeeded = DestCharPointerType::getBytesRequiredFor (c);
360 
361  maxBytes -= bytesNeeded;
362  if (c == 0 || maxBytes < 0)
363  break;
364 
365  dest.write (c);
366  }
367 
368  dest.writeNull();
369 
370  return (size_t) getAddressDifference (dest.getAddress(), startAddress)
371  + sizeof (typename DestCharPointerType::CharType);
372  }
373 
376  template <typename DestCharPointerType, typename SrcCharPointerType>
377  static void copyWithCharLimit (DestCharPointerType& dest, SrcCharPointerType src, int maxChars) noexcept
378  {
379  while (--maxChars > 0)
380  {
381  const juce_wchar c = src.getAndAdvance();
382  if (c == 0)
383  break;
384 
385  dest.write (c);
386  }
387 
388  dest.writeNull();
389  }
390 
392  template <typename CharPointerType1, typename CharPointerType2>
393  static int compare (CharPointerType1 s1, CharPointerType2 s2) noexcept
394  {
395  for (;;)
396  {
397  const int c1 = (int) s1.getAndAdvance();
398  const int c2 = (int) s2.getAndAdvance();
399  const int diff = c1 - c2;
400 
401  if (diff != 0) return diff < 0 ? -1 : 1;
402  if (c1 == 0) break;
403  }
404 
405  return 0;
406  }
407 
409  template <typename CharPointerType1, typename CharPointerType2>
410  static int compareUpTo (CharPointerType1 s1, CharPointerType2 s2, int maxChars) noexcept
411  {
412  while (--maxChars >= 0)
413  {
414  const int c1 = (int) s1.getAndAdvance();
415  const int c2 = (int) s2.getAndAdvance();
416  const int diff = c1 - c2;
417 
418  if (diff != 0) return diff < 0 ? -1 : 1;
419  if (c1 == 0) break;
420  }
421 
422  return 0;
423  }
424 
426  template <typename CharPointerType1, typename CharPointerType2>
427  static int compareIgnoreCase (CharPointerType1 s1, CharPointerType2 s2) noexcept
428  {
429  for (;;)
430  {
431  const int c1 = (int) s1.toUpperCase();
432  const int c2 = (int) s2.toUpperCase();
433  const int diff = c1 - c2;
434 
435  if (diff != 0) return diff < 0 ? -1 : 1;
436  if (c1 == 0) break;
437 
438  ++s1; ++s2;
439  }
440 
441  return 0;
442  }
443 
445  template <typename CharPointerType1, typename CharPointerType2>
446  static int compareIgnoreCaseUpTo (CharPointerType1 s1, CharPointerType2 s2, int maxChars) noexcept
447  {
448  while (--maxChars >= 0)
449  {
450  const int c1 = (int) s1.toUpperCase();
451  const int c2 = (int) s2.toUpperCase();
452  const int diff = c1 - c2;
453 
454  if (diff != 0) return diff < 0 ? -1 : 1;
455  if (c1 == 0) break;
456 
457  ++s1; ++s2;
458  }
459 
460  return 0;
461  }
462 
466  template <typename CharPointerType1, typename CharPointerType2>
467  static int indexOf (CharPointerType1 textToSearch, const CharPointerType2 substringToLookFor) noexcept
468  {
469  int index = 0;
470  const int substringLength = (int) substringToLookFor.length();
471 
472  for (;;)
473  {
474  if (textToSearch.compareUpTo (substringToLookFor, substringLength) == 0)
475  return index;
476 
477  if (textToSearch.getAndAdvance() == 0)
478  return -1;
479 
480  ++index;
481  }
482  }
483 
488  template <typename CharPointerType1, typename CharPointerType2>
489  static CharPointerType1 find (CharPointerType1 textToSearch, const CharPointerType2 substringToLookFor) noexcept
490  {
491  const int substringLength = (int) substringToLookFor.length();
492 
493  while (textToSearch.compareUpTo (substringToLookFor, substringLength) != 0
494  && ! textToSearch.isEmpty())
495  ++textToSearch;
496 
497  return textToSearch;
498  }
499 
504  template <typename CharPointerType>
505  static CharPointerType find (CharPointerType textToSearch, const juce_wchar charToLookFor) noexcept
506  {
507  for (;; ++textToSearch)
508  {
509  const juce_wchar c = *textToSearch;
510 
511  if (c == charToLookFor || c == 0)
512  break;
513  }
514 
515  return textToSearch;
516  }
517 
522  template <typename CharPointerType1, typename CharPointerType2>
523  static int indexOfIgnoreCase (CharPointerType1 haystack, const CharPointerType2 needle) noexcept
524  {
525  int index = 0;
526  const int needleLength = (int) needle.length();
527 
528  for (;;)
529  {
530  if (haystack.compareIgnoreCaseUpTo (needle, needleLength) == 0)
531  return index;
532 
533  if (haystack.getAndAdvance() == 0)
534  return -1;
535 
536  ++index;
537  }
538  }
539 
543  template <typename Type>
544  static int indexOfChar (Type text, const juce_wchar charToFind) noexcept
545  {
546  int i = 0;
547 
548  while (! text.isEmpty())
549  {
550  if (text.getAndAdvance() == charToFind)
551  return i;
552 
553  ++i;
554  }
555 
556  return -1;
557  }
558 
563  template <typename Type>
564  static int indexOfCharIgnoreCase (Type text, juce_wchar charToFind) noexcept
565  {
566  charToFind = CharacterFunctions::toLowerCase (charToFind);
567  int i = 0;
568 
569  while (! text.isEmpty())
570  {
571  if (text.toLowerCase() == charToFind)
572  return i;
573 
574  ++text;
575  ++i;
576  }
577 
578  return -1;
579  }
580 
585  template <typename Type>
586  static Type findEndOfWhitespace (Type text) noexcept
587  {
588  while (text.isWhitespace())
589  ++text;
590 
591  return text;
592  }
593 
597  template <typename Type, typename BreakType>
598  static Type findEndOfToken (Type text, const BreakType breakCharacters, const Type quoteCharacters)
599  {
600  juce_wchar currentQuoteChar = 0;
601 
602  while (! text.isEmpty())
603  {
604  const juce_wchar c = text.getAndAdvance();
605 
606  if (currentQuoteChar == 0 && breakCharacters.indexOf (c) >= 0)
607  {
608  --text;
609  break;
610  }
611 
612  if (quoteCharacters.indexOf (c) >= 0)
613  {
614  if (currentQuoteChar == 0)
615  currentQuoteChar = c;
616  else if (currentQuoteChar == c)
617  currentQuoteChar = 0;
618  }
619  }
620 
621  return text;
622  }
623 
624 private:
625  static double mulexp10 (const double value, int exponent) noexcept;
626 };
627 
628 
629 #endif // JUCE_CHARACTERFUNCTIONS_H_INCLUDED
static IntType getIntValue(const CharPointerType text) noexcept
Definition: juce_CharacterFunctions.h:261
static size_t lengthUpTo(CharPointerType text, const size_t maxCharsToCount) noexcept
Definition: juce_CharacterFunctions.h:307
#define noexcept
Definition: juce_CompilerSupport.h:141
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
TOUCHINPUT int
Definition: juce_win32_Windowing.cpp:123
static double getDoubleValue(CharPointerType text) noexcept
Definition: juce_CharacterFunctions.h:253
static int getHexDigitValue(juce_wchar digit) noexcept
Definition: juce_CharacterFunctions.cpp:111
#define JUCE_API
Definition: juce_StandardHeader.h:139
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
unsigned int uint32
Definition: juce_MathsFunctions.h:51
static Type findEndOfToken(Type text, const BreakType breakCharacters, const Type quoteCharacters)
Definition: juce_CharacterFunctions.h:598
static void copyWithCharLimit(DestCharPointerType &dest, SrcCharPointerType src, int maxChars) noexcept
Definition: juce_CharacterFunctions.h:377
static double readDoubleValue(CharPointerType &text) noexcept
Definition: juce_CharacterFunctions.h:122
static int compareIgnoreCase(CharPointerType1 s1, CharPointerType2 s2) noexcept
Definition: juce_CharacterFunctions.h:427
static ResultType parse(CharPointerType t) noexcept
Definition: juce_CharacterFunctions.h:287
static size_t lengthUpTo(CharPointerType start, const CharPointerType end) noexcept
Definition: juce_CharacterFunctions.h:320
static CharPointerType1 find(CharPointerType1 textToSearch, const CharPointerType2 substringToLookFor) noexcept
Definition: juce_CharacterFunctions.h:489
static int indexOfChar(Type text, const juce_wchar charToFind) noexcept
Definition: juce_CharacterFunctions.h:544
static int compareUpTo(CharPointerType1 s1, CharPointerType2 s2, int maxChars) noexcept
Definition: juce_CharacterFunctions.h:410
static int indexOfCharIgnoreCase(Type text, juce_wchar charToFind) noexcept
Definition: juce_CharacterFunctions.h:564
Definition: juce_CharacterFunctions.h:284
static int compareIgnoreCaseUpTo(CharPointerType1 s1, CharPointerType2 s2, int maxChars) noexcept
Definition: juce_CharacterFunctions.h:446
static CharPointerType find(CharPointerType textToSearch, const juce_wchar charToLookFor) noexcept
Definition: juce_CharacterFunctions.h:505
Definition: juce_CharacterFunctions.h:79
#define max(x, y)
Definition: os.h:79
wchar_t juce_wchar
Definition: juce_CharacterFunctions.h:49
static int indexOfIgnoreCase(CharPointerType1 haystack, const CharPointerType2 needle) noexcept
Definition: juce_CharacterFunctions.h:523
int getAddressDifference(Type1 *pointer1, Type2 *pointer2) noexcept
Definition: juce_Memory.h:59