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;
277 case '"':
case '\\':
case '/':
case 'b':
case 'f':
278 case 'n':
case 'r':
case 't':
case 'u':
279 iter->
state = __STRING | flag;
287 case '\n':
case '\r':
288 iter->
state = __STRUCT | flag;
302 switch (iter->
state & ~__FLAGS) {
303 case __STRING:
case __UTF8:
case __ESC:
313 if ((iter->
state & __SUB_FLAG) && (iter->
state & __KEY_FLAG)) {
318 if ((iter->
state & ~__FLAGS) != __STRUCT) {
319 iter->
state = __STRUCT | (iter->
state & __FLAGS);
320 return iter->
cur - *value;
345 static const char *reasons[] = {
347 "Invalid array separator",
348 "Expected object key",
349 "Expected object value",
351 "Expected array close bracket",
352 "Expected object close brace",
353 "Mismatched bracket",
354 "Escape not allowed",
355 "Character not allowed",
359 "Expected key separator",
366 int linepos = 1, colpos = 1, code;
369 for (l = p = start; p && p != iter->
cur; ++p) {
383 loc->
reason = code == 0 ? strerror(errno) : reasons[code];
390 return len > 0 && (*val ==
'{' || *val ==
'[');
396 return len > 0 && *val ==
'{';
402 return len > 0 && *val ==
'[';
408 return len == 4 && strncmp(val,
"null", 4) == 0;
418 if (len <= 0 || len >= (
int)
sizeof(buf))
421 for (pos = 0; pos < len; ++pos) {
423 case '+':
case '-':
case '0' ...
'9':
case '.':
case 'e':
case 'E':
break;
428 memcpy(buf, val, len);
432 return len > 0 &&
end == buf + len;
445 val = signbit(val) ? FLT_MIN : FLT_MAX;
458 if (len <= 0 || len >= (
int)
sizeof(buf))
461 memcpy(buf, val, len);
464 *result = strtol(buf, &
end, 0);
465 return len > 0 &&
end == buf + len;
476 return len == 4 && strncmp(val,
"true", 4) == 0;
481 return len == 5 && strncmp(val,
"false", 5) == 0;
501 return len > 1 && *val ==
'"';
508 for (i = 0; i < num; i++) {
510 if (v >=
'0' && v <=
'9')
512 else if (v >=
'a' && v <=
'f')
514 else if (v >=
'A' && v <=
'F')
530 memmove(result, val, len);
533 for (p = val+1; p < val + len; p++) {
546 else if (*p ==
'u') {
547 uint8_t prefix[] = { 0, 0xc0, 0xe0, 0xf0 };
548 uint32_t idx, n, v, cp, enc[] = { 0x80, 0x800, 0x10000 };
549 if (val + len - p < 5 ||
556 if (cp >= 0xd800 && cp <= 0xdbff) {
557 if (val + len - p < 7 ||
558 p[1] !=
'\\' || p[2] !=
'u' ||
560 v < 0xdc00 || v > 0xdfff)
563 cp = 0x010000 + (((cp & 0x3ff) << 10) | (v & 0x3ff));
564 }
else if (cp >= 0xdc00 && cp <= 0xdfff)
567 for (idx = 0; idx < 3; idx++)
570 for (n = idx; n > 0; n--, cp >>= 6)
571 result[n] = (cp | 0x80) & 0xbf;
572 *result++ = (cp | prefix[idx]) & 0xff;
576 }
else if (*p ==
'\"') {
594 static const char hex[] = {
"0123456789abcdef" };
595#define __PUT(c) { if (len < size) *str++ = c; len++; }
619 if (*val > 0 && *val < 0x20) {
622 __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:511
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:406
SPA_API_JSON int spa_json_parse_hex(const char *p, int num, uint32_t *res)
Definition json-core.h:516
SPA_API_JSON int spa_json_parse_float(const char *val, int len, float *result)
Definition json-core.h:424
SPA_API_JSON char * spa_json_format_float(char *str, int size, float val)
Definition json-core.h:453
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:354
SPA_API_JSON int spa_json_parse_int(const char *val, int len, int *result)
Definition json-core.h:465
SPA_API_JSON bool spa_json_is_null(const char *val, int len)
Definition json-core.h:418
SPA_API_JSON bool spa_json_is_true(const char *val, int len)
Definition json-core.h:486
#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:496
#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:501
SPA_API_JSON bool spa_json_is_int(const char *val, int len)
Definition json-core.h:479
#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:535
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:412
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:491
SPA_API_JSON int spa_json_parse_string(const char *val, int len, char *result)
Definition json-core.h:598
#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:447
SPA_API_JSON int spa_json_is_container(const char *val, int len)
Definition json-core.h:400
SPA_API_JSON int spa_json_encode_string(char *str, int size, const char *val)
Definition json-core.h:603
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