Skip to content

Commit

Permalink
CreateString and FormatString: No longer needs or uses the max_size
Browse files Browse the repository at this point in the history
… argument

This improvement handles the size automatically, no need to specify this manually anymore. Public API will be changed in a follow-up.
  • Loading branch information
mikke89 committed Jul 7, 2024
1 parent 6a8385f commit 0f8c707
Show file tree
Hide file tree
Showing 2 changed files with 63 additions and 18 deletions.
48 changes: 30 additions & 18 deletions Source/Core/StringUtilities.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -37,23 +37,36 @@

namespace Rml {

static int FormatString(String& string, size_t max_size, const char* format, va_list argument_list)
static int FormatString(String& string, const char* format, va_list argument_list)
{
const int INTERNAL_BUFFER_SIZE = 1024;
static char buffer[INTERNAL_BUFFER_SIZE];
constexpr size_t InternalBufferSize = 256;
char buffer[InternalBufferSize];
char* buffer_ptr = buffer;

if (max_size + 1 > INTERNAL_BUFFER_SIZE)
buffer_ptr = new char[max_size + 1];
size_t max_size = InternalBufferSize;
int length = 0;

int length = vsnprintf(buffer_ptr, max_size, format, argument_list);
buffer_ptr[length >= 0 ? length : max_size] = '\0';
#ifdef RMLUI_DEBUG
if (length == -1)
for (int i = 0; i < 2; i++)
{
Log::Message(Log::LT_WARNING, "FormatString: String truncated to %zu bytes when processing %s", max_size, format);
va_list argument_list_copy;
va_copy(argument_list_copy, argument_list);

length = vsnprintf(buffer_ptr, max_size, format, argument_list_copy);

va_end(argument_list_copy);

if (length < 0)
{
RMLUI_ERRORMSG("Error while formatting string");
return 0;
}

if ((size_t)length < max_size || i > 0)
break;

max_size = (size_t)length + 1;
buffer_ptr = new char[max_size];
}
#endif

string = buffer_ptr;

Expand All @@ -63,21 +76,20 @@ static int FormatString(String& string, size_t max_size, const char* format, va_
return length;
}

int FormatString(String& string, size_t max_size, const char* format, ...)
int FormatString(String& string, size_t /*max_size*/, const char* format, ...)
{
va_list argument_list;
va_start(argument_list, format);
int result = FormatString(string, (int)max_size, format, argument_list);
int result = FormatString(string, format, argument_list);
va_end(argument_list);
return result;
}
String CreateString(size_t max_size, const char* format, ...)
String CreateString(size_t /*max_size*/, const char* format, ...)
{
String result;
result.reserve(max_size);
va_list argument_list;
va_start(argument_list, format);
FormatString(result, max_size, format, argument_list);
FormatString(result, format, argument_list);
va_end(argument_list);
return result;
}
Expand Down Expand Up @@ -164,7 +176,7 @@ String StringUtilities::DecodeRml(const String& s)
size_t j = 0;
for (; j < 8; j++)
{
auto const& c = s[start + j];
const auto& c = s[start + j];
if (!((c >= '0' && c <= '9') || (c >= 'a' && c <= 'f') || (c >= 'A' && c <= 'F')))
break;
}
Expand All @@ -188,7 +200,7 @@ String StringUtilities::DecodeRml(const String& s)
size_t j = 0;
for (; j < 8; j++)
{
auto const& c = s[start + j];
const auto& c = s[start + j];
if (!(c >= '0' && c <= '9'))
break;
}
Expand Down
33 changes: 33 additions & 0 deletions Tests/Source/UnitTests/StringUtilities.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -148,3 +148,36 @@ TEST_CASE("StringUtilities::ConvertCharacterOffsetToByteOffset")
CHECK(ConvertCharacterOffsetToByteOffset("a\xE2\x82\xAC" "b", 4) == 5);
// clang-format on
}

TEST_CASE("CreateString")
{
CHECK(Rml::CreateString(0, "Hello %s!", "world") == "Hello world!");
CHECK(Rml::CreateString(0, "%g, %d, %.2f", 0.5f, 5, 2.f) == "0.5, 5, 2.00");

constexpr int InternalBufferSize = 256;
for (int string_size : {InternalBufferSize - 1, InternalBufferSize, InternalBufferSize + 1})
{
Rml::String large_string(string_size, 'x');
CHECK(Rml::CreateString(0, "%s", large_string.c_str()) == large_string);
}
}

TEST_CASE("FormatString")
{
{
Rml::String result;
int length = Rml::FormatString(result, 0, "Hello %s!", "world");
CHECK(result == "Hello world!");
CHECK(length == 12);
}

constexpr int InternalBufferSize = 256;
for (int string_size : {InternalBufferSize - 1, InternalBufferSize, InternalBufferSize + 1})
{
const Rml::String large_string(string_size, 'x');
Rml::String result;
int length = Rml::FormatString(result, 0, "%s", large_string.c_str());
CHECK(result == large_string);
CHECK(length == string_size);
}
}

0 comments on commit 0f8c707

Please sign in to comment.