Loading...
Searching...
No Matches
juce_CharPointer_UTF16.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_UTF16 final
{
public:
#if JUCE_NATIVE_WCHAR_IS_UTF16
using CharType = wchar_t;
#else
using CharType = int16;
#endif
inline explicit CharPointer_UTF16 (const CharType* rawPointer) noexcept
: data (const_cast<CharType*> (rawPointer))
{
}
inline CharPointer_UTF16 (const CharPointer_UTF16& other) = default;
inline CharPointer_UTF16 operator= (CharPointer_UTF16 other) noexcept
{
data = other.data;
return *this;
}
inline CharPointer_UTF16 operator= (const CharType* text) noexcept
{
data = const_cast<CharType*> (text);
return *this;
}
inline bool operator== (CharPointer_UTF16 other) const noexcept { return data == other.data; }
inline bool operator!= (CharPointer_UTF16 other) const noexcept { return data != other.data; }
inline bool operator<= (CharPointer_UTF16 other) const noexcept { return data <= other.data; }
inline bool operator< (CharPointer_UTF16 other) const noexcept { return data < other.data; }
inline bool operator>= (CharPointer_UTF16 other) const noexcept { return data >= other.data; }
inline bool operator> (CharPointer_UTF16 other) const noexcept { return data > other.data; }
inline CharType* getAddress() const noexcept { return data; }
inline operator const CharType*() const noexcept { return data; }
inline bool isEmpty() const noexcept { return *data == 0; }
inline bool isNotEmpty() const noexcept { return *data != 0; }
juce_wchar operator*() const noexcept
{
auto n = (uint32) (uint16) *data;
if (n >= 0xd800 && n <= 0xdfff && ((uint32) (uint16) data[1]) >= 0xdc00)
n = 0x10000 + (((n - 0xd800) << 10) | (((uint32) (uint16) data[1]) - 0xdc00));
return (juce_wchar) n;
}
CharPointer_UTF16 operator++() noexcept
{
auto n = (uint32) (uint16) *data++;
if (n >= 0xd800 && n <= 0xdfff && ((uint32) (uint16) *data) >= 0xdc00)
++data;
return *this;
}
CharPointer_UTF16 operator--() noexcept
{
auto n = (uint32) (uint16) (*--data);
if (n >= 0xdc00 && n <= 0xdfff)
--data;
return *this;
}
juce_wchar getAndAdvance() noexcept
{
auto n = (uint32) (uint16) *data++;
if (n >= 0xd800 && n <= 0xdfff && ((uint32) (uint16) *data) >= 0xdc00)
n = 0x10000 + ((((n - 0xd800) << 10) | (((uint32) (uint16) *data++) - 0xdc00)));
return (juce_wchar) n;
}
CharPointer_UTF16 operator++ (int) noexcept
{
auto 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_UTF16 operator+ (int numToSkip) const noexcept
{
auto p (*this);
p += numToSkip;
return p;
}
CharPointer_UTF16 operator- (int numToSkip) const noexcept
{
auto p (*this);
p += -numToSkip;
return p;
}
void write (juce_wchar charToWrite) noexcept
{
if (charToWrite >= 0x10000)
{
charToWrite -= 0x10000;
*data++ = (CharType) (0xd800 + (charToWrite >> 10));
*data++ = (CharType) (0xdc00 + (charToWrite & 0x3ff));
}
else
{
*data++ = (CharType) charToWrite;
}
}
inline void writeNull() const noexcept
{
*data = 0;
}
size_t length() const noexcept
{
auto* d = data;
size_t count = 0;
for (;;)
{
auto n = (uint32) (uint16) *d++;
if (n >= 0xd800 && n <= 0xdfff)
{
if (*d++ == 0)
break;
}
else if (n == 0)
break;
++count;
}
return count;
}
size_t lengthUpTo (size_t maxCharsToCount) const noexcept
{
return CharacterFunctions::lengthUpTo (*this, maxCharsToCount);
}
size_t lengthUpTo (CharPointer_UTF16 end) const noexcept
{
return CharacterFunctions::lengthUpTo (*this, end);
}
size_t sizeInBytes() const noexcept
{
return sizeof (CharType) * (findNullIndex (data) + 1);
}
static size_t getBytesRequiredFor (juce_wchar charToWrite) noexcept
{
return (charToWrite >= 0x10000) ? (sizeof (CharType) * 2) : sizeof (CharType);
}
template <class CharPointer>
static size_t getBytesRequiredFor (CharPointer text) noexcept
{
size_t count = 0;
juce_wchar n;
while ((n = text.getAndAdvance()) != 0)
count += getBytesRequiredFor (n);
return count;
}
CharPointer_UTF16 findTerminatingNull() const noexcept
{
auto* t = data;
while (*t != 0)
++t;
return CharPointer_UTF16 (t);
}
template <typename CharPointer>
void writeAll (CharPointer src) noexcept
{
CharacterFunctions::copyAll (*this, src);
}
void writeAll (CharPointer_UTF16 src) noexcept
{
auto* s = src.data;
while ((*data = *s) != 0)
{
++data;
++s;
}
}
template <typename CharPointer>
size_t writeWithDestByteLimit (CharPointer src, size_t maxDestBytes) noexcept
{
return CharacterFunctions::copyWithDestByteLimit (*this, src, maxDestBytes);
}
template <typename CharPointer>
void writeWithCharLimit (CharPointer src, int maxChars) noexcept
{
CharacterFunctions::copyWithCharLimit (*this, src, maxChars);
}
template <typename CharPointer>
int compare (CharPointer other) const noexcept
{
return CharacterFunctions::compare (*this, other);
}
template <typename CharPointer>
int compareUpTo (CharPointer other, int maxChars) const noexcept
{
return CharacterFunctions::compareUpTo (*this, other, maxChars);
}
template <typename CharPointer>
int compareIgnoreCase (CharPointer other) const noexcept
{
return CharacterFunctions::compareIgnoreCase (*this, other);
}
template <typename CharPointer>
int compareIgnoreCaseUpTo (CharPointer other, int maxChars) const noexcept
{
return CharacterFunctions::compareIgnoreCaseUpTo (*this, other, maxChars);
}
#if JUCE_MSVC && ! defined (DOXYGEN)
int compareIgnoreCase (CharPointer_UTF16 other) const noexcept
{
return _wcsicmp (data, other.data);
}
int compareIgnoreCaseUpTo (CharPointer_UTF16 other, int maxChars) const noexcept
{
return _wcsnicmp (data, other.data, (size_t) maxChars);
}
int indexOf (CharPointer_UTF16 stringToFind) const noexcept
{
const CharType* const t = wcsstr (data, stringToFind.getAddress());
return t == nullptr ? -1 : (int) (t - data);
}
#endif
template <typename CharPointer>
int indexOf (CharPointer stringToFind) const noexcept
{
return CharacterFunctions::indexOf (*this, stringToFind);
}
int indexOf (juce_wchar charToFind) const noexcept
{
return CharacterFunctions::indexOfChar (*this, charToFind);
}
int indexOf (juce_wchar charToFind, bool ignoreCase) const noexcept
{
return ignoreCase ? CharacterFunctions::indexOfCharIgnoreCase (*this, charToFind)
: CharacterFunctions::indexOfChar (*this, charToFind);
}
bool isWhitespace() const noexcept { return CharacterFunctions::isWhitespace (operator*()) != 0; }
bool isDigit() const noexcept { return CharacterFunctions::isDigit (operator*()) != 0; }
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
{
#if JUCE_MSVC
return _wtoi (data);
#else
return CharacterFunctions::getIntValue<int, CharPointer_UTF16> (*this);
#endif
}
int64 getIntValue64() const noexcept
{
#if JUCE_MSVC
return _wtoi64 (data);
#else
return CharacterFunctions::getIntValue<int64, CharPointer_UTF16> (*this);
#endif
}
double getDoubleValue() const noexcept { return CharacterFunctions::getDoubleValue (*this); }
CharPointer_UTF16 findEndOfWhitespace() const noexcept { return CharacterFunctions::findEndOfWhitespace (*this); }
void incrementToEndOfWhitespace() noexcept { CharacterFunctions::incrementToEndOfWhitespace (*this); }
static bool canRepresent (juce_wchar character) noexcept
{
auto n = (uint32) character;
return n < 0x10ffff && (n < 0xd800 || n > 0xdfff);
}
static bool isValidString (const CharType* dataToTest, int maxBytesToRead)
{
maxBytesToRead /= (int) sizeof (CharType);
while (--maxBytesToRead >= 0 && *dataToTest != 0)
{
auto n = (uint32) (uint16) *dataToTest++;
if (n >= 0xd800)
{
if (n > 0x10ffff)
return false;
if (n <= 0xdfff)
{
if (n > 0xdc00)
return false;
auto nextChar = (uint32) (uint16) *dataToTest++;
if (nextChar < 0xdc00 || nextChar > 0xdfff)
return false;
}
}
}
return true;
}
CharPointer_UTF16 atomicSwap (CharPointer_UTF16 newValue)
{
return CharPointer_UTF16 (reinterpret_cast<Atomic<CharType*>&> (data).exchange (newValue.data));
}
enum
{
byteOrderMarkBE1 = 0xfe,
byteOrderMarkBE2 = 0xff,
byteOrderMarkLE1 = 0xff,
byteOrderMarkLE2 = 0xfe
};
static bool isByteOrderMarkBigEndian (const void* possibleByteOrder) noexcept
{
JUCE_BEGIN_IGNORE_WARNINGS_MSVC (28182)
jassert (possibleByteOrder != nullptr);
auto c = static_cast<const uint8*> (possibleByteOrder);
return c[0] == (uint8) byteOrderMarkBE1
&& c[1] == (uint8) byteOrderMarkBE2;
JUCE_END_IGNORE_WARNINGS_MSVC
}
static bool isByteOrderMarkLittleEndian (const void* possibleByteOrder) noexcept
{
JUCE_BEGIN_IGNORE_WARNINGS_MSVC (28182)
jassert (possibleByteOrder != nullptr);
auto c = static_cast<const uint8*> (possibleByteOrder);
return c[0] == (uint8) byteOrderMarkLE1
&& c[1] == (uint8) byteOrderMarkLE2;
JUCE_END_IGNORE_WARNINGS_MSVC
}
private:
CharType* data;
static unsigned int findNullIndex (const CharType* t) noexcept
{
unsigned int n = 0;
while (t[n] != 0)
++n;
return n;
}
};
} // namespace juce
juce::CharPointer_UTF16
Definition juce_CharPointer_UTF16.h:35
juce::CharPointer_UTF16::toUpperCase
juce_wchar toUpperCase() const noexcept
Definition juce_CharPointer_UTF16.h:399
juce::CharPointer_UTF16::getIntValue32
int getIntValue32() const noexcept
Definition juce_CharPointer_UTF16.h:404
juce::CharPointer_UTF16::operator*
juce_wchar operator*() const noexcept
Definition juce_CharPointer_UTF16.h:83
juce::CharPointer_UTF16::operator-
CharPointer_UTF16 operator-(int numToSkip) const noexcept
Definition juce_CharPointer_UTF16.h:173
juce::CharPointer_UTF16::isNotEmpty
bool isNotEmpty() const noexcept
Definition juce_CharPointer_UTF16.h:80
juce::CharPointer_UTF16::operator++
CharPointer_UTF16 operator++() noexcept
Definition juce_CharPointer_UTF16.h:94
juce::CharPointer_UTF16::writeWithDestByteLimit
size_t writeWithDestByteLimit(CharPointer src, size_t maxDestBytes) noexcept
Definition juce_CharPointer_UTF16.h:304
juce::CharPointer_UTF16::getBytesRequiredFor
static size_t getBytesRequiredFor(juce_wchar charToWrite) noexcept
Definition juce_CharPointer_UTF16.h:248
juce::CharPointer_UTF16::writeAll
void writeAll(CharPointer src) noexcept
Definition juce_CharPointer_UTF16.h:282
juce::CharPointer_UTF16::canRepresent
static bool canRepresent(juce_wchar character) noexcept
Definition juce_CharPointer_UTF16.h:433
juce::CharPointer_UTF16::operator==
bool operator==(CharPointer_UTF16 other) const noexcept
Definition juce_CharPointer_UTF16.h:63
juce::CharPointer_UTF16::writeNull
void writeNull() const noexcept
Definition juce_CharPointer_UTF16.h:196
juce::CharPointer_UTF16::toLowerCase
juce_wchar toLowerCase() const noexcept
Definition juce_CharPointer_UTF16.h:401
juce::CharPointer_UTF16::isUpperCase
bool isUpperCase() const noexcept
Definition juce_CharPointer_UTF16.h:394
juce::CharPointer_UTF16::compareIgnoreCaseUpTo
int compareIgnoreCaseUpTo(CharPointer other, int maxChars) const noexcept
Definition juce_CharPointer_UTF16.h:342
juce::CharPointer_UTF16::getIntValue64
int64 getIntValue64() const noexcept
Definition juce_CharPointer_UTF16.h:414
juce::CharPointer_UTF16::compare
int compare(CharPointer other) const noexcept
Definition juce_CharPointer_UTF16.h:321
juce::CharPointer_UTF16::isLetter
bool isLetter() const noexcept
Definition juce_CharPointer_UTF16.h:390
juce::CharPointer_UTF16::lengthUpTo
size_t lengthUpTo(size_t maxCharsToCount) const noexcept
Definition juce_CharPointer_UTF16.h:226
juce::CharPointer_UTF16::atomicSwap
CharPointer_UTF16 atomicSwap(CharPointer_UTF16 newValue)
Definition juce_CharPointer_UTF16.h:470
juce::CharPointer_UTF16::getBytesRequiredFor
static size_t getBytesRequiredFor(CharPointer text) noexcept
Definition juce_CharPointer_UTF16.h:258
juce::CharPointer_UTF16::operator--
CharPointer_UTF16 operator--() noexcept
Definition juce_CharPointer_UTF16.h:105
juce::CharPointer_UTF16::operator[]
juce_wchar operator[](int characterIndex) const noexcept
Definition juce_CharPointer_UTF16.h:157
juce::CharPointer_UTF16::getDoubleValue
double getDoubleValue() const noexcept
Definition juce_CharPointer_UTF16.h:424
juce::CharPointer_UTF16::length
size_t length() const noexcept
Definition juce_CharPointer_UTF16.h:202
juce::CharPointer_UTF16::findTerminatingNull
CharPointer_UTF16 findTerminatingNull() const noexcept
Definition juce_CharPointer_UTF16.h:270
juce::CharPointer_UTF16::lengthUpTo
size_t lengthUpTo(CharPointer_UTF16 end) const noexcept
Definition juce_CharPointer_UTF16.h:232
juce::CharPointer_UTF16::compareIgnoreCase
int compareIgnoreCase(CharPointer other) const noexcept
Definition juce_CharPointer_UTF16.h:335
juce::CharPointer_UTF16::getAddress
CharType * getAddress() const noexcept
Definition juce_CharPointer_UTF16.h:71
juce::CharPointer_UTF16::sizeInBytes
size_t sizeInBytes() const noexcept
Definition juce_CharPointer_UTF16.h:240
juce::CharPointer_UTF16::isByteOrderMarkBigEndian
static bool isByteOrderMarkBigEndian(const void *possibleByteOrder) noexcept
Definition juce_CharPointer_UTF16.h:487
juce::CharPointer_UTF16::operator+
CharPointer_UTF16 operator+(int numToSkip) const noexcept
Definition juce_CharPointer_UTF16.h:165
juce::CharPointer_UTF16::findEndOfWhitespace
CharPointer_UTF16 findEndOfWhitespace() const noexcept
Definition juce_CharPointer_UTF16.h:427
juce::CharPointer_UTF16::getAndAdvance
juce_wchar getAndAdvance() noexcept
Definition juce_CharPointer_UTF16.h:117
juce::CharPointer_UTF16::isDigit
bool isDigit() const noexcept
Definition juce_CharPointer_UTF16.h:388
juce::CharPointer_UTF16::compareUpTo
int compareUpTo(CharPointer other, int maxChars) const noexcept
Definition juce_CharPointer_UTF16.h:328
juce::CharPointer_UTF16::writeAll
void writeAll(CharPointer_UTF16 src) noexcept
Definition juce_CharPointer_UTF16.h:288
juce::CharPointer_UTF16::isLowerCase
bool isLowerCase() const noexcept
Definition juce_CharPointer_UTF16.h:396
juce::CharPointer_UTF16::incrementToEndOfWhitespace
void incrementToEndOfWhitespace() noexcept
Definition juce_CharPointer_UTF16.h:430
juce::CharPointer_UTF16::isEmpty
bool isEmpty() const noexcept
Definition juce_CharPointer_UTF16.h:77
juce::CharPointer_UTF16::indexOf
int indexOf(juce_wchar charToFind) const noexcept
Definition juce_CharPointer_UTF16.h:373
juce::CharPointer_UTF16::writeWithCharLimit
void writeWithCharLimit(CharPointer src, int maxChars) noexcept
Definition juce_CharPointer_UTF16.h:314
juce::CharPointer_UTF16::isLetterOrDigit
bool isLetterOrDigit() const noexcept
Definition juce_CharPointer_UTF16.h:392
juce::CharPointer_UTF16::indexOf
int indexOf(CharPointer stringToFind) const noexcept
Definition juce_CharPointer_UTF16.h:367
juce::CharPointer_UTF16::write
void write(juce_wchar charToWrite) noexcept
Definition juce_CharPointer_UTF16.h:181
juce::CharPointer_UTF16::isValidString
static bool isValidString(const CharType *dataToTest, int maxBytesToRead)
Definition juce_CharPointer_UTF16.h:440
juce::CharPointer_UTF16::isWhitespace
bool isWhitespace() const noexcept
Definition juce_CharPointer_UTF16.h:386
juce::CharPointer_UTF16::operator-=
void operator-=(int numToSkip) noexcept
Definition juce_CharPointer_UTF16.h:151
juce::CharPointer_UTF16::isByteOrderMarkLittleEndian
static bool isByteOrderMarkLittleEndian(const void *possibleByteOrder) noexcept
Definition juce_CharPointer_UTF16.h:501
juce::CharPointer_UTF16::operator+=
void operator+=(int numToSkip) noexcept
Definition juce_CharPointer_UTF16.h:136
juce::CharPointer_UTF16::indexOf
int indexOf(juce_wchar charToFind, bool ignoreCase) const noexcept
Definition juce_CharPointer_UTF16.h:379
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::isDigit
static bool isDigit(char character) noexcept
Definition juce_CharacterFunctions.cpp:69
juce::CharacterFunctions::getIntValue
static IntType getIntValue(const CharPointerType text) noexcept
Definition juce_CharacterFunctions.h:465
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