Merge branch 'main' into blocks-metadata

This commit is contained in:
MihailRis
2024-09-13 13:22:27 +03:00
19 changed files with 267 additions and 51 deletions
+27 -6
View File
@@ -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<Map_sptr>(value).get());
const auto bytes = to_binary(std::get<Map_sptr>(value).get());
builder.put(bytes.data(), bytes.size());
break;
}
case Type::list:
builder.put(BJSON_TYPE_LIST);
for (auto& element : std::get<List_sptr>(value)->values) {
for (const auto& element : std::get<List_sptr>(value)->values) {
to_binary(builder, element);
}
builder.put(BJSON_END);
break;
case Type::bytes: {
const auto& bytes = std::get<ByteBuffer_sptr>(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<integer_t>(value);
if (val >= 0 && val <= 255) {
@@ -113,11 +120,25 @@ 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));
}
auto bytes = std::make_shared<ByteBuffer>(reader.pointer(), size);
reader.skip(size);
return bytes;
}
}
throw std::runtime_error(
"type support not implemented for <"+std::to_string(typecode)+">");
}
static std::unique_ptr<List> array_from_binary(ByteReader& reader) {
+6 -2
View File
@@ -11,7 +11,7 @@ void ByteBuilder::put(ubyte b) {
}
void ByteBuilder::putCStr(const char* str) {
size_t size = strlen(str) + 1;
size_t size = std::strlen(str) + 1;
buffer.reserve(buffer.size() + size);
for (size_t i = 0; i < size; i++) {
buffer.push_back(str[i]);
@@ -172,7 +172,7 @@ const char* ByteReader::getCString() {
}
std::string ByteReader::getString() {
uint32_t length = (uint32_t)getInt32();
uint32_t length = static_cast<uint32_t>(getInt32());
if (pos + length > size) {
throw std::runtime_error("buffer underflow");
}
@@ -186,6 +186,10 @@ bool ByteReader::hasNext() const {
return pos < size;
}
size_t ByteReader::remaining() const {
return size - pos;
}
const ubyte* ByteReader::pointer() const {
return data + pos;
}
+2
View File
@@ -72,6 +72,8 @@ public:
std::string getString();
/// @return true if there is at least one byte remains
bool hasNext() const;
/// @return Number of remaining bytes in buffer
size_t remaining() const;
const ubyte* pointer() const;
void skip(size_t n);
+54 -21
View File
@@ -44,6 +44,14 @@ void stringifyObj(
bool nice
);
void stringifyArr(
const List* list,
std::stringstream& ss,
int indent,
const std::string& indentstr,
bool nice
);
void stringifyValue(
const Value& value,
std::stringstream& ss,
@@ -54,26 +62,11 @@ void stringifyValue(
if (auto map = std::get_if<Map_sptr>(&value)) {
stringifyObj(map->get(), ss, indent, indentstr, nice);
} else if (auto listptr = std::get_if<List_sptr>(&value)) {
auto list = *listptr;
if (list->size() == 0) {
ss << "[]";
return;
}
ss << '[';
for (uint i = 0; i < list->size(); i++) {
Value& value = list->get(i);
if (i > 0 || nice) {
newline(ss, nice, indent, indentstr);
}
stringifyValue(value, ss, indent + 1, indentstr, nice);
if (i + 1 < list->size()) {
ss << ',';
}
}
if (nice) {
newline(ss, true, indent - 1, indentstr);
}
ss << ']';
stringifyArr(listptr->get(), ss, indent, indentstr, nice);
} else if (auto bytesptr = std::get_if<ByteBuffer_sptr>(&value)) {
auto bytes = bytesptr->get();
ss << "\"" << util::base64_encode(bytes->data(), bytes->size());
ss << "\"";
} else if (auto flag = std::get_if<bool>(&value)) {
ss << (*flag ? "true" : "false");
} else if (auto num = std::get_if<number_t>(&value)) {
@@ -87,6 +80,38 @@ void stringifyValue(
}
}
void stringifyArr(
const List* list,
std::stringstream& ss,
int indent,
const std::string& indentstr,
bool nice
) {
if (list == nullptr) {
ss << "nullptr";
return;
}
if (list->values.empty()) {
ss << "[]";
return;
}
ss << "[";
for (size_t i = 0; i < list->size(); i++) {
if (i > 0 || nice) {
newline(ss, nice, indent, indentstr);
}
const Value& value = list->values[i];
stringifyValue(value, ss, indent + 1, indentstr, nice);
if (i + 1 < list->size()) {
ss << ',';
}
}
if (nice) {
newline(ss, true, indent - 1, indentstr);
}
ss << ']';
}
void stringifyObj(
const Map* obj,
std::stringstream& ss,
@@ -103,7 +128,7 @@ void stringifyObj(
return;
}
ss << "{";
uint index = 0;
size_t index = 0;
for (auto& entry : obj->values) {
const std::string& key = entry.first;
if (index > 0 || nice) {
@@ -131,6 +156,14 @@ std::string json::stringify(
return ss.str();
}
std::string json::stringify(
const dynamic::List* arr, bool nice, const std::string& indent
) {
std::stringstream ss;
stringifyArr(arr, ss, 1, indent, nice);
return ss.str();
}
std::string json::stringify(
const dynamic::Value& value, bool nice, const std::string& indent
) {
+4
View File
@@ -14,6 +14,10 @@ namespace json {
const dynamic::Map* obj, bool nice, const std::string& indent
);
std::string stringify(
const dynamic::List* arr, bool nice, const std::string& indent
);
std::string stringify(
const dynamic::Value& value, bool nice, const std::string& indent
);