14#include <simstr/sstring.h>
19#ifndef __has_declspec_attribute
20#define __has_declspec_attribute(x) 0
23#ifdef SIMJSON_IN_SHARED
24 #if defined(_MSC_VER) || (defined(__clang__) && __has_declspec_attribute(dllexport))
26 #define SIMJSON_API __declspec(dllexport)
28 #define SIMJSON_API __declspec(dllimport)
30 #elif (defined(__GNUC__) || defined(__GNUG__)) && defined(SIMSTR_EXPORT)
31 #define SIMJSON_API __attribute__((visibility("default")))
44using namespace simstr;
45using namespace simstr::literals;
60 struct emptyString_t {};
61 struct emptyObject_t {};
62 struct emptyArray_t {};
64 inline static const null_t null;
65 inline static const emptyString_t emptyString;
66 inline static const emptyObject_t emptyObject;
67 inline static const emptyArray_t emptyArray;
70enum class JsonParseResult {
77struct StreamedJsonParserBase {
84 u16s currentUnicode_[2]{};
91using KeyType = StoreType<K, strhash<K>>;
93template<
typename T,
typename K>
94concept JsonType = std::is_integral_v<std::remove_cvref_t<T>> ||
95 std::is_floating_point_v<std::remove_cvref_t<T>> ||
96 std::is_constructible_v<sstring<K>, T>;
98template<
typename T,
typename K>
99concept JsonKeyType = std::convertible_to<T, simple_str<K>> ||
100 std::same_as<std::remove_cvref_t<T>, KeyType<K>>;
102template<
typename T,
typename K>
103concept JsonArraySource =
requires(
const T& t) {
104 { t.empty() } -> std::same_as<bool>;
105 { t.size() } -> std::same_as<size_t>;
106 { *t.begin() } -> JsonType<K>;
107 { *t.end() } -> JsonType<K>;
110template<
typename T,
typename K>
111concept JsonObjectSource =
requires(
const T& t) {
112 { t.empty() } -> std::same_as<bool>;
113 { t.size() } -> std::same_as<size_t>;
114 { t.begin()->first } -> JsonKeyType<K>;
115 { t.end()->first } -> JsonKeyType<K>;
116 { t.begin()->second } -> JsonType<K>;
117 { t.end()->second } -> JsonType<K>;
131 using strType = sstring<K>;
132 using ssType = simple_str<K>;
135 using obj_type = hashStrMap<K, JsonValueTempl<K>>;
136 using arr_type = std::vector<JsonValueTempl<K>>;
137 using json_object = std::shared_ptr<obj_type>;
138 using json_array = std::shared_ptr<arr_type>;
150 switch (other.type_) {
152 new (&val_.text) strType(std::move(other.val_.text));
155 new (&val_.object) json_object(std::move(other.val_.object));
158 new (&val_.array) json_array(std::move(other.val_.array));
161 memcpy(&val_, &other.val_,
sizeof(val_));
163 other.type_ = Undefined;
191 new (&val_.text) strType(std::move(t));
196 new (&val_.text) strType(t);
200 template<StrExprForType<K> A>
202 new (&val_.text) strType(e);
206 template<typename T, size_t N = const_lit_for<K, T>::Count>
208 new (&val_.text) strType(std::forward<T>(str));
219 new (&val_.object) json_object(std::make_shared<obj_type>());
224 new (&val_.array) json_array(std::make_shared<arr_type>());
230 struct KeyInit : std::pair<const jt::KeyType<K>, json_value> {
231 using base = std::pair<const jt::KeyType<K>, json_value>;
232 KeyInit(
const jt::KeyType<K>& k,
const json_value& v) : base(k, v){}
233 KeyInit(ssType k,
const json_value& v) : base(obj_type::toStoreType(k), v){}
235 using ObjectInit = std::initializer_list<KeyInit>;
242 new (&val_.object) json_object(std::make_shared<obj_type>(std::move(
reinterpret_cast<std::initializer_list<std::pair<const jt::KeyType<K>, json_value
>>&>(init))));
244 using ArrayInit = std::initializer_list<json_value>;
251 new (&val_.array) json_array(std::make_shared<arr_type>(std::move(init)));
261 auto& arr = *as_array();
262 arr.reserve(obj.size());
263 for (const auto& e : obj) {
276 auto& me = *as_object();
277 for (const auto& [f, s] : obj) {
284 const json_value& from;
297 Type
type()
const {
return type_; }
312 bool is_null()
const {
return type_ == Null; };
321 bool is_real()
const {
return type_ == Real; }
324 bool is_text()
const {
return type_ == Text; }
339 assert(type_ == Boolean);
350 if (type_ == Boolean) {
357 template<
typename Exc,
typename ... Args>
requires (std::is_constructible_v<Exc, Args...>)
359 if (type_ == Boolean) {
362 throw Exc(std::forward<Args>(args)...);
372 assert(type_ == Integer);
378 if (type_ == Integer) {
385 template<
typename Exc,
typename ... Args>
requires (std::is_constructible_v<Exc, Args...>)
387 if (type_ == Integer) {
390 throw Exc(std::forward<Args>(args)...);
403 template<
typename Exc,
typename ... Args>
requires (std::is_constructible_v<Exc, Args...>)
408 throw Exc(std::forward<Args>(args)...);
414 assert(type_ == Real);
419 std::optional<double>
real()
const {
427 template<
typename Exc,
typename ... Args>
requires (std::is_constructible_v<Exc, Args...>)
432 throw Exc(std::forward<Args>(args)...);
449 template<
typename Exc,
typename ... Args>
requires (std::is_constructible_v<Exc, Args...>)
454 throw Exc(std::forward<Args>(args)...);
461 template<
typename Exc,
typename ... Args>
requires (std::is_constructible_v<Exc, Args...>)
466 throw Exc(std::forward<Args>(args)...);
474 assert(type_ == Text);
480 std::optional<strType>
text()
const {
488 template<
typename Exc,
typename ... Args>
requires (std::is_constructible_v<Exc, Args...>)
493 throw Exc(std::forward<Args>(args)...);
497 template<
typename Exc,
typename ... Args>
requires (std::is_constructible_v<Exc, Args...>)
499 if (type_ == Text && !val_.text.template trimmed<ssType>().is_empty()) {
502 throw Exc(std::forward<Args>(args)...);
512 assert(type_ == Object);
518 assert(type_ == Object);
524 assert(type_ == Array);
530 assert(type_ == Array);
535 void swap(json_value& other)
noexcept {
536 char tmp[
sizeof(*this)];
537 memcpy(tmp,
this,
sizeof(*
this));
538 memcpy((
void*)
this, &other,
sizeof(*
this));
539 memcpy((
void*)&other, tmp,
sizeof(*
this));
560 template<jt::JsonKeyType<K> T>
561 const json_value&
at(T&& key)
const {
562 if (type_ == Object) {
580 template<jt::JsonKeyType<K> T>
582 return at(std::forward<T>(key));
604 template<jt::JsonKeyType<K> T,
typename...Args>
606 const json_value& res =
at(std::forward<T>(key));
607 if constexpr (
sizeof...(Args) == 0) {
610 return res.
is_undefined() ? res : res(std::forward<Args>(args)...);
627 template<jt::JsonKeyType<K> T>
629 if (type_ != Object) {
630 assert(
this != &UNDEFINED);
633 return as_object()->try_emplace(std::forward<T>(key)).first->second;
655 template<jt::JsonKeyType<K> Key,
typename ... Args>
656 json_value&
set(Key&& key, Args&& ... args) {
657 if (type_ != Object) {
658 assert(
this != &UNDEFINED);
661 return as_object()->emplace(std::forward<Key>(key), std::forward<Args>(args)...).first->second;
665 const json_value&
at(
size_t idx)
const {
666 if (type_ == Array) {
668 if (idx < arr.size()) {
694 if (type_ != Array) {
695 assert(
this != &UNDEFINED);
702 if (idx >= arr.size()) {
710 if (type_ == Array) {
712 }
else if (type_ == Object) {
737 SIMJSON_API
void merge(
const json_value& other,
bool replace =
true,
bool append_arrays =
false);
752 static std::tuple<json_value, JsonParseResult, unsigned, unsigned>
parse(ssType jsonString);
773 SIMJSON_API
void store(lstring<K, 0, true>& stream,
bool prettify =
false,
bool order_keys =
false, K indent_symbol =
' ',
unsigned indent_count = 2)
const;
794 lstring<K, 0, true>
store(
bool prettify =
false,
bool order_keys =
false, K indent_symbol =
' ',
unsigned indent_count = 2)
const {
795 lstring<K, 0, true> res;
796 store(res, prettify, order_keys, indent_symbol, indent_count);
801 SIMJSON_API
static const json_value UNDEFINED;
807 Value() : boolean(false){}
831 using strType =
typename JsonValueTempl<K>::strType;
832 using ssType =
typename JsonValueTempl<K>::ssType;
847 return process<true, true>(text);
860 return last ? process<false, true>(chunk) : process<false, false>(chunk);
865 template<
bool All,
bool Last>
866 SIMJSON_API JsonParseResult process(ssType chunk);
868 static bool isWhiteSpace(K symbol) {
869 return symbol ==
' ' || symbol ==
'\t' || symbol ==
'\n' || symbol ==
'\r';
873 bool processUnicode(K symbol);
875 template<
bool Compound,
int NewState,
typename ... Args>
876 JsonValueTempl<K>* addValue(JsonValueTempl<K>* current, Args&& ... args);
878 JsonValueTempl<K>* popStack();
880 template<
bool asInt,
bool All>
881 JsonValueTempl<K>* addNumber(JsonValueTempl<K>* current);
884 const K* startProcess_ {};
885 std::vector<JsonValueTempl<K>*> stack_{&result_};
886 chunked_string_builder<K> text_{512};
892 auto res = parser.
parseAll(jsonString);
893 return {std::move(parser.result_), res, parser.line_, parser.col_};
911#if defined (SIMJSON_EXPORT) || !defined (SIMJSON_IN_SHARED)
Класс для представления json значения.
Definition json.h:129
JsonValueTempl(const emptyString_t &)
Definition json.h:215
std::optional< int64_t > number_int() const
Definition json.cpp:319
bool is_array() const
Definition json.h:327
JsonValueTempl(const A &e)
Definition json.h:201
json_value & operator[](size_t idx)
Access an array element by index.
Definition json.h:693
JsonValueTempl(jt::JsonObjectSource< K > auto const &obj)
Constructor from any standard container with pairs containing a string key in first and a JSON value ...
Definition json.h:274
SIMJSON_API std::optional< double > number_real() const
Definition json.cpp:330
const json_value & operator[](size_t idx) const
Definition json.h:676
int64_t integer_or_throw(Args &&...args) const
Definition json.h:386
double number_real_or_throw(Args &&...args) const
Definition json.h:462
bool is_boolean() const
Definition json.h:315
JsonValueTempl(const emptyArray_t &)
Definition json.h:223
const json_array & as_array() const
Definition json.h:529
std::optional< bool > boolean() const
Get a boolean if a boolean is stored, or nothing.
Definition json.h:349
JsonValueTempl(double v)
Definition json.h:186
int64_t as_integer() const
Definition json.h:371
JsonValueTempl & operator=(json_value t) noexcept
Definition json.h:544
JsonValueTempl(ssType t)
Definition json.h:195
const json_value & at(T &&key) const
Access to a property of a constant object by key.
Definition json.h:561
std::optional< double > real() const
Definition json.h:419
bool is_integer() const
Definition json.h:318
bool as_boolean() const
Get the value as boolean. The debug version checks that the value is indeed boolean.
Definition json.h:338
double real_or_throw(Args &&...args)
Definition json.h:428
JsonValueTempl(const null_t &)
Definition json.h:212
JsonValueTempl()
Definition json.h:142
bool is_object() const
Definition json.h:330
lstring< K, 0, true > store(bool prettify=false, bool order_keys=false, K indent_symbol=' ', unsigned indent_count=2) const
Serialize a json value to a string.
Definition json.h:794
void swap(json_value &other) noexcept
Definition json.h:535
std::optional< strType > text() const
Definition json.h:480
SIMJSON_API ~JsonValueTempl()
Definition json.cpp:154
json_value & set(Key &&key, Args &&... args)
Setting the value of a json object property by key.
Definition json.h:656
JsonValueTempl(bool v)
Definition json.h:183
SIMJSON_API void store(lstring< K, 0, true > &stream, bool prettify=false, bool order_keys=false, K indent_symbol=' ', unsigned indent_count=2) const
Serialize json value to string.
Definition json.cpp:504
JsonValueTempl(int16_t v)
Definition json.h:174
JsonValueTempl(T &&str)
Definition json.h:207
SIMJSON_API JsonValueTempl(const JsonValueTempl &other)
Definition json.cpp:128
SIMJSON_API void merge(const json_value &other, bool replace=true, bool append_arrays=false)
Merge with other JSON.
Definition json.cpp:386
JsonValueTempl(strType t)
Definition json.h:190
JsonValueTempl(ObjectInit &&init)
Constructor from initializer to create json::object. JsonValue v = {{"key1"_h, 1},...
Definition json.h:241
const strType & not_empty_text_or_throw(Args &&...args) const
Definition json.h:498
json_value & operator[](T &&key)
Access to an object property by key.
Definition json.h:628
SIMJSON_API JsonValueTempl(const Clone &clone)
Clone constructor. In this case, "deep" copies are created for objects and arrays.
Definition json.cpp:197
SIMJSON_API bool to_boolean() const
Definition json.cpp:224
json_object & as_object()
Definition json.h:511
json_array & as_array()
Definition json.h:523
SIMJSON_API std::optional< int64_t > to_integer() const
Get the value converted to an integer or nothing. The logic is the same as in javascript 1 * val....
Definition json.cpp:252
JsonValueTempl(ArrayInit &&init)
Constructor from initializer to create json::array. JsonValue json = {"key1", 12, false,...
Definition json.h:250
const json_object & as_object() const
Definition json.h:517
JsonValueTempl(const emptyObject_t &)
Definition json.h:218
const json_value & operator()(T &&key, Args &&...args) const
Access to a property of a constant object by a set of keys.
Definition json.h:605
JsonValueTempl(int8_t v)
Definition json.h:171
SIMJSON_API strType to_text() const
Definition json.cpp:341
int64_t to_integer_or_throw(Args &&...args) const
Definition json.h:404
bool is_text() const
Definition json.h:324
std::optional< int64_t > integer() const
Definition json.h:377
bool is_undefined() const
Definition json.h:309
JsonValueTempl(int32_t v)
Definition json.h:177
const json_value & operator[](T &&key) const
Access to a property of a constant object by key.
Definition json.h:581
const strType & as_text() const
Definition json.h:473
JsonValueTempl(JsonValueTempl &&other) noexcept
Definition json.h:148
JsonValueTempl(int64_t v)
Definition json.h:180
json_value clone() const
Definition json.h:300
JsonValueTempl(jt::JsonArraySource< K > auto const &obj)
Constructor from any standard array container containing JSON values.
Definition json.h:259
const strType & text_or_throw(Args &&...args) const
Definition json.h:489
bool is_null() const
Definition json.h:312
static std::tuple< json_value, JsonParseResult, unsigned, unsigned > parse(ssType jsonString)
Parse text to json.
Definition json.h:890
SIMJSON_API JsonValueTempl(Type type)
Definition json.cpp:171
double as_real() const
Definition json.h:413
bool is_real() const
Definition json.h:321
bool boolean_or_throw(Args &&...args) const
Definition json.h:358
int64_t number_int_or_throw(Args &&...args) const
Definition json.h:450
SIMJSON_API double to_real() const
Definition json.cpp:299
size_t size() const
Definition json.h:709
Type type() const
Definition json.h:297
const json_value & at(size_t idx) const
Definition json.h:665
Library namespace.
Definition json.h:43
JsonValueTempl< u16s > JsonValueU
Definition json.h:904
JsonValueTempl< uws > JsonValueW
Definition json.h:901
SIMJSON_API stringa get_file_content(stra filePath)
Read the file into a line.
Definition json.cpp:1140
JsonValueTempl< u8s > JsonValue
Definition json.h:898
JsonValueTempl< u32s > JsonValueUU
Definition json.h:907
Parser for text in JsonValue. Allows you to parse JSON in chunks of text. For example,...
Definition json.h:827
JsonParseResult parseAll(ssType text)
Parse all the text in one go.
Definition json.h:846
JsonParseResult processChunk(ssType chunk, bool last)
Parse a piece of text.
Definition json.h:859