add dv::value support to json::stringify & add dv.cpp
This commit is contained in:
parent
f05ed4942d
commit
ceaa676a3a
@ -52,6 +52,22 @@ void stringifyArr(
|
|||||||
bool nice
|
bool nice
|
||||||
);
|
);
|
||||||
|
|
||||||
|
void stringifyObj(
|
||||||
|
const dv::value& obj,
|
||||||
|
std::stringstream& ss,
|
||||||
|
int indent,
|
||||||
|
const std::string& indentstr,
|
||||||
|
bool nice
|
||||||
|
);
|
||||||
|
|
||||||
|
void stringifyList(
|
||||||
|
const dv::value& list,
|
||||||
|
std::stringstream& ss,
|
||||||
|
int indent,
|
||||||
|
const std::string& indentstr,
|
||||||
|
bool nice
|
||||||
|
);
|
||||||
|
|
||||||
void stringifyValue(
|
void stringifyValue(
|
||||||
const Value& value,
|
const Value& value,
|
||||||
std::stringstream& ss,
|
std::stringstream& ss,
|
||||||
@ -80,6 +96,46 @@ void stringifyValue(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void stringifyValue(
|
||||||
|
const dv::value& value,
|
||||||
|
std::stringstream& ss,
|
||||||
|
int indent,
|
||||||
|
const std::string& indentstr,
|
||||||
|
bool nice
|
||||||
|
) {
|
||||||
|
using dv::value_type;
|
||||||
|
|
||||||
|
switch (value.getType()) {
|
||||||
|
case value_type::object:
|
||||||
|
stringifyObj(value, ss, indent, indentstr, nice);
|
||||||
|
break;
|
||||||
|
case value_type::list:
|
||||||
|
stringifyList(value, ss, indent, indentstr, nice);
|
||||||
|
break;
|
||||||
|
case value_type::bytes: {
|
||||||
|
const auto& bytes = value.asBytes();
|
||||||
|
ss << "\"" << util::base64_encode(bytes.data(), bytes.size());
|
||||||
|
ss << "\"";
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case value_type::string:
|
||||||
|
ss << util::escape(value.asString());
|
||||||
|
break;
|
||||||
|
case value_type::number:
|
||||||
|
ss << std::setprecision(15) << value.asNumber();
|
||||||
|
break;
|
||||||
|
case value_type::integer:
|
||||||
|
ss << value.asInteger();
|
||||||
|
break;
|
||||||
|
case value_type::boolean:
|
||||||
|
ss << (value.asBoolean() ? "true" : "false");
|
||||||
|
break;
|
||||||
|
case value_type::none:
|
||||||
|
ss << "null";
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void stringifyArr(
|
void stringifyArr(
|
||||||
const List* list,
|
const List* list,
|
||||||
std::stringstream& ss,
|
std::stringstream& ss,
|
||||||
@ -148,6 +204,64 @@ void stringifyObj(
|
|||||||
ss << '}';
|
ss << '}';
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void stringifyList(
|
||||||
|
const dv::value& list,
|
||||||
|
std::stringstream& ss,
|
||||||
|
int indent,
|
||||||
|
const std::string& indentstr,
|
||||||
|
bool nice
|
||||||
|
) {
|
||||||
|
if (list.empty()) {
|
||||||
|
ss << "[]";
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
ss << "[";
|
||||||
|
for (size_t i = 0; i < list.size(); i++) {
|
||||||
|
if (i > 0 || nice) {
|
||||||
|
newline(ss, nice, indent, indentstr);
|
||||||
|
}
|
||||||
|
const auto& value = list[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 dv::value& obj,
|
||||||
|
std::stringstream& ss,
|
||||||
|
int indent,
|
||||||
|
const std::string& indentstr,
|
||||||
|
bool nice
|
||||||
|
) {
|
||||||
|
if (obj.empty()) {
|
||||||
|
ss << "{}";
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
ss << "{";
|
||||||
|
size_t index = 0;
|
||||||
|
for (auto& [key, value] : obj.asObject()) {
|
||||||
|
if (index > 0 || nice) {
|
||||||
|
newline(ss, nice, indent, indentstr);
|
||||||
|
}
|
||||||
|
ss << util::escape(key) << ": ";
|
||||||
|
stringifyValue(value, ss, indent + 1, indentstr, nice);
|
||||||
|
index++;
|
||||||
|
if (index < obj.size()) {
|
||||||
|
ss << ',';
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (nice) {
|
||||||
|
newline(ss, true, indent - 1, indentstr);
|
||||||
|
}
|
||||||
|
ss << '}';
|
||||||
|
}
|
||||||
|
|
||||||
std::string json::stringify(
|
std::string json::stringify(
|
||||||
const Map* obj, bool nice, const std::string& indent
|
const Map* obj, bool nice, const std::string& indent
|
||||||
) {
|
) {
|
||||||
@ -172,6 +286,14 @@ std::string json::stringify(
|
|||||||
return ss.str();
|
return ss.str();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
std::string json::stringifyDV(
|
||||||
|
const dv::value& value, bool nice, const std::string& indent
|
||||||
|
) {
|
||||||
|
std::stringstream ss;
|
||||||
|
stringifyValue(value, ss, 1, indent, nice);
|
||||||
|
return ss.str();
|
||||||
|
}
|
||||||
|
|
||||||
Parser::Parser(std::string_view filename, std::string_view source)
|
Parser::Parser(std::string_view filename, std::string_view source)
|
||||||
: BasicParser(filename, source) {
|
: BasicParser(filename, source) {
|
||||||
}
|
}
|
||||||
|
|||||||
@ -3,6 +3,7 @@
|
|||||||
#include <string>
|
#include <string>
|
||||||
|
|
||||||
#include "data/dynamic.hpp"
|
#include "data/dynamic.hpp"
|
||||||
|
#include "data/dv.hpp"
|
||||||
#include "typedefs.hpp"
|
#include "typedefs.hpp"
|
||||||
#include "binary_json.hpp"
|
#include "binary_json.hpp"
|
||||||
|
|
||||||
@ -21,4 +22,8 @@ namespace json {
|
|||||||
std::string stringify(
|
std::string stringify(
|
||||||
const dynamic::Value& value, bool nice, const std::string& indent
|
const dynamic::Value& value, bool nice, const std::string& indent
|
||||||
);
|
);
|
||||||
|
|
||||||
|
std::string stringifyDV(
|
||||||
|
const dv::value& value, bool nice, const std::string& indent=" "
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|||||||
180
src/data/dv.cpp
Normal file
180
src/data/dv.cpp
Normal file
@ -0,0 +1,180 @@
|
|||||||
|
#include "dv.hpp"
|
||||||
|
|
||||||
|
#include "util/Buffer.hpp"
|
||||||
|
|
||||||
|
namespace dv {
|
||||||
|
value::value(value_type type) : type(type) {
|
||||||
|
switch (type) {
|
||||||
|
case value_type::object:
|
||||||
|
val.object = std::make_shared<objects::Object>();
|
||||||
|
break;
|
||||||
|
case value_type::list:
|
||||||
|
val.list = std::make_shared<objects::List>();
|
||||||
|
break;
|
||||||
|
case value_type::bytes:
|
||||||
|
val.bytes = nullptr; // no default size
|
||||||
|
break;
|
||||||
|
case value_type::string:
|
||||||
|
val.string = std::make_unique<std::string>("");
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
value& value::operator[](const key_t& key) {
|
||||||
|
if (type == value_type::object) {
|
||||||
|
return (*val.object)[key];
|
||||||
|
}
|
||||||
|
throw std::runtime_error("value is not an object");
|
||||||
|
}
|
||||||
|
const value& value::operator[](const key_t& key) const {
|
||||||
|
if (type == value_type::object) {
|
||||||
|
return (*val.object)[key];
|
||||||
|
}
|
||||||
|
throw std::runtime_error("value is not an object");
|
||||||
|
}
|
||||||
|
|
||||||
|
value& value::operator=(const objects::Bytes& bytes) {
|
||||||
|
return setBytes(std::make_shared<objects::Bytes>(bytes));
|
||||||
|
}
|
||||||
|
|
||||||
|
value& value::operator[](size_t index) {
|
||||||
|
if (type == value_type::list) {
|
||||||
|
return (*val.list)[index];
|
||||||
|
}
|
||||||
|
throw std::runtime_error("value is not a list");
|
||||||
|
}
|
||||||
|
const value& value::operator[](size_t index) const {
|
||||||
|
if (type == value_type::list) {
|
||||||
|
return (*val.list)[index];
|
||||||
|
}
|
||||||
|
throw std::runtime_error("value is not a list");
|
||||||
|
}
|
||||||
|
|
||||||
|
value& value::add(value v) {
|
||||||
|
if (type == value_type::list) {
|
||||||
|
return val.list->add(std::move(v));
|
||||||
|
}
|
||||||
|
throw std::runtime_error("value is not a list");
|
||||||
|
}
|
||||||
|
|
||||||
|
value& value::object(const key_t& key) {
|
||||||
|
reference ref = this->operator[](key);
|
||||||
|
ref = dv::object();
|
||||||
|
return ref;
|
||||||
|
}
|
||||||
|
|
||||||
|
value& value::list(const key_t& key) {
|
||||||
|
reference ref = this->operator[](key);
|
||||||
|
ref = dv::list();
|
||||||
|
return ref;
|
||||||
|
}
|
||||||
|
|
||||||
|
value& value::object() {
|
||||||
|
return add(dv::object());
|
||||||
|
}
|
||||||
|
|
||||||
|
value& value::list() {
|
||||||
|
return add(dv::list());
|
||||||
|
}
|
||||||
|
|
||||||
|
list_t::iterator value::begin() {
|
||||||
|
if (type == value_type::list) {
|
||||||
|
return val.list->begin();
|
||||||
|
}
|
||||||
|
throw std::runtime_error("value is not a list");
|
||||||
|
}
|
||||||
|
|
||||||
|
list_t::iterator value::end() {
|
||||||
|
if (type == value_type::list) {
|
||||||
|
return val.list->end();
|
||||||
|
}
|
||||||
|
throw std::runtime_error("value is not a list");
|
||||||
|
}
|
||||||
|
|
||||||
|
list_t::const_iterator value::begin() const {
|
||||||
|
if (type == value_type::list) {
|
||||||
|
const auto& constlist = *val.list;
|
||||||
|
return constlist.begin();
|
||||||
|
}
|
||||||
|
throw std::runtime_error("value is not a list");
|
||||||
|
}
|
||||||
|
|
||||||
|
list_t::const_iterator value::end() const {
|
||||||
|
if (type == value_type::list) {
|
||||||
|
const auto& constlist = *val.list;
|
||||||
|
return constlist.end();
|
||||||
|
}
|
||||||
|
throw std::runtime_error("value is not a list");
|
||||||
|
}
|
||||||
|
|
||||||
|
const std::string& value::asString() const {
|
||||||
|
if (type == value_type::string) {
|
||||||
|
return *val.string;
|
||||||
|
}
|
||||||
|
throw std::runtime_error("type error");
|
||||||
|
}
|
||||||
|
|
||||||
|
integer_t value::asInteger() const {
|
||||||
|
if (type == value_type::integer) {
|
||||||
|
return val.integer;
|
||||||
|
} else if (type == value_type::number) {
|
||||||
|
return static_cast<integer_t>(val.number);
|
||||||
|
}
|
||||||
|
throw std::runtime_error("type error");
|
||||||
|
}
|
||||||
|
|
||||||
|
number_t value::asNumber() const {
|
||||||
|
if (type == value_type::number) {
|
||||||
|
return val.number;
|
||||||
|
} else if (type == value_type::integer) {
|
||||||
|
return static_cast<number_t>(val.integer);
|
||||||
|
}
|
||||||
|
throw std::runtime_error("type error");
|
||||||
|
}
|
||||||
|
|
||||||
|
boolean_t value::asBoolean() const {
|
||||||
|
if (type == value_type::boolean) {
|
||||||
|
return val.boolean;
|
||||||
|
} else if (type == value_type::integer) {
|
||||||
|
return val.integer != 0;
|
||||||
|
}
|
||||||
|
throw std::runtime_error("type error");
|
||||||
|
}
|
||||||
|
|
||||||
|
objects::Bytes& value::asBytes() {
|
||||||
|
if (type == value_type::bytes) {
|
||||||
|
return *val.bytes;
|
||||||
|
}
|
||||||
|
throw std::runtime_error("type error");
|
||||||
|
}
|
||||||
|
|
||||||
|
const objects::Bytes& value::asBytes() const {
|
||||||
|
if (type == value_type::bytes) {
|
||||||
|
return *val.bytes;
|
||||||
|
}
|
||||||
|
throw std::runtime_error("type error");
|
||||||
|
}
|
||||||
|
|
||||||
|
const objects::Object& value::asObject() const {
|
||||||
|
if (type == value_type::object) {
|
||||||
|
return *val.object;
|
||||||
|
}
|
||||||
|
throw std::runtime_error("type error");
|
||||||
|
}
|
||||||
|
|
||||||
|
const size_t value::size() const {
|
||||||
|
switch (type) {
|
||||||
|
case value_type::list:
|
||||||
|
return val.list->size();
|
||||||
|
case value_type::object:
|
||||||
|
return val.object->size();
|
||||||
|
case value_type::string:
|
||||||
|
return val.string->size();
|
||||||
|
default:
|
||||||
|
throw std::runtime_error("type error");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
227
src/data/dv.hpp
227
src/data/dv.hpp
@ -168,58 +168,60 @@ namespace dv {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
value& operator=(int8_t v) {
|
inline value& operator=(int8_t v) {
|
||||||
return setInteger(v);
|
return setInteger(v);
|
||||||
}
|
}
|
||||||
value& operator=(int16_t v) {
|
inline value& operator=(int16_t v) {
|
||||||
return setInteger(v);
|
return setInteger(v);
|
||||||
}
|
}
|
||||||
value& operator=(int32_t v) {
|
inline value& operator=(int32_t v) {
|
||||||
return setInteger(v);
|
return setInteger(v);
|
||||||
}
|
}
|
||||||
value& operator=(int64_t v) {
|
inline value& operator=(int64_t v) {
|
||||||
return setInteger(v);
|
return setInteger(v);
|
||||||
}
|
}
|
||||||
value& operator=(uint8_t v) {
|
inline value& operator=(uint8_t v) {
|
||||||
return setInteger(v);
|
return setInteger(v);
|
||||||
}
|
}
|
||||||
value& operator=(uint16_t v) {
|
inline value& operator=(uint16_t v) {
|
||||||
return setInteger(v);
|
return setInteger(v);
|
||||||
}
|
}
|
||||||
value& operator=(uint32_t v) {
|
inline value& operator=(uint32_t v) {
|
||||||
return setInteger(v);
|
return setInteger(v);
|
||||||
}
|
}
|
||||||
value& operator=(uint64_t v) {
|
inline value& operator=(uint64_t v) {
|
||||||
return setInteger(v);
|
return setInteger(v);
|
||||||
}
|
}
|
||||||
value& operator=(float v) {
|
inline value& operator=(float v) {
|
||||||
return setNumber(v);
|
return setNumber(v);
|
||||||
}
|
}
|
||||||
value& operator=(double v) {
|
inline value& operator=(double v) {
|
||||||
return setNumber(v);
|
return setNumber(v);
|
||||||
}
|
}
|
||||||
value& operator=(bool v) {
|
inline value& operator=(bool v) {
|
||||||
return setBoolean(v);
|
return setBoolean(v);
|
||||||
}
|
}
|
||||||
value& operator=(std::string_view v) {
|
inline value& operator=(std::string_view v) {
|
||||||
return setString(std::string(v));
|
return setString(std::string(v));
|
||||||
}
|
}
|
||||||
value& operator=(std::string v) {
|
inline value& operator=(std::string v) {
|
||||||
return setString(std::move(v));
|
return setString(std::move(v));
|
||||||
}
|
}
|
||||||
value& operator=(const char* v) {
|
inline value& operator=(const char* v) {
|
||||||
return setString(v);
|
return setString(v);
|
||||||
}
|
}
|
||||||
value& operator=(std::shared_ptr<objects::List> ptr) {
|
inline value& operator=(std::shared_ptr<objects::List> ptr) {
|
||||||
return setList(ptr);
|
return setList(ptr);
|
||||||
}
|
}
|
||||||
value& operator=(std::shared_ptr<objects::Object> ptr) {
|
inline value& operator=(std::shared_ptr<objects::Object> ptr) {
|
||||||
return setObject(ptr);
|
return setObject(ptr);
|
||||||
}
|
}
|
||||||
value& operator=(std::shared_ptr<objects::Bytes> ptr) {
|
inline value& operator=(std::shared_ptr<objects::Bytes> ptr) {
|
||||||
return setBytes(ptr);
|
return setBytes(ptr);
|
||||||
}
|
}
|
||||||
value& operator=(const value& v) {
|
value& operator=(const objects::Bytes& bytes);
|
||||||
|
|
||||||
|
inline value& operator=(const value& v) {
|
||||||
switch (v.type) {
|
switch (v.type) {
|
||||||
case value_type::object:
|
case value_type::object:
|
||||||
setObject(v.val.object);
|
setObject(v.val.object);
|
||||||
@ -252,7 +254,7 @@ namespace dv {
|
|||||||
value& add(value v);
|
value& add(value v);
|
||||||
|
|
||||||
template<class T>
|
template<class T>
|
||||||
value& add(T v) {
|
inline value& add(T v) {
|
||||||
return add(value(v));
|
return add(value(v));
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -292,7 +294,7 @@ namespace dv {
|
|||||||
|
|
||||||
const objects::Object& asObject() const;
|
const objects::Object& asObject() const;
|
||||||
|
|
||||||
value_type getType() const {
|
inline value_type getType() const {
|
||||||
return type;
|
return type;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -301,22 +303,15 @@ namespace dv {
|
|||||||
const size_t length() const {
|
const size_t length() const {
|
||||||
return size();
|
return size();
|
||||||
}
|
}
|
||||||
bool empty() const {
|
inline bool empty() const {
|
||||||
return size() == 0;
|
return size() == 0;
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
using reference = value&;
|
using reference = value&;
|
||||||
using const_reference = const value&;
|
using const_reference = const value&;
|
||||||
|
|
||||||
value list();
|
|
||||||
value object();
|
|
||||||
|
|
||||||
value list(std::initializer_list<value> values);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#include "util/Buffer.hpp"
|
|
||||||
|
|
||||||
namespace dv::objects {
|
namespace dv::objects {
|
||||||
class Object {
|
class Object {
|
||||||
map_t map;
|
map_t map;
|
||||||
@ -387,185 +382,15 @@ namespace dv::objects {
|
|||||||
}
|
}
|
||||||
|
|
||||||
namespace dv {
|
namespace dv {
|
||||||
value::value(value_type type) : type(type) {
|
inline value object() {
|
||||||
switch (type) {
|
|
||||||
case value_type::object:
|
|
||||||
val.object = std::make_shared<objects::Object>();
|
|
||||||
break;
|
|
||||||
case value_type::list:
|
|
||||||
val.list = std::make_shared<objects::List>();
|
|
||||||
break;
|
|
||||||
case value_type::bytes:
|
|
||||||
val.bytes = nullptr; // no default size
|
|
||||||
break;
|
|
||||||
case value_type::string:
|
|
||||||
val.string = std::make_unique<std::string>("");
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
value& value::operator[](const key_t& key) {
|
|
||||||
if (type == value_type::object) {
|
|
||||||
return (*val.object)[key];
|
|
||||||
}
|
|
||||||
throw std::runtime_error("value is not an object");
|
|
||||||
}
|
|
||||||
const value& value::operator[](const key_t& key) const {
|
|
||||||
if (type == value_type::object) {
|
|
||||||
return (*val.object)[key];
|
|
||||||
}
|
|
||||||
throw std::runtime_error("value is not an object");
|
|
||||||
}
|
|
||||||
|
|
||||||
value& value::operator[](size_t index) {
|
|
||||||
if (type == value_type::list) {
|
|
||||||
return (*val.list)[index];
|
|
||||||
}
|
|
||||||
throw std::runtime_error("value is not a list");
|
|
||||||
}
|
|
||||||
const value& value::operator[](size_t index) const {
|
|
||||||
if (type == value_type::list) {
|
|
||||||
return (*val.list)[index];
|
|
||||||
}
|
|
||||||
throw std::runtime_error("value is not a list");
|
|
||||||
}
|
|
||||||
|
|
||||||
value& value::add(value v) {
|
|
||||||
if (type == value_type::list) {
|
|
||||||
return val.list->add(std::move(v));
|
|
||||||
}
|
|
||||||
throw std::runtime_error("value is not a list");
|
|
||||||
}
|
|
||||||
|
|
||||||
value& value::object(const key_t& key) {
|
|
||||||
reference ref = this->operator[](key);
|
|
||||||
ref = dv::object();
|
|
||||||
return ref;
|
|
||||||
}
|
|
||||||
|
|
||||||
value& value::list(const key_t& key) {
|
|
||||||
reference ref = this->operator[](key);
|
|
||||||
ref = dv::list();
|
|
||||||
return ref;
|
|
||||||
}
|
|
||||||
|
|
||||||
value& value::object() {
|
|
||||||
return add(dv::object());
|
|
||||||
}
|
|
||||||
|
|
||||||
value& value::list() {
|
|
||||||
return add(dv::list());
|
|
||||||
}
|
|
||||||
|
|
||||||
list_t::iterator value::begin() {
|
|
||||||
if (type == value_type::list) {
|
|
||||||
return val.list->begin();
|
|
||||||
}
|
|
||||||
throw std::runtime_error("value is not a list");
|
|
||||||
}
|
|
||||||
|
|
||||||
list_t::iterator value::end() {
|
|
||||||
if (type == value_type::list) {
|
|
||||||
return val.list->end();
|
|
||||||
}
|
|
||||||
throw std::runtime_error("value is not a list");
|
|
||||||
}
|
|
||||||
|
|
||||||
list_t::const_iterator value::begin() const {
|
|
||||||
if (type == value_type::list) {
|
|
||||||
const auto& constlist = *val.list;
|
|
||||||
return constlist.begin();
|
|
||||||
}
|
|
||||||
throw std::runtime_error("value is not a list");
|
|
||||||
}
|
|
||||||
|
|
||||||
list_t::const_iterator value::end() const {
|
|
||||||
if (type == value_type::list) {
|
|
||||||
const auto& constlist = *val.list;
|
|
||||||
return constlist.end();
|
|
||||||
}
|
|
||||||
throw std::runtime_error("value is not a list");
|
|
||||||
}
|
|
||||||
|
|
||||||
const std::string& value::asString() const {
|
|
||||||
if (type == value_type::string) {
|
|
||||||
return *val.string;
|
|
||||||
}
|
|
||||||
throw std::runtime_error("type error");
|
|
||||||
}
|
|
||||||
|
|
||||||
integer_t value::asInteger() const {
|
|
||||||
if (type == value_type::integer) {
|
|
||||||
return val.integer;
|
|
||||||
} else if (type == value_type::number) {
|
|
||||||
return static_cast<integer_t>(val.number);
|
|
||||||
}
|
|
||||||
throw std::runtime_error("type error");
|
|
||||||
}
|
|
||||||
|
|
||||||
number_t value::asNumber() const {
|
|
||||||
if (type == value_type::number) {
|
|
||||||
return val.number;
|
|
||||||
} else if (type == value_type::integer) {
|
|
||||||
return static_cast<number_t>(val.integer);
|
|
||||||
}
|
|
||||||
throw std::runtime_error("type error");
|
|
||||||
}
|
|
||||||
|
|
||||||
boolean_t value::asBoolean() const {
|
|
||||||
if (type == value_type::boolean) {
|
|
||||||
return val.boolean;
|
|
||||||
} else if (type == value_type::integer) {
|
|
||||||
return val.integer != 0;
|
|
||||||
}
|
|
||||||
throw std::runtime_error("type error");
|
|
||||||
}
|
|
||||||
|
|
||||||
objects::Bytes& value::asBytes() {
|
|
||||||
if (type == value_type::bytes) {
|
|
||||||
return *val.bytes;
|
|
||||||
}
|
|
||||||
throw std::runtime_error("type error");
|
|
||||||
}
|
|
||||||
|
|
||||||
const objects::Bytes& value::asBytes() const {
|
|
||||||
if (type == value_type::bytes) {
|
|
||||||
return *val.bytes;
|
|
||||||
}
|
|
||||||
throw std::runtime_error("type error");
|
|
||||||
}
|
|
||||||
|
|
||||||
const objects::Object& value::asObject() const {
|
|
||||||
if (type == value_type::object) {
|
|
||||||
return *val.object;
|
|
||||||
}
|
|
||||||
throw std::runtime_error("type error");
|
|
||||||
}
|
|
||||||
|
|
||||||
const size_t value::size() const {
|
|
||||||
switch (type) {
|
|
||||||
case value_type::list:
|
|
||||||
return val.list->size();
|
|
||||||
case value_type::object:
|
|
||||||
return val.object->size();
|
|
||||||
case value_type::string:
|
|
||||||
return val.string->size();
|
|
||||||
default:
|
|
||||||
throw std::runtime_error("type error");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
value object() {
|
|
||||||
return std::make_shared<objects::Object>();
|
return std::make_shared<objects::Object>();
|
||||||
}
|
}
|
||||||
|
|
||||||
value list() {
|
inline value list() {
|
||||||
return std::make_shared<objects::List>();
|
return std::make_shared<objects::List>();
|
||||||
}
|
}
|
||||||
|
|
||||||
value list(std::initializer_list<value> values) {
|
inline value list(std::initializer_list<value> values) {
|
||||||
return std::make_shared<objects::List>(values);
|
return std::make_shared<objects::List>(values);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -37,3 +37,38 @@ TEST(JSON, EncodeDecode) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
TEST(JSON, EncodeDecodeDV) {
|
||||||
|
const std::string name = "JSON-encoder";
|
||||||
|
const int bytesSize = 20;
|
||||||
|
const int year = 2019;
|
||||||
|
const float score = 3.141592;
|
||||||
|
dynamic::ByteBuffer srcBytes(bytesSize);
|
||||||
|
for (int i = 0; i < bytesSize; i ++) {
|
||||||
|
srcBytes[i] = rand();
|
||||||
|
}
|
||||||
|
|
||||||
|
std::string text;
|
||||||
|
{
|
||||||
|
auto map = dv::object();
|
||||||
|
map["name"] = name;
|
||||||
|
map["year"] = year;
|
||||||
|
map["score"] = score;
|
||||||
|
map["data"] = srcBytes;
|
||||||
|
|
||||||
|
text = json::stringifyDV(map, false, "");
|
||||||
|
}
|
||||||
|
{
|
||||||
|
auto map = json::parse(text);
|
||||||
|
EXPECT_EQ(map->get<std::string>("name"), name);
|
||||||
|
EXPECT_EQ(map->get<integer_t>("year"), year);
|
||||||
|
EXPECT_FLOAT_EQ(map->get<number_t>("score"), score);
|
||||||
|
auto b64string = map->get<std::string>("data");
|
||||||
|
|
||||||
|
auto bytes = util::base64_decode(b64string);
|
||||||
|
EXPECT_EQ(bytes.size(), bytesSize);
|
||||||
|
for (int i = 0; i < bytesSize; i++) {
|
||||||
|
EXPECT_EQ(bytes[i], srcBytes[i]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user