| @@ -605,6 +605,30 @@ void String::append (const String& textToAppend, size_t maxCharsToTake) | |||||
| appendCharPointer (textToAppend.text, maxCharsToTake); | appendCharPointer (textToAppend.text, maxCharsToTake); | ||||
| } | } | ||||
| void String::appendCharPointer (const CharPointerType textToAppend) | |||||
| { | |||||
| appendCharPointer (textToAppend, textToAppend.findTerminatingNull()); | |||||
| } | |||||
| void String::appendCharPointer (const CharPointerType startOfTextToAppend, | |||||
| const CharPointerType endOfTextToAppend) | |||||
| { | |||||
| jassert (startOfTextToAppend.getAddress() != nullptr && endOfTextToAppend.getAddress() != nullptr); | |||||
| jassert (startOfTextToAppend.getAddress() <= endOfTextToAppend.getAddress()); | |||||
| const size_t extraBytesNeeded = endOfTextToAppend.getAddress() - startOfTextToAppend.getAddress(); | |||||
| if (extraBytesNeeded > 0) | |||||
| { | |||||
| const size_t byteOffsetOfNull = getByteOffsetOfEnd(); | |||||
| preallocateBytes (byteOffsetOfNull + extraBytesNeeded); | |||||
| char* const newStringStart = addBytesToPointer (text.getAddress(), (int) byteOffsetOfNull); | |||||
| memcpy (newStringStart, startOfTextToAppend.getAddress(), extraBytesNeeded); | |||||
| CharPointerType (newStringStart + extraBytesNeeded).writeNull(); | |||||
| } | |||||
| } | |||||
| String& String::operator+= (const wchar_t* const t) | String& String::operator+= (const wchar_t* const t) | ||||
| { | { | ||||
| appendCharPointer (castToCharPointer_wchar_t (t)); | appendCharPointer (castToCharPointer_wchar_t (t)); | ||||
| @@ -628,7 +652,7 @@ String& String::operator+= (const char* const t) | |||||
| */ | */ | ||||
| jassert (t == nullptr || CharPointer_ASCII::isValidString (t, std::numeric_limits<int>::max())); | jassert (t == nullptr || CharPointer_ASCII::isValidString (t, std::numeric_limits<int>::max())); | ||||
| appendCharPointer (CharPointer_ASCII (t)); | |||||
| appendCharPointer (CharPointer_UTF8 (t)); // (using UTF8 here triggers a faster code-path than ascii) | |||||
| return *this; | return *this; | ||||
| } | } | ||||
| @@ -217,6 +217,17 @@ public: | |||||
| */ | */ | ||||
| void append (const String& textToAppend, size_t maxCharsToTake); | void append (const String& textToAppend, size_t maxCharsToTake); | ||||
| /** Appends a string to the end of this one. | |||||
| @param startOfTextToAppend the start of the string to add. This must not be a nullptr | |||||
| @param endOfTextToAppend the end of the string to add. This must not be a nullptr | |||||
| */ | |||||
| void appendCharPointer (const CharPointerType startOfTextToAppend, | |||||
| const CharPointerType endOfTextToAppend); | |||||
| /** Appends a string to the end of this one. */ | |||||
| void appendCharPointer (const CharPointerType textToAppend); | |||||
| /** Appends a string to the end of this one. | /** Appends a string to the end of this one. | ||||
| @param textToAppend the string to add | @param textToAppend the string to add | ||||
| @@ -326,7 +326,6 @@ void XmlDocument::readQuotedString (String& result) | |||||
| else | else | ||||
| { | { | ||||
| const String::CharPointerType start (input); | const String::CharPointerType start (input); | ||||
| size_t numChars = 0; | |||||
| for (;;) | for (;;) | ||||
| { | { | ||||
| @@ -334,13 +333,13 @@ void XmlDocument::readQuotedString (String& result) | |||||
| if (character == quote) | if (character == quote) | ||||
| { | { | ||||
| result.appendCharPointer (start, numChars); | |||||
| result.appendCharPointer (start, input); | |||||
| ++input; | ++input; | ||||
| return; | return; | ||||
| } | } | ||||
| else if (character == '&') | else if (character == '&') | ||||
| { | { | ||||
| result.appendCharPointer (start, numChars); | |||||
| result.appendCharPointer (start, input); | |||||
| break; | break; | ||||
| } | } | ||||
| else if (character == 0) | else if (character == 0) | ||||
| @@ -351,7 +350,6 @@ void XmlDocument::readQuotedString (String& result) | |||||
| } | } | ||||
| ++input; | ++input; | ||||
| ++numChars; | |||||
| } | } | ||||
| } | } | ||||
| } | } | ||||
| @@ -582,17 +580,15 @@ void XmlDocument::readChildElements (XmlElement* parent) | |||||
| else | else | ||||
| { | { | ||||
| const String::CharPointerType start (input); | const String::CharPointerType start (input); | ||||
| size_t len = 0; | |||||
| for (;;) | for (;;) | ||||
| { | { | ||||
| const juce_wchar nextChar = *input; | const juce_wchar nextChar = *input; | ||||
| if (nextChar == '<' || nextChar == '&') | if (nextChar == '<' || nextChar == '&') | ||||
| { | |||||
| break; | break; | ||||
| } | |||||
| else if (nextChar == 0) | |||||
| if (nextChar == 0) | |||||
| { | { | ||||
| setLastError ("unmatched tags", false); | setLastError ("unmatched tags", false); | ||||
| outOfData = true; | outOfData = true; | ||||
| @@ -600,17 +596,14 @@ void XmlDocument::readChildElements (XmlElement* parent) | |||||
| } | } | ||||
| ++input; | ++input; | ||||
| ++len; | |||||
| } | } | ||||
| textElementContent.appendCharPointer (start, len); | |||||
| textElementContent.appendCharPointer (start, input); | |||||
| } | } | ||||
| } | } | ||||
| if ((! ignoreEmptyTextElements) || textElementContent.containsNonWhitespaceChars()) | if ((! ignoreEmptyTextElements) || textElementContent.containsNonWhitespaceChars()) | ||||
| { | |||||
| childAppender.append (XmlElement::createTextElement (textElementContent)); | childAppender.append (XmlElement::createTextElement (textElementContent)); | ||||
| } | |||||
| } | } | ||||
| } | } | ||||
| } | } | ||||