5#ifndef SPA_UTILS_JSON_H
6#define SPA_UTILS_JSON_H
37#define SPA_JSON_ERROR_FLAG 0x100
42#define SPA_JSON_INIT(data,size) ((struct spa_json) { (data), (data)+(size), NULL, 0, 0 })
48#define SPA_JSON_ENTER(iter) ((struct spa_json) { (iter)->cur, (iter)->end, (iter), (iter)->state & 0xff0, 0 })
55#define SPA_JSON_SAVE(iter) ((struct spa_json) { (iter)->cur, (iter)->end, NULL, (iter)->state, 0 })
57#define SPA_JSON_START(iter,p) ((struct spa_json) { (p), (iter)->end, NULL, 0, 0 })
63 int utf8_remain = 0, err = 0;
65 __NONE, __STRUCT, __BARE, __STRING, __UTF8, __ESC, __COMMENT,
67 __PREV_ARRAY_FLAG = 0x20,
72 __ERROR_INVALID_ARRAY_SEPARATOR,
73 __ERROR_EXPECTED_OBJECT_KEY,
74 __ERROR_EXPECTED_OBJECT_VALUE,
75 __ERROR_TOO_DEEP_NESTING,
76 __ERROR_EXPECTED_ARRAY_CLOSE,
77 __ERROR_EXPECTED_OBJECT_CLOSE,
78 __ERROR_MISMATCHED_BRACKET,
79 __ERROR_ESCAPE_NOT_ALLOWED,
80 __ERROR_CHARACTERS_NOT_ALLOWED,
81 __ERROR_INVALID_ESCAPE,
82 __ERROR_INVALID_STATE,
83 __ERROR_UNFINISHED_STRING,
85 uint64_t array_stack[8] = {0};
92 for (; iter->
cur < iter->
end; iter->
cur++) {
93 unsigned char cur = (
unsigned char)*iter->
cur;
96#define _SPA_ERROR(reason) { err = __ERROR_ ## reason; goto error; }
98 flag = iter->
state & __FLAGS;
99 switch (iter->
state & ~__FLAGS) {
101 flag &= ~(__KEY_FLAG | __PREV_ARRAY_FLAG);
102 iter->
state = __STRUCT | flag;
107 case '\0':
case '\t':
case ' ':
case '\r':
case '\n':
case ',':
110 if (flag & __ARRAY_FLAG)
112 if (!(flag & __KEY_FLAG))
114 iter->
state |= __SUB_FLAG;
117 iter->
state = __COMMENT | flag;
120 if (flag & __KEY_FLAG)
122 if (!(flag & __ARRAY_FLAG))
125 iter->
state = __STRING | flag;
128 if (!(flag & __ARRAY_FLAG)) {
133 if ((iter->
state & __SUB_FLAG) && !(flag & __KEY_FLAG))
137 iter->
state = __STRUCT | __SUB_FLAG | flag;
144 if (iter->
depth == 0) {
147 uint64_t mask = 1ULL << ((iter->
depth-1) & 0x3f);
155 if (++iter->
depth > 1)
160 if ((flag & __ARRAY_FLAG) &&
cur !=
']')
162 if (!(flag & __ARRAY_FLAG) &&
cur !=
'}')
164 if (flag & __KEY_FLAG) {
168 iter->
state = __STRUCT | __SUB_FLAG | flag;
169 if (iter->
depth == 0) {
177 if (iter->
depth == 0) {
180 uint64_t mask = 1ULL << ((iter->
depth-1) & 0x3f);
193 if (!(
cur >= 32 &&
cur <= 126))
195 if (flag & __KEY_FLAG)
197 if (!(flag & __ARRAY_FLAG))
200 iter->
state = __BARE | flag;
206 case '\t':
case ' ':
case '\r':
case '\n':
208 case ':':
case ',':
case '=':
case ']':
case '}':
209 iter->
state = __STRUCT | flag;
212 return iter->
cur - *value;
218 if (
cur >= 32 &&
cur <= 126)
225 iter->
state = __ESC | flag;
228 iter->
state = __STRUCT | flag;
231 return ++iter->
cur - *value;
240 iter->
state = __UTF8 | flag;
243 if (
cur >= 32 &&
cur <= 127)
250 if (--utf8_remain == 0)
251 iter->
state = __STRING | flag;
257 case '"':
case '\\':
case '/':
case 'b':
case 'f':
258 case 'n':
case 'r':
case 't':
case 'u':
259 iter->
state = __STRING | flag;
265 case '\n':
case '\r':
266 iter->
state = __STRUCT | flag;
277 switch (iter->
state & ~__FLAGS) {
278 case __STRING:
case __UTF8:
case __ESC:
286 if ((iter->
state & __SUB_FLAG) && (iter->
state & __KEY_FLAG)) {
291 if ((iter->
state & ~__FLAGS) != __STRUCT) {
292 iter->
state = __STRUCT | (iter->
state & __FLAGS);
293 return iter->
cur - *value;
318 static const char *reasons[] = {
320 "Invalid array separator",
321 "Expected object key",
322 "Expected object value",
324 "Expected array close bracket",
325 "Expected object close brace",
326 "Mismatched bracket",
327 "Escape not allowed",
328 "Character not allowed",
332 "Expected key separator",
339 int linepos = 1, colpos = 1, code;
342 for (l = p = start; p && p != iter->
cur; ++p) {
356 loc->
reason = code == 0 ? strerror(errno) : reasons[code];
363 return len > 0 && (*val ==
'{' || *val ==
'[');
369 return len > 0 && *val ==
'{';
375 return len > 0 && *val ==
'[';
381 return len == 4 && strncmp(val,
"null", 4) == 0;
391 if (len <= 0 || len >= (
int)
sizeof(buf))
394 for (pos = 0; pos < len; ++pos) {
396 case '+':
case '-':
case '0' ...
'9':
case '.':
case 'e':
case 'E':
break;
401 memcpy(buf, val, len);
405 return len > 0 &&
end == buf + len;
418 val = signbit(val) ? FLT_MIN : FLT_MAX;
431 if (len <= 0 || len >= (
int)
sizeof(buf))
434 memcpy(buf, val, len);
437 *result = strtol(buf, &
end, 0);
438 return len > 0 &&
end == buf + len;
449 return len == 4 && strncmp(val,
"true", 4) == 0;
454 return len == 5 && strncmp(val,
"false", 5) == 0;
474 return len > 1 && *val ==
'"';
481 for (i = 0; i < num; i++) {
483 if (v >=
'0' && v <=
'9')
485 else if (v >=
'a' && v <=
'f')
487 else if (v >=
'A' && v <=
'F')
491 *res = (*res << 4) | v;
503 memmove(result, val, len);
506 for (p = val+1; p < val + len; p++) {
519 else if (*p ==
'u') {
520 uint8_t prefix[] = { 0, 0xc0, 0xe0, 0xf0 };
521 uint32_t idx, n, v, cp, enc[] = { 0x80, 0x800, 0x10000 };
522 if (val + len - p < 5 ||
529 if (cp >= 0xd800 && cp <= 0xdbff) {
530 if (val + len - p < 7 ||
531 p[1] !=
'\\' || p[2] !=
'u' ||
533 v < 0xdc00 || v > 0xdfff)
536 cp = 0x010000 + (((cp & 0x3ff) << 10) | (v & 0x3ff));
537 }
else if (cp >= 0xdc00 && cp <= 0xdfff)
540 for (idx = 0; idx < 3; idx++)
543 for (n = idx; n > 0; n--, cp >>= 6)
544 result[n] = (cp | 0x80) & 0xbf;
545 *result++ = (cp | prefix[idx]) & 0xff;
549 }
else if (*p ==
'\"') {
567 static const char hex[] = {
"0123456789abcdef" };
568#define __PUT(c) { if (len < size) *str++ = c; len++; }
592 if (*val > 0 && *val < 0x20) {
595 __PUT(hex[((*val)>>4)&0xf]);
__PUT(hex[(*val)&0xf]);
static bool spa_json_is_string(const char *val, int len)
Definition json-core.h:482
static bool spa_json_is_float(const char *val, int len)
Definition json-core.h:418
static int spa_json_parse_float(const char *val, int len, float *result)
Definition json-core.h:395
static bool spa_json_is_true(const char *val, int len)
Definition json-core.h:457
static int spa_json_parse_stringn(const char *val, int len, char *result, int maxlen)
Definition json-core.h:506
static void spa_json_enter(struct spa_json *iter, struct spa_json *sub)
Definition json-core.h:58
static int spa_json_parse_hex(const char *p, int num, uint32_t *res)
Definition json-core.h:487
static bool spa_json_is_false(const char *val, int len)
Definition json-core.h:462
static int spa_json_parse_bool(const char *val, int len, bool *result)
Definition json-core.h:472
static bool spa_json_is_bool(const char *val, int len)
Definition json-core.h:467
#define SPA_JSON_INIT(data, size)
Definition json-core.h:49
static 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:325
#define SPA_JSON_ERROR_FLAG
Definition json-core.h:43
static char * spa_json_format_float(char *str, int size, float val)
Definition json-core.h:424
static bool spa_json_is_array(const char *val, int len)
Definition json-core.h:383
static bool spa_json_is_null(const char *val, int len)
Definition json-core.h:389
#define SPA_JSON_ENTER(iter)
Definition json-core.h:56
static int spa_json_encode_string(char *str, int size, const char *val)
Definition json-core.h:574
static int spa_json_parse_int(const char *val, int len, int *result)
Definition json-core.h:436
static int spa_json_next(struct spa_json *iter, const char **value)
Get the next token.
Definition json-core.h:71
static int spa_json_is_container(const char *val, int len)
Definition json-core.h:371
static void spa_json_init(struct spa_json *iter, const char *data, size_t size)
Definition json-core.h:51
static bool spa_json_is_int(const char *val, int len)
Definition json-core.h:450
static int spa_json_is_object(const char *val, int len)
Definition json-core.h:377
static int spa_json_parse_string(const char *val, int len, char *result)
Definition json-core.h:569
static float spa_strtof(const char *str, char **endptr)
Convert str to a float in the C locale.
Definition string.h:261
static char * spa_dtoa(char *str, size_t size, double val)
Definition string.h:354
#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:369
#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_ERROR(reason)
int line
Definition defs.h:415
const char * location
Definition defs.h:418
int col
Definition defs.h:416
size_t len
Definition defs.h:417
const char * reason
Definition defs.h:419
Definition json-core.h:38
uint32_t depth
Definition json-core.h:45
const char * cur
Definition json-core.h:39
uint32_t state
Definition json-core.h:44
const char * end
Definition json-core.h:40
struct spa_json * parent
Definition json-core.h:41