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 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 char * spa_json_format_float(char *str, int size, float val)
Definition: json-core.h:453
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