Minimal JSON parser
Dependents: WNCInterface_M2XMQTTdemo
minimal-json.h@1:0429411f7b3a, 2016-06-27 (annotated)
- Committer:
- defmacro
- Date:
- Mon Jun 27 13:14:48 2016 +0000
- Revision:
- 1:0429411f7b3a
- Parent:
- 0:aa8ded7b33eb
Add license file
Who changed what in which revision?
User | Revision | Line number | New contents of line |
---|---|---|---|
defmacro | 0:aa8ded7b33eb | 1 | #ifndef MJSON_H_ |
defmacro | 0:aa8ded7b33eb | 2 | #define MJSON_H_ |
defmacro | 0:aa8ded7b33eb | 3 | |
defmacro | 0:aa8ded7b33eb | 4 | #include <stdint.h> |
defmacro | 0:aa8ded7b33eb | 5 | #ifndef min |
defmacro | 0:aa8ded7b33eb | 6 | #define min(a, b) ((a) > (b) ? (b) : (a)) |
defmacro | 0:aa8ded7b33eb | 7 | #endif /* min */ |
defmacro | 0:aa8ded7b33eb | 8 | |
defmacro | 0:aa8ded7b33eb | 9 | #define MJSON_TYPE_NULL 1 |
defmacro | 0:aa8ded7b33eb | 10 | #define MJSON_TYPE_TRUE 2 |
defmacro | 0:aa8ded7b33eb | 11 | #define MJSON_TYPE_FALSE 3 |
defmacro | 0:aa8ded7b33eb | 12 | #define MJSON_TYPE_STRING 4 |
defmacro | 0:aa8ded7b33eb | 13 | #define MJSON_TYPE_NUMBER 5 |
defmacro | 0:aa8ded7b33eb | 14 | #define MJSON_TYPE_OBJECT 6 |
defmacro | 0:aa8ded7b33eb | 15 | #define MJSON_TYPE_ARRAY 7 |
defmacro | 0:aa8ded7b33eb | 16 | |
defmacro | 0:aa8ded7b33eb | 17 | #define MJSON_SUBTYPE_OBJECT_SEPARATOR 8 |
defmacro | 0:aa8ded7b33eb | 18 | #define MJSON_SUBTYPE_OBJECT_END 9 |
defmacro | 0:aa8ded7b33eb | 19 | #define MJSON_SUBTYPE_ARRAY_SEPARATOR 10 |
defmacro | 0:aa8ded7b33eb | 20 | #define MJSON_SUBTYPE_ARRAY_END 11 |
defmacro | 0:aa8ded7b33eb | 21 | |
defmacro | 0:aa8ded7b33eb | 22 | #define MJSON_OK 0 |
defmacro | 0:aa8ded7b33eb | 23 | #define MJSON_ERROR_READING -1 |
defmacro | 0:aa8ded7b33eb | 24 | #define MJSON_ERROR_UNKNOWN_TYPE -2 |
defmacro | 0:aa8ded7b33eb | 25 | #define MJSON_ERROR_CHECK_FAILURE -3 |
defmacro | 0:aa8ded7b33eb | 26 | #define MJSON_ERROR_TEST_NOT_TRUE -4 |
defmacro | 0:aa8ded7b33eb | 27 | |
defmacro | 0:aa8ded7b33eb | 28 | /* This should at least be 5 to hold `false` */ |
defmacro | 0:aa8ded7b33eb | 29 | #define MJSON_BUFFER_MAX_LENGTH 8 |
defmacro | 0:aa8ded7b33eb | 30 | |
defmacro | 0:aa8ded7b33eb | 31 | typedef int16_t mjson_status_t; |
defmacro | 0:aa8ded7b33eb | 32 | |
defmacro | 0:aa8ded7b33eb | 33 | struct mjson_ctx; |
defmacro | 0:aa8ded7b33eb | 34 | |
defmacro | 0:aa8ded7b33eb | 35 | typedef size_t (*mjson_reader)(struct mjson_ctx *ctx, char *data, size_t limit); |
defmacro | 0:aa8ded7b33eb | 36 | |
defmacro | 0:aa8ded7b33eb | 37 | struct mjson_ctx { |
defmacro | 0:aa8ded7b33eb | 38 | void *userdata; |
defmacro | 0:aa8ded7b33eb | 39 | mjson_reader reader; |
defmacro | 0:aa8ded7b33eb | 40 | char buffer[MJSON_BUFFER_MAX_LENGTH]; |
defmacro | 0:aa8ded7b33eb | 41 | size_t start; |
defmacro | 0:aa8ded7b33eb | 42 | size_t length; |
defmacro | 0:aa8ded7b33eb | 43 | }; |
defmacro | 0:aa8ded7b33eb | 44 | |
defmacro | 0:aa8ded7b33eb | 45 | #define MJSON_BUFFER_START_(ctx) ((ctx)->buffer + (ctx)->start) |
defmacro | 0:aa8ded7b33eb | 46 | |
defmacro | 0:aa8ded7b33eb | 47 | /* TODO: we can accept an optional length, so we won't read more data than |
defmacro | 0:aa8ded7b33eb | 48 | * needed when dealing with numbers directly |
defmacro | 0:aa8ded7b33eb | 49 | */ |
defmacro | 0:aa8ded7b33eb | 50 | void mjson_init(struct mjson_ctx *ctx, void *userdata, mjson_reader reader) |
defmacro | 0:aa8ded7b33eb | 51 | { |
defmacro | 0:aa8ded7b33eb | 52 | ctx->userdata = userdata; |
defmacro | 0:aa8ded7b33eb | 53 | ctx->reader = reader; |
defmacro | 0:aa8ded7b33eb | 54 | ctx->start = 0; |
defmacro | 0:aa8ded7b33eb | 55 | ctx->length = 0; |
defmacro | 0:aa8ded7b33eb | 56 | } |
defmacro | 0:aa8ded7b33eb | 57 | |
defmacro | 0:aa8ded7b33eb | 58 | mjson_status_t mjson_skip_value(struct mjson_ctx *ctx); |
defmacro | 0:aa8ded7b33eb | 59 | |
defmacro | 0:aa8ded7b33eb | 60 | void mjson_shift_buffer_(struct mjson_ctx *ctx) |
defmacro | 0:aa8ded7b33eb | 61 | { |
defmacro | 0:aa8ded7b33eb | 62 | size_t i; |
defmacro | 0:aa8ded7b33eb | 63 | for (i = 0; i < ctx->length; i++) { |
defmacro | 0:aa8ded7b33eb | 64 | ctx->buffer[i] = ctx->buffer[i + ctx->start]; |
defmacro | 0:aa8ded7b33eb | 65 | } |
defmacro | 0:aa8ded7b33eb | 66 | ctx->start = 0; |
defmacro | 0:aa8ded7b33eb | 67 | } |
defmacro | 0:aa8ded7b33eb | 68 | |
defmacro | 0:aa8ded7b33eb | 69 | mjson_status_t |
defmacro | 0:aa8ded7b33eb | 70 | mjson_ensure_byte_(struct mjson_ctx *ctx, size_t byte) |
defmacro | 0:aa8ded7b33eb | 71 | { |
defmacro | 0:aa8ded7b33eb | 72 | if (ctx->length >= byte) { return MJSON_OK; } |
defmacro | 0:aa8ded7b33eb | 73 | byte -= ctx->length; |
defmacro | 0:aa8ded7b33eb | 74 | if (MJSON_BUFFER_MAX_LENGTH - ctx->length - ctx->start < byte) { |
defmacro | 0:aa8ded7b33eb | 75 | mjson_shift_buffer_(ctx); |
defmacro | 0:aa8ded7b33eb | 76 | } |
defmacro | 0:aa8ded7b33eb | 77 | if (ctx->reader(ctx, &ctx->buffer[ctx->start + ctx->length], byte) < byte) { |
defmacro | 0:aa8ded7b33eb | 78 | return MJSON_ERROR_READING; |
defmacro | 0:aa8ded7b33eb | 79 | } |
defmacro | 0:aa8ded7b33eb | 80 | ctx->length += byte; |
defmacro | 0:aa8ded7b33eb | 81 | return MJSON_OK; |
defmacro | 0:aa8ded7b33eb | 82 | } |
defmacro | 0:aa8ded7b33eb | 83 | |
defmacro | 0:aa8ded7b33eb | 84 | void |
defmacro | 0:aa8ded7b33eb | 85 | mjson_consume_byte_(struct mjson_ctx *ctx, size_t byte) |
defmacro | 0:aa8ded7b33eb | 86 | { |
defmacro | 0:aa8ded7b33eb | 87 | ctx->start += byte; |
defmacro | 0:aa8ded7b33eb | 88 | ctx->length -= byte; |
defmacro | 0:aa8ded7b33eb | 89 | } |
defmacro | 0:aa8ded7b33eb | 90 | |
defmacro | 0:aa8ded7b33eb | 91 | mjson_status_t |
defmacro | 0:aa8ded7b33eb | 92 | mjson_read_byte_(struct mjson_ctx *ctx, char ch) |
defmacro | 0:aa8ded7b33eb | 93 | { |
defmacro | 0:aa8ded7b33eb | 94 | mjson_status_t status; |
defmacro | 0:aa8ded7b33eb | 95 | status = mjson_ensure_byte_(ctx, 1); |
defmacro | 0:aa8ded7b33eb | 96 | if (status != MJSON_OK) { return status; } |
defmacro | 0:aa8ded7b33eb | 97 | |
defmacro | 0:aa8ded7b33eb | 98 | if (*MJSON_BUFFER_START_(ctx) == ch) { |
defmacro | 0:aa8ded7b33eb | 99 | mjson_consume_byte_(ctx, 1); |
defmacro | 0:aa8ded7b33eb | 100 | return MJSON_OK; |
defmacro | 0:aa8ded7b33eb | 101 | } |
defmacro | 0:aa8ded7b33eb | 102 | return MJSON_ERROR_TEST_NOT_TRUE; |
defmacro | 0:aa8ded7b33eb | 103 | } |
defmacro | 0:aa8ded7b33eb | 104 | |
defmacro | 0:aa8ded7b33eb | 105 | mjson_status_t |
defmacro | 0:aa8ded7b33eb | 106 | mjson_equal_string_(const char* a, const char* b, size_t n) { |
defmacro | 0:aa8ded7b33eb | 107 | size_t i; |
defmacro | 0:aa8ded7b33eb | 108 | for (i = 0; i < n && a[i] && a[i] == b[i]; i++) ; |
defmacro | 0:aa8ded7b33eb | 109 | return i == n ? MJSON_OK : MJSON_ERROR_TEST_NOT_TRUE; |
defmacro | 0:aa8ded7b33eb | 110 | } |
defmacro | 0:aa8ded7b33eb | 111 | |
defmacro | 0:aa8ded7b33eb | 112 | mjson_status_t |
defmacro | 0:aa8ded7b33eb | 113 | mjson_read_type(struct mjson_ctx *ctx) |
defmacro | 0:aa8ded7b33eb | 114 | { |
defmacro | 0:aa8ded7b33eb | 115 | mjson_status_t status; |
defmacro | 0:aa8ded7b33eb | 116 | status = mjson_ensure_byte_(ctx, 1); |
defmacro | 0:aa8ded7b33eb | 117 | if (status != MJSON_OK) { return status; } |
defmacro | 0:aa8ded7b33eb | 118 | |
defmacro | 0:aa8ded7b33eb | 119 | switch (*MJSON_BUFFER_START_(ctx)) { |
defmacro | 0:aa8ded7b33eb | 120 | case '"': |
defmacro | 0:aa8ded7b33eb | 121 | mjson_consume_byte_(ctx, 1); |
defmacro | 0:aa8ded7b33eb | 122 | return MJSON_TYPE_STRING; |
defmacro | 0:aa8ded7b33eb | 123 | case '{': |
defmacro | 0:aa8ded7b33eb | 124 | mjson_consume_byte_(ctx, 1); |
defmacro | 0:aa8ded7b33eb | 125 | return MJSON_TYPE_OBJECT; |
defmacro | 0:aa8ded7b33eb | 126 | case '[': |
defmacro | 0:aa8ded7b33eb | 127 | mjson_consume_byte_(ctx, 1); |
defmacro | 0:aa8ded7b33eb | 128 | return MJSON_TYPE_ARRAY; |
defmacro | 0:aa8ded7b33eb | 129 | case 't': |
defmacro | 0:aa8ded7b33eb | 130 | status = mjson_ensure_byte_(ctx, 4); |
defmacro | 0:aa8ded7b33eb | 131 | if (status != MJSON_OK) { return status; } |
defmacro | 0:aa8ded7b33eb | 132 | if (mjson_equal_string_(MJSON_BUFFER_START_(ctx), "true", 4) == MJSON_OK) { |
defmacro | 0:aa8ded7b33eb | 133 | mjson_consume_byte_(ctx, 4); |
defmacro | 0:aa8ded7b33eb | 134 | return MJSON_TYPE_TRUE; |
defmacro | 0:aa8ded7b33eb | 135 | } else { |
defmacro | 0:aa8ded7b33eb | 136 | return MJSON_ERROR_UNKNOWN_TYPE; |
defmacro | 0:aa8ded7b33eb | 137 | } |
defmacro | 0:aa8ded7b33eb | 138 | break; |
defmacro | 0:aa8ded7b33eb | 139 | case 'f': |
defmacro | 0:aa8ded7b33eb | 140 | status = mjson_ensure_byte_(ctx, 5); |
defmacro | 0:aa8ded7b33eb | 141 | if (status != MJSON_OK) { return status; } |
defmacro | 0:aa8ded7b33eb | 142 | if (mjson_equal_string_(MJSON_BUFFER_START_(ctx), "false", 5) == MJSON_OK) { |
defmacro | 0:aa8ded7b33eb | 143 | mjson_consume_byte_(ctx, 5); |
defmacro | 0:aa8ded7b33eb | 144 | return MJSON_TYPE_FALSE; |
defmacro | 0:aa8ded7b33eb | 145 | } else { |
defmacro | 0:aa8ded7b33eb | 146 | return MJSON_ERROR_UNKNOWN_TYPE; |
defmacro | 0:aa8ded7b33eb | 147 | } |
defmacro | 0:aa8ded7b33eb | 148 | break; |
defmacro | 0:aa8ded7b33eb | 149 | case 'n': |
defmacro | 0:aa8ded7b33eb | 150 | status = mjson_ensure_byte_(ctx, 4); |
defmacro | 0:aa8ded7b33eb | 151 | if (status != MJSON_OK) { return status; } |
defmacro | 0:aa8ded7b33eb | 152 | if (mjson_equal_string_(MJSON_BUFFER_START_(ctx), "null", 4) == MJSON_OK) { |
defmacro | 0:aa8ded7b33eb | 153 | mjson_consume_byte_(ctx, 4); |
defmacro | 0:aa8ded7b33eb | 154 | return MJSON_TYPE_NULL; |
defmacro | 0:aa8ded7b33eb | 155 | } else { |
defmacro | 0:aa8ded7b33eb | 156 | return MJSON_ERROR_UNKNOWN_TYPE; |
defmacro | 0:aa8ded7b33eb | 157 | } |
defmacro | 0:aa8ded7b33eb | 158 | break; |
defmacro | 0:aa8ded7b33eb | 159 | case '-': |
defmacro | 0:aa8ded7b33eb | 160 | case '0': |
defmacro | 0:aa8ded7b33eb | 161 | case '1': |
defmacro | 0:aa8ded7b33eb | 162 | case '2': |
defmacro | 0:aa8ded7b33eb | 163 | case '3': |
defmacro | 0:aa8ded7b33eb | 164 | case '4': |
defmacro | 0:aa8ded7b33eb | 165 | case '5': |
defmacro | 0:aa8ded7b33eb | 166 | case '6': |
defmacro | 0:aa8ded7b33eb | 167 | case '7': |
defmacro | 0:aa8ded7b33eb | 168 | case '8': |
defmacro | 0:aa8ded7b33eb | 169 | case '9': |
defmacro | 0:aa8ded7b33eb | 170 | return MJSON_TYPE_NUMBER; |
defmacro | 0:aa8ded7b33eb | 171 | } |
defmacro | 0:aa8ded7b33eb | 172 | return MJSON_ERROR_UNKNOWN_TYPE; |
defmacro | 0:aa8ded7b33eb | 173 | } |
defmacro | 0:aa8ded7b33eb | 174 | |
defmacro | 0:aa8ded7b33eb | 175 | mjson_status_t mjson_readcheck_null(struct mjson_ctx *ctx) |
defmacro | 0:aa8ded7b33eb | 176 | { |
defmacro | 0:aa8ded7b33eb | 177 | return mjson_read_type(ctx) == MJSON_TYPE_NULL ? |
defmacro | 0:aa8ded7b33eb | 178 | MJSON_OK : MJSON_ERROR_CHECK_FAILURE; |
defmacro | 0:aa8ded7b33eb | 179 | } |
defmacro | 0:aa8ded7b33eb | 180 | |
defmacro | 0:aa8ded7b33eb | 181 | mjson_status_t mjson_readcheck_boolean(struct mjson_ctx *ctx, int8_t *b) |
defmacro | 0:aa8ded7b33eb | 182 | { |
defmacro | 0:aa8ded7b33eb | 183 | mjson_status_t t = mjson_read_type(ctx); |
defmacro | 0:aa8ded7b33eb | 184 | switch (t) { |
defmacro | 0:aa8ded7b33eb | 185 | case MJSON_TYPE_TRUE: |
defmacro | 0:aa8ded7b33eb | 186 | *b = 1; |
defmacro | 0:aa8ded7b33eb | 187 | return MJSON_OK; |
defmacro | 0:aa8ded7b33eb | 188 | case MJSON_TYPE_FALSE: |
defmacro | 0:aa8ded7b33eb | 189 | *b = 0; |
defmacro | 0:aa8ded7b33eb | 190 | return MJSON_OK; |
defmacro | 0:aa8ded7b33eb | 191 | } |
defmacro | 0:aa8ded7b33eb | 192 | return MJSON_ERROR_CHECK_FAILURE; |
defmacro | 0:aa8ded7b33eb | 193 | } |
defmacro | 0:aa8ded7b33eb | 194 | |
defmacro | 0:aa8ded7b33eb | 195 | mjson_status_t mjson_readcheck_string_start(struct mjson_ctx *ctx) |
defmacro | 0:aa8ded7b33eb | 196 | { |
defmacro | 0:aa8ded7b33eb | 197 | return mjson_read_type(ctx) == MJSON_TYPE_STRING ? |
defmacro | 0:aa8ded7b33eb | 198 | MJSON_OK : MJSON_ERROR_CHECK_FAILURE; |
defmacro | 0:aa8ded7b33eb | 199 | } |
defmacro | 0:aa8ded7b33eb | 200 | |
defmacro | 0:aa8ded7b33eb | 201 | mjson_status_t mjson_read_partial_string(struct mjson_ctx *ctx, |
defmacro | 0:aa8ded7b33eb | 202 | char *data, size_t length, |
defmacro | 0:aa8ded7b33eb | 203 | size_t *out_length) |
defmacro | 0:aa8ded7b33eb | 204 | { |
defmacro | 0:aa8ded7b33eb | 205 | mjson_status_t status; |
defmacro | 0:aa8ded7b33eb | 206 | size_t i = 0; |
defmacro | 0:aa8ded7b33eb | 207 | |
defmacro | 0:aa8ded7b33eb | 208 | while (i < length) { |
defmacro | 0:aa8ded7b33eb | 209 | status = mjson_ensure_byte_(ctx, 1); |
defmacro | 0:aa8ded7b33eb | 210 | if (status != MJSON_OK) { return status; } |
defmacro | 0:aa8ded7b33eb | 211 | |
defmacro | 0:aa8ded7b33eb | 212 | if (*MJSON_BUFFER_START_(ctx) == '"') { |
defmacro | 0:aa8ded7b33eb | 213 | break; |
defmacro | 0:aa8ded7b33eb | 214 | } else if (*MJSON_BUFFER_START_(ctx) == '\\') { |
defmacro | 0:aa8ded7b33eb | 215 | status = mjson_ensure_byte_(ctx, 2); |
defmacro | 0:aa8ded7b33eb | 216 | if (status != MJSON_OK) { return status; } |
defmacro | 0:aa8ded7b33eb | 217 | switch (MJSON_BUFFER_START_(ctx)[1]) { |
defmacro | 0:aa8ded7b33eb | 218 | case '"': |
defmacro | 0:aa8ded7b33eb | 219 | data[i++] = '"'; |
defmacro | 0:aa8ded7b33eb | 220 | break; |
defmacro | 0:aa8ded7b33eb | 221 | case '\\': |
defmacro | 0:aa8ded7b33eb | 222 | data[i++] = '\\'; |
defmacro | 0:aa8ded7b33eb | 223 | break; |
defmacro | 0:aa8ded7b33eb | 224 | case '/': |
defmacro | 0:aa8ded7b33eb | 225 | data[i++] = '/'; |
defmacro | 0:aa8ded7b33eb | 226 | break; |
defmacro | 0:aa8ded7b33eb | 227 | case 'b': |
defmacro | 0:aa8ded7b33eb | 228 | data[i++] = '\b'; |
defmacro | 0:aa8ded7b33eb | 229 | break; |
defmacro | 0:aa8ded7b33eb | 230 | case 'f': |
defmacro | 0:aa8ded7b33eb | 231 | data[i++] = '\f'; |
defmacro | 0:aa8ded7b33eb | 232 | break; |
defmacro | 0:aa8ded7b33eb | 233 | case 'n': |
defmacro | 0:aa8ded7b33eb | 234 | data[i++] = '\n'; |
defmacro | 0:aa8ded7b33eb | 235 | break; |
defmacro | 0:aa8ded7b33eb | 236 | case 'r': |
defmacro | 0:aa8ded7b33eb | 237 | data[i++] = '\r'; |
defmacro | 0:aa8ded7b33eb | 238 | break; |
defmacro | 0:aa8ded7b33eb | 239 | case 't': |
defmacro | 0:aa8ded7b33eb | 240 | data[i++] = '\t'; |
defmacro | 0:aa8ded7b33eb | 241 | break; |
defmacro | 0:aa8ded7b33eb | 242 | default: |
defmacro | 0:aa8ded7b33eb | 243 | return MJSON_ERROR_UNKNOWN_TYPE; |
defmacro | 0:aa8ded7b33eb | 244 | } |
defmacro | 0:aa8ded7b33eb | 245 | mjson_consume_byte_(ctx, 2); |
defmacro | 0:aa8ded7b33eb | 246 | } else { |
defmacro | 0:aa8ded7b33eb | 247 | data[i++] = *MJSON_BUFFER_START_(ctx); |
defmacro | 0:aa8ded7b33eb | 248 | mjson_consume_byte_(ctx, 1); |
defmacro | 0:aa8ded7b33eb | 249 | } |
defmacro | 0:aa8ded7b33eb | 250 | } |
defmacro | 0:aa8ded7b33eb | 251 | |
defmacro | 0:aa8ded7b33eb | 252 | *out_length = i; |
defmacro | 0:aa8ded7b33eb | 253 | return MJSON_OK; |
defmacro | 0:aa8ded7b33eb | 254 | } |
defmacro | 0:aa8ded7b33eb | 255 | |
defmacro | 0:aa8ded7b33eb | 256 | mjson_status_t mjson_read_string_end(struct mjson_ctx *ctx) |
defmacro | 0:aa8ded7b33eb | 257 | { |
defmacro | 0:aa8ded7b33eb | 258 | return mjson_read_byte_(ctx, '"'); |
defmacro | 0:aa8ded7b33eb | 259 | } |
defmacro | 0:aa8ded7b33eb | 260 | |
defmacro | 0:aa8ded7b33eb | 261 | /* After this you don't have to do mjson_read_string_end */ |
defmacro | 0:aa8ded7b33eb | 262 | mjson_status_t mjson_read_full_string(struct mjson_ctx *ctx, |
defmacro | 0:aa8ded7b33eb | 263 | char *data, size_t length, |
defmacro | 0:aa8ded7b33eb | 264 | size_t *out_length) |
defmacro | 0:aa8ded7b33eb | 265 | { |
defmacro | 0:aa8ded7b33eb | 266 | mjson_status_t status; |
defmacro | 0:aa8ded7b33eb | 267 | size_t full_length; |
defmacro | 0:aa8ded7b33eb | 268 | status = mjson_read_partial_string(ctx, data, length, &full_length); |
defmacro | 0:aa8ded7b33eb | 269 | if (status != MJSON_OK) { return status; } |
defmacro | 0:aa8ded7b33eb | 270 | |
defmacro | 0:aa8ded7b33eb | 271 | while (1) { |
defmacro | 0:aa8ded7b33eb | 272 | status = mjson_ensure_byte_(ctx, 1); |
defmacro | 0:aa8ded7b33eb | 273 | if (status != MJSON_OK) { return status; } |
defmacro | 0:aa8ded7b33eb | 274 | |
defmacro | 0:aa8ded7b33eb | 275 | if (*MJSON_BUFFER_START_(ctx) == '"') { |
defmacro | 0:aa8ded7b33eb | 276 | mjson_consume_byte_(ctx, 1); |
defmacro | 0:aa8ded7b33eb | 277 | *out_length = full_length; |
defmacro | 0:aa8ded7b33eb | 278 | return MJSON_OK; |
defmacro | 0:aa8ded7b33eb | 279 | } else if (*MJSON_BUFFER_START_(ctx) == '\\') { |
defmacro | 0:aa8ded7b33eb | 280 | status = mjson_ensure_byte_(ctx, 2); |
defmacro | 0:aa8ded7b33eb | 281 | if (status != MJSON_OK) { return status; } |
defmacro | 0:aa8ded7b33eb | 282 | mjson_consume_byte_(ctx, 2); |
defmacro | 0:aa8ded7b33eb | 283 | full_length++; |
defmacro | 0:aa8ded7b33eb | 284 | } else { |
defmacro | 0:aa8ded7b33eb | 285 | mjson_consume_byte_(ctx, 1); |
defmacro | 0:aa8ded7b33eb | 286 | full_length++; |
defmacro | 0:aa8ded7b33eb | 287 | } |
defmacro | 0:aa8ded7b33eb | 288 | } |
defmacro | 0:aa8ded7b33eb | 289 | /* Not reachable */ |
defmacro | 0:aa8ded7b33eb | 290 | return MJSON_ERROR_CHECK_FAILURE; |
defmacro | 0:aa8ded7b33eb | 291 | } |
defmacro | 0:aa8ded7b33eb | 292 | |
defmacro | 0:aa8ded7b33eb | 293 | mjson_status_t mjson_skip_string(struct mjson_ctx *ctx) |
defmacro | 0:aa8ded7b33eb | 294 | { |
defmacro | 0:aa8ded7b33eb | 295 | size_t temp; |
defmacro | 0:aa8ded7b33eb | 296 | return mjson_read_full_string(ctx, NULL, 0, &temp); |
defmacro | 0:aa8ded7b33eb | 297 | } |
defmacro | 0:aa8ded7b33eb | 298 | |
defmacro | 0:aa8ded7b33eb | 299 | mjson_status_t mjson_readcheck_array_start(struct mjson_ctx *ctx) |
defmacro | 0:aa8ded7b33eb | 300 | { |
defmacro | 0:aa8ded7b33eb | 301 | return mjson_read_type(ctx) == MJSON_TYPE_ARRAY ? |
defmacro | 0:aa8ded7b33eb | 302 | MJSON_OK : MJSON_ERROR_CHECK_FAILURE; |
defmacro | 0:aa8ded7b33eb | 303 | } |
defmacro | 0:aa8ded7b33eb | 304 | |
defmacro | 0:aa8ded7b33eb | 305 | mjson_status_t mjson_read_array_separator_or_end(struct mjson_ctx *ctx) |
defmacro | 0:aa8ded7b33eb | 306 | { |
defmacro | 0:aa8ded7b33eb | 307 | mjson_status_t status; |
defmacro | 0:aa8ded7b33eb | 308 | status = mjson_ensure_byte_(ctx, 1); |
defmacro | 0:aa8ded7b33eb | 309 | if (status != MJSON_OK) { return status; } |
defmacro | 0:aa8ded7b33eb | 310 | |
defmacro | 0:aa8ded7b33eb | 311 | if (*MJSON_BUFFER_START_(ctx) == ',') { |
defmacro | 0:aa8ded7b33eb | 312 | mjson_consume_byte_(ctx, 1); |
defmacro | 0:aa8ded7b33eb | 313 | return MJSON_SUBTYPE_ARRAY_SEPARATOR; |
defmacro | 0:aa8ded7b33eb | 314 | } else if (*MJSON_BUFFER_START_(ctx) == ']') { |
defmacro | 0:aa8ded7b33eb | 315 | mjson_consume_byte_(ctx, 1); |
defmacro | 0:aa8ded7b33eb | 316 | return MJSON_SUBTYPE_ARRAY_END; |
defmacro | 0:aa8ded7b33eb | 317 | } |
defmacro | 0:aa8ded7b33eb | 318 | return MJSON_ERROR_TEST_NOT_TRUE; |
defmacro | 0:aa8ded7b33eb | 319 | } |
defmacro | 0:aa8ded7b33eb | 320 | |
defmacro | 0:aa8ded7b33eb | 321 | mjson_status_t mjson_skip_array(struct mjson_ctx *ctx) |
defmacro | 0:aa8ded7b33eb | 322 | { |
defmacro | 0:aa8ded7b33eb | 323 | mjson_status_t status; |
defmacro | 0:aa8ded7b33eb | 324 | |
defmacro | 0:aa8ded7b33eb | 325 | while (mjson_read_array_separator_or_end(ctx) != MJSON_SUBTYPE_ARRAY_END) { |
defmacro | 0:aa8ded7b33eb | 326 | status = mjson_skip_value(ctx); |
defmacro | 0:aa8ded7b33eb | 327 | if (status != MJSON_OK) { return status; } |
defmacro | 0:aa8ded7b33eb | 328 | } |
defmacro | 0:aa8ded7b33eb | 329 | |
defmacro | 0:aa8ded7b33eb | 330 | return MJSON_OK; |
defmacro | 0:aa8ded7b33eb | 331 | } |
defmacro | 0:aa8ded7b33eb | 332 | |
defmacro | 0:aa8ded7b33eb | 333 | mjson_status_t mjson_readcheck_object_start(struct mjson_ctx *ctx) |
defmacro | 0:aa8ded7b33eb | 334 | { |
defmacro | 0:aa8ded7b33eb | 335 | return mjson_read_type(ctx) == MJSON_TYPE_OBJECT ? |
defmacro | 0:aa8ded7b33eb | 336 | MJSON_OK : MJSON_ERROR_CHECK_FAILURE; |
defmacro | 0:aa8ded7b33eb | 337 | } |
defmacro | 0:aa8ded7b33eb | 338 | |
defmacro | 0:aa8ded7b33eb | 339 | mjson_status_t mjson_read_object_key_separator(struct mjson_ctx *ctx) |
defmacro | 0:aa8ded7b33eb | 340 | { |
defmacro | 0:aa8ded7b33eb | 341 | return mjson_read_byte_(ctx, ':'); |
defmacro | 0:aa8ded7b33eb | 342 | } |
defmacro | 0:aa8ded7b33eb | 343 | |
defmacro | 0:aa8ded7b33eb | 344 | mjson_status_t mjson_read_object_separator_or_end(struct mjson_ctx *ctx) |
defmacro | 0:aa8ded7b33eb | 345 | { |
defmacro | 0:aa8ded7b33eb | 346 | mjson_status_t status; |
defmacro | 0:aa8ded7b33eb | 347 | status = mjson_ensure_byte_(ctx, 1); |
defmacro | 0:aa8ded7b33eb | 348 | if (status != MJSON_OK) { return status; } |
defmacro | 0:aa8ded7b33eb | 349 | |
defmacro | 0:aa8ded7b33eb | 350 | if (*MJSON_BUFFER_START_(ctx) == ',') { |
defmacro | 0:aa8ded7b33eb | 351 | mjson_consume_byte_(ctx, 1); |
defmacro | 0:aa8ded7b33eb | 352 | return MJSON_SUBTYPE_OBJECT_SEPARATOR; |
defmacro | 0:aa8ded7b33eb | 353 | } else if (*MJSON_BUFFER_START_(ctx) == '}') { |
defmacro | 0:aa8ded7b33eb | 354 | mjson_consume_byte_(ctx, 1); |
defmacro | 0:aa8ded7b33eb | 355 | return MJSON_SUBTYPE_OBJECT_END; |
defmacro | 0:aa8ded7b33eb | 356 | } |
defmacro | 0:aa8ded7b33eb | 357 | return MJSON_ERROR_TEST_NOT_TRUE; |
defmacro | 0:aa8ded7b33eb | 358 | } |
defmacro | 0:aa8ded7b33eb | 359 | |
defmacro | 0:aa8ded7b33eb | 360 | mjson_status_t mjson_skip_object(struct mjson_ctx *ctx) |
defmacro | 0:aa8ded7b33eb | 361 | { |
defmacro | 0:aa8ded7b33eb | 362 | mjson_status_t status; |
defmacro | 0:aa8ded7b33eb | 363 | |
defmacro | 0:aa8ded7b33eb | 364 | while (mjson_read_object_separator_or_end(ctx) != MJSON_SUBTYPE_OBJECT_END) { |
defmacro | 0:aa8ded7b33eb | 365 | status = mjson_readcheck_string_start(ctx); |
defmacro | 0:aa8ded7b33eb | 366 | if (status != MJSON_OK) { return status; } |
defmacro | 0:aa8ded7b33eb | 367 | |
defmacro | 0:aa8ded7b33eb | 368 | status = mjson_skip_string(ctx); |
defmacro | 0:aa8ded7b33eb | 369 | if (status != MJSON_OK) { return status; } |
defmacro | 0:aa8ded7b33eb | 370 | |
defmacro | 0:aa8ded7b33eb | 371 | status = mjson_read_object_key_separator(ctx); |
defmacro | 0:aa8ded7b33eb | 372 | if (status != MJSON_OK) { return status; } |
defmacro | 0:aa8ded7b33eb | 373 | |
defmacro | 0:aa8ded7b33eb | 374 | status = mjson_skip_value(ctx); |
defmacro | 0:aa8ded7b33eb | 375 | if (status != MJSON_OK) { return status; } |
defmacro | 0:aa8ded7b33eb | 376 | } |
defmacro | 0:aa8ded7b33eb | 377 | |
defmacro | 0:aa8ded7b33eb | 378 | return MJSON_OK; |
defmacro | 0:aa8ded7b33eb | 379 | } |
defmacro | 0:aa8ded7b33eb | 380 | |
defmacro | 0:aa8ded7b33eb | 381 | mjson_status_t mjson_read_int8(struct mjson_ctx *ctx, int8_t *out) |
defmacro | 0:aa8ded7b33eb | 382 | { |
defmacro | 0:aa8ded7b33eb | 383 | int8_t val = 0, sign = 1; |
defmacro | 0:aa8ded7b33eb | 384 | mjson_status_t status; |
defmacro | 0:aa8ded7b33eb | 385 | |
defmacro | 0:aa8ded7b33eb | 386 | status = mjson_ensure_byte_(ctx, 1); |
defmacro | 0:aa8ded7b33eb | 387 | if (status != MJSON_OK) { return status; } |
defmacro | 0:aa8ded7b33eb | 388 | if (MJSON_BUFFER_START_(ctx)[0] == '-') { |
defmacro | 0:aa8ded7b33eb | 389 | mjson_consume_byte_(ctx, 1); |
defmacro | 0:aa8ded7b33eb | 390 | sign = -1; |
defmacro | 0:aa8ded7b33eb | 391 | } |
defmacro | 0:aa8ded7b33eb | 392 | |
defmacro | 0:aa8ded7b33eb | 393 | status = mjson_ensure_byte_(ctx, 1); |
defmacro | 0:aa8ded7b33eb | 394 | if (status != MJSON_OK) { return status; } |
defmacro | 0:aa8ded7b33eb | 395 | while (MJSON_BUFFER_START_(ctx)[0] >= '0' && |
defmacro | 0:aa8ded7b33eb | 396 | MJSON_BUFFER_START_(ctx)[0] <= '9') { |
defmacro | 0:aa8ded7b33eb | 397 | val = val * 10 + (MJSON_BUFFER_START_(ctx)[0] - '0'); |
defmacro | 0:aa8ded7b33eb | 398 | |
defmacro | 0:aa8ded7b33eb | 399 | mjson_consume_byte_(ctx, 1); |
defmacro | 0:aa8ded7b33eb | 400 | status = mjson_ensure_byte_(ctx, 1); |
defmacro | 0:aa8ded7b33eb | 401 | if (status != MJSON_OK) { return status; } |
defmacro | 0:aa8ded7b33eb | 402 | } |
defmacro | 0:aa8ded7b33eb | 403 | *out = val * sign; |
defmacro | 0:aa8ded7b33eb | 404 | /* Skip additional parts */ |
defmacro | 0:aa8ded7b33eb | 405 | while ((MJSON_BUFFER_START_(ctx)[0] >= '0' && |
defmacro | 0:aa8ded7b33eb | 406 | MJSON_BUFFER_START_(ctx)[0] <= '9') || |
defmacro | 0:aa8ded7b33eb | 407 | MJSON_BUFFER_START_(ctx)[0] == '.' || |
defmacro | 0:aa8ded7b33eb | 408 | MJSON_BUFFER_START_(ctx)[0] == 'e' || |
defmacro | 0:aa8ded7b33eb | 409 | MJSON_BUFFER_START_(ctx)[0] == 'E' || |
defmacro | 0:aa8ded7b33eb | 410 | MJSON_BUFFER_START_(ctx)[0] == '+' || |
defmacro | 0:aa8ded7b33eb | 411 | MJSON_BUFFER_START_(ctx)[0] == '-') { |
defmacro | 0:aa8ded7b33eb | 412 | mjson_consume_byte_(ctx, 1); |
defmacro | 0:aa8ded7b33eb | 413 | status = mjson_ensure_byte_(ctx, 1); |
defmacro | 0:aa8ded7b33eb | 414 | if (status != MJSON_OK) { return status; } |
defmacro | 0:aa8ded7b33eb | 415 | } |
defmacro | 0:aa8ded7b33eb | 416 | return MJSON_OK; |
defmacro | 0:aa8ded7b33eb | 417 | } |
defmacro | 0:aa8ded7b33eb | 418 | |
defmacro | 0:aa8ded7b33eb | 419 | mjson_status_t mjson_read_int16(struct mjson_ctx *ctx, int16_t *out) |
defmacro | 0:aa8ded7b33eb | 420 | { |
defmacro | 0:aa8ded7b33eb | 421 | int16_t val = 0, sign = 1; |
defmacro | 0:aa8ded7b33eb | 422 | mjson_status_t status; |
defmacro | 0:aa8ded7b33eb | 423 | |
defmacro | 0:aa8ded7b33eb | 424 | status = mjson_ensure_byte_(ctx, 1); |
defmacro | 0:aa8ded7b33eb | 425 | if (status != MJSON_OK) { return status; } |
defmacro | 0:aa8ded7b33eb | 426 | if (MJSON_BUFFER_START_(ctx)[0] == '-') { |
defmacro | 0:aa8ded7b33eb | 427 | mjson_consume_byte_(ctx, 1); |
defmacro | 0:aa8ded7b33eb | 428 | sign = -1; |
defmacro | 0:aa8ded7b33eb | 429 | } |
defmacro | 0:aa8ded7b33eb | 430 | |
defmacro | 0:aa8ded7b33eb | 431 | status = mjson_ensure_byte_(ctx, 1); |
defmacro | 0:aa8ded7b33eb | 432 | if (status != MJSON_OK) { return status; } |
defmacro | 0:aa8ded7b33eb | 433 | while (MJSON_BUFFER_START_(ctx)[0] >= '0' && |
defmacro | 0:aa8ded7b33eb | 434 | MJSON_BUFFER_START_(ctx)[0] <= '9') { |
defmacro | 0:aa8ded7b33eb | 435 | val = val * 10 + (MJSON_BUFFER_START_(ctx)[0] - '0'); |
defmacro | 0:aa8ded7b33eb | 436 | |
defmacro | 0:aa8ded7b33eb | 437 | mjson_consume_byte_(ctx, 1); |
defmacro | 0:aa8ded7b33eb | 438 | status = mjson_ensure_byte_(ctx, 1); |
defmacro | 0:aa8ded7b33eb | 439 | if (status != MJSON_OK) { return status; } |
defmacro | 0:aa8ded7b33eb | 440 | } |
defmacro | 0:aa8ded7b33eb | 441 | *out = val * sign; |
defmacro | 0:aa8ded7b33eb | 442 | /* Skip additional parts */ |
defmacro | 0:aa8ded7b33eb | 443 | while ((MJSON_BUFFER_START_(ctx)[0] >= '0' && |
defmacro | 0:aa8ded7b33eb | 444 | MJSON_BUFFER_START_(ctx)[0] <= '9') || |
defmacro | 0:aa8ded7b33eb | 445 | MJSON_BUFFER_START_(ctx)[0] == '.' || |
defmacro | 0:aa8ded7b33eb | 446 | MJSON_BUFFER_START_(ctx)[0] == 'e' || |
defmacro | 0:aa8ded7b33eb | 447 | MJSON_BUFFER_START_(ctx)[0] == 'E' || |
defmacro | 0:aa8ded7b33eb | 448 | MJSON_BUFFER_START_(ctx)[0] == '+' || |
defmacro | 0:aa8ded7b33eb | 449 | MJSON_BUFFER_START_(ctx)[0] == '-') { |
defmacro | 0:aa8ded7b33eb | 450 | mjson_consume_byte_(ctx, 1); |
defmacro | 0:aa8ded7b33eb | 451 | status = mjson_ensure_byte_(ctx, 1); |
defmacro | 0:aa8ded7b33eb | 452 | if (status != MJSON_OK) { return status; } |
defmacro | 0:aa8ded7b33eb | 453 | } |
defmacro | 0:aa8ded7b33eb | 454 | return MJSON_OK; |
defmacro | 0:aa8ded7b33eb | 455 | } |
defmacro | 0:aa8ded7b33eb | 456 | |
defmacro | 0:aa8ded7b33eb | 457 | mjson_status_t mjson_read_int32(struct mjson_ctx *ctx, int32_t *out) |
defmacro | 0:aa8ded7b33eb | 458 | { |
defmacro | 0:aa8ded7b33eb | 459 | int32_t val = 0, sign = 1; |
defmacro | 0:aa8ded7b33eb | 460 | mjson_status_t status; |
defmacro | 0:aa8ded7b33eb | 461 | |
defmacro | 0:aa8ded7b33eb | 462 | status = mjson_ensure_byte_(ctx, 1); |
defmacro | 0:aa8ded7b33eb | 463 | if (status != MJSON_OK) { return status; } |
defmacro | 0:aa8ded7b33eb | 464 | if (MJSON_BUFFER_START_(ctx)[0] == '-') { |
defmacro | 0:aa8ded7b33eb | 465 | mjson_consume_byte_(ctx, 1); |
defmacro | 0:aa8ded7b33eb | 466 | sign = -1; |
defmacro | 0:aa8ded7b33eb | 467 | } |
defmacro | 0:aa8ded7b33eb | 468 | |
defmacro | 0:aa8ded7b33eb | 469 | status = mjson_ensure_byte_(ctx, 1); |
defmacro | 0:aa8ded7b33eb | 470 | if (status != MJSON_OK) { return status; } |
defmacro | 0:aa8ded7b33eb | 471 | while (MJSON_BUFFER_START_(ctx)[0] >= '0' && |
defmacro | 0:aa8ded7b33eb | 472 | MJSON_BUFFER_START_(ctx)[0] <= '9') { |
defmacro | 0:aa8ded7b33eb | 473 | val = val * 10 + (MJSON_BUFFER_START_(ctx)[0] - '0'); |
defmacro | 0:aa8ded7b33eb | 474 | |
defmacro | 0:aa8ded7b33eb | 475 | mjson_consume_byte_(ctx, 1); |
defmacro | 0:aa8ded7b33eb | 476 | status = mjson_ensure_byte_(ctx, 1); |
defmacro | 0:aa8ded7b33eb | 477 | if (status != MJSON_OK) { return status; } |
defmacro | 0:aa8ded7b33eb | 478 | } |
defmacro | 0:aa8ded7b33eb | 479 | *out = val * sign; |
defmacro | 0:aa8ded7b33eb | 480 | /* Skip additional parts */ |
defmacro | 0:aa8ded7b33eb | 481 | while ((MJSON_BUFFER_START_(ctx)[0] >= '0' && |
defmacro | 0:aa8ded7b33eb | 482 | MJSON_BUFFER_START_(ctx)[0] <= '9') || |
defmacro | 0:aa8ded7b33eb | 483 | MJSON_BUFFER_START_(ctx)[0] == '.' || |
defmacro | 0:aa8ded7b33eb | 484 | MJSON_BUFFER_START_(ctx)[0] == 'e' || |
defmacro | 0:aa8ded7b33eb | 485 | MJSON_BUFFER_START_(ctx)[0] == 'E' || |
defmacro | 0:aa8ded7b33eb | 486 | MJSON_BUFFER_START_(ctx)[0] == '+' || |
defmacro | 0:aa8ded7b33eb | 487 | MJSON_BUFFER_START_(ctx)[0] == '-') { |
defmacro | 0:aa8ded7b33eb | 488 | mjson_consume_byte_(ctx, 1); |
defmacro | 0:aa8ded7b33eb | 489 | status = mjson_ensure_byte_(ctx, 1); |
defmacro | 0:aa8ded7b33eb | 490 | if (status != MJSON_OK) { return status; } |
defmacro | 0:aa8ded7b33eb | 491 | } |
defmacro | 0:aa8ded7b33eb | 492 | return MJSON_OK; |
defmacro | 0:aa8ded7b33eb | 493 | } |
defmacro | 0:aa8ded7b33eb | 494 | |
defmacro | 0:aa8ded7b33eb | 495 | mjson_status_t mjson_read_int64(struct mjson_ctx *ctx, int64_t *out) |
defmacro | 0:aa8ded7b33eb | 496 | { |
defmacro | 0:aa8ded7b33eb | 497 | int64_t val = 0, sign = 1; |
defmacro | 0:aa8ded7b33eb | 498 | mjson_status_t status; |
defmacro | 0:aa8ded7b33eb | 499 | |
defmacro | 0:aa8ded7b33eb | 500 | status = mjson_ensure_byte_(ctx, 1); |
defmacro | 0:aa8ded7b33eb | 501 | if (status != MJSON_OK) { return status; } |
defmacro | 0:aa8ded7b33eb | 502 | if (MJSON_BUFFER_START_(ctx)[0] == '-') { |
defmacro | 0:aa8ded7b33eb | 503 | mjson_consume_byte_(ctx, 1); |
defmacro | 0:aa8ded7b33eb | 504 | sign = -1; |
defmacro | 0:aa8ded7b33eb | 505 | } |
defmacro | 0:aa8ded7b33eb | 506 | |
defmacro | 0:aa8ded7b33eb | 507 | status = mjson_ensure_byte_(ctx, 1); |
defmacro | 0:aa8ded7b33eb | 508 | if (status != MJSON_OK) { return status; } |
defmacro | 0:aa8ded7b33eb | 509 | while (MJSON_BUFFER_START_(ctx)[0] >= '0' && |
defmacro | 0:aa8ded7b33eb | 510 | MJSON_BUFFER_START_(ctx)[0] <= '9') { |
defmacro | 0:aa8ded7b33eb | 511 | val = val * 10 + (MJSON_BUFFER_START_(ctx)[0] - '0'); |
defmacro | 0:aa8ded7b33eb | 512 | |
defmacro | 0:aa8ded7b33eb | 513 | mjson_consume_byte_(ctx, 1); |
defmacro | 0:aa8ded7b33eb | 514 | status = mjson_ensure_byte_(ctx, 1); |
defmacro | 0:aa8ded7b33eb | 515 | if (status != MJSON_OK) { return status; } |
defmacro | 0:aa8ded7b33eb | 516 | } |
defmacro | 0:aa8ded7b33eb | 517 | *out = val * sign; |
defmacro | 0:aa8ded7b33eb | 518 | /* Skip additional parts */ |
defmacro | 0:aa8ded7b33eb | 519 | while ((MJSON_BUFFER_START_(ctx)[0] >= '0' && |
defmacro | 0:aa8ded7b33eb | 520 | MJSON_BUFFER_START_(ctx)[0] <= '9') || |
defmacro | 0:aa8ded7b33eb | 521 | MJSON_BUFFER_START_(ctx)[0] == '.' || |
defmacro | 0:aa8ded7b33eb | 522 | MJSON_BUFFER_START_(ctx)[0] == 'e' || |
defmacro | 0:aa8ded7b33eb | 523 | MJSON_BUFFER_START_(ctx)[0] == 'E' || |
defmacro | 0:aa8ded7b33eb | 524 | MJSON_BUFFER_START_(ctx)[0] == '+' || |
defmacro | 0:aa8ded7b33eb | 525 | MJSON_BUFFER_START_(ctx)[0] == '-') { |
defmacro | 0:aa8ded7b33eb | 526 | mjson_consume_byte_(ctx, 1); |
defmacro | 0:aa8ded7b33eb | 527 | status = mjson_ensure_byte_(ctx, 1); |
defmacro | 0:aa8ded7b33eb | 528 | if (status != MJSON_OK) { return status; } |
defmacro | 0:aa8ded7b33eb | 529 | } |
defmacro | 0:aa8ded7b33eb | 530 | return MJSON_OK; |
defmacro | 0:aa8ded7b33eb | 531 | } |
defmacro | 0:aa8ded7b33eb | 532 | /* |
defmacro | 0:aa8ded7b33eb | 533 | * We don't really support parsing to double directly here, since to implement |
defmacro | 0:aa8ded7b33eb | 534 | * full double parsing semantics, we would need pow(). However, if pow() is |
defmacro | 0:aa8ded7b33eb | 535 | * available, it is very likely that atof() is also available. Hence providing |
defmacro | 0:aa8ded7b33eb | 536 | * copying number as a string will be enough. |
defmacro | 0:aa8ded7b33eb | 537 | */ |
defmacro | 0:aa8ded7b33eb | 538 | mjson_status_t mjson_read_number_as_string(struct mjson_ctx *ctx, |
defmacro | 0:aa8ded7b33eb | 539 | char *data, size_t length, |
defmacro | 0:aa8ded7b33eb | 540 | size_t *out_length) { |
defmacro | 0:aa8ded7b33eb | 541 | mjson_status_t status; |
defmacro | 0:aa8ded7b33eb | 542 | size_t i = 0; |
defmacro | 0:aa8ded7b33eb | 543 | char ch; |
defmacro | 0:aa8ded7b33eb | 544 | |
defmacro | 0:aa8ded7b33eb | 545 | while (i < length) { |
defmacro | 0:aa8ded7b33eb | 546 | status = mjson_ensure_byte_(ctx, 1); |
defmacro | 0:aa8ded7b33eb | 547 | if (status != MJSON_OK) { return status; } |
defmacro | 0:aa8ded7b33eb | 548 | |
defmacro | 0:aa8ded7b33eb | 549 | ch = MJSON_BUFFER_START_(ctx)[0]; |
defmacro | 0:aa8ded7b33eb | 550 | if ((ch >= '0' && ch <= '9') || |
defmacro | 0:aa8ded7b33eb | 551 | ch == '.' || |
defmacro | 0:aa8ded7b33eb | 552 | ch == '+' || ch == '-' || |
defmacro | 0:aa8ded7b33eb | 553 | ch == 'e' || ch == 'E') { |
defmacro | 0:aa8ded7b33eb | 554 | data[i++] = ch; |
defmacro | 0:aa8ded7b33eb | 555 | mjson_consume_byte_(ctx, 1); |
defmacro | 0:aa8ded7b33eb | 556 | } else { |
defmacro | 0:aa8ded7b33eb | 557 | break; |
defmacro | 0:aa8ded7b33eb | 558 | } |
defmacro | 0:aa8ded7b33eb | 559 | } |
defmacro | 0:aa8ded7b33eb | 560 | status = mjson_ensure_byte_(ctx, 1); |
defmacro | 0:aa8ded7b33eb | 561 | if (status != MJSON_OK) { return status; } |
defmacro | 0:aa8ded7b33eb | 562 | ch = MJSON_BUFFER_START_(ctx)[0]; |
defmacro | 0:aa8ded7b33eb | 563 | while ((ch >= '0' && ch <= '9') || |
defmacro | 0:aa8ded7b33eb | 564 | ch == '.' || |
defmacro | 0:aa8ded7b33eb | 565 | ch == '+' || ch == '-' || |
defmacro | 0:aa8ded7b33eb | 566 | ch == 'e' || ch == 'E') { |
defmacro | 0:aa8ded7b33eb | 567 | i++; |
defmacro | 0:aa8ded7b33eb | 568 | mjson_consume_byte_(ctx, 1); |
defmacro | 0:aa8ded7b33eb | 569 | } |
defmacro | 0:aa8ded7b33eb | 570 | *out_length = i; |
defmacro | 0:aa8ded7b33eb | 571 | return MJSON_OK; |
defmacro | 0:aa8ded7b33eb | 572 | } |
defmacro | 0:aa8ded7b33eb | 573 | |
defmacro | 0:aa8ded7b33eb | 574 | mjson_status_t mjson_skip_number(struct mjson_ctx *ctx) |
defmacro | 0:aa8ded7b33eb | 575 | { |
defmacro | 0:aa8ded7b33eb | 576 | size_t temp; |
defmacro | 0:aa8ded7b33eb | 577 | return mjson_read_number_as_string(ctx, NULL, 0, &temp); |
defmacro | 0:aa8ded7b33eb | 578 | } |
defmacro | 0:aa8ded7b33eb | 579 | |
defmacro | 0:aa8ded7b33eb | 580 | mjson_status_t mjson_skip_value(struct mjson_ctx *ctx) { |
defmacro | 0:aa8ded7b33eb | 581 | mjson_status_t t = mjson_read_type(ctx); |
defmacro | 0:aa8ded7b33eb | 582 | switch (t) { |
defmacro | 0:aa8ded7b33eb | 583 | case MJSON_TYPE_ARRAY: |
defmacro | 0:aa8ded7b33eb | 584 | return mjson_skip_array(ctx); |
defmacro | 0:aa8ded7b33eb | 585 | case MJSON_TYPE_OBJECT: |
defmacro | 0:aa8ded7b33eb | 586 | return mjson_skip_object(ctx); |
defmacro | 0:aa8ded7b33eb | 587 | case MJSON_TYPE_NUMBER: |
defmacro | 0:aa8ded7b33eb | 588 | return mjson_skip_number(ctx); |
defmacro | 0:aa8ded7b33eb | 589 | case MJSON_TYPE_STRING: |
defmacro | 0:aa8ded7b33eb | 590 | return mjson_skip_string(ctx); |
defmacro | 0:aa8ded7b33eb | 591 | case MJSON_TYPE_NULL: |
defmacro | 0:aa8ded7b33eb | 592 | case MJSON_TYPE_TRUE: |
defmacro | 0:aa8ded7b33eb | 593 | case MJSON_TYPE_FALSE: |
defmacro | 0:aa8ded7b33eb | 594 | return MJSON_OK; |
defmacro | 0:aa8ded7b33eb | 595 | } |
defmacro | 0:aa8ded7b33eb | 596 | return t; |
defmacro | 0:aa8ded7b33eb | 597 | } |
defmacro | 0:aa8ded7b33eb | 598 | |
defmacro | 0:aa8ded7b33eb | 599 | #endif /* MJSON_H_ */ |