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 })
57#define SPA_JSON_ENTER(iter) ((struct spa_json) { (iter)->cur, (iter)->end, (iter), (iter)->state & 0xff0, 0 })
64#define SPA_JSON_SAVE(iter) ((struct spa_json) { (iter)->cur, (iter)->end, NULL, (iter)->state, 0 })
71#define SPA_JSON_START(iter,p) ((struct spa_json) { (p), (iter)->end, NULL, 0, 0 })
82 int utf8_remain = 0, err = 0;
84 __NONE, __STRUCT, __BARE, __STRING, __UTF8, __ESC, __COMMENT,
86 __PREV_ARRAY_FLAG = 0x20,
91 __ERROR_INVALID_ARRAY_SEPARATOR,
92 __ERROR_EXPECTED_OBJECT_KEY,
93 __ERROR_EXPECTED_OBJECT_VALUE,
94 __ERROR_TOO_DEEP_NESTING,
95 __ERROR_EXPECTED_ARRAY_CLOSE,
96 __ERROR_EXPECTED_OBJECT_CLOSE,
97 __ERROR_MISMATCHED_BRACKET,
98 __ERROR_ESCAPE_NOT_ALLOWED,
99 __ERROR_CHARACTERS_NOT_ALLOWED,
100 __ERROR_INVALID_ESCAPE,
101 __ERROR_INVALID_STATE,
102 __ERROR_UNFINISHED_STRING,
104 uint64_t array_stack[8] = {0};
111 for (; iter->
cur < iter->
end; iter->
cur++) {
112 unsigned char cur = (
unsigned char)*iter->
cur;
115#define _SPA_ERROR(reason) { err = __ERROR_ ## reason; goto error; }
117 flag = iter->
state & __FLAGS;
118 switch (iter->
state & ~__FLAGS) {
120 flag &= ~(__KEY_FLAG | __PREV_ARRAY_FLAG);
121 iter->
state = __STRUCT | flag;
126 case '\0':
case '\t':
case ' ':
case '\r':
case '\n':
case ',':
129 if (flag & __ARRAY_FLAG)
131 if (!(flag & __KEY_FLAG))
133 iter->
state |= __SUB_FLAG;
136 iter->
state = __COMMENT | flag;
139 if (flag & __KEY_FLAG)
141 if (!(flag & __ARRAY_FLAG))
144 iter->
state = __STRING | flag;
147 if (!(flag & __ARRAY_FLAG)) {
152 if ((iter->
state & __SUB_FLAG) && !(flag & __KEY_FLAG))
156 iter->
state = __STRUCT | __SUB_FLAG | flag;
163 if (iter->
depth == 0) {
166 uint64_t mask = 1ULL << ((iter->
depth-1) & 0x3f);
174 if (++iter->
depth > 1)
179 if ((flag & __ARRAY_FLAG) &&
cur !=
']')
181 if (!(flag & __ARRAY_FLAG) &&
cur !=
'}')
183 if (flag & __KEY_FLAG) {
187 iter->
state = __STRUCT | __SUB_FLAG | flag;
188 if (iter->
depth == 0) {
196 if (iter->
depth == 0) {
199 uint64_t mask = 1ULL << ((iter->
depth-1) & 0x3f);
212 if (!(
cur >= 32 &&
cur <= 126))
214 if (flag & __KEY_FLAG)
216 if (!(flag & __ARRAY_FLAG))
219 iter->
state = __BARE | flag;
225 case '\t':
case ' ':
case '\r':
case '\n':
227 case ':':
case ',':
case '=':
case ']':
case '}':
228 iter->
state = __STRUCT | flag;
231 return iter->
cur - *value;
237 if (
cur >= 32 &&
cur <= 126)
244 iter->
state = __ESC | flag;
247 iter->
state = __STRUCT | flag;
250 return ++iter->
cur - *value;
259 iter->
state = __UTF8 | flag;
262 if (
cur >= 32 &&
cur <= 127)
269 if (--utf8_remain == 0)
270 iter->
state = __STRING | flag;
278 case '"':
case '\\':
case '/':
case 'b':
case 'f':
279 case 'n':
case 'r':
case 't':
case 'u':
280 iter->
state = __STRING | flag;
288 case '\n':
case '\r':
289 iter->
state = __STRUCT | flag;
303 switch (iter->
state & ~__FLAGS) {
304 case __STRING:
case __UTF8:
case __ESC:
314 if ((iter->
state & __SUB_FLAG) && (iter->
state & __KEY_FLAG)) {
319 if ((iter->
state & ~__FLAGS) != __STRUCT) {
320 iter->
state = __STRUCT | (iter->
state & __FLAGS);
321 return iter->
cur - *value;
346 static const char *reasons[] = {
348 "Invalid array separator",
349 "Expected object key",
350 "Expected object value",
352 "Expected array close bracket",
353 "Expected object close brace",
354 "Mismatched bracket",
355 "Escape not allowed",
356 "Character not allowed",
360 "Expected key separator",
367 int linepos = 1, colpos = 1, code;
370 for (l = p = start; p && p != iter->
cur; ++p) {
384 loc->
reason = code == 0 ? strerror(errno) : reasons[code];
391 return len > 0 && (*val ==
'{' || *val ==
'[');
397 return len > 0 && *val ==
'{';
403 return len > 0 && *val ==
'[';
409 return len == 4 && strncmp(val,
"null", 4) == 0;
419 if (len <= 0 || len >= (
int)
sizeof(buf))
422 for (pos = 0; pos < len; ++pos) {
424 case '+':
case '-':
case '0' ...
'9':
case '.':
case 'e':
case 'E':
break;
429 memcpy(buf, val, len);
433 return len > 0 &&
end == buf + len;
446 val = signbit(val) ? FLT_MIN : FLT_MAX;
459 if (len <= 0 || len >= (
int)
sizeof(buf))
462 memcpy(buf, val, len);
465 *result = strtol(buf, &
end, 0);
466 return len > 0 &&
end == buf + len;
477 return len == 4 && strncmp(val,
"true", 4) == 0;
482 return len == 5 && strncmp(val,
"false", 5) == 0;
502 return len > 1 && *val ==
'"';
509 for (i = 0; i < num; i++) {
511 if (v >=
'0' && v <=
'9')
513 else if (v >=
'a' && v <=
'f')
515 else if (v >=
'A' && v <=
'F')
531 memmove(result, val, len);
534 for (p = val+1; p < val + len; p++) {
547 else if (*p ==
'u') {
548 uint8_t prefix[] = { 0, 0xc0, 0xe0, 0xf0 };
549 uint32_t idx, n, v, cp, enc[] = { 0x80, 0x800, 0x10000 };
550 if (val + len - p < 5 ||
557 if (cp >= 0xd800 && cp <= 0xdbff) {
558 if (val + len - p < 7 ||
559 p[1] !=
'\\' || p[2] !=
'u' ||
561 v < 0xdc00 || v > 0xdfff)
564 cp = 0x010000 + (((cp & 0x3ff) << 10) | (v & 0x3ff));
565 }
else if (cp >= 0xdc00 && cp <= 0xdfff)
568 for (idx = 0; idx < 3; idx++)
571 for (n = idx; n > 0; n--, cp >>= 6)
572 result[n] = (cp | 0x80) & 0xbf;
573 *result++ = (cp | prefix[idx]) & 0xff;
577 }
else if (*p ==
'\"') {
595 static const char hex[] = {
"0123456789abcdef" };
596#define __PUT(c) { if (len < size) *str++ = c; len++; }
620 if (*val > 0 && *val < 0x20) {
623 __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:75
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:512
SPA_API_JSON int spa_json_next(struct spa_json *iter, const char **value)
Get the next token.
Definition json-core.h:92
SPA_API_JSON int spa_json_is_object(const char *val, int len)
Definition json-core.h:407
SPA_API_JSON int spa_json_parse_hex(const char *p, int num, uint32_t *res)
Definition json-core.h:517
SPA_API_JSON int spa_json_parse_float(const char *val, int len, float *result)
Definition json-core.h:425
SPA_API_JSON char * spa_json_format_float(char *str, int size, float val)
Definition json-core.h:454
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:355
SPA_API_JSON int spa_json_parse_int(const char *val, int len, int *result)
Definition json-core.h:466
SPA_API_JSON bool spa_json_is_null(const char *val, int len)
Definition json-core.h:419
SPA_API_JSON bool spa_json_is_true(const char *val, int len)
Definition json-core.h:487
#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:497
#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:502
SPA_API_JSON bool spa_json_is_int(const char *val, int len)
Definition json-core.h:480
#define SPA_JSON_ENTER(iter)
Definition json-core.h:67
SPA_API_JSON void spa_json_start(struct spa_json *iter, struct spa_json *sub, const char *pos)
Definition json-core.h:85
SPA_API_JSON int spa_json_parse_stringn(const char *val, int len, char *result, int maxlen)
Definition json-core.h:536
SPA_API_JSON void spa_json_enter(struct spa_json *iter, struct spa_json *sub)
Definition json-core.h:69
SPA_API_JSON bool spa_json_is_array(const char *val, int len)
Definition json-core.h:413
SPA_API_JSON void spa_json_save(struct spa_json *iter, struct spa_json *save)
Definition json-core.h:77
SPA_API_JSON bool spa_json_is_false(const char *val, int len)
Definition json-core.h:492
SPA_API_JSON int spa_json_parse_string(const char *val, int len, char *result)
Definition json-core.h:599
#define SPA_JSON_START(iter, p)
Definition json-core.h:83
SPA_API_JSON bool spa_json_is_float(const char *val, int len)
Definition json-core.h:448
SPA_API_JSON int spa_json_is_container(const char *val, int len)
Definition json-core.h:401
SPA_API_JSON int spa_json_encode_string(char *str, int size, const char *val)
Definition json-core.h:604
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: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