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