感觉被yyjson坑了,没有索引,只有顺序读取遍历最高效。改回nlohmann::json

This commit is contained in:
fasiondog 2021-03-21 00:50:06 +08:00
parent aadf9dfb52
commit 3ad5d3ab09
8 changed files with 25447 additions and 1500 deletions

File diff suppressed because it is too large Load Diff

View File

@ -8,8 +8,6 @@
#pragma once
#include "RestHandle.h"
#include "../yyjsonpp/yyjson_doc.h"
#include "../yyjsonpp/yyjson_mut_doc.h"
namespace hku {
@ -20,29 +18,6 @@ public:
virtual void run() override {
std::string req = getReqData();
try {
yyjson::doc doc(req);
yyjson::mut_doc mut_doc(doc);
auto x = mut_doc.root();
CLS_INFO("{}", x);
CLS_INFO("{} {}", x.type_desc(), x.size());
size_t count = 0;
for (auto iter = x.arr_begin(); iter != x.arr_end(); ++iter) {
CLS_INFO("count: {}", count++);
// CLS_INFO("{} {}", iter->first, iter->second);
CLS_INFO("{}", *iter);
}
/*std::vector<int64_t> y = x.to_vector_int64_t();
for (auto i : y) {
CLS_INFO("{}", i);
}*/
/*yyjson::mut_doc mut_doc(doc);
std::vector<bool> y{true, false, true};
auto z = mut_doc.mut_arr(y);
const char* strs[3] = {"Jan", "Feb", "Mar"};
auto zz = mut_doc.mut_arr(strs, 3);*/
setResData("hello");
} catch (std::exception& e) {
CLS_INFO("req: {}", req);

View File

@ -1,80 +0,0 @@
/*
* Copyright(C) 2021 hikyuu.org
*
* Create on: 2021-03-12
* Author: fasiondog
*/
#pragma once
#include <string>
#include <exception>
#include <fmt/format.h>
namespace yyjson {
#if !defined(__clang__) && !defined(__GNUC__)
class exception : public std::exception {
public:
exception() : std::exception("Unknown exception!") {}
exception(const std::string& msg) // cppcheck-suppress noExplicitConstructor
: std::exception(msg.c_str()) {}
exception(const char* msg) : std::exception(msg) {} // cppcheck-suppress noExplicitConstructor
};
#else
// llvm 中的 std::exception 不接受参数
class exception : public std::exception {
public:
exception() : m_msg("Unknown exception!") {}
exception(const char *msg) : m_msg(msg) {} // cppcheck-suppress noExplicitConstructor
exception(const std::string &msg) : m_msg(msg) {} // cppcheck-suppress noExplicitConstructor
virtual ~exception() noexcept {}
virtual const char *what() const noexcept {
return m_msg.c_str();
}
protected:
std::string m_msg;
};
#endif /* #ifdef __clang__ */
class bad_cast : public exception {
public:
bad_cast() : exception("Type conversion failed!") {}
bad_cast(const char* msg) : exception(msg) {}
bad_cast(const std::string& msg) : exception(msg) {}
virtual ~bad_cast() {}
};
#define YYJSON_CHECK(expr, ...) \
do { \
if (!(expr)) { \
throw yyjson::exception(fmt::format("CHECK({}) {} [{}] ({}:{})", #expr, \
fmt::format(__VA_ARGS__), __FUNCTION__, __FILE__, \
__LINE__)); \
} \
} while (0)
#define YYJSON_CHECK_THROW(expr, except, ...) \
do { \
if (!(expr)) { \
throw except(fmt::format("CHECK({}) {} [{}] ({}:{})", #expr, fmt::format(__VA_ARGS__), \
__FUNCTION__, __FILE__, __LINE__)); \
} \
} while (0)
#define YYJSON_THROW(...) \
do { \
throw yyjson::exception(fmt::format("EXCEPTION: {} [{}] ({}:{})", \
fmt::format(__VA_ARGS__), __FUNCTION__, __FILE__, \
__LINE__)); \
} while (0)
#define YYJSON_THROW_EXCEPTION(except, ...) \
do { \
throw except(fmt::format("EXCEPTION: {} [{}] ({}:{})", fmt::format(__VA_ARGS__), \
__FUNCTION__, __FILE__, __LINE__)); \
} while (0)
} // namespace yyjson

View File

@ -1,119 +0,0 @@
/*
* Copyright(C) 2021 hikyuu.org
*
* Create on: 2021-03-11
* Author: fasiondog
*/
#pragma once
#include "yyjson_val_view.h"
namespace yyjson {
class doc {
public:
doc() = delete;
doc(yyjson_doc *doc) : m_doc(doc) {}
doc(const char *dat, size_t len,
yyjson_read_flag flg = YYJSON_READ_ALLOW_TRAILING_COMMAS | YYJSON_READ_ALLOW_INF_AND_NAN |
YYJSON_READ_ALLOW_COMMENTS) {
m_doc = yyjson_read(dat, len, flg);
}
doc(const std::string &dat, yyjson_read_flag flg = YYJSON_READ_ALLOW_TRAILING_COMMAS |
YYJSON_READ_ALLOW_INF_AND_NAN |
YYJSON_READ_ALLOW_COMMENTS) {
m_doc = yyjson_read(dat.c_str(), dat.size(), flg);
}
doc(const doc &) = delete;
doc(doc &&rhs) noexcept : m_doc(rhs.m_doc) {
rhs.m_doc = nullptr;
}
doc &operator=(const doc &rhs) = delete;
doc &operator=(doc &&rhs) {
if (this != &rhs) {
if (m_doc) {
yyjson_doc_free(m_doc);
}
m_doc = rhs.m_doc;
rhs.m_doc = nullptr;
}
return *this;
}
virtual ~doc() {
if (m_doc) {
yyjson_doc_free(m_doc);
}
}
operator bool() const {
return m_doc != nullptr;
}
yyjson_doc *const ptr() const {
return m_doc;
}
std::string json(yyjson_write_flag flg = YYJSON_WRITE_NOFLAG) const {
char *cstr = yyjson_write(m_doc, flg, nullptr);
YYJSON_CHECK(cstr, "Failed yyjson_write");
std::string result(cstr);
free(cstr);
return result;
}
val_view root() const {
return val_view(yyjson_doc_get_root(m_doc));
}
val_view get(const char *key) const {
return root().get(key);
}
val_view get(const std::string &key) const {
return root().get(key);
}
val_view operator[](const char *key) const {
return get(key);
}
val_view operator[](const std::string &key) const {
return get(key);
}
#if YYJSON_VERSION_HEX > 0x000200
val_view get_pointer(const char *pointer) const {
return val_view(yyjson_doc_get_pointer(m_doc, pointer));
}
val_view get_pointer(const std::string &pointer) const {
return val_view(yyjson_doc_get_pointer(m_doc, pointer.c_str()));
}
#endif
size_t get_read_size() const {
return yyjson_doc_get_read_size(m_doc);
}
size_t get_val_count() const {
return yyjson_doc_get_val_count(m_doc);
}
public:
static doc read_file(const char *path, yyjson_read_flag flg) {
return doc(yyjson_read_file(path, flg, nullptr, nullptr));
}
private:
yyjson_doc *m_doc{nullptr};
};
} // namespace yyjson

View File

@ -1,8 +0,0 @@
/*
* Copyright(C) 2021 hikyuu.org
*
* Create on: 2021-03-15
* Author: fasiondog
*/
#include "yyjson_mut_doc.h"

View File

@ -1,243 +0,0 @@
/*
* Copyright(C) 2021 hikyuu.org
*
* Create on: 2021-03-15
* Author: fasiondog
*/
#pragma once
#include <memory>
#include <map>
#include <unordered_map>
#include "yyjson_doc.h"
#include "yyjson_val_view.h"
#include "yyjson_mut_val_view.h"
namespace yyjson {
class mut_doc {
public:
mut_doc(yyjson_alc* alc = nullptr) : m_doc(yyjson_mut_doc_new(alc)) {}
mut_doc(yyjson_mut_doc* doc) : m_doc(doc) {}
mut_doc(const mut_doc&) = delete;
mut_doc(mut_doc&& rhs) : m_doc(rhs.m_doc) {
rhs.m_doc = nullptr;
}
mut_doc& operator=(const mut_doc&) = delete;
mut_doc& operator=(mut_doc&& rhs) {
if (this != &rhs) {
m_doc = rhs.m_doc;
rhs.m_doc = nullptr;
}
return *this;
}
explicit mut_doc(const doc& doc) {
if (doc) {
m_doc = yyjson_doc_mut_copy(doc.ptr(), nullptr);
}
}
mut_doc(const doc& doc, yyjson_alc* alc) {
if (doc) {
m_doc = yyjson_doc_mut_copy(doc.ptr(), alc);
}
}
virtual ~mut_doc() {
if (m_doc) {
yyjson_mut_doc_free(m_doc);
}
}
operator bool() const {
return m_doc != nullptr;
}
std::string json(yyjson_write_flag flg = YYJSON_WRITE_NOFLAG) const {
char* cstr = yyjson_mut_write(m_doc, flg, nullptr);
YYJSON_CHECK(cstr, "Failed yyjson_write");
std::string result(cstr);
free(cstr);
return result;
}
mut_val_view root() const {
return mut_val_view(yyjson_mut_doc_get_root(m_doc), m_doc);
}
void root(mut_val_view val) {
yyjson_mut_doc_set_root(m_doc, val.ptr());
}
#if YYJSON_VERSION_HEX > 0x000200
mut_val_view get_pointer(const char* pointer) const {
return mut_val_view(yyjson_mut_doc_get_pointer(m_doc, pointer));
}
mut_val_view get_pointer(const std::string& pointer) const {
return mut_val_view(yyjson_mut_doc_get_pointer(m_doc, pointer.c_str()));
}
#endif
mut_val_view copy_val(val_view val) {
return mut_val_view(yyjson_val_mut_copy(m_doc, val.ptr()), m_doc);
}
mut_val_view mut_val(nullptr_t val) {
return mut_val_view(yyjson_mut_null(m_doc), m_doc);
}
mut_val_view mut_val(bool val) {
return mut_val_view(yyjson_mut_bool(m_doc, val), m_doc);
}
mut_val_view mut_val(uint64_t val) {
return mut_val_view(yyjson_mut_uint(m_doc, val), m_doc);
}
mut_val_view mut_val(int64_t val) {
return mut_val_view(yyjson_mut_sint(m_doc, val), m_doc);
}
mut_val_view mut_val(double val) {
return mut_val_view(yyjson_mut_real(m_doc, val), m_doc);
}
mut_val_view mut_val(const char* val) {
return mut_val_view(yyjson_mut_strcpy(m_doc, val), m_doc);
}
mut_val_view mut_val(const std::string& val) {
return mut_val_view(yyjson_mut_strcpy(m_doc, val.c_str()), m_doc);
}
mut_val_view mut_val(const char* val, size_t len) {
return mut_val_view(yyjson_mut_strncpy(m_doc, val, len), m_doc);
}
mut_val_view mut_arr() {
return mut_val_view(yyjson_mut_arr(m_doc), m_doc);
}
mut_val_view mut_arr(bool* vals, size_t len) {
return mut_val_view(yyjson_mut_arr_with_bool(m_doc, vals, len), m_doc);
}
mut_val_view mut_arr(float* vals, size_t len) {
return mut_val_view(yyjson_mut_arr_with_float(m_doc, vals, len), m_doc);
}
mut_val_view mut_arr(double* vals, size_t len) {
return mut_val_view(yyjson_mut_arr_with_real(m_doc, vals, len), m_doc);
}
mut_val_view mut_arr(int8_t* vals, size_t len) {
return mut_val_view(yyjson_mut_arr_with_sint8(m_doc, vals, len), m_doc);
}
mut_val_view mut_arr(int16_t* vals, size_t len) {
return mut_val_view(yyjson_mut_arr_with_sint16(m_doc, vals, len), m_doc);
}
mut_val_view mut_arr(int32_t* vals, size_t len) {
return mut_val_view(yyjson_mut_arr_with_sint32(m_doc, vals, len), m_doc);
}
mut_val_view mut_arr(int64_t* vals, size_t len) {
return mut_val_view(yyjson_mut_arr_with_sint(m_doc, vals, len), m_doc);
}
mut_val_view mut_arr(uint8_t* vals, size_t len) {
return mut_val_view(yyjson_mut_arr_with_uint8(m_doc, vals, len), m_doc);
}
mut_val_view mut_arr(uint16_t* vals, size_t len) {
return mut_val_view(yyjson_mut_arr_with_uint16(m_doc, vals, len), m_doc);
}
mut_val_view mut_arr(uint32_t* vals, size_t len) {
return mut_val_view(yyjson_mut_arr_with_uint32(m_doc, vals, len), m_doc);
}
mut_val_view mut_arr(uint64_t* vals, size_t len) {
return mut_val_view(yyjson_mut_arr_with_uint(m_doc, vals, len), m_doc);
}
mut_val_view mut_arr(const char** vals, size_t len) {
return mut_val_view(yyjson_mut_arr_with_strcpy(m_doc, vals, len), m_doc);
}
template <typename T>
mut_val_view mut_arr(const T& vals) {
std::unique_ptr<T::value_type[]> ptr(new T::value_type[vals.size()]);
std::copy(vals.begin(), vals.end(), ptr);
return mut_arr(ptr.get(), vals.size());
}
template <typename T>
mut_val_view mut_arr(const std::vector<T>& vals) {
return mut_arr(vals.data(), vals.size());
}
template <>
mut_val_view mut_arr(const std::vector<bool>& vals) {
bool* ptr = new bool[vals.size()];
std::copy(vals.begin(), vals.end(), ptr);
mut_val_view result(mut_arr(ptr, vals.size()));
delete[] ptr;
return result;
}
/** Creates and returns a mutable object, returns NULL on error. */
mut_val_view mut_obj() {
return mut_val_view(yyjson_mut_obj(m_doc), m_doc);
}
/**
* Creates and returns a mutable object with keys and values, returns NULL on error. The keys
* and values are NOT copied. The strings should be encoded as UTF-8 with null-terminator.
* <pre>
* sample:
* const char vkeys[] = {"name", "type", "id"};
* const char *vals[] = {"Harry", "student", "888999"};
* yyjson_mut_obj_with_str(doc, keys, vals, 3);
* </pre>
*/
mut_val_view mut_obj(const char** keys, const char** vals, size_t count) {
return mut_val_view(yyjson_mut_obj_with_str(m_doc, keys, vals, count), m_doc);
}
template <typename KeyT, typename ValT>
mut_val_view mut_obj(const std::map<KeyT, ValT>& kv) {
mut_val_view result = mut_obj();
for (auto iter = kv.begin(); iter != kv.end(); ++iter) {
mut_val_view key = mut_val(iter->first);
mut_val_view val = mut_val(iter->second);
yyjson_mut_obj_add(result.ptr(), key.ptr(), val.ptr());
}
return result;
}
template <typename KeyT, typename ValT>
mut_val_view mut_obj(const std::unordered_map<KeyT, ValT>& kv) {
mut_val_view result = mut_obj();
for (auto iter = kv.begin(); iter != kv.end(); ++iter) {
mut_val_view key = mut_val(iter->first);
mut_val_view val = mut_val(iter->second);
yyjson_mut_obj_add(result.ptr(), key.ptr(), val.ptr());
}
return result;
}
private:
yyjson_mut_doc* m_doc{nullptr};
};
} // namespace yyjson

View File

@ -1,551 +0,0 @@
/*
* Copyright(C) 2021 hikyuu.org
*
* Create on: 2021-03-15
* Author: fasiondog
*/
#pragma once
#include <type_traits>
#include <string>
#include <vector>
#include <iterator>
#include <yyjson.h>
#include "yyjson_val_view.h"
#include "exception.h"
namespace yyjson {
template <class T>
class MutValArrIterator : public std::iterator<std::input_iterator_tag, T> {
public:
MutValArrIterator(T val) {
if (val && val.is_arr()) {
m_idx = 0;
m_max = unsafe_yyjson_get_len(val.ptr());
if (m_max) {
m_cur.ptr((yyjson_mut_val *)val.ptr()->uni.ptr);
m_cur.ptr(m_cur.ptr()->next);
}
}
}
//赋值
MutValArrIterator &operator=(const MutValArrIterator &iter) {
m_idx = iter.m_idx;
m_max = iter.m_max;
m_cur = iter.m_cur;
}
//不等于
bool operator!=(const MutValArrIterator &iter) {
return m_cur != iter.m_cur;
}
//等于
bool operator==(const MutValArrIterator &iter) {
return m_cur == iter.m_cur;
}
//前缀自加
MutValArrIterator &operator++() {
if (m_idx < m_max) {
m_idx++;
if (m_idx < m_max) {
m_cur.ptr(m_cur.ptr()->next);
} else {
m_cur.ptr(nullptr);
}
}
return *this;
}
//后缀自加
MutValArrIterator operator++(int) {
MutValArrIterator tmp = *this;
if (m_idx < m_max) {
m_idx++;
if (m_idx < m_max) {
m_cur.ptr(m_cur.ptr()->next);
} else {
m_cur.ptr(nullptr);
}
}
return tmp;
}
//取值
T operator*() {
return m_cur;
}
T *operator->() {
return &m_cur;
}
private:
size_t m_idx{0};
size_t m_max{0};
T m_cur;
};
#define YY_MUT_VAL_IS(typ) \
bool is_##typ() const { \
return yyjson_mut_is_##typ(m_val); \
}
class mut_val_view {
public:
mut_val_view() = default;
mut_val_view(yyjson_mut_val *val, yyjson_mut_doc *doc) : m_val(val), m_doc(doc) {}
mut_val_view(const mut_val_view &) = default;
mut_val_view &operator=(const mut_val_view &) = default;
virtual ~mut_val_view() = default;
yyjson_mut_val *ptr() const {
return m_val;
}
void ptr(yyjson_mut_val *val) {
m_val = val;
}
operator bool() const {
return m_val != nullptr;
}
bool operator==(const mut_val_view &other) {
return m_val == other.m_val;
}
bool operator!=(const mut_val_view &other) {
return m_val != other.m_val;
}
YY_MUT_VAL_IS(null)
YY_MUT_VAL_IS(true)
YY_MUT_VAL_IS(false)
YY_MUT_VAL_IS(bool)
YY_MUT_VAL_IS(uint)
YY_MUT_VAL_IS(sint)
YY_MUT_VAL_IS(int)
YY_MUT_VAL_IS(real) // double number
YY_MUT_VAL_IS(num) // integer or double number
YY_MUT_VAL_IS(str) // c字符串
YY_MUT_VAL_IS(arr) // array
YY_MUT_VAL_IS(obj) // object
YY_MUT_VAL_IS(ctn) // array or object
/** Returns value's type. */
yyjson_type type() const {
return yyjson_mut_get_type(m_val);
}
/** Returns value's subtype. */
yyjson_subtype subtype() const {
return yyjson_mut_get_subtype(m_val);
}
/** Returns value's tag. */
uint8_t tag() const {
return yyjson_mut_get_tag(m_val);
}
/**
* Returns type description, such as: "null", "string", "array", "object", "true", "false",
* "uint", "sint", "real", "unknown"
*/
const char *type_desc() const {
return yyjson_mut_get_type_desc(m_val);
}
bool value(bool fallback) const {
return yyjson_mut_is_bool(m_val) ? unsafe_yyjson_get_bool((yyjson_val *)m_val) : fallback;
}
uint64_t value(uint64_t fallback) const {
return yyjson_mut_is_int(m_val) ? unsafe_yyjson_get_uint((yyjson_val *)m_val) : fallback;
}
int64_t value(int64_t fallback) const {
return yyjson_mut_is_int(m_val) ? unsafe_yyjson_get_sint((yyjson_val *)m_val) : fallback;
}
int value(int fallback) const {
int result = fallback;
if (yyjson_mut_is_int(m_val)) {
try {
result = static_cast<int>(unsafe_yyjson_get_sint((yyjson_val *)m_val));
} catch (...) {
}
}
return result;
}
double value(double fallback) const {
return yyjson_mut_is_num(m_val) ? unsafe_yyjson_get_real((yyjson_val *)m_val) : fallback;
}
float value(float fallback) const {
return yyjson_mut_is_num(m_val) ? (float)unsafe_yyjson_get_real((yyjson_val *)m_val)
: fallback;
}
std::string value(const char *fallback) const {
return yyjson_mut_is_str(m_val) ? std::string(unsafe_yyjson_get_str((yyjson_val *)m_val))
: std::string(fallback);
}
std::string value(const std::string &fallback) const {
return yyjson_mut_is_str(m_val) ? std::string(unsafe_yyjson_get_str((yyjson_val *)m_val))
: fallback;
}
template <typename T>
T value() const {
YYJSON_THROW("Unsupport type!");
}
template <>
bool value() const {
YY_TYPE_CHECK(bool);
return unsafe_yyjson_get_bool((yyjson_val *)m_val);
}
template <>
uint64_t value() const {
YY_TYPE_CHECK(int);
return unsafe_yyjson_get_uint((yyjson_val *)m_val);
}
template <>
int64_t value() const {
YY_TYPE_CHECK(int);
return unsafe_yyjson_get_sint((yyjson_val *)m_val);
}
template <>
int value() const {
YY_TYPE_CHECK(int);
return static_cast<int>(unsafe_yyjson_get_sint((yyjson_val *)m_val));
}
template <>
double value() const {
YY_TYPE_CHECK(num);
return unsafe_yyjson_get_real((yyjson_val *)m_val);
}
template <>
float value() const {
YY_TYPE_CHECK(num);
return static_cast<float>(unsafe_yyjson_get_real((yyjson_val *)m_val));
}
template <>
std::string value() const {
YY_TYPE_CHECK(str);
return std::string(unsafe_yyjson_get_str((yyjson_val *)m_val));
}
mut_val_view get(const char *key) const {
return mut_val_view(yyjson_mut_obj_get(m_val, key), m_doc);
}
mut_val_view operator[](const char *key) {
return get(key);
}
mut_val_view get_no_mapping() const {
return mut_val_view(yyjson_mut_obj_get(m_val, NULL), m_doc);
}
#if YYJSON_VERSION_HEX > 0x000200
mut_val_view get_pointer(const char *pointer) const {
return mut_val_view(yyjson_mut_get_pointer(m_val, pointer));
}
mut_val_view get_pointer(const std::string &pointer) const {
return mut_val_view(yyjson_mut_get_pointer(m_val, pointer.c_str()));
}
#endif
size_t arr_size() const {
return yyjson_mut_arr_size(m_val);
}
/** Returns the number of key-value pairs in this object, or 0 if input is not an object. */
size_t obj_size() const {
return yyjson_mut_obj_size(m_val);
}
/** Returns the number of key-value pairs in the object , or the number of arr, else 0. */
size_t size() const {
if (is_arr()) {
return yyjson_mut_arr_size(m_val);
} else if (is_obj()) {
return yyjson_mut_obj_size(m_val);
} else {
return 0;
}
}
MutValArrIterator<mut_val_view> arr_begin() {
return MutValArrIterator<mut_val_view>(*this);
}
MutValArrIterator<mut_val_view> arr_end() {
return MutValArrIterator<mut_val_view>(mut_val_view());
}
/*typedef ArrIterator<mut_val_view> iterator;
iterator begin() {
return iterator(*this, 0);
}
iterator end() {
return iterator(*this, arr_size());
}*/
void for_each(std::function<void(mut_val_view)> func) const {
size_t idx, max;
yyjson_mut_val *val;
yyjson_mut_arr_foreach(m_val, idx, max, val) {
func(mut_val_view(val, m_doc));
}
}
void for_each(std::function<void(mut_val_view, mut_val_view)> func) {
size_t idx = 0, max = 0;
yyjson_mut_val *key = nullptr;
yyjson_mut_val *val = nullptr;
for (idx = 0, max = yyjson_mut_obj_size(m_val),
key = max ? ((yyjson_mut_val *)m_val->uni.ptr)->next->next : NULL,
val = key ? key->next : NULL;
idx < max; idx++, key = val->next, val = key->next) {
func(mut_val_view(key, m_doc), mut_val_view(val, m_doc));
}
}
mut_val_view arr_get(size_t idx) const {
return mut_val_view(yyjson_mut_arr_get(m_val, idx), m_doc);
}
mut_val_view arr_get_first() const {
return mut_val_view(yyjson_mut_arr_get_first(m_val), m_doc);
}
mut_val_view arr_get_last() const {
return mut_val_view(yyjson_mut_arr_get_last(m_val), m_doc);
}
/**
* Inserts a value into an array at a given index, returns false on error.Note that Tthis
* function takes a linear search time.
*/
bool arr_insert(size_t idx, mut_val_view val) {
return yyjson_mut_arr_insert(m_val, val.ptr(), idx);
}
/** Inserts a val at the end of the array, returns false on error. */
bool arr_append(mut_val_view val) {
return yyjson_mut_arr_append(m_val, val.ptr());
}
/** Inserts a val at the head of the array, returns false on error. */
bool arr_prepend(mut_val_view val) {
return yyjson_mut_arr_prepend(m_val, val.ptr());
}
/**
* Replaces a value at index and returns old value, returns NULL on error.
* @note Note that his function takes a linear search time.
*/
mut_val_view arr_replace(size_t idx, mut_val_view val) {
return mut_val_view(yyjson_mut_arr_replace(m_val, idx, val.ptr()), m_doc);
}
/**
* Removes and returns a value at index, returns NULL on error.
* @note Note that this function takes a linear search time.
*/
mut_val_view arr_remove(size_t idx) {
return mut_val_view(yyjson_mut_arr_remove(m_val, idx), m_doc);
}
/** Returns and returns the first value in this array, returns NULL on error. */
mut_val_view arr_remove_first() {
return mut_val_view(yyjson_mut_arr_remove_first(m_val), m_doc);
}
/** Returns and returns the last value in this array, returns NULL on error. */
mut_val_view arr_remove_last() {
return mut_val_view(yyjson_mut_arr_remove_last(m_val), m_doc);
}
/**
* Removes all values within a specified range in the array.
* @note Note that this function takes a linear search time.
*/
bool arr_remove_range(size_t idx, size_t len) {
return yyjson_mut_arr_remove_range(m_val, idx, len);
}
/** Removes all values in this array. */
bool arr_clear() {
return yyjson_mut_arr_clear(m_val);
}
bool arr_add(mut_val_view val) {
return yyjson_mut_arr_add_val(m_val, val.ptr());
}
bool arr_add(nullptr_t val) {
return yyjson_mut_arr_add_null(m_doc, m_val);
}
bool arr_add(bool val) {
return yyjson_mut_arr_add_bool(m_doc, m_val, val);
}
bool arr_add(uint64_t val) {
return yyjson_mut_arr_add_uint(m_doc, m_val, val);
}
bool arr_add(int64_t val) {
return yyjson_mut_arr_add_sint(m_doc, m_val, val);
}
bool arr_add(int val) {
return yyjson_mut_arr_add_int(m_doc, m_val, val);
}
bool arr_add(double val) {
return yyjson_mut_arr_add_real(m_doc, m_val, val);
}
bool arr_add(float val) {
return yyjson_mut_arr_add_real(m_doc, m_val, val);
}
bool arr_add(const char *val) {
return yyjson_mut_arr_add_strcpy(m_doc, m_val, val);
}
bool arr_add(const std::string &val) {
return yyjson_mut_arr_add_strcpy(m_doc, m_val, val.c_str());
}
/**
* Removes key-value pair from the object with given key.
* @note Note that this function takes a linear search time.
*/
bool obj_remove(mut_val_view key) {
return yyjson_mut_obj_remove(m_val, key.ptr());
}
/**
* Removes all key-value pairs for the given key.
* Note that this function takes a linear search time.
*/
bool obj_remove(const char *key) {
return yyjson_mut_obj_remove_str(m_val, key);
}
/** Removes all key-value pairs in this object. */
bool obj_clear() {
return yyjson_mut_obj_clear(m_val);
}
/**
* Adds a key-value pair at the end of the object. The key must be a string.
* This function allows duplicated key in one object.
*/
bool obj_add(mut_val_view key, mut_val_view val) {
return yyjson_mut_obj_add(m_val, key.ptr(), val.ptr());
}
/**
* Adds a key-value pair to the object, The key must be a string.
* This function may remove all key-value pairs for the given key before add.
* @note Note that this function takes a linear search time.
*/
bool obj_put(mut_val_view key, mut_val_view val) {
return yyjson_mut_obj_put(m_val, key.ptr(), val.ptr());
}
bool obj_add(const char *key, nullptr_t val) {
return yyjson_mut_obj_add_null(m_doc, m_val, key);
}
bool obj_add(const char *key, bool val) {
return yyjson_mut_obj_add_bool(m_doc, m_val, key, val);
}
bool obj_add(const char *key, uint64_t val) {
return yyjson_mut_obj_add_uint(m_doc, m_val, key, val);
}
bool obj_add(const char *key, int64_t val) {
return yyjson_mut_obj_add_sint(m_doc, m_val, key, val);
}
bool obj_add(const char *key, int val) {
return yyjson_mut_obj_add_int(m_doc, m_val, key, val);
}
bool obj_add(const char *key, double val) {
return yyjson_mut_obj_add_real(m_doc, m_val, key, val);
}
bool obj_add(const char *key, float val) {
return yyjson_mut_obj_add_real(m_doc, m_val, key, val);
}
bool obj_add(const char *key, const char *val) {
return yyjson_mut_obj_add_strcpy(m_doc, m_val, key, val);
}
private:
yyjson_mut_val *m_val{nullptr};
yyjson_mut_doc *m_doc{nullptr};
};
inline std::ostream &operator<<(std::ostream &os, mut_val_view val) {
if (val.is_bool()) {
if (val.value<bool>()) {
os << "true";
} else {
os << "false";
}
} else if (val.is_uint()) {
os << val.value<uint64_t>();
} else if (val.is_sint()) {
os << val.value<int64_t>();
} else if (val.is_real()) {
os << val.value<double>();
} else if (val.is_str()) {
os << "\"" << val.value<std::string>() << "\"";
} else if (val.is_null()) {
os << "null";
} else if (val.is_arr()) {
os << "[";
for (auto iter = val.arr_begin(); iter != val.arr_end(); ++iter) {
os << *iter << ", ";
}
os << "]";
/*} else if (val.is_obj()) {
os << "{";
for (auto iter = val.begin(); iter != val.end(); ++iter) {
os << iter->first << ": " << iter->second << ", ";
}
os << "}";*/
} else {
os << val.type_desc();
}
return os;
}
} // namespace yyjson

View File

@ -1,474 +0,0 @@
/*
* Copyright(C) 2021 hikyuu.org
*
* Create on: 2021-03-11
* Author: fasiondog
*/
#pragma once
#include <iostream>
#include <type_traits>
#include <string>
#include <vector>
#include <iterator>
#include <utility>
#include <yyjson.h>
#include "exception.h"
namespace yyjson {
template <class T>
class ValArrIterator : public std::iterator<std::input_iterator_tag, T> {
public:
ValArrIterator(T val) : m_val(val) {
if (m_val && m_val.is_arr()) {
m_idx = 0;
m_max = unsafe_yyjson_get_len(m_val.ptr());
m_val.ptr(unsafe_yyjson_get_first(m_val.ptr()));
}
}
//赋值
ValArrIterator &operator=(const ValArrIterator &iter) {
m_val = iter.m_val;
m_idx = iter.m_idx;
m_max = iter.m_max;
}
//不等于
bool operator!=(const ValArrIterator &iter) {
return m_val != iter.m_val;
}
//等于
bool operator==(const ValArrIterator &iter) {
return m_val == iter.m_val;
}
//前缀自加
ValArrIterator &operator++() {
if (m_val && m_idx < m_max) {
m_idx++;
if (m_idx < m_max) {
m_val.ptr(unsafe_yyjson_get_next(m_val.ptr()));
} else {
m_val.ptr(nullptr);
}
}
return *this;
}
//后缀自加
ValArrIterator operator++(int) {
ValArrIterator tmp = *this;
if (m_val && m_idx < m_max) {
m_idx++;
if (m_idx < m_max) {
m_val.ptr(unsafe_yyjson_get_next(m_val.ptr()));
} else {
m_val.ptr(nullptr);
}
}
return tmp;
}
//取值
T operator*() {
return m_val;
}
T *operator->() {
return &m_val;
}
private:
T m_val;
size_t m_idx{0};
size_t m_max{0};
};
template <class T>
class ValObjIterator : public std::iterator<std::input_iterator_tag, T> {
public:
ValObjIterator(T val) {
if (val && val.is_obj()) {
m_idx = 0;
m_max = unsafe_yyjson_get_len(val.ptr());
yyjson_val *cur = unsafe_yyjson_get_first(val.ptr());
m_cur = std::make_pair(cur, cur + 1);
m_pre = m_cur;
}
}
//赋值
ValObjIterator &operator=(const ValObjIterator &iter) {
m_cur = iter.m_cur;
m_pre = iter.m_pre;
m_idx = iter.m_idx;
m_max = iter.m_max;
}
//不等于
bool operator!=(const ValObjIterator &iter) {
return m_cur.first != iter.m_cur.first;
}
//等于
bool operator==(const ValObjIterator &iter) {
return m_cur.first == iter.m_cur.first;
}
//前缀自加
ValObjIterator &operator++() {
if (m_cur.first && m_idx < m_max) {
m_idx++;
m_pre = m_cur;
yyjson_val *cur = nullptr;
if (m_idx < m_max) {
yyjson_val *cur = unsafe_yyjson_get_next(m_cur.second.ptr());
m_cur.first = val_view(cur);
m_cur.second = val_view(cur + 1);
} else {
m_cur.first = val_view();
m_cur.second = val_view();
}
}
return *this;
}
//后缀自加
ValObjIterator operator++(int) {
ValObjIterator tmp = *this;
if (m_cur.first && m_idx < m_max) {
m_idx++;
m_pre = m_cur;
yyjson_val *cur = nullptr;
if (m_idx < m_max) {
yyjson_val *cur = unsafe_yyjson_get_next(m_cur.second.ptr());
m_cur.first = val_view(cur);
m_cur.second = val_view(cur + 1);
} else {
m_cur.first = val_view();
m_cur.second = val_view();
}
}
return tmp;
}
//取值
std::pair<T, T> operator*() {
return m_cur;
}
std::pair<T, T> *operator->() {
return &m_cur;
}
private:
std::pair<T, T> m_cur;
std::pair<T, T> m_pre;
size_t m_idx{0};
size_t m_max{0};
};
#define YY_TYPE_CHECK(typ, ...) \
{ \
if (!is_##typ()) { \
throw yyjson::bad_cast( \
fmt::format("This value type is {}, but expect " #typ, type_desc())); \
} \
}
#define YY_VAL_IS(typ) \
bool is_##typ() const { \
return yyjson_is_##typ(m_val); \
}
#define YY_VAL_GET(rtyp, typ) \
rtyp get_##typ() const { \
if (!yyjson_is_##typ(m_val)) { \
YYJSON_THROW("This value type is {}, not " #typ "!", type_desc()); \
} \
return unsafe_yyjson_get_##typ(m_val); \
}
class val_view {
public:
val_view() = default;
val_view(yyjson_val *val) : m_val(val) {}
val_view(const val_view &) = default;
val_view &operator=(const val_view &) = default;
virtual ~val_view() = default;
yyjson_val *const ptr() const {
return m_val;
}
void ptr(yyjson_val *val) {
m_val = val;
}
operator bool() {
return m_val != nullptr;
}
bool operator==(const val_view &other) {
return m_val == other.m_val;
}
bool operator!=(const val_view &other) {
return m_val != other.m_val;
}
YY_VAL_IS(null)
YY_VAL_IS(true)
YY_VAL_IS(false)
YY_VAL_IS(bool)
YY_VAL_IS(uint)
YY_VAL_IS(sint)
YY_VAL_IS(int)
YY_VAL_IS(real) // double number
YY_VAL_IS(num) // integer or double number
YY_VAL_IS(str) // c字符串
YY_VAL_IS(arr) // array
YY_VAL_IS(obj) // object
YY_VAL_IS(ctn) // array or object
/** Returns value's type. */
yyjson_type type() const {
return yyjson_get_type(m_val);
}
/** Returns value's subtype. */
yyjson_subtype subtype() const {
return yyjson_get_subtype(m_val);
}
/** Returns value's tag. */
uint8_t tag() const {
return yyjson_get_tag(m_val);
}
/**
* Returns type description, such as: "null", "string", "array", "object", "true", "false",
* "uint", "sint", "real", "unknown"
*/
const char *type_desc() const {
return yyjson_get_type_desc(m_val);
}
bool value(bool fallback) const {
return yyjson_is_bool(m_val) ? unsafe_yyjson_get_bool(m_val) : fallback;
}
uint64_t value(uint64_t fallback) const {
return yyjson_is_int(m_val) ? unsafe_yyjson_get_uint(m_val) : fallback;
}
int64_t value(int64_t fallback) const {
return yyjson_is_int(m_val) ? unsafe_yyjson_get_sint(m_val) : fallback;
}
int value(int fallback) const {
int result = fallback;
if (yyjson_is_int(m_val)) {
try {
result = static_cast<int>(unsafe_yyjson_get_sint(m_val));
} catch (...) {
}
}
return result;
}
double value(double fallback) const {
return yyjson_is_num(m_val) ? unsafe_yyjson_get_real(m_val) : fallback;
}
float value(float fallback) const {
return yyjson_is_num(m_val) ? (float)unsafe_yyjson_get_real(m_val) : fallback;
}
std::string value(const char *fallback) {
return yyjson_is_str(m_val) ? std::string(unsafe_yyjson_get_str(m_val))
: std::string(fallback);
}
std::string value(const std::string &fallback) {
return yyjson_is_str(m_val) ? std::string(unsafe_yyjson_get_str(m_val)) : fallback;
}
template <typename T>
T value() const {
YYJSON_THROW("Unsupport type!");
}
template <>
bool value() const {
YY_TYPE_CHECK(bool);
return unsafe_yyjson_get_bool(m_val);
}
template <>
uint64_t value() const {
YY_TYPE_CHECK(int);
return unsafe_yyjson_get_uint(m_val);
}
template <>
int64_t value() const {
YY_TYPE_CHECK(int);
return unsafe_yyjson_get_sint(m_val);
}
template <>
int value() const {
YY_TYPE_CHECK(int);
return static_cast<int>(unsafe_yyjson_get_sint(m_val));
}
template <>
double value() const {
YY_TYPE_CHECK(num);
return unsafe_yyjson_get_real(m_val);
}
template <>
float value() const {
YY_TYPE_CHECK(num);
return static_cast<float>(unsafe_yyjson_get_real(m_val));
}
template <>
std::string value() const {
YY_TYPE_CHECK(str);
return std::string(unsafe_yyjson_get_str(m_val));
}
val_view get(const char *key) const {
return val_view(yyjson_obj_get(m_val, key));
}
val_view get(const std::string &key) const {
return val_view(yyjson_obj_get(m_val, key.c_str()));
}
val_view get(size_t idx) const {
return val_view(yyjson_arr_get(m_val, idx));
}
val_view operator[](const char *key) {
return get(key);
}
val_view operator[](const std::string &key) {
return get(key);
}
val_view operator[](size_t idx) {
return get(idx);
}
#if YYJSON_VERSION_HEX > 0x000200
val_view get_pointer(const char *pointer) const {
return val_view(yyjson_get_pointer(m_val, pointer));
}
val_view get_pointer(const std::string& pointer) const {
return val_view(yyjson_get_pointer(m_val, pointer.c_str()));
}
#endif
ValArrIterator<val_view> arr_begin() const {
return ValArrIterator<val_view>(*this);
}
ValArrIterator<val_view> arr_end() const {
return ValArrIterator<val_view>(val_view());
}
ValObjIterator<val_view> begin() const {
return ValObjIterator<val_view>(*this);
}
ValObjIterator<val_view> end() const {
return ValObjIterator<val_view>(val_view());
}
size_t arr_size() const {
return yyjson_arr_size(m_val);
}
/** Returns the number of key-value pairs in this object, or 0 if input is not an object. */
size_t obj_size() const {
return yyjson_obj_size(m_val);
}
/** Returns the number of key-value pairs in the object , or the number of arr, else 0. */
size_t size() const {
if (is_arr()) {
return yyjson_arr_size(m_val);
} else if (is_obj()) {
return yyjson_obj_size(m_val);
} else {
return 0;
}
}
void for_each(std::function<void(val_view)> func) const {
size_t idx = 0, max = 0;
yyjson_val *val = nullptr;
yyjson_arr_foreach(m_val, idx, max, val) {
func(val_view(val));
}
}
void for_each(std::function<void(val_view, val_view)> func) const {
size_t idx = 0, max = 0;
yyjson_val *key = nullptr, *val = nullptr;
yyjson_obj_foreach(m_val, idx, max, key, val) {
func(val_view(key), val_view(val));
}
}
private:
yyjson_val *m_val{nullptr};
};
inline std::ostream &operator<<(std::ostream &os, val_view val) {
if (val.is_bool()) {
if (val.value<bool>()) {
os << "true";
} else {
os << "false";
}
} else if (val.is_uint()) {
os << val.value<uint64_t>();
} else if (val.is_sint()) {
os << val.value<int64_t>();
} else if (val.is_real()) {
os << val.value<double>();
} else if (val.is_str()) {
os << "\"" << val.value<std::string>() << "\"";
} else if (val.is_null()) {
os << "null";
} else if (val.is_arr()) {
os << "[";
for (auto iter = val.arr_begin(); iter != val.arr_end(); ++iter) {
os << *iter << ", ";
}
os << "]";
} else if (val.is_obj()) {
os << "{";
for (auto iter = val.begin(); iter != val.end(); ++iter) {
os << iter->first << ": " << iter->second << ", ";
}
os << "}";
} else {
os << val.type_desc();
}
return os;
}
} // namespace yyjson