From 3320960992afe36f4b6306130c6327e084c381b2 Mon Sep 17 00:00:00 2001 From: Steven Le Rouzic Date: Thu, 4 Apr 2024 18:37:13 +0200 Subject: Add format --- deimos/core/format.cpp | 83 ++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 83 insertions(+) create mode 100644 deimos/core/format.cpp (limited to 'deimos/core/format.cpp') diff --git a/deimos/core/format.cpp b/deimos/core/format.cpp new file mode 100644 index 0000000..f4f4e83 --- /dev/null +++ b/deimos/core/format.cpp @@ -0,0 +1,83 @@ +#include "deimos/core/format.h" +#include "deimos/core/io.h" + +#include // NOLINT +#include // NOLINT + +namespace deimos +{ + +class FormatContext +{ + IWriter* m_writer; + +public: + explicit FormatContext(IWriter* writer) : m_writer{writer} {} + + void PushChar(char c) + { + m_writer->Write(AsBytes(Span(&c, 1))); + } + + void PushString(Span str) + { + m_writer->Write(AsBytes(str)); + } + + void PushUnsignedInteger(int64_t value) + { + char buffer[64]; + const int size = snprintf(&buffer[0], 64, "%" PRIu64, value); + PushString({ &buffer[0], size }); + } + + void PushInteger(int64_t value) + { + char buffer[64]; + const int size = snprintf(&buffer[0], 64, "%" PRIi64, value); + PushString({ &buffer[0], size }); + } + + void PushArg(const FormatArg& arg) + { + switch (arg.type) + { + case FormatArg::kString: + PushString(arg.string); + break; + case FormatArg::kInteger: + PushInteger(arg.integer); + break; + case FormatArg::kUnsignedInteger: + PushUnsignedInteger(arg.integer); + break; + } + } +}; + +void FormatVa(IWriter* writer, gsl::czstring fmt, Span args) +{ + if (fmt == nullptr) { return; } + + const FormatArg* arg = args.begin(); + const FormatArg* const end_arg = args.end(); + + FormatContext ctx(writer); + + while (*fmt != '\0') + { + if (*fmt == '$' && arg < end_arg) + { + ctx.PushArg(*arg++); // NOLINT + } + else + { + ctx.PushChar(*fmt); + } + + fmt += 1; + } +} + +} // namespace deimos + -- cgit