#include "json.h" #include "json.hpp" #include "json_collections.h" #include #include #include #include namespace json { class Underlying { public: virtual auto ptr() -> struct json_value*& = 0; virtual auto ptr() const -> const struct json_value* const& = 0; virtual auto alloc_ptr() -> struct blockalloc* = 0; private: }; class ValuePtr final : public Underlying { public: explicit ValuePtr(struct blockalloc* alloc, struct json_value* value) : m_alloc(alloc) , m_value(value) { }; auto ptr() -> struct json_value*& override { return m_value; } auto ptr() const -> const struct json_value* const& override { return m_value; } auto alloc_ptr() -> struct blockalloc* override { return m_alloc; } private: struct blockalloc* m_alloc; struct json_value* m_value; }; auto Value::is(Type type) const -> bool { return json_is(m_underlying->ptr(), (enum json_type)type); } auto Value::get_type() const -> Type { return (Type)json_get_type(m_underlying->ptr()); } auto Value::get_bool() const -> bool { return json_get_bool(m_underlying->ptr()); } auto Value::get_int() const -> std::int64_t { return json_get_int(m_underlying->ptr()); } auto Value::get_float() const -> double { return json_get_float(m_underlying->ptr()); } auto Value::get_string() const -> std::string_view { return json_get_string(m_underlying->ptr()); } void Value::set_null() { json_set_null(&m_underlying->ptr()); } void Value::set_bool(bool val) { json_set_bool(&m_underlying->ptr(), val); } void Value::set_int(int64_t val) { json_set_int(&m_underlying->ptr(), val); } void Value::set_float(double val) { json_set_float(&m_underlying->ptr(), val); } void Value::set_string(std::string_view val) { char* own_str = (char*)blockalloc_alloc(m_underlying->alloc_ptr(), val.size() + 1, 2); std::strncpy(own_str, val.data(), val.size() + 1); json_set_string(m_underlying->ptr(), own_str); } auto Value::count() const -> std::size_t { return json_array_count(m_underlying->ptr()); } auto Value::get(std::size_t idx) -> std::unique_ptr { return std::make_unique(std::make_unique( m_underlying->alloc_ptr(), json_idx(m_underlying->ptr(), idx))); } auto Value::get(std::size_t idx) const -> std::unique_ptr { return std::make_unique(std::make_unique( m_underlying->alloc_ptr(), json_idx(m_underlying->ptr(), idx))); } void Value::push(std::unique_ptr value) { json_push(m_underlying->ptr(), value->m_underlying->ptr()); } auto Value::get(std::string_view key) -> std::unique_ptr { return std::make_unique( std::make_unique(m_underlying->alloc_ptr(), json_key_sized(m_underlying->ptr(), key.data(), key.size()))); } auto Value::get(std::string_view key) const -> std::unique_ptr { return std::make_unique( std::make_unique(m_underlying->alloc_ptr(), json_key_sized(m_underlying->ptr(), key.data(), key.size()))); } void Value::set(std::string_view key, std::unique_ptr value) { json_set_sized(m_underlying->ptr(), key.data(), key.size(), value->m_underlying->ptr()); } auto Value::query(const std::string& query) -> std::unique_ptr { return std::make_unique( std::make_unique(m_underlying->alloc_ptr(), json_query(m_underlying->ptr(), query.c_str()))); } class Doc final : public Underlying { public: explicit Doc() { blockalloc_construct(&m_alloc); } ~Doc() { blockalloc_destroy(&m_alloc); if (m_value) { json_free(m_value); } } int parse(std::string_view text) { m_value = json_parse(text.data(), text.size(), &m_alloc); if (!m_value) return 1; return 0; } auto ptr() -> struct json_value*& override { return m_value; } auto ptr() const -> const struct json_value* const& override { return m_value; } auto alloc_ptr() -> struct blockalloc* override { return &m_alloc; } private: struct blockalloc m_alloc; struct json_value* m_value = nullptr; }; auto parse(std::string_view text) -> std::unique_ptr { auto doc = std::make_unique(); if (doc->parse(text) != 0) return nullptr; return std::make_unique(std::move(doc)); } }