1 #ifndef UTILS_JSON_H_INCLUDED
2 #define UTILS_JSON_H_INCLUDED
13 typedef std::map<std::string, Json> JsonObject;
14 typedef std::vector<Json> JsonArray;
50 JsonNumType get_type() {
return m_type; }
51 uint64_t as_uint()
const {
return m_type == FLOAT ? m_flt : m_pos; }
52 int64_t as_int()
const {
return m_type == FLOAT ? m_flt : m_neg; }
53 double as_float()
const {
return m_type == FLOAT ? m_flt : m_neg; }
54 double as_double()
const {
return m_type == FLOAT ? m_flt : m_neg; }
56 operator uint64_t()
const {
return as_uint(); }
57 operator int64_t()
const {
return as_int(); }
58 operator double()
const {
return as_double(); }
60 bool operator==(
const JsonNum& rhs)
const {
61 if (
m_type != rhs.m_type)
return false;
63 case POS_INT:
return m_pos == rhs.m_pos;
64 case NEG_INT:
return m_neg == rhs.m_neg;
65 case FLOAT:
return m_flt == rhs.m_flt;
74 case POS_INT:
return utils::to_string(m_pos);
75 case NEG_INT:
return utils::to_string(m_neg);
76 case FLOAT:
return utils::to_string(m_flt);
117 using value_type =
typename std::conditional<c, const Json, Json>::type;
118 using difference_type = std::ptrdiff_t;
119 using pointer =
typename std::conditional<c, const Json*, Json*>::type;
120 using reference =
typename std::conditional<c, const Json&, Json&>::type;
121 using iterator_category = std::bidirectional_iterator_tag;
125 JsonObject::iterator m_obj_iter;
126 JsonArray::iterator m_arr_iter;
130 iterator(pointer json) : m_json(json) {
131 assert(json !=
nullptr);
132 switch(m_json->get_type()) {
133 case OBJECT: m_obj_iter = JsonObject::iterator();
break;
134 case ARRAY: m_arr_iter = JsonArray::iterator();
break;
137 reference operator*()
const {
138 switch(m_json->get_type()) {
139 case OBJECT:
return m_obj_iter->second;
140 case ARRAY:
return *m_arr_iter;
141 default:
return *m_json;
144 pointer operator->()
const {
145 switch(m_json->get_type()) {
146 case OBJECT:
return &m_obj_iter->second;
147 case ARRAY:
return &*m_arr_iter;
148 default:
return m_json;
152 switch(m_json->get_type()) {
153 case OBJECT: ++m_obj_iter;
break;
154 case ARRAY: ++m_arr_iter;
break;
155 default: ++m_json;
break;
165 switch(m_json->get_type()) {
166 case OBJECT: --m_obj_iter;
break;
167 case ARRAY: --m_arr_iter;
break;
168 default: --m_json;
break;
177 bool operator==(
const iterator& rhs)
const {
178 if (m_json->get_type() != rhs.m_json->get_type())
return false;
179 switch(m_json->get_type()) {
180 case OBJECT:
return m_obj_iter == rhs.m_obj_iter;
181 case ARRAY:
return m_arr_iter == rhs.m_arr_iter;
182 default:
return m_json == rhs.m_json;
185 bool operator!=(
const iterator& rhs)
const {
186 return !operator==(rhs);
190 switch(m_json->get_type()) {
191 case OBJECT:
return m_obj_iter->first;
196 switch(m_json->get_type()) {
197 case OBJECT:
return m_obj_iter->second;
198 case ARRAY:
return *m_arr_iter;
199 default:
return *m_json;
204 switch(m_json->get_type()) {
205 case OBJECT: m_obj_iter = m_json->m_obj->begin();
break;
206 case ARRAY: m_arr_iter = m_json->m_arr->begin();
break;
207 case NONE: ++m_json;
break;
211 switch(m_json->get_type()) {
212 case OBJECT: m_obj_iter = m_json->m_obj->end();
break;
213 case ARRAY: m_arr_iter = m_json->m_arr->end();
break;
214 default: ++m_json;
break;
224 JsonToken() : type(SYMBOL), str(
nullptr) {}
226 str = (
char*)malloc(2);
230 JsonToken(
const std::string& str) : type(SYMBOL) {
231 this->str = strdup(str.c_str());
237 if (type == SYMBOL && str) free(str);
242 if (type == SYMBOL) {
243 str = other.str ? strdup(other.str) :
nullptr;
249 bool operator==(
const JsonToken& rhs)
const {
250 return type == rhs.type && ( type == SYMBOL ?
251 strcmp(str, rhs.str) == 0 : num == rhs.num);
253 bool operator!=(
const JsonToken& rhs)
const {
254 return !(*
this == rhs);
264 Json(JsonValueType type) : m_type(type) {}
267 static bool lex_string(std::string& str, JsonToken& ret);
269 static bool lex_number(std::string& str, JsonToken& ret);
271 static bool lex_bool(std::string& str, JsonToken& ret);
273 static bool lex_null(std::string& str, JsonToken& ret);
276 static std::queue<JsonToken>
tokenize(std::string curr);
278 static Json
parse_tokens(std::queue<JsonToken>& tokens);
280 JsonValueType m_type;
289 Json() : m_type(NONE) {}
290 Json(
const std::string& str) : m_type(STRING), m_str(strdup(str.c_str())) {}
291 Json(
const char* str) : m_type(STRING), m_str(strdup(str)) {}
292 Json(JsonNum num) : m_type(NUMBER), m_num(num) {}
293 Json(
double num) : m_type(NUMBER), m_num(num) {}
294 Json(std::size_t num) : m_type(NUMBER), m_num(num) {}
295 Json(
int num) : m_type(NUMBER), m_num(num) {}
296 Json(JsonObject obj) : m_type(OBJECT), m_obj(new JsonObject(obj)) {}
297 Json(JsonArray arr) : m_type(ARRAY), m_arr(new JsonArray(arr)) {}
298 Json(
bool b) : m_type(BOOLEAN), m_bool(b) {}
299 Json(
const std::initializer_list<Json>& data);
300 Json(
const Json& other);
304 static Json string(
const std::string& str) {
306 s.m_str = strdup(str.c_str());
309 static Json string(
const char* str) {
311 s.m_str = strdup(str);
314 static Json number(JsonNum num) {
319 static Json object(JsonObject obj) {
321 o.m_obj =
new JsonObject(obj);
324 static Json array(JsonArray arr) {
326 a.m_arr =
new JsonArray(arr);
329 static Json boolean(
bool boolean) {
334 static Json
null() {
return Json(NONE); }
337 static Json
parse(
const std::string& json);
338 static Json
from_file(
const std::string& path);
340 JsonValueType get_type()
const {
return m_type; }
341 bool is_string()
const {
return m_type == STRING; }
342 bool is_number()
const {
return m_type == NUMBER; }
343 bool is_object()
const {
return m_type == OBJECT; }
344 bool is_array()
const {
return m_type == ARRAY; }
345 bool is_bool()
const {
return m_type == BOOLEAN; }
346 bool is_null()
const {
return m_type == NONE; }
348 std::string as_string()
const;
349 JsonNum as_number()
const;
350 uint64_t as_uint()
const {
return as_number().as_uint(); }
351 int64_t as_int()
const {
return as_number().as_int(); }
352 double as_float()
const {
return as_number().as_float(); }
353 double as_double()
const {
return as_number().as_double(); }
354 JsonObject as_object()
const {
return *m_obj; }
355 JsonArray as_array()
const {
return *m_arr; }
356 bool as_bool()
const;
358 std::size_t size()
const;
359 bool is_empty()
const {
return size() == 0; }
360 bool has_key(
const std::string& key)
const;
364 bool resize(std::size_t size);
376 Json&
merge(
const Json& other);
381 std::string
dump(std::size_t indent = 0, std::size_t offset = 0)
const;
383 operator std::string()
const {
return as_string(); }
384 operator JsonNum()
const {
return as_number(); }
385 operator uint64_t()
const {
return as_uint(); }
386 operator int64_t()
const {
return as_int(); }
387 operator int()
const {
return as_int(); }
388 operator float()
const {
return as_double(); }
389 operator double()
const {
return as_double(); }
390 operator JsonObject()
const {
return as_object(); }
391 operator JsonArray()
const {
return as_array(); }
392 operator bool()
const {
return as_bool(); }
394 Json& operator=(
const Json& other);
395 Json& operator=(Json&& other);
396 bool operator==(
const Json& other)
const;
397 bool operator!=(
const Json& other)
const {
return !(*
this == other); }
398 bool operator==(
const std::string& other)
const {
return *
this == Json::string(other); }
399 bool operator!=(
const std::string& other)
const {
return !(*
this == other); }
400 bool operator==(
const char* other)
const {
return *
this == Json::string(other); }
401 bool operator!=(
const char* other)
const {
return !(*
this == other); }
402 bool operator==(
const JsonNum& other)
const {
return *
this == Json::number(other); }
403 bool operator!=(
const JsonNum& other)
const {
return !(*
this == other); }
404 bool operator==(
const int& other)
const {
return *
this == Json::number(other); }
405 bool operator!=(
const int& other)
const {
return !(*
this == other); }
406 bool operator==(
const JsonObject& other)
const {
return *
this == Json::object(other); }
407 bool operator!=(
const JsonObject& other)
const {
return !(*
this == other); }
408 bool operator==(
const JsonArray& other)
const {
return *
this == Json::array(other); }
409 bool operator!=(
const JsonArray& other)
const {
return !(*
this == other); }
410 bool operator==(
const bool& other)
const {
return *
this == Json::boolean(other); }
411 bool operator!=(
const bool& other)
const {
return !(*
this == other); }
415 Json&
operator[](
const std::string& key)
const;
424 iterator<0> begin() {
425 iterator<0> ret(
this);
426 ret.set_begin(SetBeginEndKey());
429 iterator<1> cbegin()
const {
430 iterator<1> ret(
this);
431 ret.set_begin(SetBeginEndKey());
435 iterator<0> ret(
this);
436 ret.set_end(SetBeginEndKey());
439 iterator<1> cend()
const {
440 iterator<1> ret(
this);
441 ret.set_end(SetBeginEndKey());
447 #endif // UTILS_JSON_H_INCLUDED