@@ -104,16 +104,15 @@ namespace CodeHelpers | |||||
return n; | return n; | ||||
} | } | ||||
template <class CharType> | |||||
static void writeEscapeChars (OutputStream& out, const CharType* data, const int numChars, | |||||
static void writeEscapeChars (OutputStream& out, const char* utf8, const int numBytes, | |||||
const int maxCharsOnLine, const bool breakAtNewLines, const bool replaceSingleQuotes) | const int maxCharsOnLine, const bool breakAtNewLines, const bool replaceSingleQuotes) | ||||
{ | { | ||||
int charsOnLine = 0; | int charsOnLine = 0; | ||||
bool lastWasHexEscapeCode = false; | bool lastWasHexEscapeCode = false; | ||||
for (int i = 0; i < numChars || numChars < 0; ++i) | |||||
for (int i = 0; i < numBytes || numBytes < 0; ++i) | |||||
{ | { | ||||
const CharType c = data[i]; | |||||
const char c = utf8[i]; | |||||
bool startNewLine = false; | bool startNewLine = false; | ||||
switch (c) | switch (c) | ||||
@@ -125,7 +124,7 @@ namespace CodeHelpers | |||||
case '\"': out << "\\\""; lastWasHexEscapeCode = false; break; | case '\"': out << "\\\""; lastWasHexEscapeCode = false; break; | ||||
case 0: | case 0: | ||||
if (numChars < 0) | |||||
if (numBytes < 0) | |||||
return; | return; | ||||
out << "\\0"; | out << "\\0"; | ||||
@@ -144,9 +143,9 @@ namespace CodeHelpers | |||||
default: | default: | ||||
if (c >= 32 && c < 127 && ! (lastWasHexEscapeCode // (have to avoid following a hex escape sequence with a valid hex digit) | if (c >= 32 && c < 127 && ! (lastWasHexEscapeCode // (have to avoid following a hex escape sequence with a valid hex digit) | ||||
&& ((c >= '0' && c <= '9') || (c >= 'a' && c <= 'f') || (c >= 'A' && c <= 'F')))) | |||||
&& CharacterFunctions::getHexDigitValue (c) >= 0)) | |||||
{ | { | ||||
out << (char) c; | |||||
out << c; | |||||
lastWasHexEscapeCode = false; | lastWasHexEscapeCode = false; | ||||
} | } | ||||
else | else | ||||
@@ -159,7 +158,7 @@ namespace CodeHelpers | |||||
} | } | ||||
if ((startNewLine || (maxCharsOnLine > 0 && ++charsOnLine >= maxCharsOnLine)) | if ((startNewLine || (maxCharsOnLine > 0 && ++charsOnLine >= maxCharsOnLine)) | ||||
&& (numChars < 0 || i < numChars - 1)) | |||||
&& (numBytes < 0 || i < numBytes - 1)) | |||||
{ | { | ||||
charsOnLine = 0; | charsOnLine = 0; | ||||
out << "\"" << newLine << "\""; | out << "\"" << newLine << "\""; | ||||
@@ -170,7 +169,7 @@ namespace CodeHelpers | |||||
const String addEscapeChars (const String& s) | const String addEscapeChars (const String& s) | ||||
{ | { | ||||
MemoryOutputStream out; | MemoryOutputStream out; | ||||
writeEscapeChars (out, (const juce_wchar*) s, -1, -1, false, true); | |||||
writeEscapeChars (out, s.toUTF8().getAddress(), -1, -1, false, true); | |||||
return out.toUTF8(); | return out.toUTF8(); | ||||
} | } | ||||
@@ -192,7 +191,10 @@ namespace CodeHelpers | |||||
if (text.isEmpty()) | if (text.isEmpty()) | ||||
return "String::empty"; | return "String::empty"; | ||||
return CodeHelpers::addEscapeChars (text).quoted(); | |||||
if (CharPointer_ASCII::isValidString (text.toUTF8(), std::numeric_limits<int>::max())) | |||||
return CodeHelpers::addEscapeChars (text).quoted(); | |||||
else | |||||
return "CharPointer_UTF8 (" + CodeHelpers::addEscapeChars (text).quoted() + ")"; | |||||
} | } | ||||
const String stringLiteralIfNotEmpty (const String& text) | const String stringLiteralIfNotEmpty (const String& text) | ||||
@@ -423,7 +425,7 @@ namespace CodeHelpers | |||||
else | else | ||||
{ | { | ||||
out << "\""; | out << "\""; | ||||
writeEscapeChars (out, data, (int) mb.getSize(), maxCharsOnLine, true, false); | |||||
writeEscapeChars (out, (const char*) data, (int) mb.getSize(), maxCharsOnLine, true, false); | |||||
out << "\";"; | out << "\";"; | ||||
} | } | ||||
} | } | ||||
@@ -73,7 +73,7 @@ namespace JuceDummyNamespace {} | |||||
*/ | */ | ||||
#define JUCE_MAJOR_VERSION 1 | #define JUCE_MAJOR_VERSION 1 | ||||
#define JUCE_MINOR_VERSION 53 | #define JUCE_MINOR_VERSION 53 | ||||
#define JUCE_BUILDNUMBER 23 | |||||
#define JUCE_BUILDNUMBER 24 | |||||
/** Current Juce version number. | /** Current Juce version number. | ||||
@@ -1702,7 +1702,7 @@ public: | |||||
static int getHexDigitValue (juce_wchar digit) throw(); | static int getHexDigitValue (juce_wchar digit) throw(); | ||||
template <typename CharPointerType> | template <typename CharPointerType> | ||||
static double getDoubleValue (const CharPointerType& text) throw() | |||||
static double readDoubleValue (CharPointerType& text) throw() | |||||
{ | { | ||||
double result[3] = { 0, 0, 0 }, accumulator[2] = { 0, 0 }; | double result[3] = { 0, 0, 0 }, accumulator[2] = { 0, 0 }; | ||||
int exponentAdjustment[2] = { 0, 0 }, exponentAccumulator[2] = { -1, -1 }; | int exponentAdjustment[2] = { 0, 0 }, exponentAccumulator[2] = { -1, -1 }; | ||||
@@ -1711,36 +1711,36 @@ public: | |||||
bool isNegative = false, digitsFound = false; | bool isNegative = false, digitsFound = false; | ||||
const int maxSignificantDigits = 15 + 2; | const int maxSignificantDigits = 15 + 2; | ||||
CharPointerType s (text.findEndOfWhitespace()); | |||||
juce_wchar c = *s; | |||||
text = text.findEndOfWhitespace(); | |||||
juce_wchar c = *text; | |||||
switch (c) | switch (c) | ||||
{ | { | ||||
case '-': isNegative = true; // fall-through.. | case '-': isNegative = true; // fall-through.. | ||||
case '+': c = *++s; | |||||
case '+': c = *++text; | |||||
} | } | ||||
switch (c) | switch (c) | ||||
{ | { | ||||
case 'n': | case 'n': | ||||
case 'N': | case 'N': | ||||
if ((s[1] == 'a' || s[1] == 'A') && (s[2] == 'n' || s[2] == 'N')) | |||||
if ((text[1] == 'a' || text[1] == 'A') && (text[2] == 'n' || text[2] == 'N')) | |||||
return std::numeric_limits<double>::quiet_NaN(); | return std::numeric_limits<double>::quiet_NaN(); | ||||
break; | break; | ||||
case 'i': | case 'i': | ||||
case 'I': | case 'I': | ||||
if ((s[1] == 'n' || s[1] == 'N') && (s[2] == 'f' || s[2] == 'F')) | |||||
if ((text[1] == 'n' || text[1] == 'N') && (text[2] == 'f' || text[2] == 'F')) | |||||
return std::numeric_limits<double>::infinity(); | return std::numeric_limits<double>::infinity(); | ||||
break; | break; | ||||
} | } | ||||
for (;;) | for (;;) | ||||
{ | { | ||||
if (s.isDigit()) | |||||
if (text.isDigit()) | |||||
{ | { | ||||
lastDigit = digit; | lastDigit = digit; | ||||
digit = s.getAndAdvance() - '0'; | |||||
digit = text.getAndAdvance() - '0'; | |||||
digitsFound = true; | digitsFound = true; | ||||
if (decPointIndex != 0) | if (decPointIndex != 0) | ||||
@@ -1761,9 +1761,9 @@ public: | |||||
else | else | ||||
exponentAdjustment[0]++; | exponentAdjustment[0]++; | ||||
while (s.isDigit()) | |||||
while (text.isDigit()) | |||||
{ | { | ||||
++s; | |||||
++text; | |||||
if (decPointIndex == 0) | if (decPointIndex == 0) | ||||
exponentAdjustment[0]++; | exponentAdjustment[0]++; | ||||
} | } | ||||
@@ -1783,15 +1783,15 @@ public: | |||||
exponentAccumulator [decPointIndex]++; | exponentAccumulator [decPointIndex]++; | ||||
} | } | ||||
} | } | ||||
else if (decPointIndex == 0 && *s == '.') | |||||
else if (decPointIndex == 0 && *text == '.') | |||||
{ | { | ||||
++s; | |||||
++text; | |||||
decPointIndex = 1; | decPointIndex = 1; | ||||
if (numSignificantDigits > maxSignificantDigits) | if (numSignificantDigits > maxSignificantDigits) | ||||
{ | { | ||||
while (s.isDigit()) | |||||
++s; | |||||
while (text.isDigit()) | |||||
++text; | |||||
break; | break; | ||||
} | } | ||||
} | } | ||||
@@ -1806,19 +1806,19 @@ public: | |||||
if (decPointIndex != 0) | if (decPointIndex != 0) | ||||
result[1] = mulexp10 (result[1], exponentAccumulator[1]) + accumulator[1]; | result[1] = mulexp10 (result[1], exponentAccumulator[1]) + accumulator[1]; | ||||
c = *s; | |||||
c = *text; | |||||
if ((c == 'e' || c == 'E') && digitsFound) | if ((c == 'e' || c == 'E') && digitsFound) | ||||
{ | { | ||||
bool negativeExponent = false; | bool negativeExponent = false; | ||||
switch (*++s) | |||||
switch (*++text) | |||||
{ | { | ||||
case '-': negativeExponent = true; // fall-through.. | case '-': negativeExponent = true; // fall-through.. | ||||
case '+': ++s; | |||||
case '+': ++text; | |||||
} | } | ||||
while (s.isDigit()) | |||||
exponent = (exponent * 10) + (s.getAndAdvance() - '0'); | |||||
while (text.isDigit()) | |||||
exponent = (exponent * 10) + (text.getAndAdvance() - '0'); | |||||
if (negativeExponent) | if (negativeExponent) | ||||
exponent = -exponent; | exponent = -exponent; | ||||
@@ -1831,6 +1831,13 @@ public: | |||||
return isNegative ? -r : r; | return isNegative ? -r : r; | ||||
} | } | ||||
template <typename CharPointerType> | |||||
static double getDoubleValue (const CharPointerType& text) throw() | |||||
{ | |||||
CharPointerType t (text); | |||||
return readDoubleValue (t); | |||||
} | |||||
template <typename IntType, typename CharPointerType> | template <typename IntType, typename CharPointerType> | ||||
static IntType getIntValue (const CharPointerType& text) throw() | static IntType getIntValue (const CharPointerType& text) throw() | ||||
{ | { | ||||
@@ -4585,16 +4592,7 @@ public: | |||||
No checks are made to see if the index is within a valid range, so be careful! | No checks are made to see if the index is within a valid range, so be careful! | ||||
*/ | */ | ||||
inline const juce_wchar& operator[] (int index) const throw() { jassert (isPositiveAndNotGreaterThan (index, length())); return text [index]; } | |||||
/** Returns a character from the string such that it can also be altered. | |||||
This can be used as a way of easily changing characters in the string. | |||||
Note that the index passed-in is not checked to see whether it's in-range, so | |||||
be careful when using this. | |||||
*/ | |||||
juce_wchar& operator[] (int index); | |||||
const juce_wchar operator[] (int index) const throw(); | |||||
/** Returns the final character of the string. | /** Returns the final character of the string. | ||||
@@ -5036,15 +5034,7 @@ public: | |||||
that is returned must not be stored anywhere, as it can become invalid whenever | that is returned must not be stored anywhere, as it can become invalid whenever | ||||
any string methods (even some const ones!) are called. | any string methods (even some const ones!) are called. | ||||
*/ | */ | ||||
inline operator const juce_wchar*() const throw() { return text.getAddress(); } | |||||
/** Returns a unicode version of this string. | |||||
Because it returns a reference to the string's internal data, the pointer | |||||
that is returned must not be stored anywhere, as it can become invalid whenever | |||||
any string methods (even some const ones!) are called. | |||||
*/ | |||||
inline operator juce_wchar*() throw() { return text.getAddress(); } | |||||
inline operator const juce_wchar*() const throw() { return toUTF32().getAddress(); } | |||||
/** Returns the character pointer currently being used to store this string. | /** Returns the character pointer currently being used to store this string. | ||||
@@ -7407,7 +7397,7 @@ public: | |||||
The pool will own all the pointers that it returns, deleting them when the pool itself | The pool will own all the pointers that it returns, deleting them when the pool itself | ||||
is deleted. | is deleted. | ||||
*/ | */ | ||||
const juce_wchar* getPooledString (const String& original); | |||||
const String::CharPointerType getPooledString (const String& original); | |||||
/** Returns a pointer to a copy of the string that is passed in. | /** Returns a pointer to a copy of the string that is passed in. | ||||
@@ -7415,7 +7405,7 @@ public: | |||||
The pool will own all the pointers that it returns, deleting them when the pool itself | The pool will own all the pointers that it returns, deleting them when the pool itself | ||||
is deleted. | is deleted. | ||||
*/ | */ | ||||
const juce_wchar* getPooledString (const char* original); | |||||
const String::CharPointerType getPooledString (const char* original); | |||||
/** Returns a pointer to a copy of the string that is passed in. | /** Returns a pointer to a copy of the string that is passed in. | ||||
@@ -7423,7 +7413,7 @@ public: | |||||
The pool will own all the pointers that it returns, deleting them when the pool itself | The pool will own all the pointers that it returns, deleting them when the pool itself | ||||
is deleted. | is deleted. | ||||
*/ | */ | ||||
const juce_wchar* getPooledString (const juce_wchar* original); | |||||
const String::CharPointerType getPooledString (const juce_wchar* original); | |||||
/** Returns the number of strings in the pool. */ | /** Returns the number of strings in the pool. */ | ||||
int size() const throw(); | int size() const throw(); | ||||
@@ -8162,15 +8152,15 @@ public: | |||||
/** Writes a string of text to the stream. | /** Writes a string of text to the stream. | ||||
It can either write it as UTF8 characters or as unicode, and | |||||
can also add unicode header bytes (0xff, 0xfe) to indicate the endianness (this | |||||
should only be done at the start of a file). | |||||
It can either write the text as UTF-8 or UTF-16, and can also add the UTF-16 byte-order-mark | |||||
bytes (0xff, 0xfe) to indicate the endianness (these should only be used at the start | |||||
of a file). | |||||
The method also replaces '\\n' characters in the text with '\\r\\n'. | The method also replaces '\\n' characters in the text with '\\r\\n'. | ||||
*/ | */ | ||||
virtual void writeText (const String& text, | virtual void writeText (const String& text, | ||||
bool asUnicode, | |||||
bool writeUnicodeHeaderBytes); | |||||
bool asUTF16, | |||||
bool writeUTF16ByteOrderMark); | |||||
/** Reads data from an input stream and writes it to this stream. | /** Reads data from an input stream and writes it to this stream. | ||||
@@ -10199,8 +10189,8 @@ public: | |||||
*/ | */ | ||||
void appendNumbersToDuplicates (bool ignoreCaseWhenComparing, | void appendNumbersToDuplicates (bool ignoreCaseWhenComparing, | ||||
bool appendNumberToFirstInstance, | bool appendNumberToFirstInstance, | ||||
const juce_wchar* preNumberString = 0, | |||||
const juce_wchar* postNumberString = 0); | |||||
CharPointer_UTF8 preNumberString = CharPointer_UTF8 (0), | |||||
CharPointer_UTF8 postNumberString = CharPointer_UTF8 (0)); | |||||
/** Joins the strings in the array together into one string. | /** Joins the strings in the array together into one string. | ||||
@@ -11195,7 +11185,7 @@ public: | |||||
/** Creates a relative path that refers to a file relatively to a given directory. | /** Creates a relative path that refers to a file relatively to a given directory. | ||||
e.g. File ("/moose/foo.txt").getRelativePathFrom ("/moose/fish/haddock") | |||||
e.g. File ("/moose/foo.txt").getRelativePathFrom (File ("/moose/fish/haddock")) | |||||
would return "../../foo.txt". | would return "../../foo.txt". | ||||
If it's not possible to navigate from one file to the other, an absolute | If it's not possible to navigate from one file to the other, an absolute | ||||
@@ -20065,15 +20055,16 @@ public: | |||||
/** Returns an Expression which is a function call. */ | /** Returns an Expression which is a function call. */ | ||||
static const Expression function (const String& functionName, const Array<Expression>& parameters); | static const Expression function (const String& functionName, const Array<Expression>& parameters); | ||||
/** Returns an Expression which parses a string from a specified character index. | |||||
/** Returns an Expression which parses a string from a character pointer, and updates the pointer | |||||
to indicate where it finished. | |||||
The index value is incremented so that on return, it indicates the character that follows | |||||
The pointer is incremented so that on return, it indicates the character that follows | |||||
the end of the expression that was parsed. | the end of the expression that was parsed. | ||||
If there's a syntax error in the string, this will throw a ParseError exception. | If there's a syntax error in the string, this will throw a ParseError exception. | ||||
@throws ParseError | @throws ParseError | ||||
*/ | */ | ||||
static const Expression parse (const String& stringToParse, int& textIndexToStartFrom); | |||||
static const Expression parse (String::CharPointerType& stringToParse); | |||||
/** When evaluating an Expression object, this class is used to resolve symbols and | /** When evaluating an Expression object, this class is used to resolve symbols and | ||||
perform functions that the expression uses. | perform functions that the expression uses. | ||||
@@ -33,7 +33,7 @@ | |||||
*/ | */ | ||||
#define JUCE_MAJOR_VERSION 1 | #define JUCE_MAJOR_VERSION 1 | ||||
#define JUCE_MINOR_VERSION 53 | #define JUCE_MINOR_VERSION 53 | ||||
#define JUCE_BUILDNUMBER 23 | |||||
#define JUCE_BUILDNUMBER 24 | |||||
/** Current Juce version number. | /** Current Juce version number. | ||||
@@ -348,7 +348,7 @@ const String Time::formatted (const String& format) const | |||||
struct tm t (TimeHelpers::millisToLocal (millisSinceEpoch)); | struct tm t (TimeHelpers::millisToLocal (millisSinceEpoch)); | ||||
while (CharacterFunctions::ftime (static_cast <juce_wchar*> (buffer), bufferSize, format, &t) <= 0) | |||||
while (CharacterFunctions::ftime (buffer.getCharPointer().getAddress(), bufferSize, format.getCharPointer(), &t) <= 0) | |||||
{ | { | ||||
bufferSize += 128; | bufferSize += 128; | ||||
buffer.preallocateStorage (bufferSize); | buffer.preallocateStorage (bufferSize); | ||||
@@ -67,15 +67,13 @@ MD5::MD5 (const void* data, const size_t numBytes) | |||||
MD5::MD5 (const String& text) | MD5::MD5 (const String& text) | ||||
{ | { | ||||
ProcessContext context; | ProcessContext context; | ||||
String::CharPointerType t (text.getCharPointer()); | |||||
const int len = text.length(); | |||||
const juce_wchar* const t = text; | |||||
for (int i = 0; i < len; ++i) | |||||
while (! t.isEmpty()) | |||||
{ | { | ||||
// force the string into integer-sized unicode characters, to try to make it | // force the string into integer-sized unicode characters, to try to make it | ||||
// get the same results on all platforms + compilers. | // get the same results on all platforms + compilers. | ||||
uint32 unicodeChar = ByteOrder::swapIfBigEndian ((uint32) t[i]); | |||||
uint32 unicodeChar = ByteOrder::swapIfBigEndian ((uint32) t.getAndAdvance()); | |||||
context.processBlock (&unicodeChar, sizeof (unicodeChar)); | context.processBlock (&unicodeChar, sizeof (unicodeChar)); | ||||
} | } | ||||
@@ -54,7 +54,7 @@ namespace CppTokeniser | |||||
|| c == '_' || c == '@'; | || c == '_' || c == '@'; | ||||
} | } | ||||
bool isReservedKeyword (const juce_wchar* const token, const int tokenLength) throw() | |||||
bool isReservedKeyword (String::CharPointerType token, const int tokenLength) throw() | |||||
{ | { | ||||
static const char* const keywords2Char[] = | static const char* const keywords2Char[] = | ||||
{ "if", "do", "or", "id", 0 }; | { "if", "do", "or", "id", 0 }; | ||||
@@ -103,7 +103,7 @@ namespace CppTokeniser | |||||
int i = 0; | int i = 0; | ||||
while (k[i] != 0) | while (k[i] != 0) | ||||
{ | { | ||||
if (k[i][0] == (char) token[0] && CharPointer_UTF8 (k[i]).compare (CharPointer_UTF32 (token)) == 0) | |||||
if (token.compare (CharPointer_ASCII (k[i])) == 0) | |||||
return true; | return true; | ||||
++i; | ++i; | ||||
@@ -131,7 +131,7 @@ namespace CppTokeniser | |||||
{ | { | ||||
possibleIdentifier [tokenLength] = 0; | possibleIdentifier [tokenLength] = 0; | ||||
if (isReservedKeyword (possibleIdentifier, tokenLength)) | |||||
if (isReservedKeyword (CharPointer_UTF32 (possibleIdentifier), tokenLength)) | |||||
return CPlusPlusCodeTokeniser::tokenType_builtInKeyword; | return CPlusPlusCodeTokeniser::tokenType_builtInKeyword; | ||||
} | } | ||||
@@ -612,7 +612,7 @@ const Colour CPlusPlusCodeTokeniser::getDefaultColour (const int tokenType) | |||||
bool CPlusPlusCodeTokeniser::isReservedKeyword (const String& token) throw() | bool CPlusPlusCodeTokeniser::isReservedKeyword (const String& token) throw() | ||||
{ | { | ||||
return CppTokeniser::isReservedKeyword (token, token.length()); | |||||
return CppTokeniser::isReservedKeyword (token.getCharPointer(), token.length()); | |||||
} | } | ||||
END_JUCE_NAMESPACE | END_JUCE_NAMESPACE |
@@ -34,7 +34,7 @@ BEGIN_JUCE_NAMESPACE | |||||
class CodeDocumentLine | class CodeDocumentLine | ||||
{ | { | ||||
public: | public: | ||||
CodeDocumentLine (const juce_wchar* const line_, | |||||
CodeDocumentLine (const String::CharPointerType& line_, | |||||
const int lineLength_, | const int lineLength_, | ||||
const int numNewLineChars, | const int numNewLineChars, | ||||
const int lineStartInFile_) | const int lineStartInFile_) | ||||
@@ -45,51 +45,59 @@ public: | |||||
{ | { | ||||
} | } | ||||
~CodeDocumentLine() | |||||
{ | |||||
} | |||||
static void createLines (Array <CodeDocumentLine*>& newLines, const String& text) | static void createLines (Array <CodeDocumentLine*>& newLines, const String& text) | ||||
{ | { | ||||
const juce_wchar* const t = text; | |||||
int pos = 0; | |||||
String::CharPointerType t (text.getCharPointer()); | |||||
int charNumInFile = 0; | |||||
bool finished = t.isEmpty(); | |||||
while (t [pos] != 0) | |||||
while (! finished) | |||||
{ | { | ||||
const int startOfLine = pos; | |||||
String::CharPointerType startOfLine (t); | |||||
int startOfLineInFile = charNumInFile; | |||||
int lineLength = 0; | |||||
int numNewLineChars = 0; | int numNewLineChars = 0; | ||||
while (t[pos] != 0) | |||||
for (;;) | |||||
{ | { | ||||
if (t[pos] == '\r') | |||||
const juce_wchar c = t.getAndAdvance(); | |||||
if (c == 0) | |||||
{ | |||||
finished = true; | |||||
break; | |||||
} | |||||
++charNumInFile; | |||||
++lineLength; | |||||
if (c == '\r') | |||||
{ | { | ||||
++numNewLineChars; | ++numNewLineChars; | ||||
++pos; | |||||
if (t[pos] == '\n') | |||||
if (*t == '\n') | |||||
{ | { | ||||
++t; | |||||
++charNumInFile; | |||||
++lineLength; | |||||
++numNewLineChars; | ++numNewLineChars; | ||||
++pos; | |||||
} | } | ||||
break; | break; | ||||
} | } | ||||
if (t[pos] == '\n') | |||||
if (c == '\n') | |||||
{ | { | ||||
++numNewLineChars; | ++numNewLineChars; | ||||
++pos; | |||||
break; | break; | ||||
} | } | ||||
++pos; | |||||
} | } | ||||
newLines.add (new CodeDocumentLine (t + startOfLine, pos - startOfLine, | |||||
numNewLineChars, startOfLine)); | |||||
newLines.add (new CodeDocumentLine (startOfLine, lineLength, | |||||
numNewLineChars, startOfLineInFile)); | |||||
} | } | ||||
jassert (pos == text.length()); | |||||
jassert (charNumInFile == text.length()); | |||||
} | } | ||||
bool endsWithLineBreak() const throw() | bool endsWithLineBreak() const throw() | ||||
@@ -706,7 +714,7 @@ void CodeDocument::checkLastLineStatus() | |||||
if (lastLine != 0 && lastLine->endsWithLineBreak()) | if (lastLine != 0 && lastLine->endsWithLineBreak()) | ||||
{ | { | ||||
// check that there's an empty line at the end if the preceding one ends in a newline.. | // check that there's an empty line at the end if the preceding one ends in a newline.. | ||||
lines.add (new CodeDocumentLine (String::empty, 0, 0, lastLine->lineStartInFile + lastLine->lineLength)); | |||||
lines.add (new CodeDocumentLine (String::empty.getCharPointer(), 0, 0, lastLine->lineStartInFile + lastLine->lineLength)); | |||||
} | } | ||||
} | } | ||||
@@ -273,55 +273,56 @@ private: | |||||
void initialiseAtoms (const String& textToParse, | void initialiseAtoms (const String& textToParse, | ||||
const juce_wchar passwordCharacter) | const juce_wchar passwordCharacter) | ||||
{ | { | ||||
int i = 0; | |||||
const int len = textToParse.length(); | |||||
const juce_wchar* const text = textToParse; | |||||
String::CharPointerType text (textToParse.getCharPointer()); | |||||
while (i < len) | |||||
while (! text.isEmpty()) | |||||
{ | { | ||||
int start = i; | |||||
int numChars = 0; | |||||
String::CharPointerType start (text); | |||||
// create a whitespace atom unless it starts with non-ws | // create a whitespace atom unless it starts with non-ws | ||||
if (CharacterFunctions::isWhitespace (text[i]) | |||||
&& text[i] != '\r' | |||||
&& text[i] != '\n') | |||||
if (text.isWhitespace() && *text != '\r' && *text != '\n') | |||||
{ | { | ||||
while (i < len | |||||
&& CharacterFunctions::isWhitespace (text[i]) | |||||
&& text[i] != '\r' | |||||
&& text[i] != '\n') | |||||
do | |||||
{ | { | ||||
++i; | |||||
++text; | |||||
++numChars; | |||||
} | } | ||||
while (text.isWhitespace() && *text != '\r' && *text != '\n'); | |||||
} | } | ||||
else | else | ||||
{ | { | ||||
if (text[i] == '\r') | |||||
if (*text == '\r') | |||||
{ | { | ||||
++i; | |||||
++text; | |||||
++numChars; | |||||
if ((i < len) && (text[i] == '\n')) | |||||
if (*text == '\n') | |||||
{ | { | ||||
++start; | ++start; | ||||
++i; | |||||
++text; | |||||
} | } | ||||
} | } | ||||
else if (text[i] == '\n') | |||||
else if (*text == '\n') | |||||
{ | { | ||||
++i; | |||||
++text; | |||||
++numChars; | |||||
} | } | ||||
else | else | ||||
{ | { | ||||
while ((i < len) && ! CharacterFunctions::isWhitespace (text[i])) | |||||
++i; | |||||
while (! text.isEmpty() || text.isWhitespace()) | |||||
{ | |||||
++text; | |||||
++numChars; | |||||
} | |||||
} | } | ||||
} | } | ||||
TextAtom* const atom = new TextAtom(); | TextAtom* const atom = new TextAtom(); | ||||
atom->atomText = String (text + start, i - start); | |||||
atom->atomText = String (start, numChars); | |||||
atom->width = font.getStringWidthFloat (atom->getText (passwordCharacter)); | atom->width = font.getStringWidthFloat (atom->getText (passwordCharacter)); | ||||
atom->numChars = (uint16) (i - start); | |||||
atom->numChars = (uint16) numChars; | |||||
atoms.add (atom); | atoms.add (atom); | ||||
} | } | ||||
@@ -31,13 +31,12 @@ BEGIN_JUCE_NAMESPACE | |||||
namespace RelativePointHelpers | namespace RelativePointHelpers | ||||
{ | { | ||||
void skipComma (const juce_wchar* const s, int& i) | |||||
inline void skipComma (String::CharPointerType& s) | |||||
{ | { | ||||
while (CharacterFunctions::isWhitespace (s[i])) | |||||
++i; | |||||
s = s.findEndOfWhitespace(); | |||||
if (s[i] == ',') | |||||
++i; | |||||
if (*s == ',') | |||||
++s; | |||||
} | } | ||||
} | } | ||||
@@ -63,10 +62,10 @@ RelativePoint::RelativePoint (const RelativeCoordinate& x_, const RelativeCoordi | |||||
RelativePoint::RelativePoint (const String& s) | RelativePoint::RelativePoint (const String& s) | ||||
{ | { | ||||
int i = 0; | |||||
x = RelativeCoordinate (Expression::parse (s, i)); | |||||
RelativePointHelpers::skipComma (s, i); | |||||
y = RelativeCoordinate (Expression::parse (s, i)); | |||||
String::CharPointerType text (s.getCharPointer()); | |||||
x = RelativeCoordinate (Expression::parse (text)); | |||||
RelativePointHelpers::skipComma (text); | |||||
y = RelativeCoordinate (Expression::parse (text)); | |||||
} | } | ||||
bool RelativePoint::operator== (const RelativePoint& other) const throw() | bool RelativePoint::operator== (const RelativePoint& other) const throw() | ||||
@@ -34,13 +34,12 @@ BEGIN_JUCE_NAMESPACE | |||||
//============================================================================== | //============================================================================== | ||||
namespace RelativeRectangleHelpers | namespace RelativeRectangleHelpers | ||||
{ | { | ||||
inline void skipComma (const juce_wchar* const s, int& i) | |||||
inline void skipComma (String::CharPointerType& s) | |||||
{ | { | ||||
while (CharacterFunctions::isWhitespace (s[i])) | |||||
++i; | |||||
s = s.findEndOfWhitespace(); | |||||
if (s[i] == ',') | |||||
++i; | |||||
if (*s == ',') | |||||
++s; | |||||
} | } | ||||
bool dependsOnSymbolsOtherThanThis (const Expression& e) | bool dependsOnSymbolsOtherThanThis (const Expression& e) | ||||
@@ -95,14 +94,14 @@ RelativeRectangle::RelativeRectangle (const Rectangle<float>& rect) | |||||
RelativeRectangle::RelativeRectangle (const String& s) | RelativeRectangle::RelativeRectangle (const String& s) | ||||
{ | { | ||||
int i = 0; | |||||
left = RelativeCoordinate (Expression::parse (s, i)); | |||||
RelativeRectangleHelpers::skipComma (s, i); | |||||
top = RelativeCoordinate (Expression::parse (s, i)); | |||||
RelativeRectangleHelpers::skipComma (s, i); | |||||
right = RelativeCoordinate (Expression::parse (s, i)); | |||||
RelativeRectangleHelpers::skipComma (s, i); | |||||
bottom = RelativeCoordinate (Expression::parse (s, i)); | |||||
String::CharPointerType text (s.getCharPointer()); | |||||
left = RelativeCoordinate (Expression::parse (text)); | |||||
RelativeRectangleHelpers::skipComma (text); | |||||
top = RelativeCoordinate (Expression::parse (text)); | |||||
RelativeRectangleHelpers::skipComma (text); | |||||
right = RelativeCoordinate (Expression::parse (text)); | |||||
RelativeRectangleHelpers::skipComma (text); | |||||
bottom = RelativeCoordinate (Expression::parse (text)); | |||||
} | } | ||||
bool RelativeRectangle::operator== (const RelativeRectangle& other) const throw() | bool RelativeRectangle::operator== (const RelativeRectangle& other) const throw() | ||||
@@ -45,10 +45,6 @@ public: | |||||
{ | { | ||||
} | } | ||||
~SVGState() | |||||
{ | |||||
} | |||||
//============================================================================== | //============================================================================== | ||||
Drawable* parseSVGElement (const XmlElement& xml) | Drawable* parseSVGElement (const XmlElement& xml) | ||||
{ | { | ||||
@@ -71,12 +67,12 @@ public: | |||||
if (xml.hasAttribute ("viewBox")) | if (xml.hasAttribute ("viewBox")) | ||||
{ | { | ||||
const String viewParams (xml.getStringAttribute ("viewBox")); | |||||
int i = 0; | |||||
const String viewBoxAtt (xml.getStringAttribute ("viewBox")); | |||||
String::CharPointerType viewParams (viewBoxAtt.getCharPointer()); | |||||
float vx, vy, vw, vh; | float vx, vy, vw, vh; | ||||
if (parseCoords (viewParams, vx, vy, i, true) | |||||
&& parseCoords (viewParams, vw, vh, i, true) | |||||
if (parseCoords (viewParams, vx, vy, true) | |||||
&& parseCoords (viewParams, vw, vh, true) | |||||
&& vw > 0 | && vw > 0 | ||||
&& vh > 0) | && vh > 0) | ||||
{ | { | ||||
@@ -200,28 +196,28 @@ private: | |||||
//============================================================================== | //============================================================================== | ||||
Drawable* parsePath (const XmlElement& xml) const | Drawable* parsePath (const XmlElement& xml) const | ||||
{ | { | ||||
const String d (xml.getStringAttribute ("d").trimStart()); | |||||
const String dAttribute (xml.getStringAttribute ("d").trimStart()); | |||||
String::CharPointerType d (dAttribute.getCharPointer()); | |||||
Path path; | Path path; | ||||
if (getStyleAttribute (&xml, "fill-rule").trim().equalsIgnoreCase ("evenodd")) | if (getStyleAttribute (&xml, "fill-rule").trim().equalsIgnoreCase ("evenodd")) | ||||
path.setUsingNonZeroWinding (false); | path.setUsingNonZeroWinding (false); | ||||
int index = 0; | |||||
float lastX = 0, lastY = 0; | float lastX = 0, lastY = 0; | ||||
float lastX2 = 0, lastY2 = 0; | float lastX2 = 0, lastY2 = 0; | ||||
juce_wchar lastCommandChar = 0; | juce_wchar lastCommandChar = 0; | ||||
bool isRelative = true; | bool isRelative = true; | ||||
bool carryOn = true; | bool carryOn = true; | ||||
const String validCommandChars ("MmLlHhVvCcSsQqTtAaZz"); | |||||
const CharPointer_ASCII validCommandChars ("MmLlHhVvCcSsQqTtAaZz"); | |||||
while (d[index] != 0) | |||||
while (! d.isEmpty()) | |||||
{ | { | ||||
float x, y, x2, y2, x3, y3; | float x, y, x2, y2, x3, y3; | ||||
if (validCommandChars.containsChar (d[index])) | |||||
if (validCommandChars.indexOf (*d) >= 0) | |||||
{ | { | ||||
lastCommandChar = d [index++]; | |||||
lastCommandChar = d.getAndAdvance(); | |||||
isRelative = (lastCommandChar >= 'a' && lastCommandChar <= 'z'); | isRelative = (lastCommandChar >= 'a' && lastCommandChar <= 'z'); | ||||
} | } | ||||
@@ -231,7 +227,7 @@ private: | |||||
case 'm': | case 'm': | ||||
case 'L': | case 'L': | ||||
case 'l': | case 'l': | ||||
if (parseCoords (d, x, y, index, false)) | |||||
if (parseCoords (d, x, y, false)) | |||||
{ | { | ||||
if (isRelative) | if (isRelative) | ||||
{ | { | ||||
@@ -254,14 +250,14 @@ private: | |||||
} | } | ||||
else | else | ||||
{ | { | ||||
++index; | |||||
++d; | |||||
} | } | ||||
break; | break; | ||||
case 'H': | case 'H': | ||||
case 'h': | case 'h': | ||||
if (parseCoord (d, x, index, false, true)) | |||||
if (parseCoord (d, x, false, true)) | |||||
{ | { | ||||
if (isRelative) | if (isRelative) | ||||
x += lastX; | x += lastX; | ||||
@@ -273,13 +269,13 @@ private: | |||||
} | } | ||||
else | else | ||||
{ | { | ||||
++index; | |||||
++d; | |||||
} | } | ||||
break; | break; | ||||
case 'V': | case 'V': | ||||
case 'v': | case 'v': | ||||
if (parseCoord (d, y, index, false, false)) | |||||
if (parseCoord (d, y, false, false)) | |||||
{ | { | ||||
if (isRelative) | if (isRelative) | ||||
y += lastY; | y += lastY; | ||||
@@ -291,15 +287,15 @@ private: | |||||
} | } | ||||
else | else | ||||
{ | { | ||||
++index; | |||||
++d; | |||||
} | } | ||||
break; | break; | ||||
case 'C': | case 'C': | ||||
case 'c': | case 'c': | ||||
if (parseCoords (d, x, y, index, false) | |||||
&& parseCoords (d, x2, y2, index, false) | |||||
&& parseCoords (d, x3, y3, index, false)) | |||||
if (parseCoords (d, x, y, false) | |||||
&& parseCoords (d, x2, y2, false) | |||||
&& parseCoords (d, x3, y3, false)) | |||||
{ | { | ||||
if (isRelative) | if (isRelative) | ||||
{ | { | ||||
@@ -320,14 +316,14 @@ private: | |||||
} | } | ||||
else | else | ||||
{ | { | ||||
++index; | |||||
++d; | |||||
} | } | ||||
break; | break; | ||||
case 'S': | case 'S': | ||||
case 's': | case 's': | ||||
if (parseCoords (d, x, y, index, false) | |||||
&& parseCoords (d, x3, y3, index, false)) | |||||
if (parseCoords (d, x, y, false) | |||||
&& parseCoords (d, x3, y3, false)) | |||||
{ | { | ||||
if (isRelative) | if (isRelative) | ||||
{ | { | ||||
@@ -348,14 +344,14 @@ private: | |||||
} | } | ||||
else | else | ||||
{ | { | ||||
++index; | |||||
++d; | |||||
} | } | ||||
break; | break; | ||||
case 'Q': | case 'Q': | ||||
case 'q': | case 'q': | ||||
if (parseCoords (d, x, y, index, false) | |||||
&& parseCoords (d, x2, y2, index, false)) | |||||
if (parseCoords (d, x, y, false) | |||||
&& parseCoords (d, x2, y2, false)) | |||||
{ | { | ||||
if (isRelative) | if (isRelative) | ||||
{ | { | ||||
@@ -374,13 +370,13 @@ private: | |||||
} | } | ||||
else | else | ||||
{ | { | ||||
++index; | |||||
++d; | |||||
} | } | ||||
break; | break; | ||||
case 'T': | case 'T': | ||||
case 't': | case 't': | ||||
if (parseCoords (d, x, y, index, false)) | |||||
if (parseCoords (d, x, y, false)) | |||||
{ | { | ||||
if (isRelative) | if (isRelative) | ||||
{ | { | ||||
@@ -399,29 +395,29 @@ private: | |||||
} | } | ||||
else | else | ||||
{ | { | ||||
++index; | |||||
++d; | |||||
} | } | ||||
break; | break; | ||||
case 'A': | case 'A': | ||||
case 'a': | case 'a': | ||||
if (parseCoords (d, x, y, index, false)) | |||||
if (parseCoords (d, x, y, false)) | |||||
{ | { | ||||
String num; | String num; | ||||
if (parseNextNumber (d, num, index, false)) | |||||
if (parseNextNumber (d, num, false)) | |||||
{ | { | ||||
const float angle = num.getFloatValue() * (180.0f / float_Pi); | const float angle = num.getFloatValue() * (180.0f / float_Pi); | ||||
if (parseNextNumber (d, num, index, false)) | |||||
if (parseNextNumber (d, num, false)) | |||||
{ | { | ||||
const bool largeArc = num.getIntValue() != 0; | const bool largeArc = num.getIntValue() != 0; | ||||
if (parseNextNumber (d, num, index, false)) | |||||
if (parseNextNumber (d, num, false)) | |||||
{ | { | ||||
const bool sweep = num.getIntValue() != 0; | const bool sweep = num.getIntValue() != 0; | ||||
if (parseCoords (d, x2, y2, index, false)) | |||||
if (parseCoords (d, x2, y2, false)) | |||||
{ | { | ||||
if (isRelative) | if (isRelative) | ||||
{ | { | ||||
@@ -458,7 +454,7 @@ private: | |||||
} | } | ||||
else | else | ||||
{ | { | ||||
++index; | |||||
++d; | |||||
} | } | ||||
break; | break; | ||||
@@ -466,9 +462,7 @@ private: | |||||
case 'Z': | case 'Z': | ||||
case 'z': | case 'z': | ||||
path.closeSubPath(); | path.closeSubPath(); | ||||
while (CharacterFunctions::isWhitespace (d [index])) | |||||
++index; | |||||
d = d.findEndOfWhitespace(); | |||||
break; | break; | ||||
default: | default: | ||||
@@ -561,13 +555,12 @@ private: | |||||
Drawable* parsePolygon (const XmlElement& xml, const bool isPolyline) const | Drawable* parsePolygon (const XmlElement& xml, const bool isPolyline) const | ||||
{ | { | ||||
const String points (xml.getStringAttribute ("points")); | |||||
const String pointsAtt (xml.getStringAttribute ("points")); | |||||
String::CharPointerType points (pointsAtt.getCharPointer()); | |||||
Path path; | Path path; | ||||
int index = 0; | |||||
float x, y; | float x, y; | ||||
if (parseCoords (points, x, y, index, true)) | |||||
if (parseCoords (points, x, y, true)) | |||||
{ | { | ||||
float firstX = x; | float firstX = x; | ||||
float firstY = y; | float firstY = y; | ||||
@@ -575,7 +568,7 @@ private: | |||||
path.startNewSubPath (x, y); | path.startNewSubPath (x, y); | ||||
while (parseCoords (points, x, y, index, true)) | |||||
while (parseCoords (points, x, y, true)) | |||||
{ | { | ||||
lastX = x; | lastX = x; | ||||
lastY = y; | lastY = y; | ||||
@@ -865,12 +858,11 @@ private: | |||||
} | } | ||||
//============================================================================== | //============================================================================== | ||||
bool parseCoord (const String& s, float& value, int& index, | |||||
const bool allowUnits, const bool isX) const | |||||
bool parseCoord (String::CharPointerType& s, float& value, const bool allowUnits, const bool isX) const | |||||
{ | { | ||||
String number; | String number; | ||||
if (! parseNextNumber (s, number, index, allowUnits)) | |||||
if (! parseNextNumber (s, number, allowUnits)) | |||||
{ | { | ||||
value = 0; | value = 0; | ||||
return false; | return false; | ||||
@@ -880,11 +872,10 @@ private: | |||||
return true; | return true; | ||||
} | } | ||||
bool parseCoords (const String& s, float& x, float& y, | |||||
int& index, const bool allowUnits) const | |||||
bool parseCoords (String::CharPointerType& s, float& x, float& y, const bool allowUnits) const | |||||
{ | { | ||||
return parseCoord (s, x, index, allowUnits, true) | |||||
&& parseCoord (s, y, index, allowUnits, false); | |||||
return parseCoord (s, x, allowUnits, true) | |||||
&& parseCoord (s, y, allowUnits, false); | |||||
} | } | ||||
float getCoordLength (const String& s, const float sizeForProportions) const | float getCoordLength (const String& s, const float sizeForProportions) const | ||||
@@ -917,10 +908,10 @@ private: | |||||
void getCoordList (Array <float>& coords, const String& list, | void getCoordList (Array <float>& coords, const String& list, | ||||
const bool allowUnits, const bool isX) const | const bool allowUnits, const bool isX) const | ||||
{ | { | ||||
int index = 0; | |||||
String::CharPointerType text (list.getCharPointer()); | |||||
float value; | float value; | ||||
while (parseCoord (list, value, index, allowUnits, isX)) | |||||
while (parseCoord (text, value, allowUnits, isX)) | |||||
coords.add (value); | coords.add (value); | ||||
} | } | ||||
@@ -1034,45 +1025,55 @@ private: | |||||
} | } | ||||
//============================================================================== | //============================================================================== | ||||
static bool parseNextNumber (const String& source, String& value, int& index, const bool allowUnits) | |||||
static bool parseNextNumber (String::CharPointerType& s, String& value, const bool allowUnits) | |||||
{ | { | ||||
const juce_wchar* const s = source; | |||||
while (CharacterFunctions::isWhitespace (s[index]) || s[index] == ',') | |||||
++index; | |||||
while (s.isWhitespace() || *s == ',') | |||||
++s; | |||||
int start = index; | |||||
String::CharPointerType start (s); | |||||
int numChars = 0; | |||||
if (CharacterFunctions::isDigit (s[index]) || s[index] == '.' || s[index] == '-') | |||||
++index; | |||||
if (s.isDigit() || *s == '.' || *s == '-') | |||||
{ | |||||
++numChars; | |||||
++s; | |||||
} | |||||
while (CharacterFunctions::isDigit (s[index]) || s[index] == '.') | |||||
++index; | |||||
while (s.isDigit() || *s == '.') | |||||
{ | |||||
++numChars; | |||||
++s; | |||||
} | |||||
if ((s[index] == 'e' || s[index] == 'E') | |||||
&& (CharacterFunctions::isDigit (s[index + 1]) | |||||
|| s[index + 1] == '-' | |||||
|| s[index + 1] == '+')) | |||||
if ((*s == 'e' || *s == 'E') | |||||
&& ((s + 1).isDigit() || s[1] == '-' || s[1] == '+')) | |||||
{ | { | ||||
index += 2; | |||||
s += 2; | |||||
numChars += 2; | |||||
while (CharacterFunctions::isDigit (s[index])) | |||||
++index; | |||||
while (s.isDigit()) | |||||
{ | |||||
++numChars; | |||||
++s; | |||||
} | |||||
} | } | ||||
if (allowUnits) | if (allowUnits) | ||||
{ | { | ||||
while (CharacterFunctions::isLetter (s[index])) | |||||
++index; | |||||
while (s.isLetter()) | |||||
{ | |||||
++numChars; | |||||
++s; | |||||
} | |||||
} | } | ||||
if (index == start) | |||||
if (numChars == 0) | |||||
return false; | return false; | ||||
value = String (s + start, index - start); | |||||
value = String (start, numChars); | |||||
while (CharacterFunctions::isWhitespace (s[index]) || s[index] == ',') | |||||
++index; | |||||
while (s.isWhitespace() || *s == ',') | |||||
++s; | |||||
return true; | return true; | ||||
} | } | ||||
@@ -198,7 +198,7 @@ void GlyphArrangement::addCurtailedLineOfText (const Font& font, | |||||
font.getGlyphPositions (text, newGlyphs, xOffsets); | font.getGlyphPositions (text, newGlyphs, xOffsets); | ||||
const int textLen = newGlyphs.size(); | const int textLen = newGlyphs.size(); | ||||
const juce_wchar* const unicodeText = text; | |||||
String::CharPointerType t (text.getCharPointer()); | |||||
for (int i = 0; i < textLen; ++i) | for (int i = 0; i < textLen; ++i) | ||||
{ | { | ||||
@@ -216,7 +216,7 @@ void GlyphArrangement::addCurtailedLineOfText (const Font& font, | |||||
else | else | ||||
{ | { | ||||
glyphs.add (new PositionedGlyph (xOffset + thisX, yOffset, nextX - thisX, | glyphs.add (new PositionedGlyph (xOffset + thisX, yOffset, nextX - thisX, | ||||
font, unicodeText[i], newGlyphs.getUnchecked(i))); | |||||
font, t.getAndAdvance(), newGlyphs.getUnchecked(i))); | |||||
} | } | ||||
} | } | ||||
} | } | ||||
@@ -140,13 +140,13 @@ bool TextLayout::isEmpty() const | |||||
void TextLayout::appendText (const String& text, const Font& font) | void TextLayout::appendText (const String& text, const Font& font) | ||||
{ | { | ||||
const juce_wchar* t = text; | |||||
String::CharPointerType t (text.getCharPointer()); | |||||
String currentString; | String currentString; | ||||
int lastCharType = 0; | int lastCharType = 0; | ||||
for (;;) | for (;;) | ||||
{ | { | ||||
const juce_wchar c = *t++; | |||||
const juce_wchar c = t.getAndAdvance(); | |||||
if (c == 0) | if (c == 0) | ||||
break; | break; | ||||
@@ -175,7 +175,7 @@ void TextLayout::appendText (const String& text, const Font& font) | |||||
currentString = String::charToString (c); | currentString = String::charToString (c); | ||||
if (c == '\r' && *t == '\n') | if (c == '\r' && *t == '\n') | ||||
currentString += *t++; | |||||
currentString += t.getAndAdvance(); | |||||
} | } | ||||
else | else | ||||
{ | { | ||||
@@ -331,11 +331,11 @@ float CustomTypeface::getDescent() const | |||||
float CustomTypeface::getStringWidth (const String& text) | float CustomTypeface::getStringWidth (const String& text) | ||||
{ | { | ||||
float x = 0; | float x = 0; | ||||
const juce_wchar* t = text; | |||||
String::CharPointerType t (text.getCharPointer()); | |||||
while (*t != 0) | |||||
while (! t.isEmpty()) | |||||
{ | { | ||||
const GlyphInfo* const glyph = findGlyphSubstituting (*t++); | |||||
const GlyphInfo* const glyph = findGlyphSubstituting (t.getAndAdvance()); | |||||
if (glyph == 0 && ! isFallbackFont) | if (glyph == 0 && ! isFallbackFont) | ||||
{ | { | ||||
@@ -356,11 +356,11 @@ void CustomTypeface::getGlyphPositions (const String& text, Array <int>& resultG | |||||
{ | { | ||||
xOffsets.add (0); | xOffsets.add (0); | ||||
float x = 0; | float x = 0; | ||||
const juce_wchar* t = text; | |||||
String::CharPointerType t (text.getCharPointer()); | |||||
while (*t != 0) | |||||
while (! t.isEmpty()) | |||||
{ | { | ||||
const juce_wchar c = *t++; | |||||
const juce_wchar c = t.getAndAdvance(); | |||||
const GlyphInfo* const glyph = findGlyph (c, true); | const GlyphInfo* const glyph = findGlyph (c, true); | ||||
if (glyph == 0 && ! isFallbackFont) | if (glyph == 0 && ! isFallbackFont) | ||||
@@ -43,17 +43,20 @@ namespace PathHelpers | |||||
{ | { | ||||
const float ellipseAngularIncrement = 0.05f; | const float ellipseAngularIncrement = 0.05f; | ||||
const String nextToken (const juce_wchar*& t) | |||||
const String nextToken (String::CharPointerType& t) | |||||
{ | { | ||||
while (CharacterFunctions::isWhitespace (*t)) | |||||
++t; | |||||
t = t.findEndOfWhitespace(); | |||||
const juce_wchar* const start = t; | |||||
String::CharPointerType start (t); | |||||
int numChars = 0; | |||||
while (*t != 0 && ! CharacterFunctions::isWhitespace (*t)) | |||||
while (! (t.isEmpty() || t.isWhitespace())) | |||||
{ | |||||
++t; | ++t; | ||||
++numChars; | |||||
} | |||||
return String (start, (int) (t - start)); | |||||
return String (start, numChars); | |||||
} | } | ||||
inline double lengthOf (float x1, float y1, float x2, float y2) throw() | inline double lengthOf (float x1, float y1, float x2, float y2) throw() | ||||
@@ -1453,7 +1456,7 @@ void Path::restoreFromString (const String& stringVersion) | |||||
clear(); | clear(); | ||||
setUsingNonZeroWinding (true); | setUsingNonZeroWinding (true); | ||||
const juce_wchar* t = stringVersion; | |||||
String::CharPointerType t (stringVersion.getCharPointer()); | |||||
juce_wchar marker = 'm'; | juce_wchar marker = 'm'; | ||||
int numValues = 2; | int numValues = 2; | ||||
float values [6]; | float values [6]; | ||||
@@ -852,11 +852,8 @@ const String File::getRelativePathFrom (const File& dir) const | |||||
{ | { | ||||
String thisPath (fullPath); | String thisPath (fullPath); | ||||
{ | |||||
int len = thisPath.length(); | |||||
while (--len >= 0 && thisPath [len] == File::separator) | |||||
thisPath [len] = 0; | |||||
} | |||||
while (thisPath.endsWithChar (separator)) | |||||
thisPath = thisPath.dropLastCharacters (1); | |||||
String dirPath (addTrailingSeparator (dir.existsAsFile() ? dir.getParentDirectory().getFullPathName() | String dirPath (addTrailingSeparator (dir.existsAsFile() ? dir.getParentDirectory().getFullPathName() | ||||
: dir.fullPath)); | : dir.fullPath)); | ||||
@@ -1012,6 +1009,9 @@ public: | |||||
expect (tempFile.loadFileAsString() == "0123456789"); | expect (tempFile.loadFileAsString() == "0123456789"); | ||||
expect (! demoFolder.containsSubDirectories()); | expect (! demoFolder.containsSubDirectories()); | ||||
expectEquals (tempFile.getRelativePathFrom (demoFolder.getParentDirectory()), demoFolder.getFileName() + File::separatorString + tempFile.getFileName()); | |||||
expectEquals (demoFolder.getParentDirectory().getRelativePathFrom (tempFile), ".." + File::separatorString + ".." + File::separatorString + demoFolder.getParentDirectory().getFileName()); | |||||
expect (demoFolder.getNumberOfChildFiles (File::findFiles) == 1); | expect (demoFolder.getNumberOfChildFiles (File::findFiles) == 1); | ||||
expect (demoFolder.getNumberOfChildFiles (File::findFilesAndDirectories) == 1); | expect (demoFolder.getNumberOfChildFiles (File::findFilesAndDirectories) == 1); | ||||
expect (demoFolder.getNumberOfChildFiles (File::findDirectories) == 0); | expect (demoFolder.getNumberOfChildFiles (File::findDirectories) == 0); | ||||
@@ -166,7 +166,7 @@ public: | |||||
/** Creates a relative path that refers to a file relatively to a given directory. | /** Creates a relative path that refers to a file relatively to a given directory. | ||||
e.g. File ("/moose/foo.txt").getRelativePathFrom ("/moose/fish/haddock") | |||||
e.g. File ("/moose/foo.txt").getRelativePathFrom (File ("/moose/fish/haddock")) | |||||
would return "../../foo.txt". | would return "../../foo.txt". | ||||
If it's not possible to navigate from one file to the other, an absolute | If it's not possible to navigate from one file to the other, an absolute | ||||
@@ -131,7 +131,7 @@ int MemoryOutputStream::writeFromInputStream (InputStream& source, int64 maxNumB | |||||
const String MemoryOutputStream::toUTF8() const | const String MemoryOutputStream::toUTF8() const | ||||
{ | { | ||||
return String (static_cast <const char*> (getData()), getDataSize()); | |||||
return String::fromUTF8 (static_cast <const char*> (getData()), getDataSize()); | |||||
} | } | ||||
const String MemoryOutputStream::toString() const | const String MemoryOutputStream::toString() const | ||||
@@ -180,24 +180,29 @@ void OutputStream::writeString (const String& text) | |||||
write (temp, numBytes); | write (temp, numBytes); | ||||
} | } | ||||
void OutputStream::writeText (const String& text, const bool asUnicode, | |||||
const bool writeUnicodeHeaderBytes) | |||||
void OutputStream::writeText (const String& text, const bool asUTF16, | |||||
const bool writeUTF16ByteOrderMark) | |||||
{ | { | ||||
if (asUnicode) | |||||
if (asUTF16) | |||||
{ | { | ||||
if (writeUnicodeHeaderBytes) | |||||
if (writeUTF16ByteOrderMark) | |||||
write ("\x0ff\x0fe", 2); | write ("\x0ff\x0fe", 2); | ||||
const juce_wchar* src = text; | |||||
String::CharPointerType src (text.getCharPointer()); | |||||
bool lastCharWasReturn = false; | bool lastCharWasReturn = false; | ||||
while (*src != 0) | |||||
for (;;) | |||||
{ | { | ||||
if (*src == L'\n' && ! lastCharWasReturn) | |||||
writeShort ((short) L'\r'); | |||||
const juce_wchar c = src.getAndAdvance(); | |||||
if (c == 0) | |||||
break; | |||||
if (c == '\n' && ! lastCharWasReturn) | |||||
writeShort ((short) '\r'); | |||||
lastCharWasReturn = (*src == L'\r'); | |||||
writeShort ((short) *src++); | |||||
lastCharWasReturn = (c == L'\r'); | |||||
writeShort ((short) c); | |||||
} | } | ||||
} | } | ||||
else | else | ||||
@@ -186,15 +186,15 @@ public: | |||||
/** Writes a string of text to the stream. | /** Writes a string of text to the stream. | ||||
It can either write it as UTF8 characters or as unicode, and | |||||
can also add unicode header bytes (0xff, 0xfe) to indicate the endianness (this | |||||
should only be done at the start of a file). | |||||
It can either write the text as UTF-8 or UTF-16, and can also add the UTF-16 byte-order-mark | |||||
bytes (0xff, 0xfe) to indicate the endianness (these should only be used at the start | |||||
of a file). | |||||
The method also replaces '\\n' characters in the text with '\\r\\n'. | The method also replaces '\\n' characters in the text with '\\r\\n'. | ||||
*/ | */ | ||||
virtual void writeText (const String& text, | virtual void writeText (const String& text, | ||||
bool asUnicode, | |||||
bool writeUnicodeHeaderBytes); | |||||
bool asUTF16, | |||||
bool writeUTF16ByteOrderMark); | |||||
/** Reads data from an input stream and writes it to this stream. | /** Reads data from an input stream and writes it to this stream. | ||||
@@ -946,7 +946,7 @@ const String BigInteger::toString (const int base, const int minimumNumCharacter | |||||
void BigInteger::parseString (const String& text, const int base) | void BigInteger::parseString (const String& text, const int base) | ||||
{ | { | ||||
clear(); | clear(); | ||||
const juce_wchar* t = text; | |||||
String::CharPointerType t (text.getCharPointer()); | |||||
if (base == 2 || base == 8 || base == 16) | if (base == 2 || base == 8 || base == 16) | ||||
{ | { | ||||
@@ -954,7 +954,7 @@ void BigInteger::parseString (const String& text, const int base) | |||||
for (;;) | for (;;) | ||||
{ | { | ||||
const juce_wchar c = *t++; | |||||
const juce_wchar c = t.getAndAdvance(); | |||||
const int digit = CharacterFunctions::getHexDigitValue (c); | const int digit = CharacterFunctions::getHexDigitValue (c); | ||||
if (((uint32) digit) < (uint32) base) | if (((uint32) digit) < (uint32) base) | ||||
@@ -974,7 +974,7 @@ void BigInteger::parseString (const String& text, const int base) | |||||
for (;;) | for (;;) | ||||
{ | { | ||||
const juce_wchar c = *t++; | |||||
const juce_wchar c = t.getAndAdvance(); | |||||
if (c >= '0' && c <= '9') | if (c >= '0' && c <= '9') | ||||
{ | { | ||||
@@ -660,29 +660,26 @@ public: | |||||
{ | { | ||||
public: | public: | ||||
//============================================================================== | //============================================================================== | ||||
Parser (const String& stringToParse, int& textIndex_) | |||||
: textString (stringToParse), textIndex (textIndex_) | |||||
Parser (String::CharPointerType& stringToParse) | |||||
: text (stringToParse) | |||||
{ | { | ||||
text = textString; | |||||
} | } | ||||
const TermPtr readUpToComma() | const TermPtr readUpToComma() | ||||
{ | { | ||||
if (textString.isEmpty()) | |||||
if (text.isEmpty()) | |||||
return new Constant (0.0, false); | return new Constant (0.0, false); | ||||
const TermPtr e (readExpression()); | const TermPtr e (readExpression()); | ||||
if (e == 0 || ((! readOperator (",")) && text [textIndex] != 0)) | |||||
throw ParseError ("Syntax error: \"" + textString.substring (textIndex) + "\""); | |||||
if (e == 0 || ((! readOperator (",")) && ! text.isEmpty())) | |||||
throw ParseError ("Syntax error: \"" + String (text) + "\""); | |||||
return e; | return e; | ||||
} | } | ||||
private: | private: | ||||
const String textString; | |||||
const juce_wchar* text; | |||||
int& textIndex; | |||||
String::CharPointerType& text; | |||||
//============================================================================== | //============================================================================== | ||||
static inline bool isDecimalDigit (const juce_wchar c) throw() | static inline bool isDecimalDigit (const juce_wchar c) throw() | ||||
@@ -690,17 +687,11 @@ public: | |||||
return c >= '0' && c <= '9'; | return c >= '0' && c <= '9'; | ||||
} | } | ||||
void skipWhitespace (int& i) throw() | |||||
{ | |||||
while (CharacterFunctions::isWhitespace (text [i])) | |||||
++i; | |||||
} | |||||
bool readChar (const juce_wchar required) throw() | bool readChar (const juce_wchar required) throw() | ||||
{ | { | ||||
if (text[textIndex] == required) | |||||
if (*text == required) | |||||
{ | { | ||||
++textIndex; | |||||
++text; | |||||
return true; | return true; | ||||
} | } | ||||
@@ -709,7 +700,7 @@ public: | |||||
bool readOperator (const char* ops, char* const opType = 0) throw() | bool readOperator (const char* ops, char* const opType = 0) throw() | ||||
{ | { | ||||
skipWhitespace (textIndex); | |||||
text = text.findEndOfWhitespace(); | |||||
while (*ops != 0) | while (*ops != 0) | ||||
{ | { | ||||
@@ -729,21 +720,26 @@ public: | |||||
bool readIdentifier (String& identifier) throw() | bool readIdentifier (String& identifier) throw() | ||||
{ | { | ||||
skipWhitespace (textIndex); | |||||
int i = textIndex; | |||||
text = text.findEndOfWhitespace(); | |||||
String::CharPointerType t (text); | |||||
int numChars = 0; | |||||
if (CharacterFunctions::isLetter (text[i]) || text[i] == '_') | |||||
if (t.isLetter() || *t == '_') | |||||
{ | { | ||||
++i; | |||||
++t; | |||||
++numChars; | |||||
while (CharacterFunctions::isLetterOrDigit (text[i]) || text[i] == '_') | |||||
++i; | |||||
while (t.isLetterOrDigit() || *t == '_') | |||||
{ | |||||
++t; | |||||
++numChars; | |||||
} | |||||
} | } | ||||
if (i > textIndex) | |||||
if (numChars > 0) | |||||
{ | { | ||||
identifier = String (text + textIndex, i - textIndex); | |||||
textIndex = i; | |||||
identifier = String (text, numChars); | |||||
text = t; | |||||
return true; | return true; | ||||
} | } | ||||
@@ -752,71 +748,27 @@ public: | |||||
Term* readNumber() throw() | Term* readNumber() throw() | ||||
{ | { | ||||
skipWhitespace (textIndex); | |||||
int i = textIndex; | |||||
text = text.findEndOfWhitespace(); | |||||
String::CharPointerType t (text); | |||||
const bool isResolutionTarget = (text[i] == '@'); | |||||
const bool isResolutionTarget = (*t == '@'); | |||||
if (isResolutionTarget) | if (isResolutionTarget) | ||||
{ | { | ||||
++i; | |||||
skipWhitespace (i); | |||||
textIndex = i; | |||||
++t; | |||||
t = t.findEndOfWhitespace(); | |||||
text = t; | |||||
} | } | ||||
if (text[i] == '-') | |||||
{ | |||||
++i; | |||||
skipWhitespace (i); | |||||
} | |||||
int numDigits = 0; | |||||
while (isDecimalDigit (text[i])) | |||||
{ | |||||
++i; | |||||
++numDigits; | |||||
} | |||||
const bool hasPoint = (text[i] == '.'); | |||||
if (hasPoint) | |||||
if (*t == '-') | |||||
{ | { | ||||
++i; | |||||
while (isDecimalDigit (text[i])) | |||||
{ | |||||
++i; | |||||
++numDigits; | |||||
} | |||||
++t; | |||||
t = t.findEndOfWhitespace(); | |||||
} | } | ||||
if (numDigits == 0) | |||||
return 0; | |||||
juce_wchar c = text[i]; | |||||
const bool hasExponent = (c == 'e' || c == 'E'); | |||||
if (hasExponent) | |||||
{ | |||||
++i; | |||||
c = text[i]; | |||||
if (c == '+' || c == '-') | |||||
++i; | |||||
if (isDecimalDigit (*t) || (*t == '.' && isDecimalDigit (t[1]))) | |||||
return new Constant (CharacterFunctions::readDoubleValue (text), isResolutionTarget); | |||||
int numExpDigits = 0; | |||||
while (isDecimalDigit (text[i])) | |||||
{ | |||||
++i; | |||||
++numExpDigits; | |||||
} | |||||
if (numExpDigits == 0) | |||||
return 0; | |||||
} | |||||
const int start = textIndex; | |||||
textIndex = i; | |||||
return new Constant (String (text + start, i - start).getDoubleValue(), isResolutionTarget); | |||||
return 0; | |||||
} | } | ||||
const TermPtr readExpression() | const TermPtr readExpression() | ||||
@@ -1002,14 +954,14 @@ Expression& Expression::operator= (const Expression& other) | |||||
Expression::Expression (const String& stringToParse) | Expression::Expression (const String& stringToParse) | ||||
{ | { | ||||
int i = 0; | |||||
Helpers::Parser parser (stringToParse, i); | |||||
String::CharPointerType text (stringToParse.getCharPointer()); | |||||
Helpers::Parser parser (text); | |||||
term = parser.readUpToComma(); | term = parser.readUpToComma(); | ||||
} | } | ||||
const Expression Expression::parse (const String& stringToParse, int& textIndexToStartFrom) | |||||
const Expression Expression::parse (String::CharPointerType& stringToParse) | |||||
{ | { | ||||
Helpers::Parser parser (stringToParse, textIndexToStartFrom); | |||||
Helpers::Parser parser (stringToParse); | |||||
return Expression (parser.readUpToComma()); | return Expression (parser.readUpToComma()); | ||||
} | } | ||||
@@ -91,15 +91,16 @@ public: | |||||
/** Returns an Expression which is a function call. */ | /** Returns an Expression which is a function call. */ | ||||
static const Expression function (const String& functionName, const Array<Expression>& parameters); | static const Expression function (const String& functionName, const Array<Expression>& parameters); | ||||
/** Returns an Expression which parses a string from a specified character index. | |||||
/** Returns an Expression which parses a string from a character pointer, and updates the pointer | |||||
to indicate where it finished. | |||||
The index value is incremented so that on return, it indicates the character that follows | |||||
The pointer is incremented so that on return, it indicates the character that follows | |||||
the end of the expression that was parsed. | the end of the expression that was parsed. | ||||
If there's a syntax error in the string, this will throw a ParseError exception. | If there's a syntax error in the string, this will throw a ParseError exception. | ||||
@throws ParseError | @throws ParseError | ||||
*/ | */ | ||||
static const Expression parse (const String& stringToParse, int& textIndexToStartFrom); | |||||
static const Expression parse (String::CharPointerType& stringToParse); | |||||
//============================================================================== | //============================================================================== | ||||
/** When evaluating an Expression object, this class is used to resolve symbols and | /** When evaluating an Expression object, this class is used to resolve symbols and | ||||
@@ -336,15 +336,14 @@ const String MemoryBlock::toBase64Encoding() const | |||||
const int initialLen = destString.length(); | const int initialLen = destString.length(); | ||||
destString.preallocateStorage (initialLen + 2 + numChars); | destString.preallocateStorage (initialLen + 2 + numChars); | ||||
juce_wchar* d = destString; | |||||
String::CharPointerType d (destString.getCharPointer()); | |||||
d += initialLen; | d += initialLen; | ||||
*d++ = '.'; | |||||
d.write ('.'); | |||||
for (size_t i = 0; i < numChars; ++i) | for (size_t i = 0; i < numChars; ++i) | ||||
*d++ = encodingTable [getBitRange (i * 6, 6)]; | |||||
*d++ = 0; | |||||
d.write (encodingTable [getBitRange (i * 6, 6)]); | |||||
d.writeNull(); | |||||
return destString; | return destString; | ||||
} | } | ||||
@@ -360,13 +359,14 @@ bool MemoryBlock::fromBase64Encoding (const String& s) | |||||
setSize (numBytesNeeded, true); | setSize (numBytesNeeded, true); | ||||
const int numChars = s.length() - startPos; | const int numChars = s.length() - startPos; | ||||
const juce_wchar* srcChars = s; | |||||
String::CharPointerType srcChars (s.getCharPointer()); | |||||
srcChars += startPos; | srcChars += startPos; | ||||
int pos = 0; | int pos = 0; | ||||
for (int i = 0; i < numChars; ++i) | for (int i = 0; i < numChars; ++i) | ||||
{ | { | ||||
const char c = (char) srcChars[i]; | |||||
const char c = (char) srcChars.getAndAdvance(); | |||||
for (int j = 0; j < 64; ++j) | for (int j = 0; j < 64; ++j) | ||||
{ | { | ||||
@@ -195,7 +195,7 @@ public: | |||||
const int length = text.length(); | const int length = text.length(); | ||||
HeapBlock <CGGlyph> glyphs; | HeapBlock <CGGlyph> glyphs; | ||||
createGlyphsForString (text, length, glyphs); | |||||
createGlyphsForString (text.getCharPointer(), length, glyphs); | |||||
float x = 0; | float x = 0; | ||||
@@ -238,7 +238,7 @@ public: | |||||
const int length = text.length(); | const int length = text.length(); | ||||
HeapBlock <CGGlyph> glyphs; | HeapBlock <CGGlyph> glyphs; | ||||
createGlyphsForString (text, length, glyphs); | |||||
createGlyphsForString (text.getCharPointer(), length, glyphs); | |||||
#if SUPPORT_ONLY_10_4_FONTS | #if SUPPORT_ONLY_10_4_FONTS | ||||
HeapBlock <NSSize> advances (length); | HeapBlock <NSSize> advances (length); | ||||
@@ -340,7 +340,7 @@ private: | |||||
AffineTransform pathTransform; | AffineTransform pathTransform; | ||||
#endif | #endif | ||||
void createGlyphsForString (const juce_wchar* const text, const int length, HeapBlock <CGGlyph>& glyphs) | |||||
void createGlyphsForString (String::CharPointerType text, const int length, HeapBlock <CGGlyph>& glyphs) | |||||
{ | { | ||||
#if SUPPORT_10_4_FONTS | #if SUPPORT_10_4_FONTS | ||||
#if ! SUPPORT_ONLY_10_4_FONTS | #if ! SUPPORT_ONLY_10_4_FONTS | ||||
@@ -351,7 +351,7 @@ private: | |||||
NSGlyph* const nsGlyphs = reinterpret_cast<NSGlyph*> (glyphs.getData()); | NSGlyph* const nsGlyphs = reinterpret_cast<NSGlyph*> (glyphs.getData()); | ||||
for (int i = 0; i < length; ++i) | for (int i = 0; i < length; ++i) | ||||
nsGlyphs[i] = (NSGlyph) [nsFont _defaultGlyphForChar: text[i]]; | |||||
nsGlyphs[i] = (NSGlyph) [nsFont _defaultGlyphForChar: text.getAndAdvance()]; | |||||
return; | return; | ||||
} | } | ||||
@@ -364,7 +364,7 @@ private: | |||||
glyphs.malloc (length); | glyphs.malloc (length); | ||||
for (int i = 0; i < length; ++i) | for (int i = 0; i < length; ++i) | ||||
glyphs[i] = (CGGlyph) charToGlyphMapper->getGlyphForCharacter (text[i]); | |||||
glyphs[i] = (CGGlyph) charToGlyphMapper->getGlyphForCharacter (text.getAndAdvance()); | |||||
#endif | #endif | ||||
} | } | ||||
@@ -119,7 +119,7 @@ const String PlatformUtilities::convertToPrecomposedUnicode (const String& s) | |||||
{ | { | ||||
result.preallocateStorage (bytesRead / sizeof (UniChar) + 2); | result.preallocateStorage (bytesRead / sizeof (UniChar) + 2); | ||||
CharPointer_UTF32 dest (static_cast <juce_wchar*> (result)); | |||||
CharPointer_UTF32 dest (result.getCharPointer()); | |||||
dest.writeAll (CharPointer_UTF16 ((CharPointer_UTF16::CharType*) tempOut.getData())); | dest.writeAll (CharPointer_UTF16 ((CharPointer_UTF16::CharType*) tempOut.getData())); | ||||
} | } | ||||
@@ -233,7 +233,7 @@ void MessageManager::broadcastMessage (const String& value) | |||||
COPYDATASTRUCT data; | COPYDATASTRUCT data; | ||||
data.dwData = broadcastId; | data.dwData = broadcastId; | ||||
data.cbData = (localCopy.length() + 1) * sizeof (juce_wchar); | data.cbData = (localCopy.length() + 1) * sizeof (juce_wchar); | ||||
data.lpData = (void*) static_cast <const juce_wchar*> (localCopy); | |||||
data.lpData = (void*) localCopy.toUTF16().getAddress(); | |||||
for (int i = windows.size(); --i >= 0;) | for (int i = windows.size(); --i >= 0;) | ||||
{ | { | ||||
@@ -334,14 +334,7 @@ static Handle createHandleDataRef (Handle dataHandle, const char* fileName) | |||||
static CFStringRef juceStringToCFString (const String& s) | static CFStringRef juceStringToCFString (const String& s) | ||||
{ | { | ||||
const int len = s.length(); | |||||
const juce_wchar* const t = s; | |||||
HeapBlock <UniChar> temp (len + 2); | |||||
for (int i = 0; i <= len; ++i) | |||||
temp[i] = t[i]; | |||||
return CFStringCreateWithCharacters (kCFAllocatorDefault, temp, len); | |||||
return CFStringCreateWithCString (kCFAllocatorDefault, s.toUTF8(), kCFStringEncodingUTF8); | |||||
} | } | ||||
static bool openMovie (QTNewMoviePropertyElement* props, int prop, Movie& movie) | static bool openMovie (QTNewMoviePropertyElement* props, int prop, Movie& movie) | ||||
@@ -96,7 +96,7 @@ public: | |||||
//============================================================================== | //============================================================================== | ||||
template <typename CharPointerType> | template <typename CharPointerType> | ||||
static double getDoubleValue (const CharPointerType& text) throw() | |||||
static double readDoubleValue (CharPointerType& text) throw() | |||||
{ | { | ||||
double result[3] = { 0, 0, 0 }, accumulator[2] = { 0, 0 }; | double result[3] = { 0, 0, 0 }, accumulator[2] = { 0, 0 }; | ||||
int exponentAdjustment[2] = { 0, 0 }, exponentAccumulator[2] = { -1, -1 }; | int exponentAdjustment[2] = { 0, 0 }, exponentAccumulator[2] = { -1, -1 }; | ||||
@@ -105,36 +105,36 @@ public: | |||||
bool isNegative = false, digitsFound = false; | bool isNegative = false, digitsFound = false; | ||||
const int maxSignificantDigits = 15 + 2; | const int maxSignificantDigits = 15 + 2; | ||||
CharPointerType s (text.findEndOfWhitespace()); | |||||
juce_wchar c = *s; | |||||
text = text.findEndOfWhitespace(); | |||||
juce_wchar c = *text; | |||||
switch (c) | switch (c) | ||||
{ | { | ||||
case '-': isNegative = true; // fall-through.. | case '-': isNegative = true; // fall-through.. | ||||
case '+': c = *++s; | |||||
case '+': c = *++text; | |||||
} | } | ||||
switch (c) | switch (c) | ||||
{ | { | ||||
case 'n': | case 'n': | ||||
case 'N': | case 'N': | ||||
if ((s[1] == 'a' || s[1] == 'A') && (s[2] == 'n' || s[2] == 'N')) | |||||
if ((text[1] == 'a' || text[1] == 'A') && (text[2] == 'n' || text[2] == 'N')) | |||||
return std::numeric_limits<double>::quiet_NaN(); | return std::numeric_limits<double>::quiet_NaN(); | ||||
break; | break; | ||||
case 'i': | case 'i': | ||||
case 'I': | case 'I': | ||||
if ((s[1] == 'n' || s[1] == 'N') && (s[2] == 'f' || s[2] == 'F')) | |||||
if ((text[1] == 'n' || text[1] == 'N') && (text[2] == 'f' || text[2] == 'F')) | |||||
return std::numeric_limits<double>::infinity(); | return std::numeric_limits<double>::infinity(); | ||||
break; | break; | ||||
} | } | ||||
for (;;) | for (;;) | ||||
{ | { | ||||
if (s.isDigit()) | |||||
if (text.isDigit()) | |||||
{ | { | ||||
lastDigit = digit; | lastDigit = digit; | ||||
digit = s.getAndAdvance() - '0'; | |||||
digit = text.getAndAdvance() - '0'; | |||||
digitsFound = true; | digitsFound = true; | ||||
if (decPointIndex != 0) | if (decPointIndex != 0) | ||||
@@ -155,9 +155,9 @@ public: | |||||
else | else | ||||
exponentAdjustment[0]++; | exponentAdjustment[0]++; | ||||
while (s.isDigit()) | |||||
while (text.isDigit()) | |||||
{ | { | ||||
++s; | |||||
++text; | |||||
if (decPointIndex == 0) | if (decPointIndex == 0) | ||||
exponentAdjustment[0]++; | exponentAdjustment[0]++; | ||||
} | } | ||||
@@ -177,15 +177,15 @@ public: | |||||
exponentAccumulator [decPointIndex]++; | exponentAccumulator [decPointIndex]++; | ||||
} | } | ||||
} | } | ||||
else if (decPointIndex == 0 && *s == '.') | |||||
else if (decPointIndex == 0 && *text == '.') | |||||
{ | { | ||||
++s; | |||||
++text; | |||||
decPointIndex = 1; | decPointIndex = 1; | ||||
if (numSignificantDigits > maxSignificantDigits) | if (numSignificantDigits > maxSignificantDigits) | ||||
{ | { | ||||
while (s.isDigit()) | |||||
++s; | |||||
while (text.isDigit()) | |||||
++text; | |||||
break; | break; | ||||
} | } | ||||
} | } | ||||
@@ -200,19 +200,19 @@ public: | |||||
if (decPointIndex != 0) | if (decPointIndex != 0) | ||||
result[1] = mulexp10 (result[1], exponentAccumulator[1]) + accumulator[1]; | result[1] = mulexp10 (result[1], exponentAccumulator[1]) + accumulator[1]; | ||||
c = *s; | |||||
c = *text; | |||||
if ((c == 'e' || c == 'E') && digitsFound) | if ((c == 'e' || c == 'E') && digitsFound) | ||||
{ | { | ||||
bool negativeExponent = false; | bool negativeExponent = false; | ||||
switch (*++s) | |||||
switch (*++text) | |||||
{ | { | ||||
case '-': negativeExponent = true; // fall-through.. | case '-': negativeExponent = true; // fall-through.. | ||||
case '+': ++s; | |||||
case '+': ++text; | |||||
} | } | ||||
while (s.isDigit()) | |||||
exponent = (exponent * 10) + (s.getAndAdvance() - '0'); | |||||
while (text.isDigit()) | |||||
exponent = (exponent * 10) + (text.getAndAdvance() - '0'); | |||||
if (negativeExponent) | if (negativeExponent) | ||||
exponent = -exponent; | exponent = -exponent; | ||||
@@ -225,6 +225,13 @@ public: | |||||
return isNegative ? -r : r; | return isNegative ? -r : r; | ||||
} | } | ||||
template <typename CharPointerType> | |||||
static double getDoubleValue (const CharPointerType& text) throw() | |||||
{ | |||||
CharPointerType t (text); | |||||
return readDoubleValue (t); | |||||
} | |||||
//============================================================================== | //============================================================================== | ||||
template <typename IntType, typename CharPointerType> | template <typename IntType, typename CharPointerType> | ||||
static IntType getIntValue (const CharPointerType& text) throw() | static IntType getIntValue (const CharPointerType& text) throw() | ||||
@@ -522,6 +522,12 @@ int String::length() const throw() | |||||
return (int) text.length(); | return (int) text.length(); | ||||
} | } | ||||
const juce_wchar String::operator[] (int index) const throw() | |||||
{ | |||||
jassert (index == 0 || isPositiveAndNotGreaterThan (index, length())); | |||||
return text [index]; | |||||
} | |||||
int String::hashCode() const throw() | int String::hashCode() const throw() | ||||
{ | { | ||||
const juce_wchar* t = text; | const juce_wchar* t = text; | ||||
@@ -1449,13 +1455,6 @@ const String String::toLowerCase() const | |||||
} | } | ||||
//============================================================================== | //============================================================================== | ||||
juce_wchar& String::operator[] (const int index) | |||||
{ | |||||
jassert (isPositiveAndNotGreaterThan (index, length())); | |||||
text = StringHolder::makeUnique (text); | |||||
return text [index]; | |||||
} | |||||
juce_wchar String::getLastCharacter() const throw() | juce_wchar String::getLastCharacter() const throw() | ||||
{ | { | ||||
return isEmpty() ? juce_wchar() : text [length() - 1]; | return isEmpty() ? juce_wchar() : text [length() - 1]; | ||||
@@ -1564,18 +1563,16 @@ bool String::isQuotedString() const | |||||
const String String::unquoted() const | const String String::unquoted() const | ||||
{ | { | ||||
String s (*this); | |||||
if (s.text[0] == '"' || s.text[0] == '\'') | |||||
s = s.substring (1); | |||||
const int len = length(); | |||||
const int lastCharIndex = s.length() - 1; | |||||
if (len == 0) | |||||
return empty; | |||||
if (lastCharIndex >= 0 | |||||
&& (s [lastCharIndex] == '"' || s[lastCharIndex] == '\'')) | |||||
s [lastCharIndex] = 0; | |||||
const juce_wchar lastChar = text [len - 1]; | |||||
const int dropAtStart = (*text == '"' || *text == '\'') ? 1 : 0; | |||||
const int dropAtEnd = (lastChar == '"' || lastChar == '\'') ? 1 : 0; | |||||
return s; | |||||
return substring (dropAtStart, len - dropAtEnd); | |||||
} | } | ||||
const String String::quoted (const juce_wchar quoteCharacter) const | const String String::quoted (const juce_wchar quoteCharacter) const | ||||
@@ -1626,15 +1623,12 @@ const String String::trimStart() const | |||||
if (isEmpty()) | if (isEmpty()) | ||||
return empty; | return empty; | ||||
CharPointerType t (text); | |||||
while (t.isWhitespace()) | |||||
++t; | |||||
CharPointerType t (text.findEndOfWhitespace()); | |||||
if (t == text) | if (t == text) | ||||
return *this; | return *this; | ||||
return String (t.getAddress()); | |||||
return String (t); | |||||
} | } | ||||
const String String::trimEnd() const | const String String::trimEnd() const | ||||
@@ -2011,20 +2005,20 @@ const String String::createStringFromData (const void* const data_, const int si | |||||
result.preallocateStorage (numChars + 2); | result.preallocateStorage (numChars + 2); | ||||
const uint16* const src = (const uint16*) (data + 2); | const uint16* const src = (const uint16*) (data + 2); | ||||
juce_wchar* const dst = const_cast <juce_wchar*> (static_cast <const juce_wchar*> (result)); | |||||
CharPointerType dst (result.getCharPointer()); | |||||
if (bigEndian) | if (bigEndian) | ||||
{ | { | ||||
for (int i = 0; i < numChars; ++i) | for (int i = 0; i < numChars; ++i) | ||||
dst[i] = (juce_wchar) ByteOrder::swapIfLittleEndian (src[i]); | |||||
dst.write ((juce_wchar) ByteOrder::swapIfLittleEndian (src[i])); | |||||
} | } | ||||
else | else | ||||
{ | { | ||||
for (int i = 0; i < numChars; ++i) | for (int i = 0; i < numChars; ++i) | ||||
dst[i] = (juce_wchar) ByteOrder::swapIfBigEndian (src[i]); | |||||
dst.write ((juce_wchar) ByteOrder::swapIfBigEndian (src[i])); | |||||
} | } | ||||
dst [numChars] = 0; | |||||
dst.writeNull(); | |||||
return result; | return result; | ||||
} | } | ||||
else | else | ||||
@@ -550,16 +550,7 @@ public: | |||||
No checks are made to see if the index is within a valid range, so be careful! | No checks are made to see if the index is within a valid range, so be careful! | ||||
*/ | */ | ||||
inline const juce_wchar& operator[] (int index) const throw() { jassert (isPositiveAndNotGreaterThan (index, length())); return text [index]; } | |||||
/** Returns a character from the string such that it can also be altered. | |||||
This can be used as a way of easily changing characters in the string. | |||||
Note that the index passed-in is not checked to see whether it's in-range, so | |||||
be careful when using this. | |||||
*/ | |||||
juce_wchar& operator[] (int index); | |||||
const juce_wchar operator[] (int index) const throw(); | |||||
/** Returns the final character of the string. | /** Returns the final character of the string. | ||||
@@ -1011,16 +1002,7 @@ public: | |||||
that is returned must not be stored anywhere, as it can become invalid whenever | that is returned must not be stored anywhere, as it can become invalid whenever | ||||
any string methods (even some const ones!) are called. | any string methods (even some const ones!) are called. | ||||
*/ | */ | ||||
inline operator const juce_wchar*() const throw() { return text.getAddress(); } | |||||
//============================================================================== | |||||
/** Returns a unicode version of this string. | |||||
Because it returns a reference to the string's internal data, the pointer | |||||
that is returned must not be stored anywhere, as it can become invalid whenever | |||||
any string methods (even some const ones!) are called. | |||||
*/ | |||||
inline operator juce_wchar*() throw() { return text.getAddress(); } | |||||
inline operator const juce_wchar*() const throw() { return toUTF32().getAddress(); } | |||||
//============================================================================== | //============================================================================== | ||||
/** Returns the character pointer currently being used to store this string. | /** Returns the character pointer currently being used to store this string. | ||||
@@ -348,12 +348,15 @@ int StringArray::addTokens (const String& text, const String& breakCharacters, c | |||||
{ | { | ||||
bool insideQuotes = false; | bool insideQuotes = false; | ||||
juce_wchar currentQuoteChar = 0; | juce_wchar currentQuoteChar = 0; | ||||
int i = 0; | |||||
int tokenStart = 0; | |||||
String::CharPointerType t (text.getCharPointer()); | |||||
String::CharPointerType tokenStart (t); | |||||
int numChars = 0; | |||||
for (;;) | for (;;) | ||||
{ | { | ||||
const juce_wchar c = text[i]; | |||||
const juce_wchar c = t.getAndAdvance(); | |||||
++numChars; | |||||
const bool isBreak = (c == 0) || ((! insideQuotes) && breakCharacters.containsChar (c)); | const bool isBreak = (c == 0) || ((! insideQuotes) && breakCharacters.containsChar (c)); | ||||
@@ -377,16 +380,14 @@ int StringArray::addTokens (const String& text, const String& breakCharacters, c | |||||
} | } | ||||
else | else | ||||
{ | { | ||||
add (String (static_cast <const juce_wchar*> (text) + tokenStart, i - tokenStart)); | |||||
add (String (tokenStart, numChars - 1)); | |||||
++num; | ++num; | ||||
tokenStart = i + 1; | |||||
tokenStart = t; | |||||
numChars = 0; | |||||
} | } | ||||
if (c == 0) | if (c == 0) | ||||
break; | break; | ||||
++i; | |||||
} | } | ||||
} | } | ||||
@@ -396,41 +397,39 @@ int StringArray::addTokens (const String& text, const String& breakCharacters, c | |||||
int StringArray::addLines (const String& sourceText) | int StringArray::addLines (const String& sourceText) | ||||
{ | { | ||||
int numLines = 0; | int numLines = 0; | ||||
const juce_wchar* text = sourceText; | |||||
String::CharPointerType text (sourceText.getCharPointer()); | |||||
bool finished = text.isEmpty(); | |||||
while (*text != 0) | |||||
while (! finished) | |||||
{ | { | ||||
const juce_wchar* const startOfLine = text; | |||||
String::CharPointerType startOfLine (text); | |||||
int numChars = 0; | |||||
while (*text != 0) | |||||
for (;;) | |||||
{ | { | ||||
if (*text == '\r') | |||||
{ | |||||
++text; | |||||
if (*text == '\n') | |||||
++text; | |||||
const juce_wchar c = text.getAndAdvance(); | |||||
if (c == 0) | |||||
{ | |||||
finished = true; | |||||
break; | break; | ||||
} | } | ||||
if (*text == '\n') | |||||
if (c == '\n') | |||||
break; | |||||
if (c == '\r') | |||||
{ | { | ||||
++text; | |||||
if (*text == '\n') | |||||
++text; | |||||
break; | break; | ||||
} | } | ||||
++text; | |||||
++numChars; | |||||
} | } | ||||
const juce_wchar* endOfLine = text; | |||||
if (endOfLine > startOfLine && (*(endOfLine - 1) == '\r' || *(endOfLine - 1) == '\n')) | |||||
--endOfLine; | |||||
if (endOfLine > startOfLine && (*(endOfLine - 1) == '\r' || *(endOfLine - 1) == '\n')) | |||||
--endOfLine; | |||||
add (String (startOfLine, jmax (0, (int) (endOfLine - startOfLine)))); | |||||
add (String (startOfLine, numChars)); | |||||
++numLines; | ++numLines; | ||||
} | } | ||||
@@ -460,15 +459,15 @@ void StringArray::removeDuplicates (const bool ignoreCase) | |||||
void StringArray::appendNumbersToDuplicates (const bool ignoreCase, | void StringArray::appendNumbersToDuplicates (const bool ignoreCase, | ||||
const bool appendNumberToFirstInstance, | const bool appendNumberToFirstInstance, | ||||
const juce_wchar* preNumberString, | |||||
const juce_wchar* postNumberString) | |||||
CharPointer_UTF8 preNumberString, | |||||
CharPointer_UTF8 postNumberString) | |||||
{ | { | ||||
String defaultPre (" ("), defaultPost (")"); // (these aren't literals because of non-unicode literals on Android) | |||||
CharPointer_UTF8 defaultPre (" ("), defaultPost (")"); | |||||
if (preNumberString == 0) | |||||
if (preNumberString.getAddress() == 0) | |||||
preNumberString = defaultPre; | preNumberString = defaultPre; | ||||
if (postNumberString == 0) | |||||
if (postNumberString.getAddress() == 0) | |||||
postNumberString = defaultPost; | postNumberString = defaultPost; | ||||
for (int i = 0; i < size() - 1; ++i) | for (int i = 0; i < size() - 1; ++i) | ||||
@@ -484,13 +483,13 @@ void StringArray::appendNumbersToDuplicates (const bool ignoreCase, | |||||
int number = 0; | int number = 0; | ||||
if (appendNumberToFirstInstance) | if (appendNumberToFirstInstance) | ||||
s = original + preNumberString + String (++number) + postNumberString; | |||||
s = original + String (preNumberString) + String (++number) + String (postNumberString); | |||||
else | else | ||||
++number; | ++number; | ||||
while (nextIndex >= 0) | while (nextIndex >= 0) | ||||
{ | { | ||||
set (nextIndex, (*this)[nextIndex] + preNumberString + String (++number) + postNumberString); | |||||
set (nextIndex, (*this)[nextIndex] + String (preNumberString) + String (++number) + String (postNumberString)); | |||||
nextIndex = indexOf (original, ignoreCase, nextIndex + 1); | nextIndex = indexOf (original, ignoreCase, nextIndex + 1); | ||||
} | } | ||||
} | } | ||||
@@ -292,8 +292,8 @@ public: | |||||
*/ | */ | ||||
void appendNumbersToDuplicates (bool ignoreCaseWhenComparing, | void appendNumbersToDuplicates (bool ignoreCaseWhenComparing, | ||||
bool appendNumberToFirstInstance, | bool appendNumberToFirstInstance, | ||||
const juce_wchar* preNumberString = 0, | |||||
const juce_wchar* postNumberString = 0); | |||||
CharPointer_UTF8 preNumberString = CharPointer_UTF8 (0), | |||||
CharPointer_UTF8 postNumberString = CharPointer_UTF8 (0)); | |||||
//============================================================================== | //============================================================================== | ||||
/** Joins the strings in the array together into one string. | /** Joins the strings in the array together into one string. | ||||
@@ -37,7 +37,7 @@ StringPool::~StringPool() {} | |||||
namespace StringPoolHelpers | namespace StringPoolHelpers | ||||
{ | { | ||||
template <class StringType> | template <class StringType> | ||||
const juce_wchar* getPooledStringFromArray (Array<String>& strings, StringType newString) | |||||
const String::CharPointerType getPooledStringFromArray (Array<String>& strings, StringType newString) | |||||
{ | { | ||||
int start = 0; | int start = 0; | ||||
int end = strings.size(); | int end = strings.size(); | ||||
@@ -48,14 +48,14 @@ namespace StringPoolHelpers | |||||
{ | { | ||||
jassert (start <= end); | jassert (start <= end); | ||||
strings.insert (start, newString); | strings.insert (start, newString); | ||||
return strings.getReference (start); | |||||
return strings.getReference (start).getCharPointer(); | |||||
} | } | ||||
else | else | ||||
{ | { | ||||
const String& startString = strings.getReference (start); | const String& startString = strings.getReference (start); | ||||
if (startString == newString) | if (startString == newString) | ||||
return startString; | |||||
return startString.getCharPointer(); | |||||
const int halfway = (start + end) >> 1; | const int halfway = (start + end) >> 1; | ||||
@@ -65,13 +65,13 @@ namespace StringPoolHelpers | |||||
++start; | ++start; | ||||
strings.insert (start, newString); | strings.insert (start, newString); | ||||
return strings.getReference (start); | |||||
return strings.getReference (start).getCharPointer(); | |||||
} | } | ||||
const int comp = strings.getReference (halfway).compare (newString); | const int comp = strings.getReference (halfway).compare (newString); | ||||
if (comp == 0) | if (comp == 0) | ||||
return strings.getReference (halfway); | |||||
return strings.getReference (halfway).getCharPointer(); | |||||
else if (comp < 0) | else if (comp < 0) | ||||
start = halfway; | start = halfway; | ||||
else | else | ||||
@@ -81,26 +81,26 @@ namespace StringPoolHelpers | |||||
} | } | ||||
} | } | ||||
const juce_wchar* StringPool::getPooledString (const String& s) | |||||
const String::CharPointerType StringPool::getPooledString (const String& s) | |||||
{ | { | ||||
if (s.isEmpty()) | if (s.isEmpty()) | ||||
return String::empty; | |||||
return String::empty.getCharPointer(); | |||||
return StringPoolHelpers::getPooledStringFromArray (strings, s); | return StringPoolHelpers::getPooledStringFromArray (strings, s); | ||||
} | } | ||||
const juce_wchar* StringPool::getPooledString (const char* const s) | |||||
const String::CharPointerType StringPool::getPooledString (const char* const s) | |||||
{ | { | ||||
if (s == 0 || *s == 0) | if (s == 0 || *s == 0) | ||||
return String::empty; | |||||
return String::empty.getCharPointer(); | |||||
return StringPoolHelpers::getPooledStringFromArray (strings, s); | return StringPoolHelpers::getPooledStringFromArray (strings, s); | ||||
} | } | ||||
const juce_wchar* StringPool::getPooledString (const juce_wchar* const s) | |||||
const String::CharPointerType StringPool::getPooledString (const juce_wchar* const s) | |||||
{ | { | ||||
if (s == 0 || *s == 0) | if (s == 0 || *s == 0) | ||||
return String::empty; | |||||
return String::empty.getCharPointer(); | |||||
return StringPoolHelpers::getPooledStringFromArray (strings, s); | return StringPoolHelpers::getPooledStringFromArray (strings, s); | ||||
} | } | ||||
@@ -112,7 +112,7 @@ int StringPool::size() const throw() | |||||
const juce_wchar* StringPool::operator[] (const int index) const throw() | const juce_wchar* StringPool::operator[] (const int index) const throw() | ||||
{ | { | ||||
return strings [index]; | |||||
return strings [index].getCharPointer(); | |||||
} | } | ||||
END_JUCE_NAMESPACE | END_JUCE_NAMESPACE |
@@ -58,7 +58,7 @@ public: | |||||
The pool will own all the pointers that it returns, deleting them when the pool itself | The pool will own all the pointers that it returns, deleting them when the pool itself | ||||
is deleted. | is deleted. | ||||
*/ | */ | ||||
const juce_wchar* getPooledString (const String& original); | |||||
const String::CharPointerType getPooledString (const String& original); | |||||
/** Returns a pointer to a copy of the string that is passed in. | /** Returns a pointer to a copy of the string that is passed in. | ||||
@@ -66,7 +66,7 @@ public: | |||||
The pool will own all the pointers that it returns, deleting them when the pool itself | The pool will own all the pointers that it returns, deleting them when the pool itself | ||||
is deleted. | is deleted. | ||||
*/ | */ | ||||
const juce_wchar* getPooledString (const char* original); | |||||
const String::CharPointerType getPooledString (const char* original); | |||||
/** Returns a pointer to a copy of the string that is passed in. | /** Returns a pointer to a copy of the string that is passed in. | ||||
@@ -74,7 +74,7 @@ public: | |||||
The pool will own all the pointers that it returns, deleting them when the pool itself | The pool will own all the pointers that it returns, deleting them when the pool itself | ||||
is deleted. | is deleted. | ||||
*/ | */ | ||||
const juce_wchar* getPooledString (const juce_wchar* original); | |||||
const String::CharPointerType getPooledString (const juce_wchar* original); | |||||
//============================================================================== | //============================================================================== | ||||
/** Returns the number of strings in the pool. */ | /** Returns the number of strings in the pool. */ | ||||
@@ -47,8 +47,8 @@ XmlElement::XmlAttributeNode::XmlAttributeNode (const String& name_, const Strin | |||||
{ | { | ||||
#if JUCE_DEBUG | #if JUCE_DEBUG | ||||
// this checks whether the attribute name string contains any illegal characters.. | // this checks whether the attribute name string contains any illegal characters.. | ||||
for (const juce_wchar* t = name; *t != 0; ++t) | |||||
jassert (CharacterFunctions::isLetterOrDigit (*t) || *t == '_' || *t == '-' || *t == ':'); | |||||
for (String::CharPointerType t (name.getCharPointer()); ! t.isEmpty(); ++t) | |||||
jassert (t.isLetterOrDigit() || *t == '_' || *t == '-' || *t == ':'); | |||||
#endif | #endif | ||||
} | } | ||||
@@ -155,16 +155,16 @@ namespace XmlOutputFunctions | |||||
void escapeIllegalXmlChars (OutputStream& outputStream, const String& text, const bool changeNewLines) | void escapeIllegalXmlChars (OutputStream& outputStream, const String& text, const bool changeNewLines) | ||||
{ | { | ||||
const juce_wchar* t = text; | |||||
String::CharPointerType t (text.getCharPointer()); | |||||
for (;;) | for (;;) | ||||
{ | { | ||||
const juce_wchar character = *t++; | |||||
const uint32 character = (uint32) t.getAndAdvance(); | |||||
if (character == 0) | if (character == 0) | ||||
break; | break; | ||||
if (isLegalXmlChar ((uint32) character)) | |||||
if (isLegalXmlChar (character)) | |||||
{ | { | ||||
outputStream << (char) character; | outputStream << (char) character; | ||||
} | } | ||||
@@ -186,7 +186,7 @@ namespace XmlOutputFunctions | |||||
} | } | ||||
// Note: deliberate fall-through here! | // Note: deliberate fall-through here! | ||||
default: | default: | ||||
outputStream << "&#" << ((int) (unsigned int) character) << ';'; | |||||
outputStream << "&#" << ((int) character) << ';'; | |||||
break; | break; | ||||
} | } | ||||
} | } | ||||