Loading...
Searching...
No Matches
juce_String.h
/*
==============================================================================
This file is part of the JUCE library.
Copyright (c) 2022 - Raw Material Software Limited
JUCE is an open source library subject to commercial or open-source
licensing.
The code included in this file is provided under the terms of the ISC license
http://www.isc.org/downloads/software-support-policy/isc-license. Permission
To use, copy, modify, and/or distribute this software for any purpose with or
without fee is hereby granted provided that the above copyright notice and
this permission notice appear in all copies.
JUCE IS PROVIDED "AS IS" WITHOUT ANY WARRANTY, AND ALL WARRANTIES, WHETHER
EXPRESSED OR IMPLIED, INCLUDING MERCHANTABILITY AND FITNESS FOR PURPOSE, ARE
DISCLAIMED.
==============================================================================
*/
#if ! defined (DOXYGEN) && (JUCE_MAC || JUCE_IOS)
// Annoyingly we can only forward-declare a typedef by forward-declaring the
// aliased type
#if __has_attribute(objc_bridge)
#define JUCE_CF_BRIDGED_TYPE(T) __attribute__ ((objc_bridge (T)))
#else
#define JUCE_CF_BRIDGED_TYPE(T)
#endif
typedef const struct JUCE_CF_BRIDGED_TYPE(NSString) __CFString * CFStringRef;
#undef JUCE_CF_BRIDGED_TYPE
#endif
namespace juce
{
//==============================================================================
class JUCE_API String final
{
public:
//==============================================================================
String() noexcept;
String (const String&) noexcept;
String (String&&) noexcept;
String (const char* text);
String (const char* text, size_t maxChars);
String (const wchar_t* text);
String (const wchar_t* text, size_t maxChars);
//==============================================================================
String (CharPointer_UTF8 text);
String (CharPointer_UTF8 text, size_t maxChars);
String (CharPointer_UTF8 start, CharPointer_UTF8 end);
//==============================================================================
String (CharPointer_UTF16 text);
String (CharPointer_UTF16 text, size_t maxChars);
String (CharPointer_UTF16 start, CharPointer_UTF16 end);
//==============================================================================
String (CharPointer_UTF32 text);
String (CharPointer_UTF32 text, size_t maxChars);
String (CharPointer_UTF32 start, CharPointer_UTF32 end);
//==============================================================================
String (CharPointer_ASCII text);
String (const std::string&);
String (StringRef);
//==============================================================================
static String charToString (juce_wchar character);
~String() noexcept;
#if (JUCE_STRING_UTF_TYPE == 32)
using CharPointerType = CharPointer_UTF32;
#elif (JUCE_STRING_UTF_TYPE == 16)
using CharPointerType = CharPointer_UTF16;
#elif (DOXYGEN || JUCE_STRING_UTF_TYPE == 8)
using CharPointerType = CharPointer_UTF8;
#else
#error "You must set the value of JUCE_STRING_UTF_TYPE to be either 8, 16, or 32!"
#endif
//==============================================================================
int hashCode() const noexcept;
int64 hashCode64() const noexcept;
size_t hash() const noexcept;
int length() const noexcept;
//==============================================================================
// Assignment and concatenation operators..
String& operator= (const String& other) noexcept;
String& operator= (String&& other) noexcept;
String& operator+= (const String& stringToAppend);
String& operator+= (const char* textToAppend);
String& operator+= (const wchar_t* textToAppend);
String& operator+= (StringRef textToAppend);
String& operator+= (int numberToAppend);
String& operator+= (long numberToAppend);
String& operator+= (int64 numberToAppend);
String& operator+= (uint64 numberToAppend);
String& operator+= (char characterToAppend);
String& operator+= (wchar_t characterToAppend);
#if ! JUCE_NATIVE_WCHAR_IS_UTF32
String& operator+= (juce_wchar characterToAppend);
#endif
void append (const String& textToAppend, size_t maxCharsToTake);
void appendCharPointer (CharPointerType startOfTextToAppend,
CharPointerType endOfTextToAppend);
template <class CharPointer>
void appendCharPointer (CharPointer startOfTextToAppend,
CharPointer endOfTextToAppend)
{
jassert (startOfTextToAppend.getAddress() != nullptr && endOfTextToAppend.getAddress() != nullptr);
size_t extraBytesNeeded = 0, numChars = 1;
for (auto t = startOfTextToAppend; t != endOfTextToAppend && ! t.isEmpty(); ++numChars)
extraBytesNeeded += CharPointerType::getBytesRequiredFor (t.getAndAdvance());
if (extraBytesNeeded > 0)
{
auto byteOffsetOfNull = getByteOffsetOfEnd();
preallocateBytes (byteOffsetOfNull + extraBytesNeeded);
CharPointerType (addBytesToPointer (text.getAddress(), (int) byteOffsetOfNull))
.writeWithCharLimit (startOfTextToAppend, (int) numChars);
}
}
void appendCharPointer (CharPointerType textToAppend);
template <class CharPointer>
void appendCharPointer (CharPointer textToAppend, size_t maxCharsToTake)
{
if (textToAppend.getAddress() != nullptr)
{
size_t extraBytesNeeded = 0, numChars = 1;
for (auto t = textToAppend; numChars <= maxCharsToTake && ! t.isEmpty(); ++numChars)
extraBytesNeeded += CharPointerType::getBytesRequiredFor (t.getAndAdvance());
if (extraBytesNeeded > 0)
{
auto byteOffsetOfNull = getByteOffsetOfEnd();
preallocateBytes (byteOffsetOfNull + extraBytesNeeded);
CharPointerType (addBytesToPointer (text.getAddress(), (int) byteOffsetOfNull))
.writeWithCharLimit (textToAppend, (int) numChars);
}
}
}
template <class CharPointer>
void appendCharPointer (CharPointer textToAppend)
{
appendCharPointer (textToAppend, std::numeric_limits<size_t>::max());
}
//==============================================================================
// Comparison methods..
bool isEmpty() const noexcept { return text.isEmpty(); }
bool isNotEmpty() const noexcept { return ! text.isEmpty(); }
void clear() noexcept;
bool equalsIgnoreCase (const String& other) const noexcept;
bool equalsIgnoreCase (StringRef other) const noexcept;
bool equalsIgnoreCase (const wchar_t* other) const noexcept;
bool equalsIgnoreCase (const char* other) const noexcept;
int compare (const String& other) const noexcept;
int compare (const char* other) const noexcept;
int compare (const wchar_t* other) const noexcept;
int compareIgnoreCase (const String& other) const noexcept;
int compareNatural (StringRef other, bool isCaseSensitive = false) const noexcept;
bool startsWith (StringRef text) const noexcept;
bool startsWithChar (juce_wchar character) const noexcept;
bool startsWithIgnoreCase (StringRef text) const noexcept;
bool endsWith (StringRef text) const noexcept;
bool endsWithChar (juce_wchar character) const noexcept;
bool endsWithIgnoreCase (StringRef text) const noexcept;
bool contains (StringRef text) const noexcept;
bool containsChar (juce_wchar character) const noexcept;
bool containsIgnoreCase (StringRef text) const noexcept;
bool containsWholeWord (StringRef wordToLookFor) const noexcept;
bool containsWholeWordIgnoreCase (StringRef wordToLookFor) const noexcept;
int indexOfWholeWord (StringRef wordToLookFor) const noexcept;
int indexOfWholeWordIgnoreCase (StringRef wordToLookFor) const noexcept;
bool containsAnyOf (StringRef charactersItMightContain) const noexcept;
bool containsOnly (StringRef charactersItMightContain) const noexcept;
bool containsNonWhitespaceChars() const noexcept;
bool matchesWildcard (StringRef wildcard, bool ignoreCase) const noexcept;
//==============================================================================
// Substring location methods..
int indexOfChar (juce_wchar characterToLookFor) const noexcept;
int indexOfChar (int startIndex, juce_wchar characterToLookFor) const noexcept;
int indexOfAnyOf (StringRef charactersToLookFor,
int startIndex = 0,
bool ignoreCase = false) const noexcept;
int indexOf (StringRef textToLookFor) const noexcept;
int indexOf (int startIndex, StringRef textToLookFor) const noexcept;
int indexOfIgnoreCase (StringRef textToLookFor) const noexcept;
int indexOfIgnoreCase (int startIndex, StringRef textToLookFor) const noexcept;
int lastIndexOfChar (juce_wchar character) const noexcept;
int lastIndexOf (StringRef textToLookFor) const noexcept;
int lastIndexOfIgnoreCase (StringRef textToLookFor) const noexcept;
int lastIndexOfAnyOf (StringRef charactersToLookFor,
bool ignoreCase = false) const noexcept;
//==============================================================================
// Substring extraction and manipulation methods..
juce_wchar operator[] (int index) const noexcept;
juce_wchar getLastCharacter() const noexcept;
//==============================================================================
String substring (int startIndex, int endIndex) const;
String substring (int startIndex) const;
String dropLastCharacters (int numberToDrop) const;
String getLastCharacters (int numCharacters) const;
//==============================================================================
String fromFirstOccurrenceOf (StringRef substringToStartFrom,
bool includeSubStringInResult,
bool ignoreCase) const;
String fromLastOccurrenceOf (StringRef substringToFind,
bool includeSubStringInResult,
bool ignoreCase) const;
String upToFirstOccurrenceOf (StringRef substringToEndWith,
bool includeSubStringInResult,
bool ignoreCase) const;
String upToLastOccurrenceOf (StringRef substringToFind,
bool includeSubStringInResult,
bool ignoreCase) const;
//==============================================================================
String trim() const;
String trimStart() const;
String trimEnd() const;
String trimCharactersAtStart (StringRef charactersToTrim) const;
String trimCharactersAtEnd (StringRef charactersToTrim) const;
//==============================================================================
String toUpperCase() const;
String toLowerCase() const;
//==============================================================================
String replaceSection (int startIndex,
int numCharactersToReplace,
StringRef stringToInsert) const;
String replace (StringRef stringToReplace,
StringRef stringToInsertInstead,
bool ignoreCase = false) const;
String replaceFirstOccurrenceOf (StringRef stringToReplace,
StringRef stringToInsertInstead,
bool ignoreCase = false) const;
String replaceCharacter (juce_wchar characterToReplace,
juce_wchar characterToInsertInstead) const;
String replaceCharacters (StringRef charactersToReplace,
StringRef charactersToInsertInstead) const;
String retainCharacters (StringRef charactersToRetain) const;
String removeCharacters (StringRef charactersToRemove) const;
String initialSectionContainingOnly (StringRef permittedCharacters) const;
String initialSectionNotContaining (StringRef charactersToStopAt) const;
//==============================================================================
bool isQuotedString() const;
String unquoted() const;
String quoted (juce_wchar quoteCharacter = '"') const;
//==============================================================================
static String repeatedString (StringRef stringToRepeat,
int numberOfTimesToRepeat);
String paddedLeft (juce_wchar padCharacter, int minimumLength) const;
String paddedRight (juce_wchar padCharacter, int minimumLength) const;
static String createStringFromData (const void* data, int size);
template <typename... Args>
static String formatted (const String& formatStr, Args... args) { return formattedRaw (formatStr.toRawUTF8(), args...); }
CharPointerType begin() const { return getCharPointer(); }
CharPointerType end() const { return begin().findTerminatingNull(); }
//==============================================================================
// Numeric conversions..
explicit String (int decimalInteger);
explicit String (unsigned int decimalInteger);
explicit String (short decimalInteger);
explicit String (unsigned short decimalInteger);
explicit String (int64 largeIntegerValue);
explicit String (uint64 largeIntegerValue);
explicit String (long decimalInteger);
explicit String (unsigned long decimalInteger);
explicit String (float floatValue);
explicit String (double doubleValue);
String (float floatValue, int numberOfDecimalPlaces, bool useScientificNotation = false);
String (double doubleValue, int numberOfDecimalPlaces, bool useScientificNotation = false);
#ifndef DOXYGEN
// Automatically creating a String from a bool opens up lots of nasty type conversion edge cases.
// If you want a String representation of a bool you can cast the bool to an int first.
explicit String (bool) = delete;
#endif
int getIntValue() const noexcept;
int64 getLargeIntValue() const noexcept;
int getTrailingIntValue() const noexcept;
float getFloatValue() const noexcept;
double getDoubleValue() const noexcept;
int getHexValue32() const noexcept;
int64 getHexValue64() const noexcept;
template <typename IntegerType>
static String toHexString (IntegerType number) { return createHex (number); }
static String toHexString (const void* data, int size, int groupSize = 1);
template <typename DecimalType>
static String toDecimalStringWithSignificantFigures (DecimalType number, int numberOfSignificantFigures)
{
jassert (numberOfSignificantFigures > 0);
if (exactlyEqual (number, DecimalType()))
{
if (numberOfSignificantFigures > 1)
{
String result ("0.0");
for (int i = 2; i < numberOfSignificantFigures; ++i)
result += "0";
return result;
}
return "0";
}
auto numDigitsBeforePoint = (int) std::ceil (std::log10 (number < 0 ? -number : number));
auto shift = numberOfSignificantFigures - numDigitsBeforePoint;
auto factor = std::pow (10.0, shift);
auto rounded = std::round (number * factor) / factor;
std::stringstream ss;
ss << std::fixed << std::setprecision (std::max (shift, 0)) << rounded;
return ss.str();
}
//==============================================================================
CharPointerType getCharPointer() const noexcept { return text; }
CharPointer_UTF8 toUTF8() const;
const char* toRawUTF8() const;
CharPointer_UTF16 toUTF16() const;
CharPointer_UTF32 toUTF32() const;
const wchar_t* toWideCharPointer() const;
std::string toStdString() const;
//==============================================================================
static String fromUTF8 (const char* utf8buffer, int bufferSizeBytes = -1);
size_t getNumBytesAsUTF8() const noexcept;
//==============================================================================
size_t copyToUTF8 (CharPointer_UTF8::CharType* destBuffer, size_t maxBufferSizeBytes) const noexcept;
size_t copyToUTF16 (CharPointer_UTF16::CharType* destBuffer, size_t maxBufferSizeBytes) const noexcept;
size_t copyToUTF32 (CharPointer_UTF32::CharType* destBuffer, size_t maxBufferSizeBytes) const noexcept;
//==============================================================================
void preallocateBytes (size_t numBytesNeeded);
void swapWith (String& other) noexcept;
//==============================================================================
#if JUCE_MAC || JUCE_IOS || DOXYGEN
static String fromCFString (CFStringRef cfString);
CFStringRef toCFString() const;
String convertToPrecomposedUnicode() const;
#endif
int getReferenceCount() const noexcept;
//==============================================================================
#if JUCE_ALLOW_STATIC_NULL_VARIABLES && ! defined (DOXYGEN)
[[deprecated ("This was a static empty string object, but is now deprecated as it's too easy to accidentally "
"use it indirectly during a static constructor, leading to hard-to-find order-of-initialisation "
"problems. If you need an empty String object, just use String() or {}. For returning an empty "
"String from a function by reference, use a function-local static String object and return that.")]]
static const String empty;
#endif
private:
//==============================================================================
CharPointerType text;
//==============================================================================
struct PreallocationBytes
{
explicit PreallocationBytes (size_t) noexcept;
size_t numBytes;
};
explicit String (const PreallocationBytes&); // This constructor preallocates a certain amount of memory
size_t getByteOffsetOfEnd() const noexcept;
// This private cast operator should prevent strings being accidentally cast
// to bools (this is possible because the compiler can add an implicit cast
// via a const char*)
operator bool() const noexcept { return false; }
//==============================================================================
static String formattedRaw (const char*, ...);
static String createHex (uint8);
static String createHex (uint16);
static String createHex (uint32);
static String createHex (uint64);
template <typename Type>
static String createHex (Type n) { return createHex (static_cast<typename TypeHelpers::UnsignedTypeWithSize<(int) sizeof (n)>::type> (n)); }
};
//==============================================================================
JUCE_API String JUCE_CALLTYPE operator+ (const char* string1, const String& string2);
JUCE_API String JUCE_CALLTYPE operator+ (const wchar_t* string1, const String& string2);
JUCE_API String JUCE_CALLTYPE operator+ (char string1, const String& string2);
JUCE_API String JUCE_CALLTYPE operator+ (wchar_t string1, const String& string2);
#if ! JUCE_NATIVE_WCHAR_IS_UTF32
JUCE_API String JUCE_CALLTYPE operator+ (juce_wchar string1, const String& string2);
#endif
JUCE_API String JUCE_CALLTYPE operator+ (String string1, const String& string2);
JUCE_API String JUCE_CALLTYPE operator+ (String string1, const char* string2);
JUCE_API String JUCE_CALLTYPE operator+ (String string1, const wchar_t* string2);
JUCE_API String JUCE_CALLTYPE operator+ (String string1, const std::string& string2);
JUCE_API String JUCE_CALLTYPE operator+ (String string1, char characterToAppend);
JUCE_API String JUCE_CALLTYPE operator+ (String string1, wchar_t characterToAppend);
#if ! JUCE_NATIVE_WCHAR_IS_UTF32
JUCE_API String JUCE_CALLTYPE operator+ (String string1, juce_wchar characterToAppend);
#endif
//==============================================================================
JUCE_API String& JUCE_CALLTYPE operator<< (String& string1, char characterToAppend);
JUCE_API String& JUCE_CALLTYPE operator<< (String& string1, wchar_t characterToAppend);
#if ! JUCE_NATIVE_WCHAR_IS_UTF32
JUCE_API String& JUCE_CALLTYPE operator<< (String& string1, juce_wchar characterToAppend);
#endif
JUCE_API String& JUCE_CALLTYPE operator<< (String& string1, const char* string2);
JUCE_API String& JUCE_CALLTYPE operator<< (String& string1, const wchar_t* string2);
JUCE_API String& JUCE_CALLTYPE operator<< (String& string1, const String& string2);
JUCE_API String& JUCE_CALLTYPE operator<< (String& string1, StringRef string2);
JUCE_API String& JUCE_CALLTYPE operator<< (String& string1, const std::string& string2);
JUCE_API String& JUCE_CALLTYPE operator<< (String& string1, uint8 number);
JUCE_API String& JUCE_CALLTYPE operator<< (String& string1, short number);
JUCE_API String& JUCE_CALLTYPE operator<< (String& string1, int number);
JUCE_API String& JUCE_CALLTYPE operator<< (String& string1, long number);
JUCE_API String& JUCE_CALLTYPE operator<< (String& string1, unsigned long number);
JUCE_API String& JUCE_CALLTYPE operator<< (String& string1, int64 number);
JUCE_API String& JUCE_CALLTYPE operator<< (String& string1, uint64 number);
JUCE_API String& JUCE_CALLTYPE operator<< (String& string1, float number);
JUCE_API String& JUCE_CALLTYPE operator<< (String& string1, double number);
#ifndef DOXYGEN
// Automatically creating a String from a bool opens up lots of nasty type conversion edge cases.
// If you want a String representation of a bool you can cast the bool to an int first.
String& JUCE_CALLTYPE operator<< (String&, bool) = delete;
#endif
//==============================================================================
JUCE_API bool JUCE_CALLTYPE operator== (const String& string1, const String& string2) noexcept;
JUCE_API bool JUCE_CALLTYPE operator== (const String& string1, const char* string2) noexcept;
JUCE_API bool JUCE_CALLTYPE operator== (const String& string1, const wchar_t* string2) noexcept;
JUCE_API bool JUCE_CALLTYPE operator== (const String& string1, CharPointer_UTF8 string2) noexcept;
JUCE_API bool JUCE_CALLTYPE operator== (const String& string1, CharPointer_UTF16 string2) noexcept;
JUCE_API bool JUCE_CALLTYPE operator== (const String& string1, CharPointer_UTF32 string2) noexcept;
JUCE_API bool JUCE_CALLTYPE operator!= (const String& string1, const String& string2) noexcept;
JUCE_API bool JUCE_CALLTYPE operator!= (const String& string1, const char* string2) noexcept;
JUCE_API bool JUCE_CALLTYPE operator!= (const String& string1, const wchar_t* string2) noexcept;
JUCE_API bool JUCE_CALLTYPE operator!= (const String& string1, CharPointer_UTF8 string2) noexcept;
JUCE_API bool JUCE_CALLTYPE operator!= (const String& string1, CharPointer_UTF16 string2) noexcept;
JUCE_API bool JUCE_CALLTYPE operator!= (const String& string1, CharPointer_UTF32 string2) noexcept;
//==============================================================================
template <class traits>
std::basic_ostream <char, traits>& JUCE_CALLTYPE operator<< (std::basic_ostream <char, traits>& stream, const String& stringToWrite)
{
return stream << stringToWrite.toRawUTF8();
}
template <class traits>
std::basic_ostream <wchar_t, traits>& JUCE_CALLTYPE operator<< (std::basic_ostream <wchar_t, traits>& stream, const String& stringToWrite)
{
return stream << stringToWrite.toWideCharPointer();
}
JUCE_API OutputStream& JUCE_CALLTYPE operator<< (OutputStream& stream, const String& stringToWrite);
JUCE_API OutputStream& JUCE_CALLTYPE operator<< (OutputStream& stream, StringRef stringToWrite);
} // namespace juce
#ifndef DOXYGEN
namespace std
{
template <> struct hash<juce::String>
{
size_t operator() (const juce::String& s) const noexcept { return s.hash(); }
};
}
#endif
juce::CharPointer_ASCII
Definition juce_CharPointer_ASCII.h:38
juce::CharPointer_UTF16
Definition juce_CharPointer_UTF16.h:35
juce::CharPointer_UTF32
Definition juce_CharPointer_UTF32.h:35
juce::CharPointer_UTF8
Definition juce_CharPointer_UTF8.h:35
juce::StringRef
Definition juce_StringRef.h:62
juce::String
Definition juce_String.h:53
juce::String::getCharPointer
CharPointerType getCharPointer() const noexcept
Definition juce_String.h:1153
juce::String::begin
CharPointerType begin() const
Definition juce_String.h:923
juce::String::length
int length() const noexcept
Definition juce_String.cpp:511
juce::String::isEmpty
bool isEmpty() const noexcept
Definition juce_String.h:310
juce::String::String
String() noexcept
Definition juce_String.cpp:234
juce::String::append
void append(const String &textToAppend, size_t maxCharsToTake)
Definition juce_String.cpp:706
juce::String::toDecimalStringWithSignificantFigures
static String toDecimalStringWithSignificantFigures(DecimalType number, int numberOfSignificantFigures)
Definition juce_String.h:1116
juce::String::hashCode64
int64 hashCode64() const noexcept
Definition juce_String.cpp:550
juce::String::appendCharPointer
void appendCharPointer(CharPointer startOfTextToAppend, CharPointer endOfTextToAppend)
Definition juce_String.h:247
juce::String::appendCharPointer
void appendCharPointer(CharPointerType startOfTextToAppend, CharPointerType endOfTextToAppend)
Definition juce_String.cpp:717
juce::String::preallocateBytes
void preallocateBytes(size_t numBytesNeeded)
Definition juce_String.cpp:284
juce::String::hash
size_t hash() const noexcept
Definition juce_String.cpp:551
juce::String::formatted
static String formatted(const String &formatStr, Args... args)
Definition juce_String.h:920
juce::String::end
CharPointerType end() const
Definition juce_String.h:949
juce::String::toHexString
static String toHexString(IntegerType number)
Definition juce_String.h:1097
juce::String::appendCharPointer
void appendCharPointer(CharPointer textToAppend, size_t maxCharsToTake)
Definition juce_String.h:276
juce::String::appendCharPointer
void appendCharPointer(CharPointer textToAppend)
Definition juce_String.h:298
juce::String::charToString
static String charToString(juce_wchar character)
Definition juce_String.cpp:359
juce::String::hashCode
int hashCode() const noexcept
Definition juce_String.cpp:549
juce::String::isNotEmpty
bool isNotEmpty() const noexcept
Definition juce_String.h:316