29 #ifndef JUCE_CHARACTERFUNCTIONS_H_INCLUDED 30 #define JUCE_CHARACTERFUNCTIONS_H_INCLUDED 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 40 #define JUCE_NATIVE_WCHAR_IS_UTF8 0 42 #define JUCE_NATIVE_WCHAR_IS_UTF16 0 44 #define JUCE_NATIVE_WCHAR_IS_UTF32 1 47 #if JUCE_NATIVE_WCHAR_IS_UTF32 || DOXYGEN 56 #define JUCE_T(stringLiteral) (L##stringLiteral) 59 #if JUCE_DEFINE_T_MACRO 67 #define T(stringLiteral) JUCE_T(stringLiteral) 94 static bool isWhitespace (
char character)
noexcept;
99 static bool isDigit (
char character)
noexcept;
104 static bool isLetter (
char character)
noexcept;
109 static bool isLetterOrDigit (
char character)
noexcept;
121 template <
typename CharPo
interType>
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;
131 text = text.findEndOfWhitespace();
136 case '-': isNegative =
true;
137 case '+': c = *++text;
144 if ((text[1] ==
'a' || text[1] ==
'A') && (text[2] ==
'n' || text[2] ==
'N'))
145 return std::numeric_limits<double>::quiet_NaN();
150 if ((text[1] ==
'n' || text[1] ==
'N') && (text[2] ==
'f' || text[2] ==
'F'))
151 return std::numeric_limits<double>::infinity();
160 digit = (int) text.getAndAdvance() -
'0';
163 if (decPointIndex != 0)
164 exponentAdjustment[1]++;
166 if (numSignificantDigits == 0 && digit == 0)
169 if (++numSignificantDigits > maxSignificantDigits)
172 ++accumulator [decPointIndex];
173 else if (digit == 5 && (lastDigit & 1) != 0)
174 ++accumulator [decPointIndex];
176 if (decPointIndex > 0)
177 exponentAdjustment[1]--;
179 exponentAdjustment[0]++;
181 while (text.isDigit())
184 if (decPointIndex == 0)
185 exponentAdjustment[0]++;
190 const double maxAccumulatorValue = (double) ((std::numeric_limits<unsigned int>::max() - 9) / 10);
191 if (accumulator [decPointIndex] > maxAccumulatorValue)
193 result [decPointIndex] = mulexp10 (result [decPointIndex], exponentAccumulator [decPointIndex])
194 + accumulator [decPointIndex];
195 accumulator [decPointIndex] = 0;
196 exponentAccumulator [decPointIndex] = 0;
199 accumulator [decPointIndex] = accumulator[decPointIndex] * 10 + digit;
200 exponentAccumulator [decPointIndex]++;
203 else if (decPointIndex == 0 && *text ==
'.')
208 if (numSignificantDigits > maxSignificantDigits)
210 while (text.isDigit())
221 result[0] = mulexp10 (result[0], exponentAccumulator[0]) + accumulator[0];
223 if (decPointIndex != 0)
224 result[1] = mulexp10 (result[1], exponentAccumulator[1]) + accumulator[1];
227 if ((c ==
'e' || c ==
'E') && digitsFound)
229 bool negativeExponent =
false;
233 case '-': negativeExponent =
true;
237 while (text.isDigit())
238 exponent = (exponent * 10) + ((int) text.getAndAdvance() -
'0');
240 if (negativeExponent)
241 exponent = -exponent;
244 double r = mulexp10 (result[0], exponent + exponentAdjustment[0]);
245 if (decPointIndex != 0)
246 r += mulexp10 (result[1], exponent - exponentAdjustment[1]);
248 return isNegative ? -r : r;
252 template <
typename CharPo
interType>
255 return readDoubleValue (text);
260 template <
typename IntType,
typename CharPo
interType>
264 CharPointerType s (text.findEndOfWhitespace());
266 const bool isNeg = *s ==
'-';
274 if (c >=
'0' && c <=
'9')
275 v = v * 10 + (IntType) (c -
'0');
280 return isNeg ? -v : v;
283 template <
typename ResultType>
286 template <
typename CharPo
interType>
287 static ResultType
parse (CharPointerType t) noexcept
289 ResultType result = 0;
291 while (! t.isEmpty())
296 result = (result << 4) | hexValue;
306 template <
typename CharPo
interType>
307 static size_t lengthUpTo (CharPointerType text,
const size_t maxCharsToCount) noexcept
311 while (len < maxCharsToCount && text.getAndAdvance() != 0)
319 template <
typename CharPo
interType>
320 static size_t lengthUpTo (CharPointerType start,
const CharPointerType end) noexcept
324 while (start < end && start.getAndAdvance() != 0)
331 template <
typename DestCharPo
interType,
typename SrcCharPo
interType>
332 static void copyAll (DestCharPointerType& dest, SrcCharPointerType src) noexcept
349 template <
typename DestCharPo
interType,
typename SrcCharPo
interType>
350 static size_t copyWithDestByteLimit (DestCharPointerType& dest, SrcCharPointerType src,
size_t maxBytesToWrite) noexcept
352 typename DestCharPointerType::CharType
const*
const startAddress = dest.getAddress();
353 ssize_t maxBytes = (ssize_t) maxBytesToWrite;
354 maxBytes -=
sizeof (
typename DestCharPointerType::CharType);
359 const size_t bytesNeeded = DestCharPointerType::getBytesRequiredFor (c);
361 maxBytes -= bytesNeeded;
362 if (c == 0 || maxBytes < 0)
371 +
sizeof (
typename DestCharPointerType::CharType);
376 template <
typename DestCharPo
interType,
typename SrcCharPo
interType>
377 static void copyWithCharLimit (DestCharPointerType& dest, SrcCharPointerType src,
int maxChars) noexcept
379 while (--maxChars > 0)
392 template <
typename CharPo
interType1,
typename CharPo
interType2>
393 static int compare (CharPointerType1 s1, CharPointerType2 s2) noexcept
397 const int c1 = (int) s1.getAndAdvance();
398 const int c2 = (int) s2.getAndAdvance();
399 const int diff = c1 - c2;
401 if (diff != 0)
return diff < 0 ? -1 : 1;
409 template <
typename CharPo
interType1,
typename CharPo
interType2>
410 static int compareUpTo (CharPointerType1 s1, CharPointerType2 s2,
int maxChars) noexcept
412 while (--maxChars >= 0)
414 const int c1 = (int) s1.getAndAdvance();
415 const int c2 = (int) s2.getAndAdvance();
416 const int diff = c1 - c2;
418 if (diff != 0)
return diff < 0 ? -1 : 1;
426 template <
typename CharPo
interType1,
typename CharPo
interType2>
431 const int c1 = (int) s1.toUpperCase();
432 const int c2 = (int) s2.toUpperCase();
433 const int diff = c1 - c2;
435 if (diff != 0)
return diff < 0 ? -1 : 1;
445 template <
typename CharPo
interType1,
typename CharPo
interType2>
448 while (--maxChars >= 0)
450 const int c1 = (int) s1.toUpperCase();
451 const int c2 = (int) s2.toUpperCase();
452 const int diff = c1 - c2;
454 if (diff != 0)
return diff < 0 ? -1 : 1;
466 template <
typename CharPo
interType1,
typename CharPo
interType2>
467 static int indexOf (CharPointerType1 textToSearch,
const CharPointerType2 substringToLookFor) noexcept
470 const int substringLength = (int) substringToLookFor.length();
474 if (textToSearch.compareUpTo (substringToLookFor, substringLength) == 0)
477 if (textToSearch.getAndAdvance() == 0)
488 template <
typename CharPo
interType1,
typename CharPo
interType2>
489 static CharPointerType1
find (CharPointerType1 textToSearch,
const CharPointerType2 substringToLookFor) noexcept
491 const int substringLength = (int) substringToLookFor.length();
493 while (textToSearch.compareUpTo (substringToLookFor, substringLength) != 0
494 && ! textToSearch.isEmpty())
504 template <
typename CharPo
interType>
505 static CharPointerType
find (CharPointerType textToSearch,
const juce_wchar charToLookFor) noexcept
507 for (;; ++textToSearch)
511 if (c == charToLookFor || c == 0)
522 template <
typename CharPo
interType1,
typename CharPo
interType2>
523 static int indexOfIgnoreCase (CharPointerType1 haystack,
const CharPointerType2 needle) noexcept
526 const int needleLength = (int) needle.length();
530 if (haystack.compareIgnoreCaseUpTo (needle, needleLength) == 0)
533 if (haystack.getAndAdvance() == 0)
543 template <
typename Type>
548 while (! text.isEmpty())
550 if (text.getAndAdvance() == charToFind)
563 template <
typename Type>
569 while (! text.isEmpty())
571 if (text.toLowerCase() == charToFind)
585 template <
typename Type>
588 while (text.isWhitespace())
597 template <
typename Type,
typename BreakType>
598 static Type
findEndOfToken (Type text,
const BreakType breakCharacters,
const Type quoteCharacters)
602 while (! text.isEmpty())
606 if (currentQuoteChar == 0 && breakCharacters.indexOf (c) >= 0)
612 if (quoteCharacters.indexOf (c) >= 0)
614 if (currentQuoteChar == 0)
615 currentQuoteChar = c;
616 else if (currentQuoteChar == c)
617 currentQuoteChar = 0;
625 static double mulexp10 (
const double value,
int exponent)
noexcept;
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
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
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