40#include "yyjson/yyjson.h"
41#include "nibble_base64/base64.h"
60int _lite3_json_enc_obj(
const unsigned char *buf,
size_t buflen,
size_t ofs,
size_t nesting_depth, yyjson_mut_doc *doc, yyjson_mut_val *coll);
61int _lite3_json_enc_arr(
const unsigned char *buf,
size_t buflen,
size_t ofs,
size_t nesting_depth, yyjson_mut_doc *doc, yyjson_mut_val *coll);
63int _lite3_json_enc_switch(
const unsigned char *buf,
size_t buflen,
size_t nesting_depth, yyjson_mut_doc *doc, yyjson_mut_val **yy_val,
lite3_val *val)
68 *yy_val = yyjson_mut_null(doc);
71 *yy_val = yyjson_mut_bool(doc, lite3_val_bool(val));
74 *yy_val = yyjson_mut_sint(doc, lite3_val_i64(val));
77 *yy_val = yyjson_mut_double(doc, lite3_val_f64(val));
82 const u8 *bytes = lite3_val_bytes(val, &bytes_len);
84 char *b64 = nibble_base64(bytes, (
int)bytes_len, &b64_len);
86 LITE3_PRINT_ERROR(
"FAILED TO CONVERT BYTES TO BASE64\n");
98 *yy_val = yyjson_mut_strncpy(doc, b64, (
size_t)b64_len);
109 *yy_val = yyjson_mut_strn(doc, str, str_len);
112 *yy_val = yyjson_mut_obj(doc);
113 size_t obj_ofs = (size_t)((u8 *)val - buf);
114 if (_lite3_json_enc_obj(buf, buflen, obj_ofs, nesting_depth, doc, *yy_val) < 0)
118 *yy_val = yyjson_mut_arr(doc);
119 size_t arr_ofs = (size_t)((u8 *)val - buf);
120 if (_lite3_json_enc_arr(buf, buflen, arr_ofs, nesting_depth, doc, *yy_val) < 0)
124 LITE3_PRINT_ERROR(
"FAILED TO BUILD JSON DOCUMENT: VALUE TYPE INVALID\n");
136int _lite3_json_enc_obj(
const unsigned char *buf,
size_t buflen,
size_t ofs,
size_t nesting_depth, yyjson_mut_doc *doc, yyjson_mut_val *coll)
139 LITE3_PRINT_ERROR(
"FAILED TO BUILD JSON DOCUMENT: nesting_depth > LITE3_JSON_NESTING_DEPTH_MAX\n");
150 yyjson_mut_val *yy_val;
153 if ((ret = _lite3_json_enc_switch(buf, buflen, nesting_depth, doc, &yy_val, val)) < 0)
155 if (!yyjson_mut_obj_add(coll, yyjson_mut_str(doc,
LITE3_STR(buf, key)), yy_val)) {
156 LITE3_PRINT_ERROR(
"FAILED TO BUILD JSON DOCUMENT: ADDING KEY-VALUE PAIR FAILED\n");
169int _lite3_json_enc_arr(
const unsigned char *buf,
size_t buflen,
size_t ofs,
size_t nesting_depth, yyjson_mut_doc *doc, yyjson_mut_val *coll)
172 LITE3_PRINT_ERROR(
"FAILED TO BUILD JSON DOCUMENT: nesting_depth > LITE3_JSON_NESTING_DEPTH_MAX\n");
182 yyjson_mut_val *yy_val;
185 if ((ret = _lite3_json_enc_switch(buf, buflen, nesting_depth, doc, &yy_val, val)) < 0)
187 if (!yyjson_mut_arr_append(coll, yy_val)) {
188 LITE3_PRINT_ERROR(
"FAILED TO BUILD JSON DOCUMENT: APPENDING ARRAY ELEMENT FAILED\n");
196yyjson_mut_doc *_lite3_json_enc_doc(
const unsigned char *buf,
size_t buflen,
size_t ofs)
198 if (_lite3_verify_get(buf, buflen, ofs) < 0)
200 yyjson_mut_doc *doc = yyjson_mut_doc_new(NULL);
203 yyjson_mut_val *root;
204 switch (*(buf + ofs)) {
206 root = yyjson_mut_obj(doc);
207 if (_lite3_json_enc_obj(buf, buflen, ofs, 0, doc, root) < 0)
211 root = yyjson_mut_arr(doc);
212 if (_lite3_json_enc_arr(buf, buflen, ofs, 0, doc, root) < 0)
216 LITE3_PRINT_ERROR(
"INVALID ARGUMENT: EXPECTING ARRAY OR OBJECT TYPE\n");
220 yyjson_mut_doc_set_root(doc, root);
223 yyjson_mut_doc_free(doc);
229 yyjson_mut_doc *doc = _lite3_json_enc_doc(buf, buflen, ofs);
233 yyjson_write_err err;
234 char *json = yyjson_mut_write_opts(doc, YYJSON_WRITE_PRETTY, NULL, &len, &err);
235 yyjson_mut_doc_free(doc);
238 LITE3_PRINT_ERROR(
"FAILED TO WRITE JSON\tyyjson error code: %u msg:%s\n", err.code, err.msg);
242 fwrite(json, 1, len, stdout);
248char *
lite3_json_enc(
const unsigned char *buf,
size_t buflen,
size_t ofs,
size_t *restrict out_len)
250 yyjson_mut_doc *doc = _lite3_json_enc_doc(buf, buflen, ofs);
253 yyjson_write_err err;
254 char *json = yyjson_mut_write_opts(doc, YYJSON_WRITE_NOFLAG, NULL, out_len, &err);
255 yyjson_mut_doc_free(doc);
257 LITE3_PRINT_ERROR(
"FAILED TO WRITE JSON\tyyjson error code: %u msg:%s\n", err.code, err.msg);
264char *
lite3_json_enc_pretty(
const unsigned char *buf,
size_t buflen,
size_t ofs,
size_t *restrict out_len)
266 yyjson_mut_doc *doc = _lite3_json_enc_doc(buf, buflen, ofs);
269 yyjson_write_err err;
270 char *json = yyjson_mut_write_opts(doc, YYJSON_WRITE_PRETTY, NULL, out_len, &err);
271 yyjson_mut_doc_free(doc);
273 LITE3_PRINT_ERROR(
"FAILED TO WRITE JSON\tyyjson error code: %u msg:%s\n", err.code, err.msg);
280int64_t
lite3_json_enc_buf(
const unsigned char *buf,
size_t buflen,
size_t ofs,
char *restrict json_buf,
size_t json_bufsz)
282 yyjson_mut_doc *doc = _lite3_json_enc_doc(buf, buflen, ofs);
285 yyjson_write_err err;
286 size_t ret = yyjson_mut_write_buf(json_buf, json_bufsz, doc, YYJSON_WRITE_NOFLAG, &err);
287 assert(ret <= INT64_MAX);
288 yyjson_mut_doc_free(doc);
290 LITE3_PRINT_ERROR(
"FAILED TO WRITE JSON\tyyjson error code: %u msg:%s\n", err.code, err.msg);
297int64_t lite3_json_enc_buf_pretty(
const unsigned char *buf,
size_t buflen,
size_t ofs,
char *restrict json_buf,
size_t json_bufsz)
299 yyjson_mut_doc *doc = _lite3_json_enc_doc(buf, buflen, ofs);
302 yyjson_write_err err;
303 size_t ret = yyjson_mut_write_buf(json_buf, json_bufsz, doc, YYJSON_WRITE_PRETTY, &err);
304 assert(ret <= INT64_MAX);
305 yyjson_mut_doc_free(doc);
307 LITE3_PRINT_ERROR(
"FAILED TO WRITE JSON\tyyjson error code: %u msg:%s\n", err.code, err.msg);
#define LITE3_JSON_NESTING_DEPTH_MAX
Maximum nesting limit for JSON documents being encoded or decoded.
#define LITE3_ITER_ITEM
Return value of lite3_iter_next(); iterator produced an item, continue;.
int lite3_iter_next(const unsigned char *buf, size_t buflen, lite3_iter *iter, lite3_str *out_key, size_t *out_val_ofs)
Get the next item from a lite3 iterator.
static int lite3_iter_create(const unsigned char *buf, size_t buflen, size_t ofs, lite3_iter *out)
Create a lite3 iterator for the given object or array.
char * lite3_json_enc_pretty(const unsigned char *buf, size_t buflen, size_t ofs, size_t *__restrict out_len)
Convert Lite³ to JSON prettified string.
int lite3_json_print(const unsigned char *buf, size_t buflen, size_t ofs)
Print Lite³ buffer as JSON to stdout
int64_t lite3_json_enc_buf(const unsigned char *buf, size_t buflen, size_t ofs, char *__restrict json_buf, size_t json_bufsz)
Convert Lite³ to JSON and write to output buffer.
char * lite3_json_enc(const unsigned char *buf, size_t buflen, size_t ofs, size_t *__restrict out_len)
Convert Lite³ to JSON string.
lite3_type
enum containing all Lite³ types
#define LITE3_STR(buf, val)
Generational pointer / safe access wrapper.
@ LITE3_TYPE_ARRAY
maps to 'array' type in JSON
@ LITE3_TYPE_STRING
maps to 'string' type in JSON
@ LITE3_TYPE_BOOL
maps to 'boolean' type in JSON; underlying datatype: bool
@ LITE3_TYPE_BYTES
coverted to base64 string in JSON
@ LITE3_TYPE_F64
maps to 'number' type in JSON; underlying datatype: double
@ LITE3_TYPE_OBJECT
maps to 'object' type in JSON
@ LITE3_TYPE_I64
maps to 'number' type in JSON; underlying datatype: int64_t
@ LITE3_TYPE_NULL
maps to 'null' type in JSON
static const char * lite3_val_str_n(lite3_val *val, size_t *out_len)
static enum lite3_type lite3_val_type(lite3_val *val)
Returns the value type of *val
Struct containing iterator state.
Struct holding a reference to a string inside a Lite³ buffer.
Struct representing a value inside a Lite³ buffer.