192 lines
4.5 KiB
C++
192 lines
4.5 KiB
C++
#include "json.h"
|
|
#include "json.hpp"
|
|
#include "json_collections.h"
|
|
#include <cstdint>
|
|
#include <cstring>
|
|
#include <memory>
|
|
#include <string>
|
|
|
|
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<Value>
|
|
{
|
|
return std::make_unique<Value>(std::make_unique<ValuePtr>(
|
|
m_underlying->alloc_ptr(), json_idx(m_underlying->ptr(), idx)));
|
|
}
|
|
auto Value::get(std::size_t idx) const -> std::unique_ptr<const Value>
|
|
{
|
|
return std::make_unique<Value>(std::make_unique<ValuePtr>(
|
|
m_underlying->alloc_ptr(), json_idx(m_underlying->ptr(), idx)));
|
|
}
|
|
void Value::push(std::unique_ptr<Value> value)
|
|
{
|
|
json_push(m_underlying->ptr(), value->m_underlying->ptr());
|
|
}
|
|
|
|
auto Value::get(std::string_view key) -> std::unique_ptr<Value>
|
|
{
|
|
return std::make_unique<Value>(
|
|
std::make_unique<ValuePtr>(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<const Value>
|
|
{
|
|
return std::make_unique<Value>(
|
|
std::make_unique<ValuePtr>(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> 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<Value>
|
|
{
|
|
return std::make_unique<Value>(
|
|
std::make_unique<ValuePtr>(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<Value>
|
|
{
|
|
auto doc = std::make_unique<Doc>();
|
|
if (doc->parse(text) != 0)
|
|
return nullptr;
|
|
return std::make_unique<Value>(std::move(doc));
|
|
}
|
|
|
|
}
|