From 6f4a7db910c24188378fc7dc952bb6d72676b4ff Mon Sep 17 00:00:00 2001 From: MihailRis Date: Thu, 12 Sep 2024 16:24:51 +0300 Subject: [PATCH] add binary_json BJSON_TYPE_BYTES support --- src/coders/binary_json.cpp | 31 +++++++++++++++++++++++++------ src/data/dynamic.hpp | 18 +++++++++++++++--- src/data/dynamic_fwd.hpp | 4 ++++ 3 files changed, 44 insertions(+), 9 deletions(-) diff --git a/src/coders/binary_json.cpp b/src/coders/binary_json.cpp index 9b8bac22..026593b7 100644 --- a/src/coders/binary_json.cpp +++ b/src/coders/binary_json.cpp @@ -14,17 +14,24 @@ static void to_binary(ByteBuilder& builder, const Value& value) { case Type::none: throw std::runtime_error("none value is not implemented"); case Type::map: { - auto bytes = to_binary(std::get(value).get()); + const auto bytes = to_binary(std::get(value).get()); builder.put(bytes.data(), bytes.size()); break; } case Type::list: builder.put(BJSON_TYPE_LIST); - for (auto& element : std::get(value)->values) { + for (const auto& element : std::get(value)->values) { to_binary(builder, element); } builder.put(BJSON_END); break; + case Type::bytes: { + const auto bytes = std::get(value).get(); + builder.put(BJSON_TYPE_BYTES); + builder.putInt32(bytes->size()); + builder.put(bytes->data(), bytes->size()); + break; + } case Type::integer: { auto val = std::get(value); if (val >= 0 && val <= 255) { @@ -113,11 +120,23 @@ static Value value_from_binary(ByteReader& reader) { return (typecode - BJSON_TYPE_FALSE) != 0; case BJSON_TYPE_STRING: return reader.getString(); - default: - throw std::runtime_error( - "type " + std::to_string(typecode) + " is not supported" - ); + case BJSON_TYPE_NULL: + return NONE; + case BJSON_TYPE_BYTES: { + int32_t size = reader.getInt32(); + if (size < 0) { + throw std::runtime_error( + "invalid byte-buffer size "+std::to_string(size)); + } + if (size > reader.remaining()) { + throw std::runtime_error( + "buffer_size > remaining_size "+std::to_string(size)); + } + return std::make_shared(reader.pointer(), size); + } } + throw std::runtime_error( + "type support not implemented for <"+std::to_string(typecode)+">"); } static std::unique_ptr array_from_binary(ByteReader& reader) { diff --git a/src/data/dynamic.hpp b/src/data/dynamic.hpp index 9525a898..838e5fa8 100644 --- a/src/data/dynamic.hpp +++ b/src/data/dynamic.hpp @@ -11,7 +11,16 @@ #include "dynamic_fwd.hpp" namespace dynamic { - enum class Type { none = 0, map, list, string, number, boolean, integer }; + enum class Type { + none = 0, + map, + list, + string, + number, + boolean, + integer, + bytes + }; const std::string& type_name(const Value& value); List_sptr create_list(std::initializer_list values = {}); @@ -59,10 +68,13 @@ namespace dynamic { } List& put(std::unique_ptr value) { - return put(Map_sptr(value.release())); + return put(Map_sptr(std::move(value))); } List& put(std::unique_ptr value) { - return put(List_sptr(value.release())); + return put(List_sptr(std::move(value))); + } + List& put(std::unique_ptr value) { + return put(ByteBuffer_sptr(std::move(value))); } List& put(const Value& value); diff --git a/src/data/dynamic_fwd.hpp b/src/data/dynamic_fwd.hpp index 148e244b..c4f8eb87 100644 --- a/src/data/dynamic_fwd.hpp +++ b/src/data/dynamic_fwd.hpp @@ -6,13 +6,16 @@ #include #include "typedefs.hpp" +#include "util/Buffer.hpp" namespace dynamic { class Map; class List; + using ByteBuffer = util::Buffer; using Map_sptr = std::shared_ptr; using List_sptr = std::shared_ptr; + using ByteBuffer_sptr = std::shared_ptr; struct none {}; @@ -22,6 +25,7 @@ namespace dynamic { none, Map_sptr, List_sptr, + ByteBuffer_sptr, std::string, number_t, bool,