diff --git a/lib/glacier/string/str_format.h b/lib/glacier/string/str_format.h index 3ce86bc..ca00e3e 100644 --- a/lib/glacier/string/str_format.h +++ b/lib/glacier/string/str_format.h @@ -59,10 +59,15 @@ void StrFormatInternal(StringBuilder& builder, StringView format, T value, } template -StringBuilder StrFormat(StringView format, Args... args) { - StringBuilder builder; +String StrFormat(StringView format, Args... args) { + VariableStringBuilder builder; + StrFormatInternal(builder, format, args...); + return builder.ToString(); +} + +template +void StrFormat(StringBuilder& builder, StringView format, Args... args) { StrFormatInternal(builder, format, args...); - return glcr::Move(builder); } } // namespace glcr diff --git a/lib/glacier/string/string_builder.cpp b/lib/glacier/string/string_builder.cpp index aa4d2d5..3b75e86 100644 --- a/lib/glacier/string/string_builder.cpp +++ b/lib/glacier/string/string_builder.cpp @@ -2,23 +2,29 @@ namespace glcr { -void StringBuilder::PushBack(const StringView& str) { - if (capacity() < size() + str.size()) { - uint64_t new_capacity = capacity() == 0 ? 1 : capacity() * 2; +uint64_t VariableStringBuilder::size() const { return data_.size(); } + +void VariableStringBuilder::PushBack(const StringView& str) { + if (data_.capacity() < size() + str.size()) { + uint64_t new_capacity = data_.capacity() == 0 ? 1 : data_.capacity() * 2; while (new_capacity < size() + str.size()) { new_capacity *= 2; } - Resize(new_capacity); + data_.Resize(new_capacity); } for (uint64_t i = 0; i < str.size(); i++) { - Vector::PushBack(str[i]); + data_.PushBack(str[i]); } } -String StringBuilder::ToString() const { return String(RawPtr(), size()); } +void VariableStringBuilder::PushBack(const char str) { data_.PushBack(str); } -StringBuilder::operator StringView() const { - return StringView(RawPtr(), size()); +String VariableStringBuilder::ToString() const { + return String(data_.RawPtr(), size()); +} + +VariableStringBuilder::operator StringView() const { + return StringView(data_.RawPtr(), size()); } } // namespace glcr diff --git a/lib/glacier/string/string_builder.h b/lib/glacier/string/string_builder.h index 6e31bcb..2342033 100644 --- a/lib/glacier/string/string_builder.h +++ b/lib/glacier/string/string_builder.h @@ -6,21 +6,39 @@ namespace glcr { -class StringBuilder : public Vector { +class StringBuilder { public: - StringBuilder() : Vector() {} - StringBuilder(const StringBuilder&) = delete; - StringBuilder(StringBuilder&& str) : Vector(Move(str)) {} + virtual uint64_t size() const = 0; + virtual void PushBack(const StringView& str) = 0; + virtual void PushBack(const char str) = 0; - void PushBack(const StringView& str); - using Vector::PushBack; + virtual String ToString() const = 0; - String ToString() const; + virtual operator StringView() const = 0; +}; + +class VariableStringBuilder : public StringBuilder { + public: + VariableStringBuilder() = default; + VariableStringBuilder(const VariableStringBuilder&) = delete; + VariableStringBuilder(VariableStringBuilder&&) = default; + + ~VariableStringBuilder() = default; + + virtual uint64_t size() const override; + + virtual void PushBack(const StringView& str) override; + virtual void PushBack(const char str) override; + + virtual String ToString() const override; // Note that this could become invalidated // at any time if more characters are pushed // onto the builder. - operator StringView() const; + virtual operator StringView() const override; + + private: + Vector data_; }; } // namespace glcr diff --git a/lib/mammoth/include/mammoth/debug.h b/lib/mammoth/include/mammoth/debug.h index 6cbc7d5..f06bf99 100644 --- a/lib/mammoth/include/mammoth/debug.h +++ b/lib/mammoth/include/mammoth/debug.h @@ -6,7 +6,7 @@ #include // TODO: Take StringView here instead. -void dbgln(const glcr::StringBuilder& builder); +void dbgln(const glcr::String& string); template void dbgln(const glcr::StringView& fmt, Args... args) { diff --git a/lib/mammoth/src/debug.cpp b/lib/mammoth/src/debug.cpp index f415ca2..337580c 100644 --- a/lib/mammoth/src/debug.cpp +++ b/lib/mammoth/src/debug.cpp @@ -3,10 +3,7 @@ #include #include -void dbgln(const glcr::StringBuilder& builder) { - glcr::String str = builder.ToString(); - (void)ZDebug(str.cstr()); -} +void dbgln(const glcr::String& string) { (void)ZDebug(string.cstr()); } void check(uint64_t code) { switch (code) { diff --git a/zion/debug/debug.h b/zion/debug/debug.h index c2fa9cc..aeace6f 100644 --- a/zion/debug/debug.h +++ b/zion/debug/debug.h @@ -11,6 +11,14 @@ void early_dbgln(const char* str); void dbgln(const glcr::StringView& str); +// TODO: Write a version of StrFormat that +// accepts a fix-sized buffer for output +// to use in the kernel. That way we make +// dbgln and panic calls without allocation. +// Optionally, add a dbgln_unbounded method for +// things like the Debug syscall where the formatted +// string may be fairly large. + template void dbgln(const char* str, Args... args) { dbgln(glcr::StrFormat(str, args...));