[Glacier] Add a specific VariableStringBuilder for StrFormat.

This commit is contained in:
Drew Galbraith 2023-11-09 08:52:30 -08:00
parent a745f45b5d
commit 601f29c324
6 changed files with 58 additions and 24 deletions

View File

@ -59,10 +59,15 @@ void StrFormatInternal(StringBuilder& builder, StringView format, T value,
} }
template <typename... Args> template <typename... Args>
StringBuilder StrFormat(StringView format, Args... args) { String StrFormat(StringView format, Args... args) {
StringBuilder builder; VariableStringBuilder builder;
StrFormatInternal(builder, format, args...);
return builder.ToString();
}
template <typename... Args>
void StrFormat(StringBuilder& builder, StringView format, Args... args) {
StrFormatInternal(builder, format, args...); StrFormatInternal(builder, format, args...);
return glcr::Move(builder);
} }
} // namespace glcr } // namespace glcr

View File

@ -2,23 +2,29 @@
namespace glcr { namespace glcr {
void StringBuilder::PushBack(const StringView& str) { uint64_t VariableStringBuilder::size() const { return data_.size(); }
if (capacity() < size() + str.size()) {
uint64_t new_capacity = capacity() == 0 ? 1 : capacity() * 2; 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()) { while (new_capacity < size() + str.size()) {
new_capacity *= 2; new_capacity *= 2;
} }
Resize(new_capacity); data_.Resize(new_capacity);
} }
for (uint64_t i = 0; i < str.size(); i++) { for (uint64_t i = 0; i < str.size(); i++) {
Vector<char>::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 { String VariableStringBuilder::ToString() const {
return StringView(RawPtr(), size()); return String(data_.RawPtr(), size());
}
VariableStringBuilder::operator StringView() const {
return StringView(data_.RawPtr(), size());
} }
} // namespace glcr } // namespace glcr

View File

@ -6,21 +6,39 @@
namespace glcr { namespace glcr {
class StringBuilder : public Vector<char> { class StringBuilder {
public: public:
StringBuilder() : Vector<char>() {} virtual uint64_t size() const = 0;
StringBuilder(const StringBuilder&) = delete; virtual void PushBack(const StringView& str) = 0;
StringBuilder(StringBuilder&& str) : Vector<char>(Move(str)) {} virtual void PushBack(const char str) = 0;
void PushBack(const StringView& str); virtual String ToString() const = 0;
using Vector<char>::PushBack;
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 // Note that this could become invalidated
// at any time if more characters are pushed // at any time if more characters are pushed
// onto the builder. // onto the builder.
operator StringView() const; virtual operator StringView() const override;
private:
Vector<char> data_;
}; };
} // namespace glcr } // namespace glcr

View File

@ -6,7 +6,7 @@
#include <ztypes.h> #include <ztypes.h>
// TODO: Take StringView here instead. // TODO: Take StringView here instead.
void dbgln(const glcr::StringBuilder& builder); void dbgln(const glcr::String& string);
template <typename... Args> template <typename... Args>
void dbgln(const glcr::StringView& fmt, Args... args) { void dbgln(const glcr::StringView& fmt, Args... args) {

View File

@ -3,10 +3,7 @@
#include <glacier/status/error.h> #include <glacier/status/error.h>
#include <zcall.h> #include <zcall.h>
void dbgln(const glcr::StringBuilder& builder) { void dbgln(const glcr::String& string) { (void)ZDebug(string.cstr()); }
glcr::String str = builder.ToString();
(void)ZDebug(str.cstr());
}
void check(uint64_t code) { void check(uint64_t code) {
switch (code) { switch (code) {

View File

@ -11,6 +11,14 @@ void early_dbgln(const char* str);
void dbgln(const glcr::StringView& 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 <typename... Args> template <typename... Args>
void dbgln(const char* str, Args... args) { void dbgln(const char* str, Args... args) {
dbgln(glcr::StrFormat(str, args...)); dbgln(glcr::StrFormat(str, args...));