5#ifndef SPA_UTILS_JSON_H
6#define SPA_UTILS_JSON_H
25 #define SPA_API_JSON SPA_API_IMPL
27 #define SPA_API_JSON static inline
45#define SPA_JSON_ERROR_FLAG 0x100
50#define SPA_JSON_INIT(data,size) ((struct spa_json) { (data), (data)+(size), NULL, 0, 0 })
56#define SPA_JSON_ENTER(iter) ((struct spa_json) { (iter)->cur, (iter)->end, (iter), (iter)->state & 0xff0, 0 })
63#define SPA_JSON_SAVE(iter) ((struct spa_json) { (iter)->cur, (iter)->end, NULL, (iter)->state, 0 })
70#define SPA_JSON_START(iter,p) ((struct spa_json) { (p), (iter)->end, NULL, 0, 0 })
81 int utf8_remain = 0, err = 0;
83 __NONE, __STRUCT, __BARE, __STRING, __UTF8, __ESC, __COMMENT,
85 __PREV_ARRAY_FLAG = 0x20,
90 __ERROR_INVALID_ARRAY_SEPARATOR,
91 __ERROR_EXPECTED_OBJECT_KEY,
92 __ERROR_EXPECTED_OBJECT_VALUE,
93 __ERROR_TOO_DEEP_NESTING,
94 __ERROR_EXPECTED_ARRAY_CLOSE,
95 __ERROR_EXPECTED_OBJECT_CLOSE,
96 __ERROR_MISMATCHED_BRACKET,
97 __ERROR_ESCAPE_NOT_ALLOWED,
98 __ERROR_CHARACTERS_NOT_ALLOWED,
99 __ERROR_INVALID_ESCAPE,
100 __ERROR_INVALID_STATE,
101 __ERROR_UNFINISHED_STRING,
103 uint64_t array_stack[8] = {0};
110 for (; iter->
cur < iter->
end; iter->
cur++) {
111 unsigned char cur = (
unsigned char)*iter->
cur;
114#define
_SPA_ERROR(reason) { err = __ERROR_ ## reason;
goto error; }
116 flag = iter->
state & __FLAGS;
117 switch (iter->
state & ~__FLAGS) {
119 flag &= ~(__KEY_FLAG | __PREV_ARRAY_FLAG);
120 iter->
state = __STRUCT | flag;
125 case '\0':
case '\t':
case ' ':
case '\r':
case '\n':
case ',':
128 if (flag & __ARRAY_FLAG)
130 if (!(flag & __KEY_FLAG))
132 iter->
state |= __SUB_FLAG;
135 iter->
state = __COMMENT | flag;
138 if (flag & __KEY_FLAG)
140 if (!(flag & __ARRAY_FLAG))
143 iter->
state = __STRING | flag;
146 if (!(flag & __ARRAY_FLAG)) {
151 if ((iter->
state & __SUB_FLAG) && !(flag & __KEY_FLAG))
155 iter->
state = __STRUCT | __SUB_FLAG | flag;
162 if (iter->
depth == 0) {
165 uint64_t mask = 1ULL << ((iter->
depth-1) & 0x3f);
173 if (++iter->
depth > 1)
178 if ((flag & __ARRAY_FLAG) &&
cur !=
']')
180 if (!(flag & __ARRAY_FLAG) &&
cur !=
'}')
182 if (flag & __KEY_FLAG) {
186 iter->
state = __STRUCT | __SUB_FLAG | flag;
187 if (iter->
depth == 0) {
195 if (iter->
depth == 0) {
198 uint64_t mask = 1ULL << ((iter->
depth-1) & 0x3f);
211 if (!(
cur >= 32 &&
cur <= 126))
213 if (flag & __KEY_FLAG)
215 if (!(flag & __ARRAY_FLAG))
218 iter->
state = __BARE | flag;
224 case '\t':
case ' ':
case '\r':
case '\n':
226 case ':':
case ',':
case '=':
case ']':
case '}':
227 iter->
state = __STRUCT | flag;
230 return iter->
cur - *value;
236 if (
cur >= 32 &&
cur <= 126)
243 iter->
state = __ESC | flag;
246 iter->
state = __STRUCT | flag;
249 return ++iter->
cur - *value;
258 iter->
state = __UTF8 | flag;
261 if (
cur >= 32 &&
cur <= 127)
268 if (--utf8_remain == 0)
269 iter->
state = __STRING | flag;
275 case '"':
case '\\':
case '/':
case 'b':
case 'f':
276 case 'n':
case 'r':
case 't':
case 'u':
277 iter->
state = __STRING | flag;
283 case '\n':
case '\r':
284 iter->
state = __STRUCT | flag;
295 switch (iter->
state & ~__FLAGS) {
296 case __STRING:
case __UTF8:
case __ESC:
304 if ((iter->
state & __SUB_FLAG) && (iter->
state & __KEY_FLAG)) {
309 if ((iter->
state & ~__FLAGS) != __STRUCT) {
310 iter->
state = __STRUCT | (iter->
state & __FLAGS);
311 return iter->
cur - *value;
336 static const char *reasons[] = {
338 "Invalid array separator",
339 "Expected object key",
340 "Expected object value",
342 "Expected array close bracket",
343 "Expected object close brace",
344 "Mismatched bracket",
345 "Escape not allowed",
346 "Character not allowed",
350 "Expected key separator",
357 int linepos = 1, colpos = 1, code;
360 for (l = p = start; p && p != iter->
cur; ++p) {
374 loc->
reason = code == 0 ? strerror(errno) : reasons[code];
381 return len > 0 && (*val ==
'{' || *val ==
'[');
387 return len > 0 && *val ==
'{';
393 return len > 0 && *val ==
'[';
399 return len == 4 && strncmp(val,
"null", 4) == 0;
409 if (len <= 0 || len >= (
int)
sizeof(buf))
412 for (pos = 0; pos < len; ++pos) {
414 case '+':
case '-':
case '0' ...
'9':
case '.':
case 'e':
case 'E':
break;
419 memcpy(buf, val, len);
423 return len > 0 &&
end == buf + len;
436 val = signbit(val) ? FLT_MIN : FLT_MAX;
449 if (len <= 0 || len >= (
int)
sizeof(buf))
452 memcpy(buf, val, len);
455 *result = strtol(buf, &
end, 0);
456 return len > 0 &&
end == buf + len;
467 return len == 4 && strncmp(val,
"true", 4) == 0;
472 return len == 5 && strncmp(val,
"false", 5) == 0;
492 return len > 1 && *val ==
'"';
499 for (i = 0; i < num; i++) {
501 if (v >=
'0' && v <=
'9')
503 else if (v >=
'a' && v <=
'f')
505 else if (v >=
'A' && v <=
'F')
521 memmove(result, val, len);
524 for (p = val+1; p < val + len; p++) {
537 else if (*p ==
'u') {
538 uint8_t prefix[] = { 0, 0xc0, 0xe0, 0xf0 };
539 uint32_t idx, n, v, cp, enc[] = { 0x80, 0x800, 0x10000 };
540 if (val + len - p < 5 ||
547 if (cp >= 0xd800 && cp <= 0xdbff) {
548 if (val + len - p < 7 ||
549 p[1] !=
'\\' || p[2] !=
'u' ||
551 v < 0xdc00 || v > 0xdfff)
554 cp = 0x010000 + (((cp & 0x3ff) << 10) | (v & 0x3ff));
555 }
else if (cp >= 0xdc00 && cp <= 0xdfff)
558 for (idx = 0; idx < 3; idx++)
561 for (n = idx; n > 0; n--, cp >>= 6)
562 result[n] = (cp | 0x80) & 0xbf;
563 *result++ = (cp | prefix[idx]) & 0xff;
567 }
else if (*p ==
'\"') {
585 static const char hex[] = {
"0123456789abcdef" };
586#define __PUT(c) { if (len < size) *str++ = c; len++; }
610 if (*val > 0 && *val < 0x20) {
613 __PUT(hex[((*val)>>4)&0xf]);
__PUT(hex[(*val)&0xf]);
uint32_t int int res
Definition: core.h:433
#define SPA_JSON_SAVE(iter)
Definition: json-core.h:74
SPA_API_JSON void spa_json_init(struct spa_json *iter, const char *data, size_t size)
Definition: json-core.h:61
SPA_API_JSON bool spa_json_is_string(const char *val, int len)
Definition: json-core.h:502
SPA_API_JSON int spa_json_next(struct spa_json *iter, const char **value)
Get the next token.
Definition: json-core.h:91
SPA_API_JSON int spa_json_is_object(const char *val, int len)
Definition: json-core.h:397
SPA_API_JSON int spa_json_parse_hex(const char *p, int num, uint32_t *res)
Definition: json-core.h:507
SPA_API_JSON int spa_json_parse_float(const char *val, int len, float *result)
Definition: json-core.h:415
SPA_API_JSON char * spa_json_format_float(char *str, int size, float val)
Definition: json-core.h:444
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:345
SPA_API_JSON int spa_json_parse_int(const char *val, int len, int *result)
Definition: json-core.h:456
SPA_API_JSON bool spa_json_is_null(const char *val, int len)
Definition: json-core.h:409
SPA_API_JSON bool spa_json_is_true(const char *val, int len)
Definition: json-core.h:477
#define SPA_JSON_INIT(data, size)
Definition: json-core.h:59
SPA_API_JSON bool spa_json_is_bool(const char *val, int len)
Definition: json-core.h:487
#define SPA_JSON_ERROR_FLAG
Definition: json-core.h:53
SPA_API_JSON int spa_json_parse_bool(const char *val, int len, bool *result)
Definition: json-core.h:492
SPA_API_JSON bool spa_json_is_int(const char *val, int len)
Definition: json-core.h:470
#define SPA_JSON_ENTER(iter)
Definition: json-core.h:66
SPA_API_JSON void spa_json_start(struct spa_json *iter, struct spa_json *sub, const char *pos)
Definition: json-core.h:84
SPA_API_JSON int spa_json_parse_stringn(const char *val, int len, char *result, int maxlen)
Definition: json-core.h:526
SPA_API_JSON void spa_json_enter(struct spa_json *iter, struct spa_json *sub)
Definition: json-core.h:68
SPA_API_JSON bool spa_json_is_array(const char *val, int len)
Definition: json-core.h:403
SPA_API_JSON void spa_json_save(struct spa_json *iter, struct spa_json *save)
Definition: json-core.h:76
SPA_API_JSON bool spa_json_is_false(const char *val, int len)
Definition: json-core.h:482
SPA_API_JSON int spa_json_parse_string(const char *val, int len, char *result)
Definition: json-core.h:589
#define SPA_JSON_START(iter, p)
Definition: json-core.h:82
SPA_API_JSON bool spa_json_is_float(const char *val, int len)
Definition: json-core.h:438
SPA_API_JSON int spa_json_is_container(const char *val, int len)
Definition: json-core.h:391
SPA_API_JSON int spa_json_encode_string(char *str, int size, const char *val)
Definition: json-core.h:594
SPA_API_STRING char * spa_dtoa(char *str, size_t size, double val)
Definition: string.h:364
SPA_API_STRING float spa_strtof(const char *str, char **endptr)
Convert str to a float in the C locale.
Definition: string.h:271
#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:394
#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:34
#define _SPA_ERROR(reason)
int line
Definition: defs.h:440
const char * location
Definition: defs.h:443
int col
Definition: defs.h:441
size_t len
Definition: defs.h:442
const char * reason
Definition: defs.h:444
Definition: json-core.h:48
uint32_t depth
Definition: json-core.h:55
const char * cur
Definition: json-core.h:49
uint32_t state
Definition: json-core.h:54
const char * end
Definition: json-core.h:50
struct spa_json * parent
Definition: json-core.h:51