5#ifndef SPA_UTILS_JSON_H
6#define SPA_UTILS_JSON_H
26 #define SPA_API_JSON SPA_API_IMPL
28 #define SPA_API_JSON static inline
46#define SPA_JSON_ERROR_FLAG 0x100
51#define SPA_JSON_INIT(data,size) ((struct spa_json) { (data), (data)+(size), NULL, 0, 0 })
58#define SPA_JSON_INIT_RELAX(type,data,size) \
59 ((struct spa_json) { (data), (data)+(size), NULL, (uint32_t)((type) == '[' ? 0x10 : 0x0), 0 })
66#define SPA_JSON_ENTER(iter) ((struct spa_json) { (iter)->cur, (iter)->end, (iter), (iter)->state & 0xff0, 0 })
73#define SPA_JSON_SAVE(iter) ((struct spa_json) { (iter)->cur, (iter)->end, NULL, (iter)->state, 0 })
80#define SPA_JSON_START(iter,p) ((struct spa_json) { (p), (iter)->end, NULL, 0, 0 })
91 int utf8_remain = 0, err = 0;
93 __NONE, __STRUCT, __BARE, __STRING, __UTF8, __ESC, __COMMENT,
95 __PREV_ARRAY_FLAG = 0x20,
100 __ERROR_INVALID_ARRAY_SEPARATOR,
101 __ERROR_EXPECTED_OBJECT_KEY,
102 __ERROR_EXPECTED_OBJECT_VALUE,
103 __ERROR_TOO_DEEP_NESTING,
104 __ERROR_EXPECTED_ARRAY_CLOSE,
105 __ERROR_EXPECTED_OBJECT_CLOSE,
106 __ERROR_MISMATCHED_BRACKET,
107 __ERROR_ESCAPE_NOT_ALLOWED,
108 __ERROR_CHARACTERS_NOT_ALLOWED,
109 __ERROR_INVALID_ESCAPE,
110 __ERROR_INVALID_STATE,
111 __ERROR_UNFINISHED_STRING,
113 uint64_t array_stack[8] = {0};
120 for (; iter->
cur < iter->
end; iter->
cur++) {
121 unsigned char cur = (
unsigned char)*iter->
cur;
124#define _SPA_ERROR(reason) { err = __ERROR_ ## reason; goto error; }
126 flag = iter->
state & __FLAGS;
127 switch (iter->
state & ~__FLAGS) {
129 flag &= ~(__KEY_FLAG | __PREV_ARRAY_FLAG);
130 iter->
state = __STRUCT | flag;
135 case '\0':
case '\t':
case ' ':
case '\r':
case '\n':
case ',':
138 if (flag & __ARRAY_FLAG)
140 if (!(flag & __KEY_FLAG))
142 iter->
state |= __SUB_FLAG;
145 iter->
state = __COMMENT | flag;
148 if (flag & __KEY_FLAG)
150 if (!(flag & __ARRAY_FLAG))
153 iter->
state = __STRING | flag;
156 if (!(flag & __ARRAY_FLAG)) {
161 if ((iter->
state & __SUB_FLAG) && !(flag & __KEY_FLAG))
165 iter->
state = __STRUCT | __SUB_FLAG | flag;
172 if (iter->
depth == 0) {
175 uint64_t mask = 1ULL << ((iter->
depth-1) & 0x3f);
183 if (++iter->
depth > 1)
188 if ((flag & __ARRAY_FLAG) &&
cur !=
']')
190 if (!(flag & __ARRAY_FLAG) &&
cur !=
'}')
192 if (flag & __KEY_FLAG) {
196 iter->
state = __STRUCT | __SUB_FLAG | flag;
197 if (iter->
depth == 0) {
205 if (iter->
depth == 0) {
208 uint64_t mask = 1ULL << ((iter->
depth-1) & 0x3f);
221 if (!(
cur >= 32 &&
cur <= 126))
223 if (flag & __KEY_FLAG)
225 if (!(flag & __ARRAY_FLAG))
228 iter->
state = __BARE | flag;
234 case '\t':
case ' ':
case '\r':
case '\n':
235 case '"':
case '#':
case '{':
case '[':
236 case ':':
case ',':
case '=':
case ']':
case '}':
237 iter->
state = __STRUCT | flag;
240 return iter->
cur - *value;
246 if (
cur >= 32 &&
cur <= 126)
253 iter->
state = __ESC | flag;
256 iter->
state = __STRUCT | flag;
259 return ++iter->
cur - *value;
268 iter->
state = __UTF8 | flag;
271 if (
cur >= 32 &&
cur <= 127)
278 if (--utf8_remain == 0)
279 iter->
state = __STRING | flag;
287 case '"':
case '\\':
case '/':
case 'b':
case 'f':
288 case 'n':
case 'r':
case 't':
case 'u':
289 iter->
state = __STRING | flag;
297 case '\n':
case '\r':
298 iter->
state = __STRUCT | flag;
312 switch (iter->
state & ~__FLAGS) {
313 case __STRING:
case __UTF8:
case __ESC:
323 if ((iter->
state & __SUB_FLAG) && (iter->
state & __KEY_FLAG)) {
328 if ((iter->
state & ~__FLAGS) != __STRUCT) {
329 iter->
state = __STRUCT | (iter->
state & __FLAGS);
330 return iter->
cur - *value;
355 static const char *reasons[] = {
357 "Invalid array separator",
358 "Expected object key",
359 "Expected object value",
361 "Expected array close bracket",
362 "Expected object close brace",
363 "Mismatched bracket",
364 "Escape not allowed",
365 "Character not allowed",
369 "Expected key separator",
376 int linepos = 1, colpos = 1, code;
379 for (l = p = start; p && p != iter->
cur; ++p) {
393 loc->
reason = code == 0 ? strerror(errno) : reasons[code];
400 return len > 0 && (*
val ==
'{' || *
val ==
'[');
404 return len > 0 && (*
val ==
'}' || *
val ==
']');
410 return len > 0 && *
val ==
'{';
416 return len > 0 && *
val ==
'[';
422 return len == 4 && strncmp(
val,
"null", 4) == 0;
430 if (len <= 0 || len >= (
int)
sizeof(buf))
433 memcpy(buf,
val, len);
437 return len > 0 &&
end == buf + len;
450 val = signbit(
val) ? FLT_MIN : FLT_MAX;
462 if (len <= 0 || len >= (
int)
sizeof(buf))
465 memcpy(buf,
val, len);
468 *result = strtol(buf, &
end, 0);
469 return len > 0 &&
end == buf + len;
479 static const int8_t trans[9][7] = {
481 {-1, -1, -1, -1, 6, 7, -1 },
482 { 1, 1, -1, -1, 6, 7, -1 },
483 { 2, 2, -1, -1, -1, 7, -1 },
484 { 3, 3, -1, -1, -1, -1, -1 },
485 { 1, 0, 5, -1, -1, -1, -1 },
486 { 1, 0, -1, -1, -1, -1, -1 },
487 { 2, 2, -1, -1, -1, -1, -1 },
488 { 3, 3, 8, 8, -1, -1, -1 },
489 { 3, 3, -1, -1, -1, -1, -1 },
491 static const int8_t char_class[128] = {
492 6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,
493 6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,
494 6,6,6,6,6,6,6,6,6,6,6,3,6,2,4,6,
495 1,0,0,0,0,0,0,0,0,0,6,6,6,6,6,6,
496 6,6,6,6,6,5,6,6,6,6,6,6,6,6,6,6,
497 6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,
498 6,6,6,6,6,5,6,6,6,6,6,6,6,6,6,6,
499 6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,
503 for (i = 0; i < len; i++) {
513 return len == 4 && strncmp(
val,
"true", 4) == 0;
518 return len == 5 && strncmp(
val,
"false", 5) == 0;
538 return len > 1 && *
val ==
'"';
543 static const char *REJECT =
"\"\\'=:,{}[]()#";
544 for (i = 0; i < size &&
val[i]; i++) {
545 if (
val[i] <= 0x20 || strchr(REJECT,
val[i]) != NULL)
553 const char *v = *
val;
554 static const char *REJECT =
"\"\\'=:,{}[]()#";
555 int trimmed = 0, bad = 0;
556 for (i = 0; i < l && v[i]; i++) {
557 if (i == 0 && v[0] ==
'\"')
559 else if ((i+1 == l || !v[i+1]) && v[i] ==
'\"')
561 else if (v[i] <= 0x20 || strchr(REJECT, v[i]) != NULL)
564 if (trimmed == 0 && bad == 0 && i > 0)
566 else if (trimmed == 2) {
567 if (bad == 0 && i > 2 &&
585 for (i = 0; i < num; i++) {
587 if (v >=
'0' && v <=
'9')
589 else if (v >=
'a' && v <=
'f')
591 else if (v >=
'A' && v <=
'F')
607 memmove(result,
val, len);
610 for (p =
val+1; p <
val + len; p++) {
623 else if (*p ==
'u') {
624 uint8_t prefix[] = { 0, 0xc0, 0xe0, 0xf0 };
625 uint32_t idx, n, v, cp, enc[] = { 0x80, 0x800, 0x10000 };
626 if (
val + len - p < 5 ||
633 if (cp >= 0xd800 && cp <= 0xdbff) {
634 if (
val + len - p < 7 ||
635 p[1] !=
'\\' || p[2] !=
'u' ||
637 v < 0xdc00 || v > 0xdfff)
640 cp = 0x010000 + (((cp & 0x3ff) << 10) | (v & 0x3ff));
641 }
else if (cp >= 0xdc00 && cp <= 0xdfff)
644 for (idx = 0; idx < 3; idx++)
647 for (n = idx; n > 0; n--, cp >>= 6)
648 result[n] = (cp | 0x80) & 0xbf;
649 *result++ = (cp | prefix[idx]) & 0xff;
653 }
else if (*p ==
'\"') {
671 static const char hex[] = {
"0123456789abcdef" };
672#define __PUT(c) { if (len < size) *str++ = c; len++; }
696 if (*
val > 0 && *
val < 0x20) {
uint32_t int int res
Definition core.h:433
bool const char const char char * val
Definition json-builder.h:370
#define SPA_JSON_SAVE(iter)
Definition json-core.h:84
SPA_API_JSON void spa_json_init(struct spa_json *iter, const char *data, size_t size)
Definition json-core.h:62
SPA_API_JSON bool spa_json_is_string(const char *val, int len)
Definition json-core.h:548
SPA_API_JSON int spa_json_next(struct spa_json *iter, const char **value)
Get the next token.
Definition json-core.h:101
SPA_API_JSON int spa_json_is_container_end(const char *val, int len)
Definition json-core.h:414
SPA_API_JSON int spa_json_is_object(const char *val, int len)
Definition json-core.h:420
SPA_API_JSON int spa_json_parse_hex(const char *p, int num, uint32_t *res)
Definition json-core.h:593
SPA_API_JSON int spa_json_parse_float(const char *val, int len, float *result)
Definition json-core.h:438
SPA_API_JSON char * spa_json_format_float(char *str, int size, float val)
Definition json-core.h:458
SPA_API_JSON bool spa_json_get_error(struct spa_json *iter, const char *start, struct spa_error_location *loc)
Return if there was a parse error, and its possible location.
Definition json-core.h:364
SPA_API_JSON int spa_json_parse_int(const char *val, int len, int *result)
Definition json-core.h:470
#define SPA_JSON_INIT_RELAX(type, data, size)
Definition json-core.h:67
SPA_API_JSON bool spa_json_is_null(const char *val, int len)
Definition json-core.h:432
SPA_API_JSON bool spa_json_is_true(const char *val, int len)
Definition json-core.h:523
#define SPA_JSON_INIT(data, size)
Definition json-core.h:60
SPA_API_JSON bool spa_json_is_bool(const char *val, int len)
Definition json-core.h:533
SPA_API_JSON void spa_json_init_relax(struct spa_json *iter, char type, const char *data, size_t size)
Definition json-core.h:70
#define SPA_JSON_ERROR_FLAG
Definition json-core.h:54
SPA_API_JSON int spa_json_parse_bool(const char *val, int len, bool *result)
Definition json-core.h:538
SPA_API_JSON bool spa_json_is_int(const char *val, int len)
Definition json-core.h:483
#define SPA_JSON_ENTER(iter)
Definition json-core.h:76
SPA_API_JSON void spa_json_start(struct spa_json *iter, struct spa_json *sub, const char *pos)
Definition json-core.h:94
SPA_API_JSON int spa_json_parse_stringn(const char *val, int len, char *result, int maxlen)
Definition json-core.h:612
SPA_API_JSON bool spa_json_make_simple_string(const char **val, int *len)
Definition json-core.h:562
SPA_API_JSON bool spa_json_is_json_number(const char *val, int len)
Definition json-core.h:489
SPA_API_JSON void spa_json_enter(struct spa_json *iter, struct spa_json *sub)
Definition json-core.h:78
SPA_API_JSON bool spa_json_is_array(const char *val, int len)
Definition json-core.h:426
SPA_API_JSON bool spa_json_is_simple_string(const char *val, int size)
Definition json-core.h:552
SPA_API_JSON void spa_json_save(struct spa_json *iter, struct spa_json *save)
Definition json-core.h:86
SPA_API_JSON bool spa_json_is_false(const char *val, int len)
Definition json-core.h:528
SPA_API_JSON int spa_json_parse_string(const char *val, int len, char *result)
Definition json-core.h:675
#define SPA_JSON_START(iter, p)
Definition json-core.h:92
SPA_API_JSON bool spa_json_is_float(const char *val, int len)
Definition json-core.h:452
SPA_API_JSON int spa_json_is_container(const char *val, int len)
Definition json-core.h:410
SPA_API_JSON int spa_json_encode_string(char *str, int size, const char *val)
Definition json-core.h:680
SPA_API_STRING char * spa_dtoa(char *str, size_t size, double val)
Definition string.h:365
SPA_API_STRING float spa_strtof(const char *str, char **endptr)
Convert str to a float in the C locale.
Definition string.h:272
#define SPA_CLAMP(v, low, high)
Definition defs.h:177
#define SPA_FLAG_UPDATE(field, flag, val)
Definition defs.h:104
#define SPA_N_ELEMENTS(arr)
Definition defs.h:143
#define SPA_FLAG_IS_SET(field, flag)
Definition defs.h:90
#define SPA_UNLIKELY(x)
Definition defs.h:398
#define SPA_FALLTHROUGH
SPA_FALLTHROUGH is an annotation to suppress compiler warnings about switch cases that fall through w...
Definition defs.h:84
#define SPA_FLAG_CLEAR(field, flag)
Definition defs.h:94
#define SPA_PTRDIFF(p1, p2)
Definition defs.h:238
#define SPA_API_JSON
Definition json-core.h:35
#define _SPA_ERROR(reason)
int line
Definition defs.h:444
const char * location
Definition defs.h:447
int col
Definition defs.h:445
size_t len
Definition defs.h:446
const char * reason
Definition defs.h:448
Definition json-core.h:49
uint32_t depth
Definition json-core.h:56
const char * cur
Definition json-core.h:50
uint32_t state
Definition json-core.h:55
const char * end
Definition json-core.h:51
struct spa_json * parent
Definition json-core.h:52