diff --git a/libluna/include/luna/String.h b/libluna/include/luna/String.h index 6fd22e94..7b22c4ea 100644 --- a/libluna/include/luna/String.h +++ b/libluna/include/luna/String.h @@ -1,6 +1,7 @@ #pragma once #include #include +#include class String { @@ -22,6 +23,9 @@ class String Result substring(usize begin, usize size) const; + static Result format(const String& fmt, ...); + static Result format(StringView fmt, ...); + static Result from_cstring(const char* str); const char* chars() const @@ -75,4 +79,6 @@ class String bool m_inline { true }; usize m_length { 0 }; + + static Result vformat(StringView fmt, va_list ap); }; diff --git a/libluna/include/luna/Units.h b/libluna/include/luna/Units.h index 3872c7ac..dccc8010 100644 --- a/libluna/include/luna/Units.h +++ b/libluna/include/luna/Units.h @@ -2,5 +2,4 @@ #include #include -usize to_dynamic_unit_cstr(usize value, char* buffer, usize max); Result to_dynamic_unit(usize value); diff --git a/libluna/src/String.cpp b/libluna/src/String.cpp index ec99bde1..3d0fc465 100644 --- a/libluna/src/String.cpp +++ b/libluna/src/String.cpp @@ -1,6 +1,8 @@ #include #include +#include #include +#include String::String() { @@ -61,6 +63,43 @@ const char& String::operator[](usize index) const return chars()[index]; } +Result String::format(const String& fmt, ...) +{ + va_list ap; + va_start(ap, fmt); + + auto rc = vformat(fmt.view(), ap); + + va_end(ap); + + return rc; +} + +Result String::format(StringView fmt, ...) +{ + va_list ap; + va_start(ap, fmt); + + auto rc = vformat(fmt, ap); + + va_end(ap); + + return rc; +} + +Result String::vformat(StringView fmt, va_list ap) +{ + Vector buf; + + TRY(cstyle_format( + fmt.chars(), [](char c, void* data) -> Result { return ((Vector*)data)->try_append(c); }, &buf, + ap)); + + TRY(buf.try_append(0)); + + return from_cstring(buf.data()); +} + Result String::from_cstring(const char* str) { usize len = strlen(str); diff --git a/libluna/src/Units.cpp b/libluna/src/Units.cpp index 19e79847..fd05f853 100644 --- a/libluna/src/Units.cpp +++ b/libluna/src/Units.cpp @@ -1,12 +1,11 @@ #include -#include #include #include #include -usize to_dynamic_unit_cstr(usize value, char* buffer, usize max) +Result to_dynamic_unit(usize value) { - if (value < 1024) { return string_format(buffer, max, "%zu bytes", value); } + if (value < 1024) { return String::format("%zu bytes"_sv, value); } const char* unit_prefixes = "KMGTPE"; while (value > (1024 * 1024)) @@ -15,14 +14,5 @@ usize to_dynamic_unit_cstr(usize value, char* buffer, usize max) unit_prefixes++; } - return string_format(buffer, max, "%zu.%zu %ciB", value / 1024, (value % 1024) / 103, *unit_prefixes); -} - -Result to_dynamic_unit(usize value) -{ - char* const buf = TRY(make_array(64)); - - to_dynamic_unit_cstr(value, buf, 64); - - return String { buf }; + return String::format("%zu.%zu %ciB"_sv, value / 1024, (value % 1024) / 103, *unit_prefixes); }