27 #pragma warning (push)
28 #pragma warning (disable: 4514 4996)
33#if defined (JUCE_STRINGS_ARE_UNICODE) && ! JUCE_STRINGS_ARE_UNICODE
34 #error "JUCE_STRINGS_ARE_UNICODE is deprecated! All strings are now unicode by default."
37#if JUCE_NATIVE_WCHAR_IS_UTF8
38 using CharPointer_wchar_t = CharPointer_UTF8;
39#elif JUCE_NATIVE_WCHAR_IS_UTF16
40 using CharPointer_wchar_t = CharPointer_UTF16;
42 using CharPointer_wchar_t = CharPointer_UTF32;
45static inline CharPointer_wchar_t castToCharPointer_wchar_t (
const void* t)
noexcept
47 return CharPointer_wchar_t (
static_cast<const CharPointer_wchar_t::CharType*
> (t));
55 size_t allocatedBytes;
56 String::CharPointerType::CharType text;
59static const EmptyString emptyString = { 0x3fffffff,
sizeof (String::CharPointerType::CharType), 0 };
68 using CharType = String::CharPointerType::CharType;
73 numBytes = (numBytes + 3) & ~(
size_t) 3;
75 s->refCount.
value = 0;
76 s->allocatedNumBytes = numBytes;
80 template <
class CharPo
inter>
83 if (text.getAddress() ==
nullptr || text.isEmpty())
87 auto dest = createUninitialisedBytes (bytesNeeded);
92 template <
class CharPo
inter>
93 static CharPointerType createFromCharPointer (
const CharPointer text,
size_t maxChars)
95 if (text.getAddress() ==
nullptr || text.isEmpty() || maxChars == 0)
100 size_t bytesNeeded =
sizeof (CharType);
102 while (numChars < maxChars && ! end.isEmpty())
108 auto dest = createUninitialisedBytes (bytesNeeded);
113 template <
class CharPo
inter>
114 static CharPointerType createFromCharPointer (
const CharPointer start,
const CharPointer end)
116 if (start.getAddress() ==
nullptr || start.isEmpty())
121 auto bytesNeeded =
sizeof (CharType);
123 while (e < end && ! e.isEmpty())
129 auto dest = createUninitialisedBytes (bytesNeeded);
136 if (start.getAddress() ==
nullptr || start.isEmpty())
139 auto numBytes = (size_t) (
reinterpret_cast<const char*
> (end.
getAddress())
140 -
reinterpret_cast<const char*
> (start.getAddress()));
141 auto dest = createUninitialisedBytes (numBytes +
sizeof (CharType));
142 memcpy (dest.getAddress(), start, numBytes);
143 dest.getAddress()[numBytes /
sizeof (CharType)] = 0;
147 static CharPointerType createFromFixedLength (
const char*
const src,
const size_t numChars)
149 auto dest = createUninitialisedBytes (numChars *
sizeof (CharType) +
sizeof (CharType));
157 auto* b = bufferFromText (text);
163 static inline void release (
StringHolder*
const b)
noexcept
166 if (--(b->refCount) == -1)
167 delete[]
reinterpret_cast<char*
> (b);
172 release (bufferFromText (text));
175 static inline int getReferenceCount (
const CharPointerType text)
noexcept
177 return bufferFromText (text)->refCount.
get() + 1;
183 auto* b = bufferFromText (text);
187 auto newText = createUninitialisedBytes (numBytes);
192 if (b->allocatedNumBytes >= numBytes && b->refCount.
get() <= 0)
195 auto newText = createUninitialisedBytes (jmax (b->allocatedNumBytes, numBytes));
196 memcpy (newText.getAddress(), text.getAddress(), b->allocatedNumBytes);
202 static size_t getAllocatedNumBytes (
const CharPointerType text)
noexcept
204 return bufferFromText (text)->allocatedNumBytes;
209 size_t allocatedNumBytes;
216 return reinterpret_cast<StringHolder*
> (
reinterpret_cast<char*
> (text.getAddress())
217 - (
reinterpret_cast<size_t> (
reinterpret_cast<StringHolder*
> (128)->text) - 128));
220 void compileTimeChecks()
223 #if JUCE_NATIVE_WCHAR_IS_UTF8
224 static_assert (
sizeof (wchar_t) == 1,
"JUCE_NATIVE_WCHAR_IS_* macro has incorrect value");
225 #elif JUCE_NATIVE_WCHAR_IS_UTF16
226 static_assert (
sizeof (wchar_t) == 2,
"JUCE_NATIVE_WCHAR_IS_* macro has incorrect value");
227 #elif JUCE_NATIVE_WCHAR_IS_UTF32
228 static_assert (
sizeof (wchar_t) == 4,
"JUCE_NATIVE_WCHAR_IS_* macro has incorrect value");
230 #error "native wchar_t size is unknown"
234 "StringHolder is not large enough to hold an empty String");
238JUCE_DECLARE_DEPRECATED_STATIC (
const String String::empty;)
247 StringHolder::release (text);
252 StringHolder::retain (text);
257 std::swap (text, other.text);
262 StringHolder::release (text);
263 text = &(emptyString.text);
268 StringHolder::retain (other.text);
269 StringHolder::release (text.atomicSwap (other.text));
275 other.text = &(emptyString.text);
280 std::swap (text, other.text);
284inline String::PreallocationBytes::PreallocationBytes (
const size_t num) noexcept : numBytes (num) {}
287 : text (StringHolder::createUninitialisedBytes (preallocationSize.numBytes + sizeof (CharPointerType::CharType)))
293 text = StringHolder::makeUniqueWithByteSize (text, numBytesNeeded +
sizeof (CharPointerType::CharType));
298 return StringHolder::getReferenceCount (text);
376namespace NumberToStringConverters
380 charsNeededForInt = 32,
381 charsNeededForDouble = 48
384 template <
typename Type>
385 static char* printDigits (
char* t, Type v)
noexcept
391 *--t =
'0' + (char) (v % 10);
400 static char* numberToString (
char* t, int64 n)
noexcept
403 return printDigits (t,
static_cast<uint64
> (n));
407 t = printDigits (t,
static_cast<uint64
> (-(n + 1)) + 1);
412 static char* numberToString (
char* t, uint64 v)
noexcept
414 return printDigits (t, v);
417 static char* numberToString (
char* t,
int n)
noexcept
420 return printDigits (t,
static_cast<unsigned int> (n));
424 t = printDigits (t,
static_cast<unsigned int> (-(n + 1)) + 1);
429 static char* numberToString (
char* t,
unsigned int v)
noexcept
431 return printDigits (t, v);
434 static char* numberToString (
char* t,
long n)
noexcept
437 return printDigits (t,
static_cast<unsigned long> (n));
439 t = printDigits (t,
static_cast<unsigned long> (-(n + 1)) + 1);
444 static char* numberToString (
char* t,
unsigned long v)
noexcept
446 return printDigits (t, v);
453 static const std::locale classicLocale (std::locale::classic());
454 imbue (classicLocale);
455 setp (d, d + charsNeededForDouble);
458 size_t writeDouble (
double n,
int numDecPlaces,
bool useScientificNotation)
461 std::ostream o (
this);
463 if (numDecPlaces > 0)
465 o.setf (useScientificNotation ? std::ios_base::scientific : std::ios_base::fixed);
466 o.precision ((std::streamsize) numDecPlaces);
472 return (
size_t) (pptr() - pbase());
476 static char* doubleToString (
char* buffer,
double n,
int numDecPlaces,
bool useScientificNotation,
size_t& len)
noexcept
479 len = strm.writeDouble (n, numDecPlaces, useScientificNotation);
480 jassert (len <= charsNeededForDouble);
484 template <
typename IntegerType>
487 char buffer [charsNeededForInt];
488 auto* end = buffer + numElementsInArray (buffer);
489 auto* start = numberToString (end, number);
490 return StringHolder::createFromFixedLength (start, (
size_t) (end - start - 1));
493 static String::CharPointerType createFromDouble (
double number,
int numberOfDecimalPlaces,
bool useScientificNotation)
495 char buffer [charsNeededForDouble];
497 auto start = doubleToString (buffer, number, numberOfDecimalPlaces, useScientificNotation, len);
498 return StringHolder::createFromFixedLength (start, len);
503String::String (
int number) : text (NumberToStringConverters::createFromInteger (number)) {}
504String::String (
unsigned int number) : text (NumberToStringConverters::createFromInteger (number)) {}
505String::String (
short number) : text (NumberToStringConverters::createFromInteger ((int) number)) {}
506String::String (
unsigned short number) : text (NumberToStringConverters::createFromInteger ((unsigned int) number)) {}
507String::String (int64 number) : text (NumberToStringConverters::createFromInteger (number)) {}
508String::String (uint64 number) : text (NumberToStringConverters::createFromInteger (number)) {}
509String::String (
long number) : text (NumberToStringConverters::createFromInteger (number)) {}
510String::String (
unsigned long number) : text (NumberToStringConverters::createFromInteger (number)) {}
512String::String (
float number) : text (NumberToStringConverters::createFromDouble ((double) number, 0, false)) {}
513String::String (
double number) : text (NumberToStringConverters::createFromDouble ( number, 0, false)) {}
514String::String (
float number,
int numberOfDecimalPlaces,
bool useScientificNotation) : text (NumberToStringConverters::createFromDouble ((double) number, numberOfDecimalPlaces, useScientificNotation)) {}
515String::String (
double number,
int numberOfDecimalPlaces,
bool useScientificNotation) : text (NumberToStringConverters::createFromDouble ( number, numberOfDecimalPlaces, useScientificNotation)) {}
520 return (
int) text.
length();
525 return (
size_t) (((
char*) text.findTerminatingNull().getAddress()) - (
char*) text.getAddress());
528size_t String::getByteOffsetOfEnd() const noexcept
530 return findByteOffsetOfEnd (text);
535 jassert (index == 0 || (index > 0 && index <= (
int) text.lengthUpTo ((
size_t) index + 1)));
539template <
typename Type>
542 template <
typename CharPo
inter>
543 static Type calculate (CharPointer t)
noexcept
547 while (! t.isEmpty())
548 result = ((Type) multiplier) * result + (Type) t.getAndAdvance();
553 enum { multiplier =
sizeof (Type) > 4 ? 101 : 31 };
561JUCE_API bool JUCE_CALLTYPE operator== (
const String& s1,
const String& s2)
noexcept {
return s1.compare (s2) == 0; }
562JUCE_API bool JUCE_CALLTYPE operator!= (
const String& s1,
const String& s2)
noexcept {
return s1.compare (s2) != 0; }
563JUCE_API bool JUCE_CALLTYPE operator== (
const String& s1,
const char* s2)
noexcept {
return s1.compare (s2) == 0; }
564JUCE_API bool JUCE_CALLTYPE operator!= (
const String& s1,
const char* s2)
noexcept {
return s1.compare (s2) != 0; }
565JUCE_API bool JUCE_CALLTYPE operator== (
const String& s1,
const wchar_t* s2)
noexcept {
return s1.compare (s2) == 0; }
566JUCE_API bool JUCE_CALLTYPE operator!= (
const String& s1,
const wchar_t* s2)
noexcept {
return s1.compare (s2) != 0; }
567JUCE_API bool JUCE_CALLTYPE operator== (
const String& s1, StringRef s2)
noexcept {
return s1.getCharPointer().compare (s2.text) == 0; }
568JUCE_API bool JUCE_CALLTYPE operator!= (
const String& s1, StringRef s2)
noexcept {
return s1.getCharPointer().compare (s2.text) != 0; }
569JUCE_API bool JUCE_CALLTYPE operator== (
const String& s1,
const CharPointer_UTF8 s2)
noexcept {
return s1.getCharPointer().compare (s2) == 0; }
570JUCE_API bool JUCE_CALLTYPE operator!= (
const String& s1,
const CharPointer_UTF8 s2)
noexcept {
return s1.getCharPointer().compare (s2) != 0; }
571JUCE_API bool JUCE_CALLTYPE operator== (
const String& s1,
const CharPointer_UTF16 s2)
noexcept {
return s1.getCharPointer().compare (s2) == 0; }
572JUCE_API bool JUCE_CALLTYPE operator!= (
const String& s1,
const CharPointer_UTF16 s2)
noexcept {
return s1.getCharPointer().compare (s2) != 0; }
573JUCE_API bool JUCE_CALLTYPE operator== (
const String& s1,
const CharPointer_UTF32 s2)
noexcept {
return s1.getCharPointer().compare (s2) == 0; }
574JUCE_API bool JUCE_CALLTYPE operator!= (
const String& s1,
const CharPointer_UTF32 s2)
noexcept {
return s1.getCharPointer().compare (s2) != 0; }
575JUCE_API bool JUCE_CALLTYPE operator> (
const String& s1,
const String& s2)
noexcept {
return s1.compare (s2) > 0; }
576JUCE_API bool JUCE_CALLTYPE operator< (
const String& s1,
const String& s2)
noexcept {
return s1.compare (s2) < 0; }
577JUCE_API bool JUCE_CALLTYPE operator>= (
const String& s1,
const String& s2)
noexcept {
return s1.compare (s2) >= 0; }
578JUCE_API bool JUCE_CALLTYPE operator<= (
const String& s1,
const String& s2)
noexcept {
return s1.compare (s2) <= 0; }
582 return t !=
nullptr ? text.compareIgnoreCase (castToCharPointer_wchar_t (t)) == 0
594 return text.compareIgnoreCase (t.text) == 0;
599 return text == other.text
600 || text.compareIgnoreCase (other.text) == 0;
603int String::compare (
const String& other)
const noexcept {
return (text == other.text) ? 0 : text.compare (other.text); }
605int String::compare (
const wchar_t*
const other)
const noexcept {
return text.compare (castToCharPointer_wchar_t (other)); }
612 auto c1 = s1.getAndAdvance();
615 auto c2 = s2.getAndAdvance();
618 if (! (isDigit1 || isDigit2))
return bias;
619 if (! isDigit1)
return -1;
620 if (! isDigit2)
return 1;
622 if (c1 != c2 && bias == 0)
623 bias = c1 < c2 ? -1 : 1;
625 jassert (c1 != 0 && c2 != 0);
633 auto c1 = s1.getAndAdvance();
636 auto c2 = s2.getAndAdvance();
639 if (! (isDigit1 || isDigit2))
return 0;
640 if (! isDigit1)
return -1;
641 if (! isDigit2)
return 1;
642 if (c1 < c2)
return -1;
643 if (c1 > c2)
return 1;
649 bool firstLoop =
true;
653 const bool hasSpace1 = s1.isWhitespace();
654 const bool hasSpace2 = s2.isWhitespace();
656 if ((! firstLoop) && (hasSpace1 ^ hasSpace2))
658 if (s1.isEmpty())
return -1;
659 if (s2.isEmpty())
return 1;
661 return hasSpace2 ? 1 : -1;
666 if (hasSpace1) s1 = s1.findEndOfWhitespace();
667 if (hasSpace2) s2 = s2.findEndOfWhitespace();
669 if (s1.isDigit() && s2.isDigit())
671 auto result = (*s1 ==
'0' || *s2 ==
'0') ? stringCompareLeft (s1, s2)
672 : stringCompareRight (s1, s2);
678 auto c1 = s1.getAndAdvance();
679 auto c2 = s2.getAndAdvance();
681 if (c1 != c2 && ! isCaseSensitive)
697 if (isAlphaNum2 && ! isAlphaNum1)
return -1;
698 if (isAlphaNum1 && ! isAlphaNum2)
return 1;
700 return c1 < c2 ? -1 : 1;
703 jassert (c1 != 0 && c2 != 0);
709 return naturalStringCompare (getCharPointer(), other.text, isCaseSensitive);
716 : textToAppend.text, maxCharsToTake);
727 jassert (startOfTextToAppend.
getAddress() !=
nullptr && endOfTextToAppend.
getAddress() !=
nullptr);
729 auto extraBytesNeeded = getAddressDifference (endOfTextToAppend.
getAddress(),
731 jassert (extraBytesNeeded >= 0);
733 if (extraBytesNeeded > 0)
735 auto byteOffsetOfNull = getByteOffsetOfEnd();
738 auto* newStringStart = addBytesToPointer (text.
getAddress(), (
int) byteOffsetOfNull);
739 memcpy (newStringStart, startOfTextToAppend.
getAddress(), (
size_t) extraBytesNeeded);
775 const char asString[] = { ch, 0 };
781 const wchar_t asString[] = { ch, 0 };
785#if ! JUCE_NATIVE_WCHAR_IS_UTF32
788 const juce_wchar asString[] = { ch, 0 };
794namespace StringHelpers
796 template <
typename T>
797 inline String& operationAddAssign (String& str,
const T number)
799 char buffer [(
sizeof(T) * 8) / 2];
800 auto* end = buffer + numElementsInArray (buffer);
801 auto* start = NumberToStringConverters::numberToString (end, number);
803 #if JUCE_STRING_UTF_TYPE == 8
806 str.appendCharPointer (CharPointer_ASCII (start), CharPointer_ASCII (end));
819JUCE_API String JUCE_CALLTYPE operator+ (
const wchar_t* s1,
const String& s2) { String s (s1);
return s += s2; }
824JUCE_API String JUCE_CALLTYPE operator+ (String s1,
const String& s2) {
return s1 += s2; }
825JUCE_API String JUCE_CALLTYPE operator+ (String s1,
const char* s2) {
return s1 += s2; }
826JUCE_API String JUCE_CALLTYPE operator+ (String s1,
const wchar_t* s2) {
return s1 += s2; }
827JUCE_API String JUCE_CALLTYPE operator+ (String s1,
const std::string& s2) {
return s1 += s2.c_str(); }
829JUCE_API String JUCE_CALLTYPE operator+ (String s1,
char s2) {
return s1 += s2; }
830JUCE_API String JUCE_CALLTYPE operator+ (String s1,
wchar_t s2) {
return s1 += s2; }
832#if ! JUCE_NATIVE_WCHAR_IS_UTF32
834JUCE_API String JUCE_CALLTYPE operator+ (String s1, juce_wchar s2) {
return s1 += s2; }
835JUCE_API String& JUCE_CALLTYPE operator<< (String& s1, juce_wchar s2) {
return s1 += s2; }
838JUCE_API String& JUCE_CALLTYPE operator<< (String& s1,
char s2) {
return s1 += s2; }
839JUCE_API String& JUCE_CALLTYPE operator<< (String& s1,
wchar_t s2) {
return s1 += s2; }
841JUCE_API String& JUCE_CALLTYPE operator<< (String& s1,
const char* s2) {
return s1 += s2; }
842JUCE_API String& JUCE_CALLTYPE operator<< (String& s1,
const wchar_t* s2) {
return s1 += s2; }
843JUCE_API String& JUCE_CALLTYPE operator<< (String& s1,
const String& s2) {
return s1 += s2; }
844JUCE_API String& JUCE_CALLTYPE operator<< (String& s1, StringRef s2) {
return s1 += s2; }
845JUCE_API String& JUCE_CALLTYPE operator<< (String& s1,
const std::string& s2) {
return s1 += s2.c_str(); }
847JUCE_API String& JUCE_CALLTYPE operator<< (String& s1, uint8 number) {
return s1 += (int) number; }
848JUCE_API String& JUCE_CALLTYPE operator<< (String& s1,
short number) {
return s1 += (int) number; }
849JUCE_API String& JUCE_CALLTYPE operator<< (String& s1,
int number) {
return s1 += number; }
850JUCE_API String& JUCE_CALLTYPE operator<< (String& s1,
long number) {
return s1 += String (number); }
851JUCE_API String& JUCE_CALLTYPE operator<< (String& s1,
unsigned long number) {
return s1 += String (number); }
852JUCE_API String& JUCE_CALLTYPE operator<< (String& s1, int64 number) {
return s1 += String (number); }
853JUCE_API String& JUCE_CALLTYPE operator<< (String& s1, uint64 number) {
return s1 += String (number); }
854JUCE_API String& JUCE_CALLTYPE operator<< (String& s1,
float number) {
return s1 += String (number); }
855JUCE_API String& JUCE_CALLTYPE operator<< (String& s1,
double number) {
return s1 += String (number); }
857JUCE_API OutputStream& JUCE_CALLTYPE operator<< (OutputStream& stream,
const String& text)
859 return operator<< (stream, StringRef (text));
862JUCE_API OutputStream& JUCE_CALLTYPE operator<< (OutputStream& stream, StringRef text)
866 #if (JUCE_STRING_UTF_TYPE == 8)
867 stream.write (text.text.getAddress(), numBytes);
871 HeapBlock<char> temp (numBytes + 1);
872 CharPointer_UTF8 (temp).writeAll (text.text);
873 stream.write (temp, numBytes);
882 return text.indexOf (character);
889 for (
int i = 0; ! t.isEmpty(); ++i)
893 if (t.getAndAdvance() == character)
910 for (
int i = 0; ! t.isEmpty(); ++i)
911 if (t.getAndAdvance() == character)
921 for (
int i = 0; ! t.isEmpty(); ++i)
925 if (charactersToLookFor.text.indexOf (t.getAndAdvance(), ignoreCase) >= 0)
939 return other.isEmpty() ? 0 : text.indexOf (other.text);
954 for (
int i = startIndex; --i >= 0;)
962 auto found = t.indexOf (other.text);
963 return found >= 0 ? found + startIndex : found;
973 for (
int i = startIndex; --i >= 0;)
982 return found >= 0 ? found + startIndex : found;
987 if (other.isNotEmpty())
989 auto len = other.length();
990 int i = length() - len;
994 for (
auto n = text + i; i >= 0; --i)
996 if (n.compareUpTo (other.text, len) == 0)
1009 if (other.isNotEmpty())
1011 auto len = other.length();
1012 int i = length() - len;
1016 for (
auto n = text + i; i >= 0; --i)
1018 if (n.compareIgnoreCaseUpTo (other.text, len) == 0)
1034 for (
int i = 0; ! t.isEmpty(); ++i)
1035 if (charactersToLookFor.text.indexOf (t.getAndAdvance(), ignoreCase) >= 0)
1043 return indexOf (other) >= 0;
1048 return text.indexOf (character) >= 0;
1053 return indexOfIgnoreCase (t) >= 0;
1058 if (word.isNotEmpty())
1061 auto wordLen = word.length();
1062 auto end = (int) t.length() - wordLen;
1064 for (
int i = 0; i <= end; ++i)
1066 if (t.compareUpTo (word.text, wordLen) == 0
1067 && (i == 0 || ! (t - 1).isLetterOrDigit())
1068 && ! (t + wordLen).isLetterOrDigit())
1080 if (word.isNotEmpty())
1083 auto wordLen = word.length();
1084 auto end = (int) t.length() - wordLen;
1086 for (
int i = 0; i <= end; ++i)
1088 if (t.compareIgnoreCaseUpTo (word.text, wordLen) == 0
1089 && (i == 0 || ! (t - 1).isLetterOrDigit())
1090 && ! (t + wordLen).isLetterOrDigit())
1102 return indexOfWholeWord (wordToLookFor) >= 0;
1107 return indexOfWholeWordIgnoreCase (wordToLookFor) >= 0;
1111template <
typename CharPo
inter>
1114 static bool matches (CharPointer wildcard, CharPointer test,
const bool ignoreCase)
noexcept
1118 auto wc = wildcard.getAndAdvance();
1121 return wildcard.isEmpty() || matchesAnywhere (wildcard, test, ignoreCase);
1123 if (! characterMatches (wc, test.getAndAdvance(), ignoreCase))
1131 static bool characterMatches (
const juce_wchar wc,
const juce_wchar tc,
const bool ignoreCase)
noexcept
1133 return (wc == tc) || (wc ==
'?' && tc != 0)
1137 static bool matchesAnywhere (
const CharPointer wildcard, CharPointer test,
const bool ignoreCase)
noexcept
1139 for (; ! test.isEmpty(); ++test)
1140 if (matches (wildcard, test, ignoreCase))
1155 if (numberOfTimesToRepeat <= 0)
1158 String result (PreallocationBytes (findByteOffsetOfEnd (stringToRepeat) * (
size_t) numberOfTimesToRepeat));
1159 auto n = result.text;
1161 while (--numberOfTimesToRepeat >= 0)
1169 jassert (padCharacter != 0);
1171 auto extraChars = minimumLength;
1174 while (! end.isEmpty())
1180 if (extraChars <= 0 || padCharacter == 0)
1183 auto currentByteSize = (size_t) (((
char*) end.getAddress()) - (
char*) text.getAddress());
1185 auto n = result.text;
1187 while (--extraChars >= 0)
1188 n.
write (padCharacter);
1196 jassert (padCharacter != 0);
1198 auto extraChars = minimumLength;
1207 if (extraChars <= 0 || padCharacter == 0)
1210 auto currentByteSize = (size_t) (((
char*) end.
getAddress()) - (
char*) text.getAddress());
1212 auto n = result.text;
1216 while (--extraChars >= 0)
1217 n.write (padCharacter);
1233 if (numCharsToReplace < 0)
1236 numCharsToReplace = 0;
1240 auto insertPoint = text;
1242 for (
int i = 0; i < index; ++i)
1244 if (insertPoint.isEmpty())
1248 return *
this + stringToInsert;
1254 auto startOfRemainder = insertPoint;
1256 for (
int i = 0; i < numCharsToReplace && ! startOfRemainder.isEmpty(); ++i)
1259 if (insertPoint == text && startOfRemainder.isEmpty())
1260 return stringToInsert.
text;
1262 auto initialBytes = (size_t) (((
char*) insertPoint.getAddress()) - (
char*) text.getAddress());
1263 auto newStringBytes = findByteOffsetOfEnd (stringToInsert);
1264 auto remainderBytes = (size_t) (((
char*) startOfRemainder.findTerminatingNull().getAddress()) - (
char*) startOfRemainder.getAddress());
1266 auto newTotalBytes = initialBytes + newStringBytes + remainderBytes;
1268 if (newTotalBytes <= 0)
1271 String result (PreallocationBytes ((
size_t) newTotalBytes));
1273 auto* dest = (
char*) result.text.
getAddress();
1274 memcpy (dest, text.getAddress(), initialBytes);
1275 dest += initialBytes;
1277 dest += newStringBytes;
1278 memcpy (dest, startOfRemainder.getAddress(), remainderBytes);
1279 dest += remainderBytes;
1287 auto stringToReplaceLen = stringToReplace.
length();
1288 auto stringToInsertLen = stringToInsert.
length();
1294 : result.
indexOf (i, stringToReplace))) >= 0)
1296 result = result.
replaceSection (i, stringToReplaceLen, stringToInsert);
1297 i += stringToInsertLen;
1305 auto stringToReplaceLen = stringToReplace.
length();
1310 return replaceSection (index, stringToReplaceLen, stringToInsert);
1324 : source (s), allocatedBytes (StringHolder::getAllocatedNumBytes (s))
1330 void write (juce_wchar c)
1334 if (bytesWritten > allocatedBytes)
1336 allocatedBytes += jmax ((
size_t) 8, allocatedBytes / 16);
1347 size_t allocatedBytes, bytesWritten = 0;
1361 if (c == charToReplace)
1370 return std::move (builder.result);
1377 jassert (charactersToReplace.
length() == charactersToInsertInstead.
length());
1384 auto index = charactersToReplace.
text.
indexOf (c);
1387 c = charactersToInsertInstead [index];
1395 return std::move (builder.result);
1401 return text.compareUpTo (other.text, other.length()) == 0;
1406 return text.compareIgnoreCaseUpTo (other.text, other.length()) == 0;
1411 jassert (character != 0);
1413 return *text == character;
1418 jassert (character != 0);
1423 auto t = text.findTerminatingNull();
1424 return *--t == character;
1429 auto end = text.findTerminatingNull();
1430 auto otherEnd = other.text.findTerminatingNull();
1432 while (end > text && otherEnd > other.text)
1437 if (*end != *otherEnd)
1441 return otherEnd == other.text;
1446 auto end = text.findTerminatingNull();
1447 auto otherEnd = other.text.findTerminatingNull();
1449 while (end > text && otherEnd > other.text)
1454 if (end.toLowerCase() != otherEnd.toLowerCase())
1458 return otherEnd == other.text;
1477 return std::move (builder.result);
1495 return std::move (builder.result);
1550 while (--start >= 0)
1563 return String (text, (
size_t) jmax (0,
length() - numberToDrop));
1568 return String (text + jmax (0,
length() - jmax (0, numCharacters)));
1611static bool isQuoteCharacter (juce_wchar c)
noexcept
1613 return c ==
'"' || c ==
'\'';
1618 return isQuoteCharacter (*text.findEndOfWhitespace());
1623 if (! isQuoteCharacter (*text))
1627 return substring (1, len - (isQuoteCharacter (text[len - 1]) ? 1 : 0));
1641 t += quoteCharacter;
1652 if (! (--end).isWhitespace())
1668 auto trimmedEnd = findTrimmedEnd (start, end);
1670 if (trimmedEnd <= start)
1673 if (text < start || trimmedEnd < end)
1674 return String (start, trimmedEnd);
1684 auto t = text.findEndOfWhitespace();
1698 auto trimmedEnd = findTrimmedEnd (text, end);
1700 if (trimmedEnd < end)
1701 return String (text, trimmedEnd);
1714 return t == text ? *this :
String (t);
1722 auto trimmedEnd = end;
1724 while (trimmedEnd > text)
1726 if (charactersToTrim.
text.
indexOf (*--trimmedEnd) < 0)
1733 if (trimmedEnd < end)
1734 return String (text, trimmedEnd);
1760 return std::move (builder.result);
1781 return std::move (builder.result);
1786 for (
auto t = text; ! t.isEmpty(); ++t)
1795 for (
auto t = text; ! t.isEmpty(); ++t)
1804 for (
auto t = text; ! t.isEmpty();)
1805 if (chars.text.indexOf (t.getAndAdvance()) < 0)
1813 for (
auto t = text; ! t.isEmpty();)
1814 if (chars.text.indexOf (t.getAndAdvance()) >= 0)
1822 for (
auto t = text; ! t.isEmpty(); ++t)
1823 if (! t.isWhitespace())
1829String String::formattedRaw (
const char* pf, ...)
1831 size_t bufferSize = 256;
1836 va_start (args, pf);
1840 int num = (int) vsnprintf (temp.get(), bufferSize - 1, pf, args);
1841 if (num >=
static_cast<int> (bufferSize))
1844 String wideCharVersion (pf);
1846 const int num = (int)
1852 (temp.get(), bufferSize - 1, wideCharVersion.toWideCharPointer(), args);
1857 return String (temp.get());
1861 if (num == 0 || bufferSize > 65536)
1878 auto t = text.findTerminatingNull();
1890 n +=
static_cast<juce_wchar
> (mult) * (*t -
'0');
1897static const char hexDigits[] =
"0123456789abcdef";
1899template <
typename Type>
1900static String hexToString (Type v)
1902 String::CharPointerType::CharType buffer[32];
1903 auto* end = buffer + numElementsInArray (buffer) - 1;
1909 *--t = hexDigits [(int) (v & 15)];
1918String String::createHex (uint8 n) {
return hexToString (n); }
1919String String::createHex (uint16 n) {
return hexToString (n); }
1920String String::createHex (uint32 n) {
return hexToString (n); }
1921String String::createHex (uint64 n) {
return hexToString (n); }
1928 int numChars = (size * 2) + 2;
1930 numChars += size / groupSize;
1932 String s (PreallocationBytes (
sizeof (CharPointerType::CharType) * (
size_t) numChars));
1934 auto* data =
static_cast<const unsigned char*
> (d);
1937 for (
int i = 0; i < size; ++i)
1939 const unsigned char nextByte = *data++;
1940 dest.
write ((juce_wchar) hexDigits [nextByte >> 4]);
1941 dest.write ((juce_wchar) hexDigits [nextByte & 0xf]);
1943 if (groupSize > 0 && (i % groupSize) == (groupSize - 1) && i < (size - 1))
1944 dest.write ((juce_wchar)
' ');
1955static String getStringFromWindows1252Codepage (
const char* data,
size_t num)
1959 for (
size_t i = 0; i < num; ++i)
1968 auto* data =
static_cast<const uint8*
> (unknownData);
1970 if (size <= 0 || data ==
nullptr)
1979 const int numChars = size / 2 - 1;
1983 auto src =
reinterpret_cast<const uint16*
> (data + 2);
1987 for (
int i = 0; i < numChars; ++i)
1992 for (
int i = 0; i < numChars; ++i)
1997 return std::move (builder.result);
2000 auto* start = (
const char*) data;
2012 return getStringFromWindows1252Codepage (start, (
size_t) size);
2016static const juce_wchar emptyChar = 0;
2018template <
class CharPo
interType_Src,
class CharPo
interType_Dest>
2021 static CharPointerType_Dest convert (
const String& s)
2023 auto& source =
const_cast<String&
> (s);
2025 using DestChar =
typename CharPointerType_Dest::CharType;
2027 if (source.isEmpty())
2028 return CharPointerType_Dest (
reinterpret_cast<const DestChar*
> (&emptyChar));
2030 CharPointerType_Src text (source.getCharPointer());
2031 auto extraBytesNeeded = CharPointerType_Dest::getBytesRequiredFor (text) +
sizeof (
typename CharPointerType_Dest::CharType);
2032 auto endOffset = (text.sizeInBytes() + 3) & ~3u;
2034 source.preallocateBytes (endOffset + extraBytesNeeded);
2035 text = source.getCharPointer();
2037 void*
const newSpace = addBytesToPointer (text.getAddress(), (
int) endOffset);
2038 const CharPointerType_Dest extraSpace (
static_cast<DestChar*
> (newSpace));
2041 auto bytesToClear = (size_t) jmin ((
int) extraBytesNeeded, 4);
2042 zeromem (addBytesToPointer (newSpace, extraBytesNeeded - bytesToClear), bytesToClear);
2045 CharPointerType_Dest (extraSpace).writeAll (text);
2082std::string String::toStdString()
const
2088template <
class CharPo
interType_Src,
class CharPo
interType_Dest>
2091 static size_t copyToBuffer (
const CharPointerType_Src source,
typename CharPointerType_Dest::CharType*
const buffer,
const size_t maxBufferSizeBytes)
2093 jassert (((ssize_t) maxBufferSizeBytes) >= 0);
2095 if (buffer ==
nullptr)
2096 return CharPointerType_Dest::getBytesRequiredFor (source) +
sizeof (
typename CharPointerType_Dest::CharType);
2098 return CharPointerType_Dest (buffer).writeWithDestByteLimit (source, maxBufferSizeBytes);
2102size_t String::copyToUTF8 (CharPointer_UTF8::CharType*
const buffer,
size_t maxBufferSizeBytes)
const noexcept
2107size_t String::copyToUTF16 (CharPointer_UTF16::CharType*
const buffer,
size_t maxBufferSizeBytes)
const noexcept
2112size_t String::copyToUTF32 (CharPointer_UTF32::CharType*
const buffer,
size_t maxBufferSizeBytes)
const noexcept
2125 if (buffer !=
nullptr)
2127 if (bufferSizeBytes < 0)
2130 if (bufferSizeBytes > 0)
2141 #pragma warning (pop)
2150 #if JUCE_STRING_UTF_TYPE != 8
2151 : text (
nullptr), stringCopy (stringLiteral)
2153 : text (stringLiteral)
2156 #if JUCE_STRING_UTF_TYPE != 8
2157 text = stringCopy.getCharPointer();
2160 jassert (stringLiteral !=
nullptr);
2162 #if JUCE_NATIVE_WCHAR_IS_UTF8
2182 jassert (stringLiteral.getAddress() !=
nullptr);
2190static String reduceLengthOfFloatString (
const String& input)
2193 const auto end = start + (int) input.
length();
2194 auto trimStart = end;
2195 auto trimEnd = trimStart;
2196 auto exponentTrimStart = end;
2197 auto exponentTrimEnd = exponentTrimStart;
2199 decltype (*start) currentChar =
'\0';
2201 for (
auto c = end - 1; c > start; --c)
2205 if (currentChar ==
'0' && c + 1 == trimStart)
2209 else if (currentChar ==
'.')
2211 if (trimStart == c + 1 && trimStart != end && *trimStart ==
'0')
2216 else if (currentChar ==
'e' || currentChar ==
'E')
2225 exponentTrimStart = cNext;
2227 if (cNext != end && *cNext ==
'+')
2230 exponentTrimEnd = cNext;
2233 while (cNext != end && *cNext++ ==
'0')
2234 exponentTrimEnd = cNext;
2236 if (exponentTrimEnd == end)
2237 exponentTrimStart = c;
2240 trimEnd = trimStart;
2244 if ((trimStart != trimEnd && currentChar ==
'.') || exponentTrimStart != exponentTrimEnd)
2246 if (trimStart == trimEnd)
2247 return String (start, exponentTrimStart) + String (exponentTrimEnd, end);
2249 if (exponentTrimStart == exponentTrimEnd)
2250 return String (start, trimStart) + String (trimEnd, end);
2252 if (trimEnd == exponentTrimStart)
2253 return String (start, trimStart) + String (exponentTrimEnd, end);
2255 return String (start, trimStart) + String (trimEnd, exponentTrimStart) + String (exponentTrimEnd, end);
2261static String serialiseDouble (
double input)
2263 auto absInput = std::abs (input);
2265 if (absInput >= 1.0e6 || absInput <= 1.0e-5)
2266 return reduceLengthOfFloatString ({ input, 15,
true });
2268 int intInput = (int) input;
2270 if ((
double) intInput == input)
2271 return { input, 1 };
2273 auto numberOfDecimalPlaces = [absInput]
2277 if (absInput >= 1.0e-3)
2279 if (absInput >= 1.0e-1)
return 16;
2280 if (absInput >= 1.0e-2)
return 17;
2284 if (absInput >= 1.0e-4)
return 19;
2288 if (absInput < 1.0e3)
2290 if (absInput < 1.0e1)
return 15;
2291 if (absInput < 1.0e2)
return 14;
2295 if (absInput < 1.0e4)
return 12;
2296 if (absInput < 1.0e5)
return 11;
2300 return reduceLengthOfFloatString (String (input, numberOfDecimalPlaces));
2307#define STRINGIFY2(X) #X
2308#define STRINGIFY(X) STRINGIFY2(X)
2310class StringTests :
public UnitTest
2313 StringTests() : UnitTest (
"String class",
"Text") {}
2315 template <
class CharPo
interType>
2316 struct TestUTFConversion
2318 static void test (UnitTest& test, Random& r)
2320 String s (createRandomWideCharString (r));
2322 typename CharPointerType::CharType buffer [300];
2324 memset (buffer, 0xff,
sizeof (buffer));
2325 CharPointerType (buffer).writeAll (s.toUTF32());
2326 test.expectEquals (String (CharPointerType (buffer)), s);
2328 memset (buffer, 0xff,
sizeof (buffer));
2329 CharPointerType (buffer).writeAll (s.toUTF16());
2330 test.expectEquals (String (CharPointerType (buffer)), s);
2332 memset (buffer, 0xff,
sizeof (buffer));
2333 CharPointerType (buffer).writeAll (s.toUTF8());
2334 test.expectEquals (String (CharPointerType (buffer)), s);
2336 test.expect (CharPointerType::isValidString (buffer, (
int) strlen ((
const char*) buffer)));
2340 static String createRandomWideCharString (Random& r)
2342 juce_wchar buffer[50] = { 0 };
2344 for (
int i = 0; i < numElementsInArray (buffer) - 1; ++i)
2350 buffer[i] = (juce_wchar) (1 + r.nextInt (0x10ffff - 1));
2352 while (! CharPointer_UTF16::canRepresent (buffer[i]));
2355 buffer[i] = (juce_wchar) (1 + r.nextInt (0xff));
2358 return CharPointer_UTF32 (buffer);
2361 void runTest()
override
2363 Random r = getRandom();
2366 beginTest (
"Basics");
2368 expect (String().length() == 0);
2369 expect (String() == String());
2370 String s1, s2 (
"abcd");
2371 expect (s1.isEmpty() && ! s1.isNotEmpty());
2372 expect (s2.isNotEmpty() && ! s2.isEmpty());
2373 expect (s2.length() == 4);
2375 expect (s2 == s1 && s1 == s2);
2376 expect (s1 ==
"abcd" && s1 == L
"abcd");
2377 expect (String (
"abcd") == String (L
"abcd"));
2378 expect (String (
"abcdefg", 4) == L
"abcd");
2379 expect (String (
"abcdefg", 4) == String (L
"abcdefg", 4));
2380 expect (String::charToString (
'x') ==
"x");
2381 expect (String::charToString (0) == String());
2382 expect (s2 +
"e" ==
"abcde" && s2 +
'e' ==
"abcde");
2383 expect (s2 + L
'e' ==
"abcde" && s2 + L
"e" ==
"abcde");
2384 expect (s1.equalsIgnoreCase (
"abcD") && s1 < "abce" && s1 >
"abbb");
2385 expect (s1.startsWith (
"ab") && s1.startsWith (
"abcd") && ! s1.startsWith (
"abcde"));
2386 expect (s1.startsWithIgnoreCase (
"aB") && s1.endsWithIgnoreCase (
"CD"));
2387 expect (s1.endsWith (
"bcd") && ! s1.endsWith (
"aabcd"));
2388 expectEquals (s1.indexOf (String()), 0);
2389 expectEquals (s1.indexOfIgnoreCase (String()), 0);
2390 expect (s1.startsWith (String()) && s1.endsWith (String()) && s1.contains (String()));
2391 expect (s1.contains (
"cd") && s1.contains (
"ab") && s1.contains (
"abcd"));
2392 expect (s1.containsChar (
'a'));
2393 expect (! s1.containsChar (
'x'));
2394 expect (! s1.containsChar (0));
2395 expect (String (
"abc foo bar").containsWholeWord (
"abc") && String (
"abc foo bar").containsWholeWord (
"abc"));
2399 beginTest (
"Operations");
2401 String s (
"012345678");
2402 expect (s.hashCode() != 0);
2403 expect (s.hashCode64() != 0);
2404 expect (s.hashCode() != (s + s).hashCode());
2405 expect (s.hashCode64() != (s + s).hashCode64());
2406 expect (s.compare (String (
"012345678")) == 0);
2407 expect (s.compare (String (
"012345679")) < 0);
2408 expect (s.compare (String (
"012345676")) > 0);
2409 expect (String(
"a").compareNatural (
"A") == 0);
2410 expect (String(
"A").compareNatural (
"B") < 0);
2411 expect (String(
"a").compareNatural (
"B") < 0);
2412 expect (String(
"10").compareNatural (
"2") > 0);
2413 expect (String(
"Abc 10").compareNatural (
"aBC 2") > 0);
2414 expect (String(
"Abc 1").compareNatural (
"aBC 2") < 0);
2415 expect (s.substring (2, 3) == String::charToString (s[2]));
2416 expect (s.substring (0, 1) == String::charToString (s[0]));
2417 expect (s.getLastCharacter() == s [s.length() - 1]);
2418 expect (String::charToString (s.getLastCharacter()) == s.getLastCharacters (1));
2419 expect (s.substring (0, 3) == L
"012");
2420 expect (s.substring (0, 100) == s);
2421 expect (s.substring (-1, 100) == s);
2422 expect (s.substring (3) ==
"345678");
2423 expect (s.indexOf (String (L
"45")) == 4);
2424 expect (String (
"444445").indexOf (
"45") == 4);
2425 expect (String (
"444445").lastIndexOfChar (
'4') == 4);
2426 expect (String (
"45454545x").lastIndexOf (String (L
"45")) == 6);
2427 expect (String (
"45454545x").lastIndexOfAnyOf (
"456") == 7);
2428 expect (String (
"45454545x").lastIndexOfAnyOf (String (L
"456x")) == 8);
2429 expect (String (
"abABaBaBa").lastIndexOfIgnoreCase (
"aB") == 6);
2430 expect (s.indexOfChar (L
'4') == 4);
2431 expect (s + s ==
"012345678012345678");
2432 expect (s.startsWith (s));
2433 expect (s.startsWith (s.substring (0, 4)));
2434 expect (s.startsWith (s.dropLastCharacters (4)));
2435 expect (s.endsWith (s.substring (5)));
2436 expect (s.endsWith (s));
2437 expect (s.contains (s.substring (3, 6)));
2438 expect (s.contains (s.substring (3)));
2439 expect (s.startsWithChar (s[0]));
2440 expect (s.endsWithChar (s.getLastCharacter()));
2441 expect (s [s.length()] == 0);
2442 expect (String (
"abcdEFGH").toLowerCase() == String (
"abcdefgh"));
2443 expect (String (
"abcdEFGH").toUpperCase() == String (
"ABCDEFGH"));
2445 expect (String (StringRef (
"abc")) ==
"abc");
2446 expect (String (StringRef (
"abc")) == StringRef (
"abc"));
2447 expect (String (
"abc") + StringRef (
"def") ==
"abcdef");
2450 s2 << ((int) 4) << ((short) 5) <<
"678" << L
"9" <<
'0';
2452 expect (s2 ==
"1234567890xyz");
2454 expect (s2 ==
"1234567890xyz123");
2456 expect (s2 ==
"1234567890xyz123123");
2457 s2 << StringRef (
"def");
2458 expect (s2 ==
"1234567890xyz123123def");
2462 String numStr (std::numeric_limits<int16>::max());
2463 expect (numStr ==
"32767");
2466 String numStr (std::numeric_limits<int16>::min());
2467 expect (numStr ==
"-32768");
2471 numStr << std::numeric_limits<int16>::max();
2472 expect (numStr ==
"32767");
2476 numStr << std::numeric_limits<int16>::min();
2477 expect (numStr ==
"-32768");
2481 String numStr (std::numeric_limits<int32>::max());
2482 expect (numStr ==
"2147483647");
2485 String numStr (std::numeric_limits<int32>::min());
2486 expect (numStr ==
"-2147483648");
2490 numStr << std::numeric_limits<int32>::max();
2491 expect (numStr ==
"2147483647");
2495 numStr << std::numeric_limits<int32>::min();
2496 expect (numStr ==
"-2147483648");
2500 String numStr (std::numeric_limits<uint32>::max());
2501 expect (numStr ==
"4294967295");
2504 String numStr (std::numeric_limits<uint32>::min());
2505 expect (numStr ==
"0");
2509 String numStr (std::numeric_limits<int64>::max());
2510 expect (numStr ==
"9223372036854775807");
2513 String numStr (std::numeric_limits<int64>::min());
2514 expect (numStr ==
"-9223372036854775808");
2518 numStr << std::numeric_limits<int64>::max();
2519 expect (numStr ==
"9223372036854775807");
2523 numStr << std::numeric_limits<int64>::min();
2524 expect (numStr ==
"-9223372036854775808");
2528 String numStr (std::numeric_limits<uint64>::max());
2529 expect (numStr ==
"18446744073709551615");
2532 String numStr (std::numeric_limits<uint64>::min());
2533 expect (numStr ==
"0");
2537 numStr << std::numeric_limits<uint64>::max();
2538 expect (numStr ==
"18446744073709551615");
2542 numStr << std::numeric_limits<uint64>::min();
2543 expect (numStr ==
"0");
2547 String numStr (std::numeric_limits<size_t>::min());
2548 expect (numStr ==
"0");
2551 beginTest (
"Numeric conversions");
2552 expect (String().getIntValue() == 0);
2553 expect (String().getDoubleValue() == 0.0);
2554 expect (String().getFloatValue() == 0.0f);
2555 expect (s.getIntValue() == 12345678);
2556 expect (s.getLargeIntValue() == (int64) 12345678);
2557 expect (s.getDoubleValue() == 12345678.0);
2558 expect (s.getFloatValue() == 12345678.0f);
2559 expect (String (-1234).getIntValue() == -1234);
2560 expect (String ((int64) -1234).getLargeIntValue() == -1234);
2561 expect (String (-1234.56).getDoubleValue() == -1234.56);
2562 expect (String (-1234.56f).getFloatValue() == -1234.56f);
2563 expect (String (std::numeric_limits<int>::max()).getIntValue() == std::numeric_limits<int>::max());
2564 expect (String (std::numeric_limits<int>::min()).getIntValue() == std::numeric_limits<int>::min());
2565 expect (String (std::numeric_limits<int64>::max()).getLargeIntValue() == std::numeric_limits<int64>::max());
2566 expect (String (std::numeric_limits<int64>::min()).getLargeIntValue() == std::numeric_limits<int64>::min());
2567 expect ((
"xyz" + s).getTrailingIntValue() == s.getIntValue());
2568 expect (s.getHexValue32() == 0x12345678);
2569 expect (s.getHexValue64() == (int64) 0x12345678);
2570 expect (String::toHexString (0x1234abcd).equalsIgnoreCase (
"1234abcd"));
2571 expect (String::toHexString ((int64) 0x1234abcd).equalsIgnoreCase (
"1234abcd"));
2572 expect (String::toHexString ((
short) 0x12ab).equalsIgnoreCase (
"12ab"));
2573 expect (String::toHexString ((
size_t) 0x12ab).equalsIgnoreCase (
"12ab"));
2574 expect (String::toHexString ((
long) 0x12ab).equalsIgnoreCase (
"12ab"));
2575 expect (String::toHexString ((int8) -1).equalsIgnoreCase (
"ff"));
2576 expect (String::toHexString ((int16) -1).equalsIgnoreCase (
"ffff"));
2577 expect (String::toHexString ((int32) -1).equalsIgnoreCase (
"ffffffff"));
2578 expect (String::toHexString ((int64) -1).equalsIgnoreCase (
"ffffffffffffffff"));
2580 unsigned char data[] = { 1, 2, 3, 4, 0xa, 0xb, 0xc, 0xd };
2581 expect (String::toHexString (data, 8, 0).equalsIgnoreCase (
"010203040a0b0c0d"));
2582 expect (String::toHexString (data, 8, 1).equalsIgnoreCase (
"01 02 03 04 0a 0b 0c 0d"));
2583 expect (String::toHexString (data, 8, 2).equalsIgnoreCase (
"0102 0304 0a0b 0c0d"));
2585 expectEquals (String (12345.67, 4), String (
"12345.6700"));
2586 expectEquals (String (12345.67, 6), String (
"12345.670000"));
2587 expectEquals (String (2589410.5894, 7), String (
"2589410.5894000"));
2588 expectEquals (String (12345.67, 8), String (
"12345.67000000"));
2589 expectEquals (String (1e19, 4), String (
"10000000000000000000.0000"));
2590 expectEquals (String (1e-34, 36), String (
"0.000000000000000000000000000000000100"));
2591 expectEquals (String (1.39, 1), String (
"1.4"));
2593 expectEquals (String (12345.67, 4,
true), String (
"1.2346e+04"));
2594 expectEquals (String (12345.67, 6,
true), String (
"1.234567e+04"));
2595 expectEquals (String (2589410.5894, 7,
true), String (
"2.5894106e+06"));
2596 expectEquals (String (12345.67, 8,
true), String (
"1.23456700e+04"));
2597 expectEquals (String (1e19, 4,
true), String (
"1.0000e+19"));
2598 expectEquals (String (1e-34, 5,
true), String (
"1.00000e-34"));
2599 expectEquals (String (1.39, 1,
true), String (
"1.4e+00"));
2601 beginTest (
"Subsections");
2604 expect (s3.equalsIgnoreCase (
"ABCdeFGhiJ"));
2605 expect (s3.compareIgnoreCase (L
"ABCdeFGhiJ") == 0);
2606 expect (s3.containsIgnoreCase (s3.substring (3)));
2607 expect (s3.indexOfAnyOf (
"xyzf", 2,
true) == 5);
2608 expect (s3.indexOfAnyOf (String (L
"xyzf"), 2,
false) == -1);
2609 expect (s3.indexOfAnyOf (
"xyzF", 2,
false) == 5);
2610 expect (s3.containsAnyOf (String (L
"zzzFs")));
2611 expect (s3.startsWith (
"abcd"));
2612 expect (s3.startsWithIgnoreCase (String (L
"abCD")));
2613 expect (s3.startsWith (String()));
2614 expect (s3.startsWithChar (
'a'));
2615 expect (s3.endsWith (String (
"HIJ")));
2616 expect (s3.endsWithIgnoreCase (String (L
"Hij")));
2617 expect (s3.endsWith (String()));
2618 expect (s3.endsWithChar (L
'J'));
2619 expect (s3.indexOf (
"HIJ") == 7);
2620 expect (s3.indexOf (String (L
"HIJK")) == -1);
2621 expect (s3.indexOfIgnoreCase (
"hij") == 7);
2622 expect (s3.indexOfIgnoreCase (String (L
"hijk")) == -1);
2623 expect (s3.toStdString() == s3.toRawUTF8());
2626 s4.append (String (
"xyz123"), 3);
2627 expect (s4 == s3 +
"xyz");
2629 expect (String (1234) < String (1235));
2630 expect (String (1235) > String (1234));
2631 expect (String (1234) >= String (1234));
2632 expect (String (1234) <= String (1234));
2633 expect (String (1235) >= String (1234));
2634 expect (String (1234) <= String (1235));
2636 String s5 (
"word word2 word3");
2637 expect (s5.containsWholeWord (String (
"word2")));
2638 expect (s5.indexOfWholeWord (
"word2") == 5);
2639 expect (s5.containsWholeWord (String (L
"word")));
2640 expect (s5.containsWholeWord (
"word3"));
2641 expect (s5.containsWholeWord (s5));
2642 expect (s5.containsWholeWordIgnoreCase (String (L
"Word2")));
2643 expect (s5.indexOfWholeWordIgnoreCase (
"Word2") == 5);
2644 expect (s5.containsWholeWordIgnoreCase (String (L
"Word")));
2645 expect (s5.containsWholeWordIgnoreCase (
"Word3"));
2646 expect (! s5.containsWholeWordIgnoreCase (String (L
"Wordx")));
2647 expect (! s5.containsWholeWordIgnoreCase (
"xWord2"));
2648 expect (s5.containsNonWhitespaceChars());
2649 expect (s5.containsOnly (
"ordw23 "));
2650 expect (! String (
" \n\r\t").containsNonWhitespaceChars());
2652 expect (s5.matchesWildcard (String (L
"wor*"),
false));
2653 expect (s5.matchesWildcard (
"wOr*",
true));
2654 expect (s5.matchesWildcard (String (L
"*word3"),
true));
2655 expect (s5.matchesWildcard (
"*word?",
true));
2656 expect (s5.matchesWildcard (String (L
"Word*3"),
true));
2657 expect (! s5.matchesWildcard (String (L
"*34"),
true));
2658 expect (String (
"xx**y").matchesWildcard (
"*y",
true));
2659 expect (String (
"xx**y").matchesWildcard (
"x*y",
true));
2660 expect (String (
"xx**y").matchesWildcard (
"xx*y",
true));
2661 expect (String (
"xx**y").matchesWildcard (
"xx*",
true));
2662 expect (String (
"xx?y").matchesWildcard (
"x??y",
true));
2663 expect (String (
"xx?y").matchesWildcard (
"xx?y",
true));
2664 expect (! String (
"xx?y").matchesWildcard (
"xx?y?",
true));
2665 expect (String (
"xx?y").matchesWildcard (
"xx??",
true));
2667 expectEquals (s5.fromFirstOccurrenceOf (String(),
true,
false), s5);
2668 expectEquals (s5.fromFirstOccurrenceOf (
"xword2",
true,
false), s5.substring (100));
2669 expectEquals (s5.fromFirstOccurrenceOf (String (L
"word2"),
true,
false), s5.substring (5));
2670 expectEquals (s5.fromFirstOccurrenceOf (
"Word2",
true,
true), s5.substring (5));
2671 expectEquals (s5.fromFirstOccurrenceOf (
"word2",
false,
false), s5.getLastCharacters (6));
2672 expectEquals (s5.fromFirstOccurrenceOf (
"Word2",
false,
true), s5.getLastCharacters (6));
2674 expectEquals (s5.fromLastOccurrenceOf (String(),
true,
false), s5);
2675 expectEquals (s5.fromLastOccurrenceOf (
"wordx",
true,
false), s5);
2676 expectEquals (s5.fromLastOccurrenceOf (
"word",
true,
false), s5.getLastCharacters (5));
2677 expectEquals (s5.fromLastOccurrenceOf (
"worD",
true,
true), s5.getLastCharacters (5));
2678 expectEquals (s5.fromLastOccurrenceOf (
"word",
false,
false), s5.getLastCharacters (1));
2679 expectEquals (s5.fromLastOccurrenceOf (
"worD",
false,
true), s5.getLastCharacters (1));
2681 expect (s5.upToFirstOccurrenceOf (String(),
true,
false).isEmpty());
2682 expectEquals (s5.upToFirstOccurrenceOf (
"word4",
true,
false), s5);
2683 expectEquals (s5.upToFirstOccurrenceOf (
"word2",
true,
false), s5.substring (0, 10));
2684 expectEquals (s5.upToFirstOccurrenceOf (
"Word2",
true,
true), s5.substring (0, 10));
2685 expectEquals (s5.upToFirstOccurrenceOf (
"word2",
false,
false), s5.substring (0, 5));
2686 expectEquals (s5.upToFirstOccurrenceOf (
"Word2",
false,
true), s5.substring (0, 5));
2688 expectEquals (s5.upToLastOccurrenceOf (String(),
true,
false), s5);
2689 expectEquals (s5.upToLastOccurrenceOf (
"zword",
true,
false), s5);
2690 expectEquals (s5.upToLastOccurrenceOf (
"word",
true,
false), s5.dropLastCharacters (1));
2691 expectEquals (s5.dropLastCharacters(1).upToLastOccurrenceOf (
"word",
true,
false), s5.dropLastCharacters (1));
2692 expectEquals (s5.upToLastOccurrenceOf (
"Word",
true,
true), s5.dropLastCharacters (1));
2693 expectEquals (s5.upToLastOccurrenceOf (
"word",
false,
false), s5.dropLastCharacters (5));
2694 expectEquals (s5.upToLastOccurrenceOf (
"Word",
false,
true), s5.dropLastCharacters (5));
2696 expectEquals (s5.replace (
"word",
"xyz",
false), String (
"xyz xyz2 xyz3"));
2697 expect (s5.replace (
"Word",
"xyz",
true) ==
"xyz xyz2 xyz3");
2698 expect (s5.dropLastCharacters (1).replace (
"Word", String (
"xyz"),
true) == L
"xyz xyz2 xyz");
2699 expect (s5.replace (
"Word",
"",
true) ==
" 2 3");
2700 expectEquals (s5.replace (
"Word2",
"xyz",
true), String (
"word xyz word3"));
2701 expect (s5.replaceCharacter (L
'w',
'x') != s5);
2702 expectEquals (s5.replaceCharacter (
'w', L
'x').replaceCharacter (
'x',
'w'), s5);
2703 expect (s5.replaceCharacters (
"wo",
"xy") != s5);
2704 expectEquals (s5.replaceCharacters (
"wo",
"xy").replaceCharacters (
"xy",
"wo"), s5);
2705 expectEquals (s5.retainCharacters (
"1wordxya"), String (
"wordwordword"));
2706 expect (s5.retainCharacters (String()).isEmpty());
2707 expect (s5.removeCharacters (
"1wordxya") ==
" 2 3");
2708 expectEquals (s5.removeCharacters (String()), s5);
2709 expect (s5.initialSectionContainingOnly (
"word") == L
"word");
2710 expect (String (
"word").initialSectionContainingOnly (
"word") == L
"word");
2711 expectEquals (s5.initialSectionNotContaining (String (
"xyz ")), String (
"word"));
2712 expectEquals (s5.initialSectionNotContaining (String (
";[:'/")), s5);
2713 expect (! s5.isQuotedString());
2714 expect (s5.quoted().isQuotedString());
2715 expect (! s5.quoted().unquoted().isQuotedString());
2716 expect (! String (
"x'").isQuotedString());
2717 expect (String (
"'x").isQuotedString());
2719 String s6 (
" \t xyz \t\r\n");
2720 expectEquals (s6.trim(), String (
"xyz"));
2721 expect (s6.trim().trim() ==
"xyz");
2722 expectEquals (s5.trim(), s5);
2723 expectEquals (s6.trimStart().trimEnd(), s6.trim());
2724 expectEquals (s6.trimStart().trimEnd(), s6.trimEnd().trimStart());
2725 expectEquals (s6.trimStart().trimStart().trimEnd().trimEnd(), s6.trimEnd().trimStart());
2726 expect (s6.trimStart() != s6.trimEnd());
2727 expectEquals ((
"\t\r\n " + s6 +
"\t\n \r").trim(), s6.trim());
2728 expect (String::repeatedString (
"xyz", 3) == L
"xyzxyzxyz");
2732 beginTest (
"UTF conversions");
2734 TestUTFConversion <CharPointer_UTF32>::test (*
this, r);
2735 TestUTFConversion <CharPointer_UTF8>::test (*
this, r);
2736 TestUTFConversion <CharPointer_UTF16>::test (*
this, r);
2740 beginTest (
"StringArray");
2743 s.addTokens (
"4,3,2,1,0",
";,",
"x");
2744 expectEquals (s.size(), 5);
2746 expectEquals (s.joinIntoString (
"-"), String (
"4-3-2-1-0"));
2748 expectEquals (s.joinIntoString (
"--"), String (
"4--3--1--0"));
2749 expectEquals (s.joinIntoString (StringRef()), String (
"4310"));
2751 expectEquals (s.joinIntoString (
"x"), String());
2754 toks.addTokens (
"x,,",
";,",
"");
2755 expectEquals (toks.size(), 3);
2756 expectEquals (toks.joinIntoString (
"-"), String (
"x--"));
2759 toks.addTokens (
",x,",
";,",
"");
2760 expectEquals (toks.size(), 3);
2761 expectEquals (toks.joinIntoString (
"-"), String (
"-x-"));
2764 toks.addTokens (
"x,'y,z',",
";,",
"'");
2765 expectEquals (toks.size(), 3);
2766 expectEquals (toks.joinIntoString (
"-"), String (
"x-'y,z'-"));
2777 expect (! v2.equals (v1));
2778 expect (! v1.equals (v2));
2779 expect (v2.equals (v3));
2780 expect (! v3.equals (v1));
2781 expect (! v1.equals (v3));
2782 expect (v1.equals (v4));
2783 expect (v4.equals (v1));
2784 expect (v5.equals (v4));
2785 expect (v4.equals (v5));
2786 expect (! v2.equals (v4));
2787 expect (! v4.equals (v2));
2791 beginTest (
"Significant figures");
2795 expectEquals (String::toDecimalStringWithSignificantFigures (13, 1), String (
"10"));
2796 expectEquals (String::toDecimalStringWithSignificantFigures (13, 2), String (
"13"));
2797 expectEquals (String::toDecimalStringWithSignificantFigures (13, 3), String (
"13.0"));
2798 expectEquals (String::toDecimalStringWithSignificantFigures (13, 4), String (
"13.00"));
2800 expectEquals (String::toDecimalStringWithSignificantFigures (19368, 1), String (
"20000"));
2801 expectEquals (String::toDecimalStringWithSignificantFigures (19348, 3), String (
"19300"));
2803 expectEquals (String::toDecimalStringWithSignificantFigures (-5, 1), String (
"-5"));
2804 expectEquals (String::toDecimalStringWithSignificantFigures (-5, 3), String (
"-5.00"));
2808 expectEquals (String::toDecimalStringWithSignificantFigures (0, 1), String (
"0"));
2809 expectEquals (String::toDecimalStringWithSignificantFigures (0, 2), String (
"0.0"));
2810 expectEquals (String::toDecimalStringWithSignificantFigures (0, 3), String (
"0.00"));
2814 expectEquals (String::toDecimalStringWithSignificantFigures (19.0, 1), String (
"20"));
2815 expectEquals (String::toDecimalStringWithSignificantFigures (19.0, 2), String (
"19"));
2816 expectEquals (String::toDecimalStringWithSignificantFigures (19.0, 3), String (
"19.0"));
2817 expectEquals (String::toDecimalStringWithSignificantFigures (19.0, 4), String (
"19.00"));
2819 expectEquals (String::toDecimalStringWithSignificantFigures (-5.45, 1), String (
"-5"));
2820 expectEquals (String::toDecimalStringWithSignificantFigures (-5.45, 3), String (
"-5.45"));
2822 expectEquals (String::toDecimalStringWithSignificantFigures (12345.6789, 9), String (
"12345.6789"));
2823 expectEquals (String::toDecimalStringWithSignificantFigures (12345.6789, 8), String (
"12345.679"));
2824 expectEquals (String::toDecimalStringWithSignificantFigures (12345.6789, 5), String (
"12346"));
2826 expectEquals (String::toDecimalStringWithSignificantFigures (0.00028647, 6), String (
"0.000286470"));
2827 expectEquals (String::toDecimalStringWithSignificantFigures (0.0028647, 6), String (
"0.00286470"));
2828 expectEquals (String::toDecimalStringWithSignificantFigures (2.8647, 6), String (
"2.86470"));
2830 expectEquals (String::toDecimalStringWithSignificantFigures (-0.0000000000019, 1), String (
"-0.000000000002"));
2834 beginTest (
"Float trimming");
2837 StringPairArray tests;
2838 tests.set (
"1",
"1");
2839 tests.set (
"1.0",
"1.0");
2840 tests.set (
"-1",
"-1");
2841 tests.set (
"-100",
"-100");
2842 tests.set (
"110",
"110");
2843 tests.set (
"9090",
"9090");
2844 tests.set (
"1000.0",
"1000.0");
2845 tests.set (
"1.0",
"1.0");
2846 tests.set (
"-1.00",
"-1.0");
2847 tests.set (
"1.20",
"1.2");
2848 tests.set (
"1.300",
"1.3");
2849 tests.set (
"1.301",
"1.301");
2850 tests.set (
"1e",
"1");
2851 tests.set (
"-1e+",
"-1");
2852 tests.set (
"1e-",
"1");
2853 tests.set (
"1e0",
"1");
2854 tests.set (
"1e+0",
"1");
2855 tests.set (
"1e-0",
"1");
2856 tests.set (
"1e000",
"1");
2857 tests.set (
"1e+000",
"1");
2858 tests.set (
"-1e-000",
"-1");
2859 tests.set (
"1e100",
"1e100");
2860 tests.set (
"100e100",
"100e100");
2861 tests.set (
"100.0e0100",
"100.0e100");
2862 tests.set (
"-1e1",
"-1e1");
2863 tests.set (
"1e10",
"1e10");
2864 tests.set (
"-1e+10",
"-1e10");
2865 tests.set (
"1e-10",
"1e-10");
2866 tests.set (
"1e0010",
"1e10");
2867 tests.set (
"1e-0010",
"1e-10");
2868 tests.set (
"1e-1",
"1e-1");
2869 tests.set (
"-1.0e1",
"-1.0e1");
2870 tests.set (
"1.0e-1",
"1.0e-1");
2871 tests.set (
"1.00e-1",
"1.0e-1");
2872 tests.set (
"1.001e1",
"1.001e1");
2873 tests.set (
"1.010e+1",
"1.01e1");
2874 tests.set (
"-1.1000e1",
"-1.1e1");
2876 for (
auto& input : tests.getAllKeys())
2877 expectEquals (reduceLengthOfFloatString (input), tests[input]);
2881 std::map<double, String> tests;
2884 tests[1.01] =
"1.01";
2885 tests[0.76378] =
"7.6378e-1";
2886 tests[-10] =
"-1.0e1";
2887 tests[10.01] =
"1.001e1";
2888 tests[10691.01] =
"1.069101e4";
2889 tests[0.0123] =
"1.23e-2";
2890 tests[-3.7e-27] =
"-3.7e-27";
2891 tests[1e+40] =
"1.0e40";
2893 for (
auto& test : tests)
2894 expectEquals (reduceLengthOfFloatString (String (test.first, 15, true)), test.second);
2899 beginTest (
"Serialisation");
2901 std::map <double, String> tests;
2903 tests[364] =
"364.0";
2904 tests[1e7] =
"1.0e7";
2905 tests[12345678901] =
"1.2345678901e10";
2907 tests[1234567890123456.7] =
"1.234567890123457e15";
2908 tests[12345678.901234567] =
"1.234567890123457e7";
2909 tests[1234567.8901234567] =
"1.234567890123457e6";
2910 tests[123456.78901234567] =
"123456.7890123457";
2911 tests[12345.678901234567] =
"12345.67890123457";
2912 tests[1234.5678901234567] =
"1234.567890123457";
2913 tests[123.45678901234567] =
"123.4567890123457";
2914 tests[12.345678901234567] =
"12.34567890123457";
2915 tests[1.2345678901234567] =
"1.234567890123457";
2916 tests[0.12345678901234567] =
"0.1234567890123457";
2917 tests[0.012345678901234567] =
"0.01234567890123457";
2918 tests[0.0012345678901234567] =
"0.001234567890123457";
2919 tests[0.00012345678901234567] =
"0.0001234567890123457";
2920 tests[0.000012345678901234567] =
"0.00001234567890123457";
2921 tests[0.0000012345678901234567] =
"1.234567890123457e-6";
2922 tests[0.00000012345678901234567] =
"1.234567890123457e-7";
2924 for (
auto& test : tests)
2926 expectEquals (serialiseDouble (test.first), test.second);
2927 expectEquals (serialiseDouble (-test.first),
"-" + test.second);
2933static StringTests stringUnitTests;
static Type swapIfLittleEndian(Type value) noexcept
Swaps the byte order of a signed or unsigned integer if the CPU is little-endian.
static Type swapIfBigEndian(Type value) noexcept
Swaps the byte order of a signed or unsigned integer if the CPU is big-endian.
Wraps a pointer to a null-terminated ASCII character string, and provides various methods to operate ...
static bool isValidString(const CharType *dataToTest, int maxBytesToRead)
Returns true if this data contains a valid string in this encoding.
Wraps a pointer to a null-terminated UTF-16 character string, and provides various methods to operate...
static bool isByteOrderMarkBigEndian(const void *possibleByteOrder) noexcept
Returns true if the first pair of bytes in this pointer are the UTF16 byte-order mark (big endian).
static bool isByteOrderMarkLittleEndian(const void *possibleByteOrder) noexcept
Returns true if the first pair of bytes in this pointer are the UTF16 byte-order mark (little endian)...
Wraps a pointer to a null-terminated UTF-32 character string, and provides various methods to operate...
Wraps a pointer to a null-terminated UTF-8 character string, and provides various methods to operate ...
void writeAll(const CharPointer src) noexcept
Copies a source string to this pointer, advancing this pointer as it goes.
CharPointer_UTF8 findTerminatingNull() const noexcept
Returns a pointer to the null character that terminates this string.
juce_wchar getAndAdvance() noexcept
Returns the character that this pointer is currently pointing to, and then advances the pointer to po...
void writeNull() const noexcept
Writes a null character to this string (leaving the pointer's position unchanged).
bool isEmpty() const noexcept
Returns true if this pointer is pointing to a null character.
juce_wchar toUpperCase() const noexcept
Returns an upper-case version of the first character of this string.
static size_t getBytesRequiredFor(const juce_wchar charToWrite) noexcept
Returns the number of bytes that would be needed to represent the given unicode character in this enc...
int indexOf(const CharPointer stringToFind) const noexcept
Returns the character index of a substring, or -1 if it isn't found.
static bool isByteOrderMark(const void *possibleByteOrder) noexcept
Returns true if the first three bytes in this pointer are the UTF8 byte-order mark (BOM).
void writeWithCharLimit(const CharPointer src, const int maxChars) noexcept
Copies a source string to this pointer, advancing this pointer as it goes.
static bool isValidString(const CharType *dataToTest, int maxBytesToRead)
Returns true if this data contains a valid string in this encoding.
juce_wchar toLowerCase() const noexcept
Returns a lower-case version of the first character of this string.
CharPointer_UTF8 findEndOfWhitespace() const noexcept
Returns the first non-whitespace character in the string.
void write(const juce_wchar charToWrite) noexcept
Writes a unicode character to this string, and advances this pointer to point to the next position.
CharType * getAddress() const noexcept
Returns the address that this pointer is pointing to.
size_t length() const noexcept
Returns the number of characters in this string.
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 juce_wchar toLowerCase(juce_wchar character) noexcept
Converts a character to lower-case.
static bool isDigit(char character) noexcept
Checks whether a character is a digit.
static bool isLetterOrDigit(char character) noexcept
Checks whether a character is alphabetic or numeric.
static juce_wchar toUpperCase(juce_wchar character) noexcept
Converts a character to upper-case.
static juce_wchar getUnicodeCharFromWindows1252Codepage(uint8 windows1252Char) noexcept
Converts a byte of Windows 1252 codepage to unicode.
Very simple container class to hold a pointer to some data on the heap.
A simple class for holding temporary references to a string literal or String.
int length() const noexcept
Returns the number of characters in the string.
String::CharPointerType text
The text that is referenced.
StringRef() noexcept
Creates a StringRef pointer to an empty string.
CharPointerType getCharPointer() const noexcept
Returns the character pointer currently being used to store this string.
bool equalsIgnoreCase(const String &other) const noexcept
Case-insensitive comparison with another string.
static String repeatedString(StringRef stringToRepeat, int numberOfTimesToRepeat)
Creates a string which is a version of a string repeated and joined together.
int indexOfChar(juce_wchar characterToLookFor) const noexcept
Searches for a character inside this string.
String upToFirstOccurrenceOf(StringRef substringToEndWith, bool includeSubStringInResult, bool ignoreCase) const
Returns the start of this string, up to the first occurrence of a substring.
int length() const noexcept
Returns the number of characters in the string.
String trim() const
Returns a copy of this string with any whitespace characters removed from the start and end.
int compareNatural(StringRef other, bool isCaseSensitive=false) const noexcept
Compares two strings, taking into account textual characteristics like numbers and spaces.
bool endsWithChar(juce_wchar character) const noexcept
Tests whether the string ends with a particular character.
String trimCharactersAtStart(StringRef charactersToTrim) const
Returns a copy of this string, having removed a specified set of characters from its start.
String toUpperCase() const
Returns an upper-case version of this string.
bool isEmpty() const noexcept
Returns true if the string contains no characters.
String() noexcept
Creates an empty string.
CharPointer_UTF16 toUTF16() const
Returns a pointer to a UTF-16 version of this string.
bool isQuotedString() const
Checks whether the string might be in quotation marks.
void append(const String &textToAppend, size_t maxCharsToTake)
Appends a string to the end of this one.
~String() noexcept
Destructor.
float getFloatValue() const noexcept
Parses this string as a floating point number.
const char * toRawUTF8() const
Returns a pointer to a UTF-8 version of this string.
bool containsIgnoreCase(StringRef text) const noexcept
Tests whether the string contains another substring.
bool startsWithChar(juce_wchar character) const noexcept
Tests whether the string begins with a particular character.
bool startsWith(StringRef text) const noexcept
Tests whether the string begins with another string.
int64 hashCode64() const noexcept
Generates a probably-unique 64-bit hashcode from this string.
bool containsChar(juce_wchar character) const noexcept
Tests whether the string contains a particular character.
String paddedLeft(juce_wchar padCharacter, int minimumLength) const
Returns a copy of this string with the specified character repeatedly added to its beginning until th...
bool startsWithIgnoreCase(StringRef text) const noexcept
Tests whether the string begins with another string.
int compareIgnoreCase(const String &other) const noexcept
Case-insensitive comparison with another string.
String removeCharacters(StringRef charactersToRemove) const
Returns a version of this string with a set of characters removed.
bool endsWithIgnoreCase(StringRef text) const noexcept
Tests whether the string ends with another string.
bool matchesWildcard(StringRef wildcard, bool ignoreCase) const noexcept
Returns true if the string matches this simple wildcard expression.
void appendCharPointer(CharPointerType startOfTextToAppend, CharPointerType endOfTextToAppend)
Appends a string to the end of this one.
String quoted(juce_wchar quoteCharacter='"') const
Adds quotation marks around a string.
String & operator+=(const String &stringToAppend)
Appends another string at the end of this one.
int indexOf(StringRef textToLookFor) const noexcept
Searches for a substring within this string.
size_t getNumBytesAsUTF8() const noexcept
Returns the number of bytes required to represent this string as UTF8.
String initialSectionContainingOnly(StringRef permittedCharacters) const
Returns a section from the start of the string that only contains a certain set of characters.
static String createStringFromData(const void *data, int size)
Creates a string from data in an unknown format.
int lastIndexOf(StringRef textToLookFor) const noexcept
Searches for a substring inside this string (working backwards from the end of the string).
String retainCharacters(StringRef charactersToRetain) const
Returns a version of this string that only retains a fixed set of characters.
void clear() noexcept
Resets this string to be empty.
int indexOfAnyOf(StringRef charactersToLookFor, int startIndex=0, bool ignoreCase=false) const noexcept
Returns the index of the first character that matches one of the characters passed-in to this method.
size_t copyToUTF16(CharPointer_UTF16::CharType *destBuffer, size_t maxBufferSizeBytes) const noexcept
Copies the string to a buffer as UTF-16 characters.
void preallocateBytes(size_t numBytesNeeded)
Increases the string's internally allocated storage.
int lastIndexOfAnyOf(StringRef charactersToLookFor, bool ignoreCase=false) const noexcept
Returns the index of the last character in this string that matches one of the characters passed-in t...
size_t hash() const noexcept
Generates a probably-unique hashcode from this string.
String dropLastCharacters(int numberToDrop) const
Returns a version of this string with a number of characters removed from the end.
juce_wchar operator[](int index) const noexcept
Returns the character at this index in the string.
bool contains(StringRef text) const noexcept
Tests whether the string contains another substring.
String trimStart() const
Returns a copy of this string with any whitespace characters removed from the start.
String trimEnd() const
Returns a copy of this string with any whitespace characters removed from the end.
String toLowerCase() const
Returns an lower-case version of this string.
String replaceFirstOccurrenceOf(StringRef stringToReplace, StringRef stringToInsertInstead, bool ignoreCase=false) const
Replaces the first occurrence of a substring with another string.
double getDoubleValue() const noexcept
Parses this string as a floating point number.
int getTrailingIntValue() const noexcept
Parses a decimal number from the end of the string.
static String toHexString(IntegerType number)
Returns a string representing this numeric value in hexadecimal.
int indexOfWholeWord(StringRef wordToLookFor) const noexcept
Finds an instance of another substring if it exists as a distinct word.
int lastIndexOfChar(juce_wchar character) const noexcept
Searches for a character inside this string (working backwards from the end of the string).
size_t copyToUTF32(CharPointer_UTF32::CharType *destBuffer, size_t maxBufferSizeBytes) const noexcept
Copies the string to a buffer as UTF-32 characters.
const wchar_t * toWideCharPointer() const
Returns a pointer to a wchar_t version of this string.
size_t copyToUTF8(CharPointer_UTF8::CharType *destBuffer, size_t maxBufferSizeBytes) const noexcept
Copies the string to a buffer as UTF-8 characters.
String replace(StringRef stringToReplace, StringRef stringToInsertInstead, bool ignoreCase=false) const
Replaces all occurrences of a substring with another string.
int lastIndexOfIgnoreCase(StringRef textToLookFor) const noexcept
Searches for a substring inside this string (working backwards from the end of the string).
String getLastCharacters(int numCharacters) const
Returns a number of characters from the end of the string.
String replaceCharacters(StringRef charactersToReplace, StringRef charactersToInsertInstead) const
Replaces a set of characters with another set.
String upToLastOccurrenceOf(StringRef substringToFind, bool includeSubStringInResult, bool ignoreCase) const
Returns the start of this string, up to the last occurrence of a substring.
String unquoted() const
Removes quotation marks from around the string, (if there are any).
String trimCharactersAtEnd(StringRef charactersToTrim) const
Returns a copy of this string, having removed a specified set of characters from its end.
bool containsWholeWord(StringRef wordToLookFor) const noexcept
Tests whether the string contains another substring as a distinct word.
static String charToString(juce_wchar character)
Creates a string from a single character.
String paddedRight(juce_wchar padCharacter, int minimumLength) const
Returns a copy of this string with the specified character repeatedly added to its end until the tota...
String replaceCharacter(juce_wchar characterToReplace, juce_wchar characterToInsertInstead) const
Returns a string with all occurrences of a character replaced with a different one.
juce_wchar getLastCharacter() const noexcept
Returns the final character of the string.
String substring(int startIndex, int endIndex) const
Returns a subsection of the string.
String fromLastOccurrenceOf(StringRef substringToFind, bool includeSubStringInResult, bool ignoreCase) const
Returns a section of the string starting from the last occurrence of a given substring.
int hashCode() const noexcept
Generates a probably-unique 32-bit hashcode from this string.
bool containsNonWhitespaceChars() const noexcept
Returns true if this string contains any non-whitespace characters.
String replaceSection(int startIndex, int numCharactersToReplace, StringRef stringToInsert) const
Replaces a sub-section of the string with another string.
String & operator=(const String &other) noexcept
Replaces this string's contents with another string.
String initialSectionNotContaining(StringRef charactersToStopAt) const
Returns a section from the start of the string that only contains a certain set of characters.
static String fromUTF8(const char *utf8buffer, int bufferSizeBytes=-1)
Creates a String from a UTF-8 encoded buffer.
int64 getLargeIntValue() const noexcept
Reads the value of the string as a decimal number (up to 64 bits in size).
CharPointer_UTF8 CharPointerType
This is the character encoding type used internally to store the string.
int64 getHexValue64() const noexcept
Parses the string as a hexadecimal number.
bool containsAnyOf(StringRef charactersItMightContain) const noexcept
Looks for any of a set of characters in the string.
bool endsWith(StringRef text) const noexcept
Tests whether the string ends with another string.
int indexOfIgnoreCase(StringRef textToLookFor) const noexcept
Searches for a substring within this string.
bool containsWholeWordIgnoreCase(StringRef wordToLookFor) const noexcept
Tests whether the string contains another substring as a distinct word.
CharPointer_UTF8 toUTF8() const
Returns a pointer to a UTF-8 version of this string.
int getReferenceCount() const noexcept
Returns the number of String objects which are currently sharing the same internal data as this one.
int indexOfWholeWordIgnoreCase(StringRef wordToLookFor) const noexcept
Finds an instance of another substring if it exists as a distinct word.
int compare(const String &other) const noexcept
Case-sensitive comparison with another string.
int getIntValue() const noexcept
Reads the value of the string as a decimal number (up to 32 bits in size).
bool containsOnly(StringRef charactersItMightContain) const noexcept
Looks for a set of characters in the string.
bool isNotEmpty() const noexcept
Returns true if the string contains at least one character.
CharPointer_UTF32 toUTF32() const
Returns a pointer to a UTF-32 version of this string.
String fromFirstOccurrenceOf(StringRef substringToStartFrom, bool includeSubStringInResult, bool ignoreCase) const
Returns a section of the string starting from a given substring.
void swapWith(String &other) noexcept
Swaps the contents of this string with another one.
int getHexValue32() const noexcept
Parses the string as a hexadecimal number.
#define JUCE_API
This macro is added to all JUCE public class declarations.
A simple wrapper around std::atomic.
Type get() const noexcept
Atomically reads and returns the current value.
std::atomic< Type > value
The std::atomic object that this class operates on.
Parses a character string, to read a hexadecimal value.