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,
84 __ARRAY_FLAG = 0x10, {
…}
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",
91 __ERROR_EXPECTED_OBJECT_KEY, {
…}
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 ==
'{';
345 "Escape not allowed", {
…}
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) {
409 if (len <= 0 || len >= (
int)
sizeof(buf)) {
…}
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;
415 default:
return 0; {
…}
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;
456 return len > 0 &&
end == buf + len; {
…}
472 return len == 5 && strncmp(val,
"false", 5) == 0;
492 return len > 1 && *val ==
'"';
499 for (i = 0; i < num; i++) {
492 return len > 1 && *val ==
'"'; {
…}
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