dynamic::Value simplified

This commit is contained in:
MihailRis
2024-05-07 18:39:12 +03:00
parent 8e83a07094
commit a4c21984d5
26 changed files with 230 additions and 297 deletions
+26 -41
View File
@@ -9,24 +9,24 @@
using namespace json;
using namespace dynamic;
static void to_binary(ByteBuilder& builder, const Value* value) {
switch (static_cast<valtype>(value->value.index())) {
static void to_binary(ByteBuilder& builder, const Value& value) {
switch (static_cast<valtype>(value.index())) {
case valtype::none:
throw std::runtime_error("none value is not implemented");
case valtype::map: {
std::vector<ubyte> bytes = to_binary(std::get<Map*>(value->value));
auto bytes = to_binary(std::get<Map_sptr>(value).get());
builder.put(bytes.data(), bytes.size());
break;
}
case valtype::list:
builder.put(BJSON_TYPE_LIST);
for (auto& element : std::get<List*>(value->value)->values) {
to_binary(builder, element.get());
for (auto& element : std::get<List_sptr>(value)->values) {
to_binary(builder, element);
}
builder.put(BJSON_END);
break;
case valtype::integer: {
auto val = std::get<integer_t>(value->value);
auto val = std::get<integer_t>(value);
if (val >= 0 && val <= 255) {
builder.put(BJSON_TYPE_BYTE);
builder.put(val);
@@ -44,14 +44,14 @@ static void to_binary(ByteBuilder& builder, const Value* value) {
}
case valtype::number:
builder.put(BJSON_TYPE_NUMBER);
builder.putFloat64(std::get<number_t>(value->value));
builder.putFloat64(std::get<number_t>(value));
break;
case valtype::boolean:
builder.put(BJSON_TYPE_FALSE + std::get<bool>(value->value));
builder.put(BJSON_TYPE_FALSE + std::get<bool>(value));
break;
case valtype::string:
builder.put(BJSON_TYPE_STRING);
builder.put(std::get<std::string>(value->value));
builder.put(std::get<std::string>(value));
break;
}
}
@@ -73,7 +73,7 @@ std::vector<ubyte> json::to_binary(const Map* obj, bool compress) {
// writing entries
for (auto& entry : obj->values) {
builder.putCStr(entry.first.c_str());
to_binary(builder, entry.second.get());
to_binary(builder, entry.second);
}
// terminating byte
builder.put(BJSON_END);
@@ -83,52 +83,40 @@ std::vector<ubyte> json::to_binary(const Map* obj, bool compress) {
return builder.build();
}
static std::unique_ptr<Value> value_from_binary(ByteReader& reader) {
static Value value_from_binary(ByteReader& reader) {
ubyte typecode = reader.get();
valvalue val;
switch (typecode) {
case BJSON_TYPE_DOCUMENT:
reader.getInt32();
val = object_from_binary(reader).release();
break;
return Map_sptr(object_from_binary(reader).release());
case BJSON_TYPE_LIST:
val = array_from_binary(reader).release();
break;
return List_sptr(array_from_binary(reader).release());
case BJSON_TYPE_BYTE:
val = static_cast<integer_t>(reader.get());
break;
return static_cast<integer_t>(reader.get());
case BJSON_TYPE_INT16:
val = static_cast<integer_t>(reader.getInt16());
break;
return static_cast<integer_t>(reader.getInt16());
case BJSON_TYPE_INT32:
val = static_cast<integer_t>(reader.getInt32());
break;
return static_cast<integer_t>(reader.getInt32());
case BJSON_TYPE_INT64:
val = reader.getInt64();
break;
return reader.getInt64();
case BJSON_TYPE_NUMBER:
val = reader.getFloat64();
break;
return reader.getFloat64();
case BJSON_TYPE_FALSE:
case BJSON_TYPE_TRUE:
val = (typecode - BJSON_TYPE_FALSE) != 0;
break;
return (typecode - BJSON_TYPE_FALSE) != 0;
case BJSON_TYPE_STRING:
val = reader.getString();
break;
return reader.getString();
default:
throw std::runtime_error(
"type "+std::to_string(typecode)+" is not supported"
);
}
return std::make_unique<Value>(val);
}
static std::unique_ptr<List> array_from_binary(ByteReader& reader) {
auto array = std::make_unique<List>();
auto& items = array->values;
while (reader.peek() != BJSON_END) {
items.push_back(value_from_binary(reader));
array->put(value_from_binary(reader));
}
reader.get();
return array;
@@ -136,16 +124,15 @@ static std::unique_ptr<List> array_from_binary(ByteReader& reader) {
static std::unique_ptr<Map> object_from_binary(ByteReader& reader) {
auto obj = std::make_unique<Map>();
auto& map = obj->values;
while (reader.peek() != BJSON_END) {
const char* key = reader.getCString();
map.insert(std::make_pair(key, value_from_binary(reader)));
obj->put(key, value_from_binary(reader));
}
reader.get();
return obj;
}
std::unique_ptr<Map> json::from_binary(const ubyte* src, size_t size) {
std::shared_ptr<Map> json::from_binary(const ubyte* src, size_t size) {
if (size < 2) {
throw std::runtime_error("bytes length is less than 2");
}
@@ -155,12 +142,10 @@ std::unique_ptr<Map> json::from_binary(const ubyte* src, size_t size) {
return from_binary(data.data(), data.size());
} else {
ByteReader reader(src, size);
std::unique_ptr<Value> value (value_from_binary(reader));
Value value = value_from_binary(reader);
if (Map* const* map = std::get_if<Map*>(&value->value)) {
std::unique_ptr<Map> obj (*map);
value->value = (Map*)nullptr;
return obj;
if (auto map = std::get_if<Map_sptr>(&value)) {
return *map;
} else {
throw std::runtime_error("root value is not an object");
}