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 })
58#define SPA_JSON_INIT_RELAX(type,data,size) \
59 ((struct spa_json) { (data), (data)+(size), NULL, (uint32_t)((type) == '[' ? 0x10 : 0x0), 0 })
66#define SPA_JSON_ENTER(iter) ((struct spa_json) { (iter)->cur, (iter)->end, (iter), (iter)->state & 0xff0, 0 })
73#define SPA_JSON_SAVE(iter) ((struct spa_json) { (iter)->cur, (iter)->end, NULL, (iter)->state, 0 })
80#define SPA_JSON_START(iter,p) ((struct spa_json) { (p), (iter)->end, NULL, 0, 0 })
91 int utf8_remain = 0, err = 0;
93 __NONE, __STRUCT, __BARE, __STRING, __UTF8, __ESC, __COMMENT,
95 __PREV_ARRAY_FLAG = 0x20,
100 __ERROR_INVALID_ARRAY_SEPARATOR,
101 __ERROR_EXPECTED_OBJECT_KEY,
102 __ERROR_EXPECTED_OBJECT_VALUE,
103 __ERROR_TOO_DEEP_NESTING,
104 __ERROR_EXPECTED_ARRAY_CLOSE,
105 __ERROR_EXPECTED_OBJECT_CLOSE,
106 __ERROR_MISMATCHED_BRACKET,
107 __ERROR_ESCAPE_NOT_ALLOWED,
108 __ERROR_CHARACTERS_NOT_ALLOWED,
109 __ERROR_INVALID_ESCAPE,
110 __ERROR_INVALID_STATE,
111 __ERROR_UNFINISHED_STRING,
113 uint64_t array_stack[8] = {0};
120 for (; iter->
cur < iter->
end; iter->
cur++) {
121 unsigned char cur = (
unsigned char)*iter->
cur;
124#define _SPA_ERROR(reason) { err = __ERROR_ ## reason; goto error; }
126 flag = iter->
state & __FLAGS;
127 switch (iter->
state & ~__FLAGS) {
129 flag &= ~(__KEY_FLAG | __PREV_ARRAY_FLAG);
130 iter->
state = __STRUCT | flag;
135 case '\0':
case '\t':
case ' ':
case '\r':
case '\n':
case ',':
138 if (flag & __ARRAY_FLAG)
140 if (!(flag & __KEY_FLAG))
142 iter->
state |= __SUB_FLAG;
145 iter->
state = __COMMENT | flag;
148 if (flag & __KEY_FLAG)
150 if (!(flag & __ARRAY_FLAG))
153 iter->
state = __STRING | flag;
156 if (!(flag & __ARRAY_FLAG)) {
161 if ((iter->
state & __SUB_FLAG) && !(flag & __KEY_FLAG))
165 iter->
state = __STRUCT | __SUB_FLAG | flag;
172 if (iter->
depth == 0) {
175 uint64_t mask = 1ULL << ((iter->
depth-1) & 0x3f);
183 if (++iter->
depth > 1)
188 if ((flag & __ARRAY_FLAG) &&
cur !=
']')
190 if (!(flag & __ARRAY_FLAG) &&
cur !=
'}')
192 if (flag & __KEY_FLAG) {
196 iter->
state = __STRUCT | __SUB_FLAG | flag;
197 if (iter->
depth == 0) {
205 if (iter->
depth == 0) {
208 uint64_t mask = 1ULL << ((iter->
depth-1) & 0x3f);
221 if (!(
cur >= 32 &&
cur <= 126))
223 if (flag & __KEY_FLAG)
225 if (!(flag & __ARRAY_FLAG))
228 iter->
state = __BARE | flag;
234 case '\t':
case ' ':
case '\r':
case '\n':
236 case ':':
case ',':
case '=':
case ']':
case '}':
237 iter->
state = __STRUCT | flag;
240 return iter->
cur - *value;
246 if (
cur >= 32 &&
cur <= 126)
253 iter->
state = __ESC | flag;
256 iter->
state = __STRUCT | flag;
259 return ++iter->
cur - *value;
268 iter->
state = __UTF8 | flag;
271 if (
cur >= 32 &&
cur <= 127)
278 if (--utf8_remain == 0)
279 iter->
state = __STRING | flag;
287 case '"':
case '\\':
case '/':
case 'b':
case 'f':
288 case 'n':
case 'r':
case 't':
case 'u':
289 iter->
state = __STRING | flag;
297 case '\n':
case '\r':
298 iter->
state = __STRUCT | flag;
312 switch (iter->
state & ~__FLAGS) {
313 case __STRING:
case __UTF8:
case __ESC:
323 if ((iter->
state & __SUB_FLAG) && (iter->
state & __KEY_FLAG)) {
328 if ((iter->
state & ~__FLAGS) != __STRUCT) {
329 iter->
state = __STRUCT | (iter->
state & __FLAGS);
330 return iter->
cur - *value;
355 static const char *reasons[] = {
357 "Invalid array separator",
358 "Expected object key",
359 "Expected object value",
361 "Expected array close bracket",
362 "Expected object close brace",
363 "Mismatched bracket",
364 "Escape not allowed",
365 "Character not allowed",
369 "Expected key separator",
376 int linepos = 1, colpos = 1, code;
379 for (l = p = start; p && p != iter->
cur; ++p) {
393 loc->
reason = code == 0 ? strerror(errno) : reasons[code];
400 return len > 0 && (*val ==
'{' || *val ==
'[');
406 return len > 0 && *val ==
'{';
412 return len > 0 && *val ==
'[';
418 return len == 4 && strncmp(val,
"null", 4) == 0;
428 if (len <= 0 || len >= (
int)
sizeof(buf))
431 for (pos = 0; pos < len; ++pos) {
433 case '+':
case '-':
case '0' ...
'9':
case '.':
case 'e':
case 'E':
break;
438 memcpy(buf, val, len);
442 return len > 0 &&
end == buf + len;
455 val = signbit(val) ? FLT_MIN : FLT_MAX;
468 if (len <= 0 || len >= (
int)
sizeof(buf))
471 memcpy(buf, val, len);
474 *result = strtol(buf, &
end, 0);
475 return len > 0 &&
end == buf + len;
486 return len == 4 && strncmp(val,
"true", 4) == 0;
491 return len == 5 && strncmp(val,
"false", 5) == 0;
511 return len > 1 && *val ==
'"';
518 for (i = 0; i < num; i++) {
520 if (v >=
'0' && v <=
'9')
522 else if (v >=
'a' && v <=
'f')
524 else if (v >=
'A' && v <=
'F')
540 memmove(result, val, len);
543 for (p = val+1; p < val + len; p++) {
556 else if (*p ==
'u') {
557 uint8_t prefix[] = { 0, 0xc0, 0xe0, 0xf0 };
558 uint32_t idx, n, v, cp, enc[] = { 0x80, 0x800, 0x10000 };
559 if (val + len - p < 5 ||
566 if (cp >= 0xd800 && cp <= 0xdbff) {
567 if (val + len - p < 7 ||
568 p[1] !=
'\\' || p[2] !=
'u' ||
570 v < 0xdc00 || v > 0xdfff)
573 cp = 0x010000 + (((cp & 0x3ff) << 10) | (v & 0x3ff));
574 }
else if (cp >= 0xdc00 && cp <= 0xdfff)
577 for (idx = 0; idx < 3; idx++)
580 for (n = idx; n > 0; n--, cp >>= 6)
581 result[n] = (cp | 0x80) & 0xbf;
582 *result++ = (cp | prefix[idx]) & 0xff;
586 }
else if (*p ==
'\"') {
604 static const char hex[] = {
"0123456789abcdef" };
605#define __PUT(c) { if (len < size) *str++ = c; len++; }
629 if (*val > 0 && *val < 0x20) {
632 __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:84
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:521
SPA_API_JSON int spa_json_next(struct spa_json *iter, const char **value)
Get the next token.
Definition json-core.h:101
SPA_API_JSON int spa_json_is_object(const char *val, int len)
Definition json-core.h:416
SPA_API_JSON int spa_json_parse_hex(const char *p, int num, uint32_t *res)
Definition json-core.h:526
SPA_API_JSON int spa_json_parse_float(const char *val, int len, float *result)
Definition json-core.h:434
SPA_API_JSON char * spa_json_format_float(char *str, int size, float val)
Definition json-core.h:463
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:364
SPA_API_JSON int spa_json_parse_int(const char *val, int len, int *result)
Definition json-core.h:475
#define SPA_JSON_INIT_RELAX(type, data, size)
Definition json-core.h:67
SPA_API_JSON bool spa_json_is_null(const char *val, int len)
Definition json-core.h:428
SPA_API_JSON bool spa_json_is_true(const char *val, int len)
Definition json-core.h:496
#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:506
SPA_API_JSON void spa_json_init_relax(struct spa_json *iter, char type, const char *data, size_t size)
Definition json-core.h:70
#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:511
SPA_API_JSON bool spa_json_is_int(const char *val, int len)
Definition json-core.h:489
#define SPA_JSON_ENTER(iter)
Definition json-core.h:76
SPA_API_JSON void spa_json_start(struct spa_json *iter, struct spa_json *sub, const char *pos)
Definition json-core.h:94
SPA_API_JSON int spa_json_parse_stringn(const char *val, int len, char *result, int maxlen)
Definition json-core.h:545
SPA_API_JSON void spa_json_enter(struct spa_json *iter, struct spa_json *sub)
Definition json-core.h:78
SPA_API_JSON bool spa_json_is_array(const char *val, int len)
Definition json-core.h:422
SPA_API_JSON void spa_json_save(struct spa_json *iter, struct spa_json *save)
Definition json-core.h:86
SPA_API_JSON bool spa_json_is_false(const char *val, int len)
Definition json-core.h:501
SPA_API_JSON int spa_json_parse_string(const char *val, int len, char *result)
Definition json-core.h:608
#define SPA_JSON_START(iter, p)
Definition json-core.h:92
SPA_API_JSON bool spa_json_is_float(const char *val, int len)
Definition json-core.h:457
SPA_API_JSON int spa_json_is_container(const char *val, int len)
Definition json-core.h:410
SPA_API_JSON int spa_json_encode_string(char *str, int size, const char *val)
Definition json-core.h:613
SPA_API_STRING char * spa_dtoa(char *str, size_t size, double val)
Definition string.h:365
SPA_API_STRING float spa_strtof(const char *str, char **endptr)
Convert str to a float in the C locale.
Definition string.h:272
#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