38#include "yyjson/yyjson.h"
43int _lite3_json_dec_obj(
unsigned char *buf,
size_t *restrict inout_buflen,
size_t ofs,
size_t bufsz,
size_t nesting_depth, yyjson_doc *doc, yyjson_val *obj);
44int _lite3_json_dec_arr(
unsigned char *buf,
size_t *restrict inout_buflen,
size_t ofs,
size_t bufsz,
size_t nesting_depth, yyjson_doc *doc, yyjson_val *arr);
46int _lite3_json_dec_obj_switch(
unsigned char *buf,
size_t *restrict inout_buflen,
size_t ofs,
size_t bufsz,
size_t nesting_depth, yyjson_doc *doc, yyjson_val *yy_key, yyjson_val *yy_val)
48 const char *key = yyjson_get_str(yy_key);
49 yyjson_type type = yyjson_get_type(yy_val);
52 case YYJSON_TYPE_NULL:
53 if ((ret =
lite3_set_null(buf, inout_buflen, ofs, bufsz, key)) < 0)
56 case YYJSON_TYPE_BOOL:
57 switch (yyjson_get_subtype(yy_val)) {
58 case YYJSON_SUBTYPE_FALSE:
59 if ((ret =
lite3_set_bool(buf, inout_buflen, ofs, bufsz, key, 0)) < 0)
62 case YYJSON_SUBTYPE_TRUE:
63 if ((ret =
lite3_set_bool(buf, inout_buflen, ofs, bufsz, key, 1)) < 0)
67 LITE3_PRINT_ERROR(
"FAILED TO READ JSON: EXPECTING BOOL SUBTYPE\n");
73 switch (yyjson_get_subtype(yy_val)) {
74 case YYJSON_SUBTYPE_SINT:
75 int64_t num_i64 = yyjson_get_sint(yy_val);
76 if ((ret =
lite3_set_i64(buf, inout_buflen, ofs, bufsz, key, num_i64)) < 0)
79 case YYJSON_SUBTYPE_UINT:
80 uint64_t num_u64 = yyjson_get_uint(yy_val);
81 if (num_u64 <= INT64_MAX) {
82 if ((ret =
lite3_set_i64(buf, inout_buflen, ofs, bufsz, key, (int64_t)num_u64)) < 0)
86 if ((ret =
lite3_set_f64(buf, inout_buflen, ofs, bufsz, key, (
double)num_u64)) < 0)
90 case YYJSON_SUBTYPE_REAL:
91 double num_f64 = yyjson_get_real(yy_val);
92 if ((ret =
lite3_set_f64(buf, inout_buflen, ofs, bufsz, key, num_f64)) < 0)
96 LITE3_PRINT_ERROR(
"FAILED TO READ JSON: EXPECTING NUM SUBTYPE\n");
101 case YYJSON_TYPE_STR:
102 const char *str = yyjson_get_str(yy_val);
103 size_t len = yyjson_get_len(yy_val);
104 if ((ret =
lite3_set_str_n(buf, inout_buflen, ofs, bufsz, key, str, len)) < 0)
107 case YYJSON_TYPE_OBJ:
109 if ((ret =
lite3_set_obj(buf, inout_buflen, ofs, bufsz, key, &obj_ofs)) < 0)
111 if ((ret = _lite3_json_dec_obj(buf, inout_buflen, obj_ofs, bufsz, nesting_depth, doc, yy_val)) < 0)
114 case YYJSON_TYPE_ARR:
116 if ((ret =
lite3_set_arr(buf, inout_buflen, ofs, bufsz, key, &arr_ofs)) < 0)
118 if ((ret = _lite3_json_dec_arr(buf, inout_buflen, arr_ofs, bufsz, nesting_depth, doc, yy_val)) < 0)
122 LITE3_PRINT_ERROR(
"FAILED TO READ JSON: INVALID TYPE\n");
129int _lite3_json_dec_arr_switch(
unsigned char *buf,
size_t *restrict inout_buflen,
size_t ofs,
size_t bufsz,
size_t nesting_depth, yyjson_doc *doc, yyjson_val *yy_val)
131 yyjson_type type = yyjson_get_type(yy_val);
134 case YYJSON_TYPE_NULL:
138 case YYJSON_TYPE_BOOL:
139 switch (yyjson_get_subtype(yy_val)) {
140 case YYJSON_SUBTYPE_FALSE:
144 case YYJSON_SUBTYPE_TRUE:
149 LITE3_PRINT_ERROR(
"FAILED TO READ JSON: EXPECTING BOOL SUBTYPE\n");
154 case YYJSON_TYPE_NUM:
155 switch (yyjson_get_subtype(yy_val)) {
156 case YYJSON_SUBTYPE_SINT:
157 int64_t num_i64 = yyjson_get_sint(yy_val);
161 case YYJSON_SUBTYPE_UINT:
162 uint64_t num_u64 = yyjson_get_uint(yy_val);
163 if (num_u64 <= INT64_MAX) {
172 case YYJSON_SUBTYPE_REAL:
173 double num_f64 = yyjson_get_real(yy_val);
178 LITE3_PRINT_ERROR(
"FAILED TO READ JSON: EXPECTING NUM SUBTYPE\n");
183 case YYJSON_TYPE_STR:
184 const char *str = yyjson_get_str(yy_val);
185 size_t len = yyjson_get_len(yy_val);
189 case YYJSON_TYPE_OBJ:
193 if ((ret = _lite3_json_dec_obj(buf, inout_buflen, obj_ofs, bufsz, nesting_depth, doc, yy_val)) < 0)
196 case YYJSON_TYPE_ARR:
200 if ((ret = _lite3_json_dec_arr(buf, inout_buflen, arr_ofs, bufsz, nesting_depth, doc, yy_val)) < 0)
204 LITE3_PRINT_ERROR(
"FAILED TO READ JSON: INVALID TYPE\n");
211int _lite3_json_dec_obj(
unsigned char *buf,
size_t *restrict inout_buflen,
size_t ofs,
size_t bufsz,
size_t nesting_depth, yyjson_doc *doc, yyjson_val *obj)
214 LITE3_PRINT_ERROR(
"FAILED TO READ JSON: nesting_depth > LITE3_JSON_NESTING_DEPTH_MAX\n");
218 yyjson_val *key, *val;
219 yyjson_obj_iter iter = yyjson_obj_iter_with(obj);
221 while ((key = yyjson_obj_iter_next(&iter))) {
222 val = yyjson_obj_iter_get_val(key);
223 if ((ret = _lite3_json_dec_obj_switch(buf, inout_buflen, ofs, bufsz, nesting_depth, doc, key, val)) < 0)
229int _lite3_json_dec_arr(
unsigned char *buf,
size_t *restrict inout_buflen,
size_t ofs,
size_t bufsz,
size_t nesting_depth, yyjson_doc *doc, yyjson_val *arr)
232 LITE3_PRINT_ERROR(
"FAILED TO READ JSON: nesting_depth > LITE3_JSON_NESTING_DEPTH_MAX\n");
237 yyjson_arr_iter iter = yyjson_arr_iter_with(arr);
239 while ((val = yyjson_arr_iter_next(&iter))) {
240 if ((ret = _lite3_json_dec_arr_switch(buf, inout_buflen, ofs, bufsz, nesting_depth, doc, val)) < 0)
246int _lite3_json_dec_doc(
unsigned char *buf,
size_t *restrict out_buflen,
size_t bufsz, yyjson_doc *doc)
248 yyjson_val *root_val = yyjson_doc_get_root(doc);
250 switch (yyjson_get_type(root_val)) {
251 case YYJSON_TYPE_OBJ:
252 if ((ret = lite3_init_obj(buf, out_buflen, bufsz)) < 0)
254 if ((ret = _lite3_json_dec_obj(buf, out_buflen, 0, bufsz, 0, doc, root_val)) < 0)
257 case YYJSON_TYPE_ARR:
258 if ((ret = lite3_init_arr(buf, out_buflen, bufsz)) < 0)
260 if ((ret = _lite3_json_dec_arr(buf, out_buflen, 0, bufsz, 0, doc, root_val)) < 0)
264 LITE3_PRINT_ERROR(
"FAILED TO READ JSON: EXPECTING ARRAY OR OBJECT TYPE\n");
268 yyjson_doc_free(doc);
271 yyjson_doc_free(doc);
275int lite3_json_dec(
unsigned char *buf,
size_t *restrict out_buflen,
size_t bufsz,
const char *restrict json_str,
size_t json_len)
278 yyjson_doc *doc = yyjson_read_opts((
char *)json_str, json_len, YYJSON_READ_NOFLAG , NULL, &err);
280 LITE3_PRINT_ERROR(
"FAILED TO READ JSON STRING\tyyjson error code: %u\tmsg:%s\tat byte position: %lu\n", err.code, err.msg, err.pos);
284 return _lite3_json_dec_doc(buf, out_buflen, bufsz, doc);
287int lite3_json_dec_file(
unsigned char *buf,
size_t *restrict out_buflen,
size_t bufsz,
const char *restrict path)
290 yyjson_doc *doc = yyjson_read_file(path, YYJSON_READ_NOFLAG , NULL, &err);
292 LITE3_PRINT_ERROR(
"FAILED TO READ JSON FILE\tyyjson error code: %u\tmsg:%s\tat byte position: %lu\n", err.code, err.msg, err.pos);
296 return _lite3_json_dec_doc(buf, out_buflen, bufsz, doc);
299int lite3_json_dec_fp(
unsigned char *buf,
size_t *restrict out_buflen,
size_t bufsz, FILE *fp)
302 yyjson_doc *doc = yyjson_read_fp(fp, YYJSON_READ_NOFLAG , NULL, &err);
304 LITE3_PRINT_ERROR(
"FAILED TO READ JSON FILE POINTER\tyyjson error code: %u\tmsg:%s\tat byte position: %lu\n", err.code, err.msg, err.pos);
308 return _lite3_json_dec_doc(buf, out_buflen, bufsz, doc);
static int lite3_arr_append_f64(unsigned char *buf, size_t *__restrict inout_buflen, size_t ofs, size_t bufsz, double value)
Append floating point to array.
static int lite3_arr_append_bool(unsigned char *buf, size_t *__restrict inout_buflen, size_t ofs, size_t bufsz, bool value)
Append boolean to array.
static int lite3_arr_append_str_n(unsigned char *buf, size_t *__restrict inout_buflen, size_t ofs, size_t bufsz, const char *__restrict str, size_t str_len)
Append string to array by length.
static int lite3_arr_append_null(unsigned char *buf, size_t *__restrict inout_buflen, size_t ofs, size_t bufsz)
Append null to array.
static int lite3_arr_append_arr(unsigned char *buf, size_t *__restrict inout_buflen, size_t ofs, size_t bufsz, size_t *__restrict out_ofs)
Append array to array.
static int lite3_arr_append_i64(unsigned char *buf, size_t *__restrict inout_buflen, size_t ofs, size_t bufsz, int64_t value)
Append integer to array.
static int lite3_arr_append_obj(unsigned char *buf, size_t *__restrict inout_buflen, size_t ofs, size_t bufsz, size_t *__restrict out_ofs)
Append object to array.
#define LITE3_JSON_NESTING_DEPTH_MAX
Maximum nesting limit for JSON documents being encoded or decoded.
int lite3_json_dec_file(unsigned char *buf, size_t *__restrict out_buflen, size_t bufsz, const char *__restrict path)
Convert JSON from file path to Lite³
int lite3_json_dec(unsigned char *buf, size_t *__restrict out_buflen, size_t bufsz, const char *__restrict json_str, size_t json_len)
Convert JSON string to Lite³
int lite3_json_dec_fp(unsigned char *buf, size_t *__restrict out_buflen, size_t bufsz, FILE *fp)
Convert JSON from file pointer to Lite³
#define lite3_set_null(buf, inout_buflen, ofs, bufsz, key)
Set null in object.
#define lite3_set_obj(buf, inout_buflen, ofs, bufsz, key, out_ofs)
Set object in object.
#define lite3_set_arr(buf, inout_buflen, ofs, bufsz, key, out_ofs)
Set array in object.
#define lite3_set_bool(buf, inout_buflen, ofs, bufsz, key, value)
Set boolean in object.
#define lite3_set_f64(buf, inout_buflen, ofs, bufsz, key, value)
Set floating point in object.
#define lite3_set_str_n(buf, inout_buflen, ofs, bufsz, key, str, str_len)
Set string in object by length.
#define lite3_set_i64(buf, inout_buflen, ofs, bufsz, key, value)
Set integer in object.