diff --git a/modules/juce_core/text/juce_String.cpp b/modules/juce_core/text/juce_String.cpp index 77845db9ba..11d367926f 100644 --- a/modules/juce_core/text/juce_String.cpp +++ b/modules/juce_core/text/juce_String.cpp @@ -684,23 +684,28 @@ String& String::operator+= (const juce_wchar ch) String& String::operator+= (const int number) { char buffer [16]; - char* const end = buffer + numElementsInArray (buffer); - char* const start = NumberToStringConverters::numberToString (end, number); + char* end = buffer + numElementsInArray (buffer); + char* start = NumberToStringConverters::numberToString (end, number); - const int numExtraChars = (int) (end - start); + #if (JUCE_STRING_UTF_TYPE == 8) + appendCharPointer (CharPointerType (start), CharPointerType (end)); + #else + appendCharPointer (CharPointer_ASCII (start), CharPointer_ASCII (end)); + #endif + return *this; +} - if (numExtraChars > 0) - { - const size_t byteOffsetOfNull = getByteOffsetOfEnd(); - const size_t newBytesNeeded = sizeof (CharPointerType::CharType) + byteOffsetOfNull - + sizeof (CharPointerType::CharType) * (size_t) numExtraChars; - - text = StringHolder::makeUniqueWithByteSize (text, newBytesNeeded); - - CharPointerType newEnd (addBytesToPointer (text.getAddress(), (int) byteOffsetOfNull)); - newEnd.writeWithCharLimit (CharPointer_ASCII (start), numExtraChars); - } +String& String::operator+= (int64 number) +{ + char buffer [32]; + char* end = buffer + numElementsInArray (buffer); + char* start = NumberToStringConverters::numberToString (end, number); + #if (JUCE_STRING_UTF_TYPE == 8) + appendCharPointer (CharPointerType (start), CharPointerType (end)); + #else + appendCharPointer (CharPointer_ASCII (start), CharPointer_ASCII (end)); + #endif return *this; } @@ -737,6 +742,7 @@ JUCE_API String& JUCE_CALLTYPE operator<< (String& s1, const long number) JUCE_API String& JUCE_CALLTYPE operator<< (String& s1, const int64 number) { return s1 += String (number); } JUCE_API String& JUCE_CALLTYPE operator<< (String& s1, const float number) { return s1 += String (number); } JUCE_API String& JUCE_CALLTYPE operator<< (String& s1, const double number) { return s1 += String (number); } +JUCE_API String& JUCE_CALLTYPE operator<< (String& s1, const uint64 number) { return s1 += String (number); } JUCE_API OutputStream& JUCE_CALLTYPE operator<< (OutputStream& stream, const String& text) { @@ -2192,6 +2198,10 @@ public: s2 << ((int) 4) << ((short) 5) << "678" << L"9" << '0'; s2 += "xyz"; expect (s2 == "1234567890xyz"); + s2 += (int) 123; + expect (s2 == "1234567890xyz123"); + s2 += (int64) 123; + expect (s2 == "1234567890xyz123123"); beginTest ("Numeric conversions"); expect (String::empty.getIntValue() == 0); diff --git a/modules/juce_core/text/juce_String.h b/modules/juce_core/text/juce_String.h index 23ed308afa..c760239be0 100644 --- a/modules/juce_core/text/juce_String.h +++ b/modules/juce_core/text/juce_String.h @@ -204,6 +204,8 @@ public: String& operator+= (const wchar_t* textToAppend); /** Appends a decimal number at the end of this string. */ String& operator+= (int numberToAppend); + /** Appends a decimal number at the end of this string. */ + String& operator+= (int64 numberToAppend); /** Appends a character at the end of this string. */ String& operator+= (char characterToAppend); /** Appends a character at the end of this string. */ @@ -228,6 +230,32 @@ public: void appendCharPointer (const CharPointerType startOfTextToAppend, const CharPointerType endOfTextToAppend); + /** 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 + */ + template + void appendCharPointer (const CharPointer startOfTextToAppend, + const CharPointer endOfTextToAppend) + { + jassert (startOfTextToAppend.getAddress() != nullptr && endOfTextToAppend.getAddress() != nullptr); + + size_t extraBytesNeeded = 0, numChars = 1; + + for (CharPointer t (startOfTextToAppend); t != endOfTextToAppend && ! t.isEmpty(); ++numChars) + extraBytesNeeded += CharPointerType::getBytesRequiredFor (t.getAndAdvance()); + + if (extraBytesNeeded > 0) + { + const size_t byteOffsetOfNull = getByteOffsetOfEnd(); + + preallocateBytes (byteOffsetOfNull + extraBytesNeeded); + CharPointerType (addBytesToPointer (text.getAddress(), (int) byteOffsetOfNull)) + .writeWithCharLimit (startOfTextToAppend, (int) numChars); + } + } + /** Appends a string to the end of this one. */ void appendCharPointer (const CharPointerType textToAppend); @@ -241,21 +269,18 @@ public: { if (textToAppend.getAddress() != nullptr) { - size_t extraBytesNeeded = 0; - size_t numChars = 0; + size_t extraBytesNeeded = 0, numChars = 1; - for (CharPointer t (textToAppend); numChars < maxCharsToTake && ! t.isEmpty();) - { + for (CharPointer t (textToAppend); numChars <= maxCharsToTake && ! t.isEmpty(); ++numChars) extraBytesNeeded += CharPointerType::getBytesRequiredFor (t.getAndAdvance()); - ++numChars; - } - if (numChars > 0) + if (extraBytesNeeded > 0) { const size_t byteOffsetOfNull = getByteOffsetOfEnd(); preallocateBytes (byteOffsetOfNull + extraBytesNeeded); - CharPointerType (addBytesToPointer (text.getAddress(), (int) byteOffsetOfNull)).writeWithCharLimit (textToAppend, (int) (numChars + 1)); + CharPointerType (addBytesToPointer (text.getAddress(), (int) byteOffsetOfNull)) + .writeWithCharLimit (textToAppend, (int) numChars); } } } @@ -264,21 +289,7 @@ public: template void appendCharPointer (const CharPointer textToAppend) { - if (textToAppend.getAddress() != nullptr) - { - size_t extraBytesNeeded = 0; - - for (CharPointer t (textToAppend); ! t.isEmpty();) - extraBytesNeeded += CharPointerType::getBytesRequiredFor (t.getAndAdvance()); - - if (extraBytesNeeded > 0) - { - const size_t byteOffsetOfNull = getByteOffsetOfEnd(); - - preallocateBytes (byteOffsetOfNull + extraBytesNeeded); - CharPointerType (addBytesToPointer (text.getAddress(), (int) byteOffsetOfNull)).writeAll (textToAppend); - } - } + appendCharPointer (textToAppend, std::numeric_limits::max()); } //============================================================================== @@ -1216,7 +1227,6 @@ private: }; explicit String (const PreallocationBytes&); // This constructor preallocates a certain amount of memory - void appendFixedLength (const char* text, int numExtraChars); size_t getByteOffsetOfEnd() const noexcept; JUCE_DEPRECATED (String (const String&, size_t));