sync json parser improvements from json2tsv repo - frontends - front-ends for s… | |
Log | |
Files | |
Refs | |
README | |
LICENSE | |
--- | |
commit a5e2f07cb75a19578454e096f2c9f77cebc30084 | |
parent f292d66dca2b0154b56fc8fa6935b947bfc74452 | |
Author: Hiltjo Posthuma <[email protected]> | |
Date: Wed, 30 Mar 2022 00:01:52 +0200 | |
sync json parser improvements from json2tsv repo | |
Diffstat: | |
M json.c | 40 +++++++++++++++++------------… | |
M json.h | 20 ++++++++++++-------- | |
2 files changed, 34 insertions(+), 26 deletions(-) | |
--- | |
diff --git a/json.c b/json.c | |
@@ -1,4 +1,3 @@ | |
-#include <ctype.h> | |
#include <errno.h> | |
#include <stdint.h> | |
#include <stdio.h> | |
@@ -9,6 +8,9 @@ | |
#include "json.h" | |
+#define ISDIGIT(c) (((unsigned)c) - '0' < 10) | |
+#define ISXDIGIT(c) ((((unsigned)c) - '0' < 10) || ((unsigned)c | 32) - 'a' < … | |
+ | |
static const unsigned char *json_data; | |
static size_t json_data_size; | |
static size_t json_data_off; | |
@@ -116,7 +118,7 @@ int | |
parsejson(const char *s, size_t slen, | |
void (*cb)(struct json_node *, size_t, const char *, void *), void *… | |
{ | |
- struct json_node nodes[JSON_MAX_NODE_DEPTH] = { 0 }; | |
+ struct json_node nodes[JSON_MAX_NODE_DEPTH] = { { 0 } }; | |
size_t depth = 0, p = 0, len, sz = 0; | |
long cp, hi, lo; | |
char pri[128], *str = NULL; | |
@@ -148,7 +150,7 @@ handlechr: | |
expect = EXPECT_VALUE; | |
break; | |
case '"': | |
- nodes[depth].type = TYPE_STRING; | |
+ nodes[depth].type = JSON_TYPE_STRING; | |
escape = 0; | |
len = 0; | |
while (1) { | |
@@ -174,8 +176,8 @@ escchr: | |
if (capacity(&str, &sz, len, 4… | |
goto end; | |
for (i = 12, cp = 0; i >= 0; i… | |
- if ((c = GETNEXT()) ==… | |
- JSON_INVALID()… | |
+ if ((c = GETNEXT()) ==… | |
+ JSON_INVALID()… | |
cp |= (hexdigit(c) << … | |
} | |
/* RFC8259 - 7. Strings - surr… | |
@@ -190,8 +192,8 @@ escchr: | |
goto escchr; | |
} | |
for (hi = cp, i = 12, … | |
- if ((c = GETNE… | |
- JSON_I… | |
+ if ((c = GETNE… | |
+ JSON_I… | |
lo |= (hexdigi… | |
} | |
/* 0xdc00 - 0xdfff - l… | |
@@ -248,11 +250,11 @@ escchr: | |
nodes[depth].index = 0; | |
if (c == '[') { | |
- nodes[depth].type = TYPE_ARRAY; | |
+ nodes[depth].type = JSON_TYPE_ARRAY; | |
expect = EXPECT_ARRAY_VALUE; | |
} else if (c == '{') { | |
iskey = 1; | |
- nodes[depth].type = TYPE_OBJECT; | |
+ nodes[depth].type = JSON_TYPE_OBJECT; | |
expect = EXPECT_OBJECT_STRING; | |
} | |
@@ -267,11 +269,12 @@ escchr: | |
case ']': | |
case '}': | |
if (!depth || | |
- (c == ']' && nodes[depth - 1].type != TYPE_ARRAY) || | |
- (c == '}' && nodes[depth - 1].type != TYPE_OBJECT)) | |
+ (c == ']' && nodes[depth - 1].type != JSON_TYPE_ARR… | |
+ (c == '}' && nodes[depth - 1].type != JSON_TYPE_OBJ… | |
JSON_INVALID(); /* unbalanced nodes */ | |
- nodes[--depth].index++; | |
+ depth--; | |
+ nodes[depth].index++; | |
expect = EXPECT_END; | |
break; | |
case ',': | |
@@ -279,7 +282,7 @@ escchr: | |
JSON_INVALID(); /* unbalanced nodes */ | |
nodes[depth - 1].index++; | |
- if (nodes[depth - 1].type == TYPE_OBJECT) { | |
+ if (nodes[depth - 1].type == JSON_TYPE_OBJECT) { | |
iskey = 1; | |
expect = EXPECT_STRING; | |
} else { | |
@@ -289,7 +292,7 @@ escchr: | |
case 't': /* true */ | |
if (GETNEXT() != 'r' || GETNEXT() != 'u' || GETNEXT() … | |
JSON_INVALID(); | |
- nodes[depth].type = TYPE_BOOL; | |
+ nodes[depth].type = JSON_TYPE_BOOL; | |
cb(nodes, depth + 1, "true", pp); | |
expect = EXPECT_END; | |
break; | |
@@ -297,26 +300,27 @@ escchr: | |
if (GETNEXT() != 'a' || GETNEXT() != 'l' || GETNEXT() … | |
GETNEXT() != 'e') | |
JSON_INVALID(); | |
- nodes[depth].type = TYPE_BOOL; | |
+ nodes[depth].type = JSON_TYPE_BOOL; | |
cb(nodes, depth + 1, "false", pp); | |
expect = EXPECT_END; | |
break; | |
case 'n': /* null */ | |
if (GETNEXT() != 'u' || GETNEXT() != 'l' || GETNEXT() … | |
JSON_INVALID(); | |
- nodes[depth].type = TYPE_NULL; | |
+ nodes[depth].type = JSON_TYPE_NULL; | |
cb(nodes, depth + 1, "null", pp); | |
expect = EXPECT_END; | |
break; | |
default: /* number */ | |
- nodes[depth].type = TYPE_NUMBER; | |
+ nodes[depth].type = JSON_TYPE_NUMBER; | |
p = 0; | |
pri[p++] = c; | |
expect = EXPECT_END; | |
while (1) { | |
c = GETNEXT(); | |
if (c == EOF || | |
- !c || !strchr("0123456789eE+-.", c) || | |
+ (!ISDIGIT(c) && c != 'e' && c != 'E' && | |
+ c != '+' && c != '-' && c != '.') || | |
p + 1 >= sizeof(pri)) { | |
pri[p] = '\0'; | |
cb(nodes, depth + 1, pri, pp); | |
diff --git a/json.h b/json.h | |
@@ -1,12 +1,15 @@ | |
-#include <stdint.h> | |
+#ifndef _JSON_H_ | |
+#define _JSON_H_ | |
+ | |
+#include <stddef.h> | |
enum JSONType { | |
- TYPE_ARRAY = 'a', | |
- TYPE_OBJECT = 'o', | |
- TYPE_STRING = 's', | |
- TYPE_BOOL = 'b', | |
- TYPE_NULL = '?', | |
- TYPE_NUMBER = 'n' | |
+ JSON_TYPE_ARRAY = 'a', | |
+ JSON_TYPE_OBJECT = 'o', | |
+ JSON_TYPE_STRING = 's', | |
+ JSON_TYPE_BOOL = 'b', | |
+ JSON_TYPE_NULL = '?', | |
+ JSON_TYPE_NUMBER = 'n' | |
}; | |
enum JSONError { | |
@@ -25,4 +28,5 @@ struct json_node { | |
int parsejson(const char *, size_t, | |
void (*cb)(struct json_node *, size_t, const char *, void *), | |
- void *); | |
+ void *); | |
+#endif |