Loading...
Searching...
No Matches
juce_CharPointer_UTF8.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.
==============================================================================
*/
namespace juce
{
//==============================================================================
class CharPointer_UTF8 final
{
public:
using CharType = char;
explicit CharPointer_UTF8 (const CharType* rawPointer) noexcept
: data (const_cast<CharType*> (rawPointer))
{
}
CharPointer_UTF8 (const CharPointer_UTF8& other) = default;
CharPointer_UTF8 operator= (CharPointer_UTF8 other) noexcept
{
data = other.data;
return *this;
}
CharPointer_UTF8 operator= (const CharType* text) noexcept
{
data = const_cast<CharType*> (text);
return *this;
}
bool operator== (CharPointer_UTF8 other) const noexcept { return data == other.data; }
bool operator!= (CharPointer_UTF8 other) const noexcept { return data != other.data; }
bool operator<= (CharPointer_UTF8 other) const noexcept { return data <= other.data; }
bool operator< (CharPointer_UTF8 other) const noexcept { return data < other.data; }
bool operator>= (CharPointer_UTF8 other) const noexcept { return data >= other.data; }
bool operator> (CharPointer_UTF8 other) const noexcept { return data > other.data; }
CharType* getAddress() const noexcept { return data; }
operator const CharType*() const noexcept { return data; }
bool isEmpty() const noexcept { return *data == 0; }
bool isNotEmpty() const noexcept { return *data != 0; }
juce_wchar operator*() const noexcept
{
auto byte = (signed char) *data;
if (byte >= 0)
return (juce_wchar) (uint8) byte;
uint32 n = (uint32) (uint8) byte;
uint32 mask = 0x7f;
uint32 bit = 0x40;
int numExtraValues = 0;
while ((n & bit) != 0 && bit > 0x8)
{
mask >>= 1;
++numExtraValues;
bit >>= 1;
}
n &= mask;
for (int i = 1; i <= numExtraValues; ++i)
{
auto nextByte = (uint32) (uint8) data[i];
if ((nextByte & 0xc0) != 0x80)
break;
n <<= 6;
n |= (nextByte & 0x3f);
}
return (juce_wchar) n;
}
CharPointer_UTF8& operator++() noexcept
{
jassert (*data != 0); // trying to advance past the end of the string?
auto n = (signed char) *data++;
if (n < 0)
{
uint8 bit = 0x40;
while ((static_cast<uint8> (n) & bit) != 0 && bit > 0x8)
{
++data;
bit = static_cast<uint8> (bit >> 1);
}
}
return *this;
}
CharPointer_UTF8 operator--() noexcept
{
int count = 0;
while ((*--data & 0xc0) == 0x80 && ++count < 4)
{}
return *this;
}
juce_wchar getAndAdvance() noexcept
{
auto byte = (signed char) *data++;
if (byte >= 0)
return (juce_wchar) (uint8) byte;
uint32 n = (uint32) (uint8) byte;
uint32 mask = 0x7f;
uint32 bit = 0x40;
int numExtraValues = 0;
while ((n & bit) != 0 && bit > 0x8)
{
mask >>= 1;
++numExtraValues;
bit >>= 1;
}
n &= mask;
while (--numExtraValues >= 0)
{
auto nextByte = (uint32) (uint8) *data;
if ((nextByte & 0xc0) != 0x80)
break;
++data;
n <<= 6;
n |= (nextByte & 0x3f);
}
return (juce_wchar) n;
}
CharPointer_UTF8 operator++ (int) noexcept
{
CharPointer_UTF8 temp (*this);
++*this;
return temp;
}
void operator+= (int numToSkip) noexcept
{
if (numToSkip < 0)
{
while (++numToSkip <= 0)
--*this;
}
else
{
while (--numToSkip >= 0)
++*this;
}
}
void operator-= (int numToSkip) noexcept
{
operator+= (-numToSkip);
}
juce_wchar operator[] (int characterIndex) const noexcept
{
auto p (*this);
p += characterIndex;
return *p;
}
CharPointer_UTF8 operator+ (int numToSkip) const noexcept
{
auto p (*this);
p += numToSkip;
return p;
}
CharPointer_UTF8 operator- (int numToSkip) const noexcept
{
auto p (*this);
p += -numToSkip;
return p;
}
size_t length() const noexcept
{
auto* d = data;
size_t count = 0;
for (;;)
{
auto n = (uint32) (uint8) *d++;
if ((n & 0x80) != 0)
{
while ((*d & 0xc0) == 0x80)
++d;
}
else if (n == 0)
break;
++count;
}
return count;
}
size_t lengthUpTo (const size_t maxCharsToCount) const noexcept
{
return CharacterFunctions::lengthUpTo (*this, maxCharsToCount);
}
size_t lengthUpTo (const CharPointer_UTF8 end) const noexcept
{
return CharacterFunctions::lengthUpTo (*this, end);
}
size_t sizeInBytes() const noexcept
{
JUCE_BEGIN_IGNORE_WARNINGS_MSVC (6387)
jassert (data != nullptr);
return strlen (data) + 1;
JUCE_END_IGNORE_WARNINGS_MSVC
}
static size_t getBytesRequiredFor (const juce_wchar charToWrite) noexcept
{
size_t num = 1;
auto c = (uint32) charToWrite;
if (c >= 0x80)
{
++num;
if (c >= 0x800)
{
++num;
if (c >= 0x10000)
++num;
}
}
return num;
}
template <class CharPointer>
static size_t getBytesRequiredFor (CharPointer text) noexcept
{
size_t count = 0;
while (auto n = text.getAndAdvance())
count += getBytesRequiredFor (n);
return count;
}
CharPointer_UTF8 findTerminatingNull() const noexcept
{
return CharPointer_UTF8 (data + strlen (data));
}
void write (const juce_wchar charToWrite) noexcept
{
auto c = (uint32) charToWrite;
if (c >= 0x80)
{
int numExtraBytes = 1;
if (c >= 0x800)
{
++numExtraBytes;
if (c >= 0x10000)
++numExtraBytes;
}
*data++ = (CharType) ((uint32) (0xff << (7 - numExtraBytes)) | (c >> (numExtraBytes * 6)));
while (--numExtraBytes >= 0)
*data++ = (CharType) (0x80 | (0x3f & (c >> (numExtraBytes * 6))));
}
else
{
*data++ = (CharType) c;
}
}
void writeNull() const noexcept
{
*data = 0;
}
template <typename CharPointer>
void writeAll (const CharPointer src) noexcept
{
CharacterFunctions::copyAll (*this, src);
}
void writeAll (const CharPointer_UTF8 src) noexcept
{
auto* s = src.data;
while ((*data = *s) != 0)
{
++data;
++s;
}
}
template <typename CharPointer>
size_t writeWithDestByteLimit (const CharPointer src, const size_t maxDestBytes) noexcept
{
return CharacterFunctions::copyWithDestByteLimit (*this, src, maxDestBytes);
}
template <typename CharPointer>
void writeWithCharLimit (const CharPointer src, const int maxChars) noexcept
{
CharacterFunctions::copyWithCharLimit (*this, src, maxChars);
}
template <typename CharPointer>
int compare (const CharPointer other) const noexcept
{
return CharacterFunctions::compare (*this, other);
}
template <typename CharPointer>
int compareUpTo (const CharPointer other, const int maxChars) const noexcept
{
return CharacterFunctions::compareUpTo (*this, other, maxChars);
}
template <typename CharPointer>
int compareIgnoreCase (const CharPointer other) const noexcept
{
return CharacterFunctions::compareIgnoreCase (*this, other);
}
int compareIgnoreCase (const CharPointer_UTF8 other) const noexcept
{
return CharacterFunctions::compareIgnoreCase (*this, other);
}
template <typename CharPointer>
int compareIgnoreCaseUpTo (const CharPointer other, const int maxChars) const noexcept
{
return CharacterFunctions::compareIgnoreCaseUpTo (*this, other, maxChars);
}
template <typename CharPointer>
int indexOf (const CharPointer stringToFind) const noexcept
{
return CharacterFunctions::indexOf (*this, stringToFind);
}
int indexOf (const juce_wchar charToFind) const noexcept
{
return CharacterFunctions::indexOfChar (*this, charToFind);
}
int indexOf (const juce_wchar charToFind, const bool ignoreCase) const noexcept
{
return ignoreCase ? CharacterFunctions::indexOfCharIgnoreCase (*this, charToFind)
: CharacterFunctions::indexOfChar (*this, charToFind);
}
bool isWhitespace() const noexcept { return CharacterFunctions::isWhitespace ((juce_wchar) *(*this)); }
bool isDigit() const noexcept { const CharType c = *data; return c >= '0' && c <= '9'; }
bool isLetter() const noexcept { return CharacterFunctions::isLetter (operator*()) != 0; }
bool isLetterOrDigit() const noexcept { return CharacterFunctions::isLetterOrDigit (operator*()) != 0; }
bool isUpperCase() const noexcept { return CharacterFunctions::isUpperCase (operator*()) != 0; }
bool isLowerCase() const noexcept { return CharacterFunctions::isLowerCase (operator*()) != 0; }
juce_wchar toUpperCase() const noexcept { return CharacterFunctions::toUpperCase (operator*()); }
juce_wchar toLowerCase() const noexcept { return CharacterFunctions::toLowerCase (operator*()); }
int getIntValue32() const noexcept { return atoi (data); }
int64 getIntValue64() const noexcept
{
#if JUCE_WINDOWS && ! JUCE_MINGW
return _atoi64 (data);
#else
return atoll (data);
#endif
}
double getDoubleValue() const noexcept { return CharacterFunctions::getDoubleValue (*this); }
CharPointer_UTF8 findEndOfWhitespace() const noexcept { return CharacterFunctions::findEndOfWhitespace (*this); }
void incrementToEndOfWhitespace() noexcept { CharacterFunctions::incrementToEndOfWhitespace (*this); }
static bool canRepresent (juce_wchar character) noexcept
{
return ((uint32) character) < (uint32) 0x10ffff;
}
static bool isValidString (const CharType* dataToTest, int maxBytesToRead)
{
while (--maxBytesToRead >= 0 && *dataToTest != 0)
{
auto byte = (signed char) *dataToTest++;
if (byte < 0)
{
int bit = 0x40;
int numExtraValues = 0;
while ((byte & bit) != 0)
{
if (bit < 8)
return false;
++numExtraValues;
bit >>= 1;
if (bit == 8 && (numExtraValues > maxBytesToRead
|| *CharPointer_UTF8 (dataToTest - 1) > 0x10ffff))
return false;
}
if (numExtraValues == 0)
return false;
maxBytesToRead -= numExtraValues;
if (maxBytesToRead < 0)
return false;
while (--numExtraValues >= 0)
if ((*dataToTest++ & 0xc0) != 0x80)
return false;
}
}
return true;
}
CharPointer_UTF8 atomicSwap (const CharPointer_UTF8 newValue)
{
return CharPointer_UTF8 (reinterpret_cast<Atomic<CharType*>&> (data).exchange (newValue.data));
}
enum
{
byteOrderMark1 = 0xef,
byteOrderMark2 = 0xbb,
byteOrderMark3 = 0xbf
};
static bool isByteOrderMark (const void* possibleByteOrder) noexcept
{
JUCE_BEGIN_IGNORE_WARNINGS_MSVC (28182)
jassert (possibleByteOrder != nullptr);
auto c = static_cast<const uint8*> (possibleByteOrder);
return c[0] == (uint8) byteOrderMark1
&& c[1] == (uint8) byteOrderMark2
&& c[2] == (uint8) byteOrderMark3;
JUCE_END_IGNORE_WARNINGS_MSVC
}
private:
CharType* data;
};
} // namespace juce
juce::CharPointer_UTF8
Definition juce_CharPointer_UTF8.h:35
juce::CharPointer_UTF8::compareIgnoreCase
int compareIgnoreCase(const CharPointer_UTF8 other) const noexcept
Definition juce_CharPointer_UTF8.h:419
juce::CharPointer_UTF8::indexOf
int indexOf(const juce_wchar charToFind) const noexcept
Definition juce_CharPointer_UTF8.h:439
juce::CharPointer_UTF8::compareUpTo
int compareUpTo(const CharPointer other, const int maxChars) const noexcept
Definition juce_CharPointer_UTF8.h:406
juce::CharPointer_UTF8::writeAll
void writeAll(const CharPointer src) noexcept
Definition juce_CharPointer_UTF8.h:360
juce::CharPointer_UTF8::operator++
CharPointer_UTF8 & operator++() noexcept
Definition juce_CharPointer_UTF8.h:115
juce::CharPointer_UTF8::findTerminatingNull
CharPointer_UTF8 findTerminatingNull() const noexcept
Definition juce_CharPointer_UTF8.h:321
juce::CharPointer_UTF8::compareIgnoreCaseUpTo
int compareIgnoreCaseUpTo(const CharPointer other, const int maxChars) const noexcept
Definition juce_CharPointer_UTF8.h:426
juce::CharPointer_UTF8::getBytesRequiredFor
static size_t getBytesRequiredFor(CharPointer text) noexcept
Definition juce_CharPointer_UTF8.h:310
juce::CharPointer_UTF8::operator+=
void operator+=(int numToSkip) noexcept
Definition juce_CharPointer_UTF8.h:192
juce::CharPointer_UTF8::isLetterOrDigit
bool isLetterOrDigit() const noexcept
Definition juce_CharPointer_UTF8.h:458
juce::CharPointer_UTF8::operator*
juce_wchar operator*() const noexcept
Definition juce_CharPointer_UTF8.h:79
juce::CharPointer_UTF8::isLetter
bool isLetter() const noexcept
Definition juce_CharPointer_UTF8.h:456
juce::CharPointer_UTF8::incrementToEndOfWhitespace
void incrementToEndOfWhitespace() noexcept
Definition juce_CharPointer_UTF8.h:489
juce::CharPointer_UTF8::lengthUpTo
size_t lengthUpTo(const CharPointer_UTF8 end) const noexcept
Definition juce_CharPointer_UTF8.h:267
juce::CharPointer_UTF8::getAndAdvance
juce_wchar getAndAdvance() noexcept
Definition juce_CharPointer_UTF8.h:147
juce::CharPointer_UTF8::writeWithDestByteLimit
size_t writeWithDestByteLimit(const CharPointer src, const size_t maxDestBytes) noexcept
Definition juce_CharPointer_UTF8.h:382
juce::CharPointer_UTF8::isNotEmpty
bool isNotEmpty() const noexcept
Definition juce_CharPointer_UTF8.h:76
juce::CharPointer_UTF8::lengthUpTo
size_t lengthUpTo(const size_t maxCharsToCount) const noexcept
Definition juce_CharPointer_UTF8.h:261
juce::CharPointer_UTF8::operator-
CharPointer_UTF8 operator-(int numToSkip) const noexcept
Definition juce_CharPointer_UTF8.h:229
juce::CharPointer_UTF8::operator-=
void operator-=(int numToSkip) noexcept
Definition juce_CharPointer_UTF8.h:207
juce::CharPointer_UTF8::getDoubleValue
double getDoubleValue() const noexcept
Definition juce_CharPointer_UTF8.h:483
juce::CharPointer_UTF8::sizeInBytes
size_t sizeInBytes() const noexcept
Definition juce_CharPointer_UTF8.h:275
juce::CharPointer_UTF8::operator--
CharPointer_UTF8 operator--() noexcept
Definition juce_CharPointer_UTF8.h:135
juce::CharPointer_UTF8::writeAll
void writeAll(const CharPointer_UTF8 src) noexcept
Definition juce_CharPointer_UTF8.h:366
juce::CharPointer_UTF8::writeNull
void writeNull() const noexcept
Definition juce_CharPointer_UTF8.h:353
juce::CharPointer_UTF8::isEmpty
bool isEmpty() const noexcept
Definition juce_CharPointer_UTF8.h:73
juce::CharPointer_UTF8::toUpperCase
juce_wchar toUpperCase() const noexcept
Definition juce_CharPointer_UTF8.h:465
juce::CharPointer_UTF8::getBytesRequiredFor
static size_t getBytesRequiredFor(const juce_wchar charToWrite) noexcept
Definition juce_CharPointer_UTF8.h:286
juce::CharPointer_UTF8::indexOf
int indexOf(const CharPointer stringToFind) const noexcept
Definition juce_CharPointer_UTF8.h:433
juce::CharPointer_UTF8::getIntValue64
int64 getIntValue64() const noexcept
Definition juce_CharPointer_UTF8.h:473
juce::CharPointer_UTF8::canRepresent
static bool canRepresent(juce_wchar character) noexcept
Definition juce_CharPointer_UTF8.h:492
juce::CharPointer_UTF8::indexOf
int indexOf(const juce_wchar charToFind, const bool ignoreCase) const noexcept
Definition juce_CharPointer_UTF8.h:445
juce::CharPointer_UTF8::getIntValue32
int getIntValue32() const noexcept
Definition juce_CharPointer_UTF8.h:470
juce::CharPointer_UTF8::isUpperCase
bool isUpperCase() const noexcept
Definition juce_CharPointer_UTF8.h:460
juce::CharPointer_UTF8::compareIgnoreCase
int compareIgnoreCase(const CharPointer other) const noexcept
Definition juce_CharPointer_UTF8.h:413
juce::CharPointer_UTF8::isLowerCase
bool isLowerCase() const noexcept
Definition juce_CharPointer_UTF8.h:462
juce::CharPointer_UTF8::isByteOrderMark
static bool isByteOrderMark(const void *possibleByteOrder) noexcept
Definition juce_CharPointer_UTF8.h:555
juce::CharPointer_UTF8::writeWithCharLimit
void writeWithCharLimit(const CharPointer src, const int maxChars) noexcept
Definition juce_CharPointer_UTF8.h:392
juce::CharPointer_UTF8::atomicSwap
CharPointer_UTF8 atomicSwap(const CharPointer_UTF8 newValue)
Definition juce_CharPointer_UTF8.h:539
juce::CharPointer_UTF8::isValidString
static bool isValidString(const CharType *dataToTest, int maxBytesToRead)
Definition juce_CharPointer_UTF8.h:498
juce::CharPointer_UTF8::toLowerCase
juce_wchar toLowerCase() const noexcept
Definition juce_CharPointer_UTF8.h:467
juce::CharPointer_UTF8::operator[]
juce_wchar operator[](int characterIndex) const noexcept
Definition juce_CharPointer_UTF8.h:213
juce::CharPointer_UTF8::operator+
CharPointer_UTF8 operator+(int numToSkip) const noexcept
Definition juce_CharPointer_UTF8.h:221
juce::CharPointer_UTF8::compare
int compare(const CharPointer other) const noexcept
Definition juce_CharPointer_UTF8.h:399
juce::CharPointer_UTF8::isWhitespace
bool isWhitespace() const noexcept
Definition juce_CharPointer_UTF8.h:452
juce::CharPointer_UTF8::operator==
bool operator==(CharPointer_UTF8 other) const noexcept
Definition juce_CharPointer_UTF8.h:59
juce::CharPointer_UTF8::findEndOfWhitespace
CharPointer_UTF8 findEndOfWhitespace() const noexcept
Definition juce_CharPointer_UTF8.h:486
juce::CharPointer_UTF8::isDigit
bool isDigit() const noexcept
Definition juce_CharPointer_UTF8.h:454
juce::CharPointer_UTF8::write
void write(const juce_wchar charToWrite) noexcept
Definition juce_CharPointer_UTF8.h:327
juce::CharPointer_UTF8::getAddress
CharType * getAddress() const noexcept
Definition juce_CharPointer_UTF8.h:67
juce::CharPointer_UTF8::length
size_t length() const noexcept
Definition juce_CharPointer_UTF8.h:237
juce::CharacterFunctions::incrementToEndOfWhitespace
static void incrementToEndOfWhitespace(Type &text) noexcept
Definition juce_CharacterFunctions.h:807
juce::CharacterFunctions::compare
static int compare(juce_wchar char1, juce_wchar char2) noexcept
Definition juce_CharacterFunctions.h:596
juce::CharacterFunctions::toLowerCase
static juce_wchar toLowerCase(juce_wchar character) noexcept
Definition juce_CharacterFunctions.cpp:33
juce::CharacterFunctions::copyWithDestByteLimit
static size_t copyWithDestByteLimit(DestCharPointerType &dest, SrcCharPointerType src, size_t maxBytesToWrite) noexcept
Definition juce_CharacterFunctions.h:553
juce::CharacterFunctions::indexOfCharIgnoreCase
static int indexOfCharIgnoreCase(Type text, juce_wchar charToFind) noexcept
Definition juce_CharacterFunctions.h:783
juce::CharacterFunctions::compareIgnoreCaseUpTo
static int compareIgnoreCaseUpTo(CharPointerType1 s1, CharPointerType2 s2, int maxChars) noexcept
Definition juce_CharacterFunctions.h:666
juce::CharacterFunctions::indexOfChar
static int indexOfChar(Type text, const juce_wchar charToFind) noexcept
Definition juce_CharacterFunctions.h:763
juce::CharacterFunctions::compareIgnoreCase
static int compareIgnoreCase(juce_wchar char1, juce_wchar char2) noexcept
Definition juce_CharacterFunctions.h:641
juce::CharacterFunctions::isLowerCase
static bool isLowerCase(juce_wchar character) noexcept
Definition juce_CharacterFunctions.cpp:47
juce::CharacterFunctions::isLetter
static bool isLetter(char character) noexcept
Definition juce_CharacterFunctions.cpp:79
juce::CharacterFunctions::indexOf
static int indexOf(CharPointerType1 textToSearch, const CharPointerType2 substringToLookFor) noexcept
Definition juce_CharacterFunctions.h:686
juce::CharacterFunctions::isWhitespace
static bool isWhitespace(char character) noexcept
Definition juce_CharacterFunctions.cpp:59
juce::CharacterFunctions::lengthUpTo
static size_t lengthUpTo(CharPointerType text, const size_t maxCharsToCount) noexcept
Definition juce_CharacterFunctions.h:517
juce::CharacterFunctions::findEndOfWhitespace
static Type findEndOfWhitespace(Type text) noexcept
Definition juce_CharacterFunctions.h:818
juce::CharacterFunctions::copyWithCharLimit
static void copyWithCharLimit(DestCharPointerType &dest, SrcCharPointerType src, int maxChars) noexcept
Definition juce_CharacterFunctions.h:580
juce::CharacterFunctions::isLetterOrDigit
static bool isLetterOrDigit(char character) noexcept
Definition juce_CharacterFunctions.cpp:90
juce::CharacterFunctions::toUpperCase
static juce_wchar toUpperCase(juce_wchar character) noexcept
Definition juce_CharacterFunctions.cpp:28
juce::CharacterFunctions::isUpperCase
static bool isUpperCase(juce_wchar character) noexcept
Definition juce_CharacterFunctions.cpp:38
juce::CharacterFunctions::getDoubleValue
static double getDoubleValue(CharPointerType text) noexcept
Definition juce_CharacterFunctions.h:457
juce::CharacterFunctions::copyAll
static void copyAll(DestCharPointerType &dest, SrcCharPointerType src) noexcept
Definition juce_CharacterFunctions.h:542
juce::CharacterFunctions::compareUpTo
static int compareUpTo(CharPointerType1 s1, CharPointerType2 s2, int maxChars) noexcept
Definition juce_CharacterFunctions.h:624
juce::Atomic
Definition juce_Atomic.h:42