diff options
| author | Dan Engelbrecht <[email protected]> | 2023-11-13 16:19:39 +0100 |
|---|---|---|
| committer | GitHub <[email protected]> | 2023-11-13 16:19:39 +0100 |
| commit | d52bed8d5a37a39c88b78a19e22f2b7b3f6dd1d6 (patch) | |
| tree | 2709bce7020faa9c73e784dd2a5997b384395b56 /src/zencore/compactbinary.cpp | |
| parent | package dependency clean-ups (#531) (diff) | |
| download | zen-d52bed8d5a37a39c88b78a19e22f2b7b3f6dd1d6.tar.xz zen-d52bed8d5a37a39c88b78a19e22f2b7b3f6dd1d6.zip | |
gc history log (#519)
- Feature: Writes a `gc.log` with settings and detailed result after each GC execution (version 2 only)
- Break out file name rotate to allow access for gclog
- CompactBinaryToJson(MemoryView Data, StringBuilderBase& InBuilder)
Diffstat (limited to 'src/zencore/compactbinary.cpp')
| -rw-r--r-- | src/zencore/compactbinary.cpp | 160 |
1 files changed, 142 insertions, 18 deletions
diff --git a/src/zencore/compactbinary.cpp b/src/zencore/compactbinary.cpp index 416b49f62..5e8ce22ed 100644 --- a/src/zencore/compactbinary.cpp +++ b/src/zencore/compactbinary.cpp @@ -1472,6 +1472,40 @@ class CbJsonWriter public: explicit CbJsonWriter(StringBuilderBase& InBuilder) : Builder(InBuilder) { NewLineAndIndent << LINE_TERMINATOR_ANSI; } + void BeginObject() + { + Builder << '{'; + NewLineAndIndent << '\t'; + NeedsNewLine = true; + } + + void EndObject() + { + NewLineAndIndent.RemoveSuffix(1); + if (NeedsComma) + { + WriteOptionalNewLine(); + } + Builder << '}'; + } + + void BeginArray() + { + Builder << '['; + NewLineAndIndent << '\t'; + NeedsNewLine = true; + } + + void EndArray() + { + NewLineAndIndent.RemoveSuffix(1); + if (NeedsComma) + { + WriteOptionalNewLine(); + } + Builder << ']'; + } + void WriteField(CbFieldView Field) { using namespace std::literals; @@ -1493,37 +1527,23 @@ public: case CbFieldType::Object: case CbFieldType::UniformObject: { - Builder << '{'; - NewLineAndIndent << '\t'; - NeedsNewLine = true; + BeginObject(); for (CbFieldView It : Field) { WriteField(It); } - NewLineAndIndent.RemoveSuffix(1); - if (NeedsComma) - { - WriteOptionalNewLine(); - } - Builder << '}'; + EndObject(); } break; case CbFieldType::Array: case CbFieldType::UniformArray: { - Builder << '['; - NewLineAndIndent << '\t'; - NeedsNewLine = true; + BeginArray(); for (CbFieldView It : Field) { WriteField(It); } - NewLineAndIndent.RemoveSuffix(1); - if (NeedsComma) - { - WriteOptionalNewLine(); - } - Builder << ']'; + EndArray(); } break; case CbFieldType::Binary: @@ -1744,6 +1764,62 @@ CompactBinaryToJson(const CbArrayView& Array, StringBuilderBase& Builder) Writer.WriteField(Array.AsFieldView()); } +void +CompactBinaryToJson(MemoryView Data, StringBuilderBase& InBuilder) +{ + std::vector<CbFieldView> Fields = ReadCompactBinaryStream(Data); + CbJsonWriter Writer(InBuilder); + if (!Fields.empty()) + { + if (Fields.size() == 1) + { + Writer.WriteField(Fields[0]); + return; + } + bool UseTopLevelObject = Fields[0].HasName(); + if (UseTopLevelObject) + { + Writer.BeginObject(); + } + else + { + Writer.BeginArray(); + } + for (const CbFieldView& Field : Fields) + { + Writer.WriteField(Field); + } + if (UseTopLevelObject) + { + Writer.EndObject(); + } + else + { + Writer.EndArray(); + } + } +} + +std::vector<CbFieldView> +ReadCompactBinaryStream(MemoryView Data) +{ + std::vector<CbFieldView> Result; + const uint8_t* Buffer = reinterpret_cast<const uint8_t*>(Data.GetData()); + uint64_t Offset = 0; + const uint64_t Size = Data.GetSize(); + while (Offset < Size) + { + if (ValidateCompactBinary(MemoryView(Buffer + Offset, Size - Offset), CbValidateMode::Default) != CbValidateError::None) + { + break; + } + CbFieldView Field(Buffer + Offset); + Offset += Field.GetSize(); + Result.emplace_back(std::move(Field)); + } + return Result; +} + ////////////////////////////////////////////////////////////////////////// class CbJsonReader @@ -2136,6 +2212,8 @@ TEST_CASE("uson.null") TEST_CASE("uson.json") { + using namespace std::literals; + SUBCASE("string") { CbObjectWriter Writer; @@ -2208,6 +2286,52 @@ TEST_CASE("uson.json") CHECK(FloatValue == 0); CHECK(DoubleValue == 0); } + + SUBCASE("stream") + { + const auto MakeObject = [&](std::string_view Name, const std::vector<int>& Fields) -> CbObject { + CbWriter Writer; + Writer.SetName(Name); + Writer.BeginObject(); + for (const auto& Field : Fields) + { + Writer.AddInteger(fmt::format("{}", Field), Field); + } + Writer.EndObject(); + return Writer.Save().AsObject(); + }; + + std::vector<uint8_t> Buffer; + + auto AppendToBuffer = [&](const void* Data, size_t Count) { + const uint8_t* AppendBytes = reinterpret_cast<const uint8_t*>(Data); + Buffer.insert(Buffer.end(), AppendBytes, AppendBytes + Count); + }; + + auto Append = [&](const CbFieldView& Field) { + Field.WriteToStream([&](const void* Data, size_t Count) { + const uint8_t* AppendBytes = reinterpret_cast<const uint8_t*>(Data); + Buffer.insert(Buffer.end(), AppendBytes, AppendBytes + Count); + }); + }; + + CbObject DataObjects[] = {MakeObject("Empty object"sv, {}), + MakeObject("OneField object"sv, {5}), + MakeObject("TwoField object"sv, {-5, 999}), + MakeObject("ThreeField object"sv, {1, 2, -129})}; + for (const CbObject& Object : DataObjects) + { + Object.AsField().WriteToStream(AppendToBuffer); + } + + ExtendableStringBuilder<128> Sb; + CompactBinaryToJson(MemoryView(Buffer.data(), Buffer.size()), Sb); + std::string JsonText = Sb.ToString().c_str(); + std::string JsonError; + json11::Json Json = json11::Json::parse(JsonText, JsonError); + std::string ParsedJsonString = Json.dump(); + CHECK(!ParsedJsonString.empty()); + } } TEST_CASE("uson.datetime") |