json.c: add len argument to callback - json2tsv - JSON to TSV converter | |
git clone git://git.codemadness.org/json2tsv | |
Log | |
Files | |
Refs | |
README | |
LICENSE | |
--- | |
commit 403d7765995d21fbe24fda7318e8ac85c87bd4b1 | |
parent 55e9552c536fcb18f28d6742cfbec3ae10766473 | |
Author: Hiltjo Posthuma <[email protected]> | |
Date: Tue, 4 Apr 2023 18:13:10 +0200 | |
json.c: add len argument to callback | |
Not important for json2tsv itself, but for other uses of json.{c,h} it saves a | |
strlen() call in some cases. | |
Note that NUL bytes (via \u0000 or so) are discarded in json.c codepointtoutf8(… | |
Diffstat: | |
M json.c | 14 +++++++------- | |
M json.h | 2 +- | |
M json2tsv.c | 22 ++++++++++++++-------- | |
3 files changed, 22 insertions(+), 16 deletions(-) | |
--- | |
diff --git a/json.c b/json.c | |
@@ -94,7 +94,7 @@ capacity(char **value, size_t *sz, size_t cur, size_t inc) | |
#define JSON_INVALID() do { ret = JSON_ERROR_INVALID; goto end; } while … | |
int | |
-parsejson(void (*cb)(struct json_node *, size_t, const char *)) | |
+parsejson(void (*cb)(struct json_node *, size_t, const char *, size_t)) | |
{ | |
struct json_node nodes[JSON_MAX_NODE_DEPTH] = { { 0 } }; | |
size_t depth = 0, p = 0, len, sz = 0; | |
@@ -205,7 +205,7 @@ escchr: | |
goto end; | |
memcpy(nodes[depth].name, str,… | |
} else { | |
- cb(nodes, depth + 1, str); | |
+ cb(nodes, depth + 1, str, len … | |
} | |
break; | |
} else { | |
@@ -234,7 +234,7 @@ escchr: | |
expect = EXPECT_OBJECT_STRING; | |
} | |
- cb(nodes, depth + 1, ""); | |
+ cb(nodes, depth + 1, "", 0); | |
depth++; | |
nodes[depth].index = 0; | |
@@ -269,7 +269,7 @@ escchr: | |
if (GETNEXT() != 'r' || GETNEXT() != 'u' || GETNEXT() … | |
JSON_INVALID(); | |
nodes[depth].type = JSON_TYPE_BOOL; | |
- cb(nodes, depth + 1, "true"); | |
+ cb(nodes, depth + 1, "true", 4); | |
expect = EXPECT_END; | |
break; | |
case 'f': /* false */ | |
@@ -277,14 +277,14 @@ escchr: | |
GETNEXT() != 'e') | |
JSON_INVALID(); | |
nodes[depth].type = JSON_TYPE_BOOL; | |
- cb(nodes, depth + 1, "false"); | |
+ cb(nodes, depth + 1, "false", 5); | |
expect = EXPECT_END; | |
break; | |
case 'n': /* null */ | |
if (GETNEXT() != 'u' || GETNEXT() != 'l' || GETNEXT() … | |
JSON_INVALID(); | |
nodes[depth].type = JSON_TYPE_NULL; | |
- cb(nodes, depth + 1, "null"); | |
+ cb(nodes, depth + 1, "null", 4); | |
expect = EXPECT_END; | |
break; | |
default: /* number */ | |
@@ -299,7 +299,7 @@ escchr: | |
c != '+' && c != '-' && c != '.') || | |
p + 1 >= sizeof(pri)) { | |
pri[p] = '\0'; | |
- cb(nodes, depth + 1, pri); | |
+ cb(nodes, depth + 1, pri, p); | |
goto handlechr; /* do not read next ch… | |
} else { | |
pri[p++] = c; | |
diff --git a/json.h b/json.h | |
@@ -26,5 +26,5 @@ struct json_node { | |
size_t index; /* count/index for array or object type */ | |
}; | |
-int parsejson(void (*cb)(struct json_node *, size_t, const char *)); | |
+int parsejson(void (*cb)(struct json_node *, size_t, const char *, size_t)); | |
#endif | |
diff --git a/json2tsv.c b/json2tsv.c | |
@@ -21,12 +21,15 @@ static int nflag = 0; /* -n flag: show indices count for ar… | |
static int rflag = 0; /* -r flag: show all control-characters */ | |
static int fs = '\t', rs = '\n'; | |
-static void (*printvalue)(const char *); | |
+static void (*printvalue)(const char *, size_t); | |
void | |
-tsv_printvalue(const char *s) | |
+tsv_printvalue(const char *s, size_t len) | |
{ | |
- for (; *s; s++) { | |
+ const char *e; | |
+ | |
+ e = s + len; | |
+ for (; s != e; s++) { | |
/* escape some chars */ | |
switch (*s) { | |
case '\n': putchar('\\'); putchar('n'); break; | |
@@ -42,9 +45,12 @@ tsv_printvalue(const char *s) | |
} | |
void | |
-rs_printvalue(const char *s) | |
+rs_printvalue(const char *s, size_t len) | |
{ | |
- for (; *s; s++) { | |
+ const char *e; | |
+ | |
+ e = e + len; | |
+ for (; s != e; s++) { | |
if (*s == fs || *s == rs) | |
continue; | |
@@ -86,12 +92,12 @@ printnum(uintmax_t x) | |
} | |
void | |
-processnode(struct json_node *nodes, size_t depth, const char *value) | |
+processnode(struct json_node *nodes, size_t depth, const char *value, size_t v… | |
{ | |
size_t i; | |
for (i = 0; i < depth; i++) { | |
- printvalue(nodes[i].name); | |
+ printvalue(nodes[i].name, strlen(nodes[i].name)); | |
if (i + 1 == depth && | |
(nodes[i].type == JSON_TYPE_OBJECT || | |
@@ -111,7 +117,7 @@ processnode(struct json_node *nodes, size_t depth, const ch… | |
putchar(fs); | |
putchar(nodes[depth - 1].type); | |
putchar(fs); | |
- printvalue(value); | |
+ printvalue(value, valuelen); | |
putchar(rs); | |
if (ferror(stdout)) { |