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), 0, 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 }) 
   61        int utf8_remain = 0, err = 0;
 
   63                __NONE, __STRUCT, __BARE, __STRING, __UTF8, __ESC, __COMMENT,
 
   65                __PREV_ARRAY_FLAG = 0x20,       
 
   70                __ERROR_INVALID_ARRAY_SEPARATOR,
 
   71                __ERROR_EXPECTED_OBJECT_KEY,
 
   72                __ERROR_EXPECTED_OBJECT_VALUE,
 
   73                __ERROR_TOO_DEEP_NESTING,
 
   74                __ERROR_EXPECTED_ARRAY_CLOSE,
 
   75                __ERROR_EXPECTED_OBJECT_CLOSE,
 
   76                __ERROR_MISMATCHED_BRACKET,
 
   77                __ERROR_ESCAPE_NOT_ALLOWED,
 
   78                __ERROR_CHARACTERS_NOT_ALLOWED,
 
   79                __ERROR_INVALID_ESCAPE,
 
   80                __ERROR_INVALID_STATE,
 
   81                __ERROR_UNFINISHED_STRING,
 
   83        uint64_t array_stack[8] = {0};          
 
   90        for (; iter->
cur < iter->
end; iter->
cur++) {
 
   91                unsigned char cur = (
unsigned char)*iter->
cur;
 
   94#define _SPA_ERROR(reason)      { err = __ERROR_ ## reason; goto error; } 
   96                flag = iter->
state & __FLAGS;
 
   97                switch (iter->
state & ~__FLAGS) {
 
   99                        flag &= ~(__KEY_FLAG | __PREV_ARRAY_FLAG);
 
  100                        iter->
state = __STRUCT | flag;
 
  105                        case '\0': 
case '\t': 
case ' ': 
case '\r': 
case '\n': 
case ',':
 
  108                                if (flag & __ARRAY_FLAG)
 
  110                                if (!(flag & __KEY_FLAG))
 
  112                                iter->
state |= __SUB_FLAG;
 
  115                                iter->
state = __COMMENT | flag;
 
  118                                if (flag & __KEY_FLAG)
 
  120                                if (!(flag & __ARRAY_FLAG))
 
  123                                iter->
state = __STRING | flag;
 
  126                                if (!(flag & __ARRAY_FLAG)) {
 
  131                                        if ((iter->
state & __SUB_FLAG) && !(flag & __KEY_FLAG))
 
  135                                iter->
state = __STRUCT | __SUB_FLAG | flag;
 
  142                                if (iter->
depth == 0) {
 
  145                                        uint64_t mask = 1ULL << ((iter->
depth-1) & 0x3f);
 
  153                                if (++iter->
depth > 1)
 
  158                                if ((flag & __ARRAY_FLAG) && 
cur != 
']')
 
  160                                if (!(flag & __ARRAY_FLAG) && 
cur != 
'}')
 
  162                                if (flag & __KEY_FLAG) {
 
  166                                iter->
state = __STRUCT | __SUB_FLAG | flag;
 
  167                                if (iter->
depth == 0) {
 
  175                                if (iter->
depth == 0) {
 
  178                                        uint64_t mask = 1ULL << ((iter->
depth-1) & 0x3f);
 
  191                                if (!(
cur >= 32 && 
cur <= 126))
 
  193                                if (flag & __KEY_FLAG)
 
  195                                if (!(flag & __ARRAY_FLAG))
 
  198                                iter->
state = __BARE | flag;
 
  204                        case '\t': 
case ' ': 
case '\r': 
case '\n':
 
  206                        case ':': 
case ',': 
case '=': 
case ']': 
case '}':
 
  207                                iter->
state = __STRUCT | flag;
 
  210                                return iter->
cur - *value;
 
  216                                if (
cur >= 32 && 
cur <= 126)
 
  223                                iter->
state = __ESC | flag;
 
  226                                iter->
state = __STRUCT | flag;
 
  229                                return ++iter->
cur - *value;
 
  238                                iter->
state = __UTF8 | flag;
 
  241                                if (
cur >= 32 && 
cur <= 127)
 
  248                                if (--utf8_remain == 0)
 
  249                                        iter->
state = __STRING | flag;
 
  255                        case '"': 
case '\\': 
case '/': 
case 'b': 
case 'f':
 
  256                        case 'n': 
case 'r': 
case 't': 
case 'u':
 
  257                                iter->
state = __STRING | flag;
 
  263                        case '\n': 
case '\r':
 
  264                                iter->
state = __STRUCT | flag;
 
  275        switch (iter->
state & ~__FLAGS) {
 
  276        case __STRING: 
case __UTF8: 
case __ESC:
 
  284        if ((iter->
state & __SUB_FLAG) && (iter->
state & __KEY_FLAG)) {
 
  289        if ((iter->
state & ~__FLAGS) != __STRUCT) {
 
  290                iter->
state = __STRUCT | (iter->
state & __FLAGS);
 
  291                return iter->
cur - *value;
 
 
  316        static const char *reasons[] = {
 
  318                "Invalid array separator",
 
  319                "Expected object key",
 
  320                "Expected object value",
 
  322                "Expected array close bracket",
 
  323                "Expected object close brace",
 
  324                "Mismatched bracket",
 
  325                "Escape not allowed",
 
  326                "Character not allowed",
 
  330                "Expected key separator",
 
  337                int linepos = 1, colpos = 1, code;
 
  340                for (l = p = start; p && p != iter->
cur; ++p) {
 
  354                loc->
reason = code == 0 ? strerror(errno) : reasons[code];
 
 
  373        return len > 0 && (*val == 
'{'  || *val == 
'[');
 
 
  390        return sub.
cur + 1 - value;
 
  396        return len > 0 && *val == 
'{';
 
 
  406        return len > 0 && *val == 
'[';
 
 
  416        return len == 4 && strncmp(val, 
"null", 4) == 0;
 
 
  426        if (len <= 0 || len >= (
int)
sizeof(buf))
 
 
  429        for (pos = 0; pos < len; ++pos) {
 
  431                case '+': 
case '-': 
case '0' ... 
'9': 
case '.': 
case 'e': 
case 'E': 
break;
 
  436        memcpy(buf, val, len);
 
  440        return len > 0 && 
end == buf + len;
 
 
  462                else if (val == -INFINITY)
 
 
  476        if (len <= 0 || len >= (
int)
sizeof(buf))
 
 
  479        memcpy(buf, val, len);
 
  482        *result = strtol(buf, &
end, 0);
 
  483        return len > 0 && 
end == buf + len;
 
 
  502        return len == 4 && strncmp(val, 
"true", 4) == 0;
 
 
  507        return len == 5 && strncmp(val, 
"false", 5) == 0;
 
  535        return len > 1 && *val == 
'"';
 
 
  542        for (i = 0; i < num; i++) {
 
  544                if (v >= 
'0' && v <= 
'9')
 
 
  546                else if (v >= 
'a' && v <= 
'f')
 
  548                else if (v >= 
'A' && v <= 
'F')
 
  552                *res = (*res << 4) | v;
 
  564                        memmove(result, val, len);
 
 
  567                for (p = val+1; p < val + len; p++) {
 
  580                                else if (*p == 
'u') {
 
  581                                        uint8_t prefix[] = { 0, 0xc0, 0xe0, 0xf0 };
 
  582                                        uint32_t idx, n, v, cp, enc[] = { 0x80, 0x800, 0x10000 };
 
  583                                        if (val + len - p < 5 ||
 
  590                                        if (cp >= 0xd800 && cp <= 0xdbff) {
 
  591                                                if (val + len - p < 7 ||
 
  592                                                    p[1] != 
'\\' || p[2] != 
'u' ||
 
  594                                                    v < 0xdc00 || v > 0xdfff)
 
  597                                                cp = 0x010000 + (((cp & 0x3ff) << 10) | (v & 0x3ff));
 
  598                                        } 
else if (cp >= 0xdc00 && cp <= 0xdfff)
 
  601                                        for (idx = 0; idx < 3; idx++)
 
  604                                        for (n = idx; n > 0; n--, cp >>= 6)
 
  605                                                result[n] = (cp | 0x80) & 0xbf;
 
  606                                        *result++ = (cp | prefix[idx]) & 0xff;
 
  610                        } 
else if (*p == 
'\"') {
 
 
  637        static const char hex[] = { 
"0123456789abcdef" };
 
  638#define __PUT(c) { if (len < size) *str++ = c; len++; } 
 
  662                        if (*val > 0 && *val < 0x20) {
 
  665                                __PUT(hex[((*val)>>4)&0xf]); 
__PUT(hex[(*val)&0xf]);
 
 
static bool spa_json_is_string(const char *val, int len)
Definition json.h:542
static bool spa_json_is_float(const char *val, int len)
Definition json.h:452
static int spa_json_parse_float(const char *val, int len, float *result)
Definition json.h:429
static bool spa_json_is_true(const char *val, int len)
Definition json.h:509
static int spa_json_parse_stringn(const char *val, int len, char *result, int maxlen)
Definition json.h:566
static int spa_json_enter_container(struct spa_json *iter, struct spa_json *sub, char type)
Definition json.h:368
static void spa_json_enter(struct spa_json *iter, struct spa_json *sub)
Definition json.h:58
static int spa_json_parse_hex(const char *p, int num, uint32_t *res)
Definition json.h:547
static bool spa_json_is_false(const char *val, int len)
Definition json.h:514
static int spa_json_get_int(struct spa_json *iter, int *res)
Definition json.h:499
static int spa_json_parse_bool(const char *val, int len, bool *result)
Definition json.h:524
static int spa_json_enter_object(struct spa_json *iter, struct spa_json *sub)
Definition json.h:407
static int spa_json_get_string(struct spa_json *iter, char *res, int maxlen)
Definition json.h:634
static bool spa_json_is_bool(const char *val, int len)
Definition json.h:519
#define SPA_JSON_INIT(data, size)
Definition json.h:49
static bool spa_json_get_error(struct spa_json *iter, const char *start, struct spa_error_location *loc)
Return it there was a parse error, and its possible location.
Definition json.h:322
#define SPA_JSON_ERROR_FLAG
Definition json.h:43
static char * spa_json_format_float(char *str, int size, float val)
Definition json.h:466
static bool spa_json_is_array(const char *val, int len)
Definition json.h:413
static int spa_json_get_bool(struct spa_json *iter, bool *res)
Definition json.h:532
static bool spa_json_is_null(const char *val, int len)
Definition json.h:423
#define SPA_JSON_ENTER(iter)
Definition json.h:56
static int spa_json_encode_string(char *str, int size, const char *val)
Definition json.h:643
static int spa_json_parse_int(const char *val, int len, int *result)
Definition json.h:480
static int spa_json_next(struct spa_json *iter, const char **value)
Get the next token.
Definition json.h:68
static int spa_json_is_container(const char *val, int len)
Definition json.h:380
static void spa_json_init(struct spa_json *iter, const char *data, size_t size)
Definition json.h:51
static bool spa_json_is_int(const char *val, int len)
Definition json.h:494
static int spa_json_enter_array(struct spa_json *iter, struct spa_json *sub)
Definition json.h:417
static int spa_json_get_float(struct spa_json *iter, float *res)
Definition json.h:457
static int spa_json_is_object(const char *val, int len)
Definition json.h:403
static int spa_json_parse_string(const char *val, int len, char *result)
Definition json.h:629
static int spa_json_container_len(struct spa_json *iter, const char *value, int len 1)
Return length of container at current position, starting at value.
Definition json.h:390
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_UNUSED
Definition defs.h:307
#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
uint32_t depth
Definition json.h:45
const char * cur
Definition json.h:39
uint32_t state
Definition json.h:44
const char * end
Definition json.h:40
struct spa_json * parent
Definition json.h:41