From b99dcd6c3b1494f44f67229b5435e629fc566b1a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Anton=20Luka=20=C5=A0ijanec?= Date: Mon, 14 Feb 2022 23:05:01 +0100 Subject: going to use libcjson after all --- src/json.c | 80 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 80 insertions(+) create mode 100644 src/json.c (limited to 'src/json.c') diff --git a/src/json.c b/src/json.c new file mode 100644 index 0000000..e23d934 --- /dev/null +++ b/src/json.c @@ -0,0 +1,80 @@ +#ifndef DC_REALLOC_K +#define DC_REALLOC_K 1.5 +#endif +struct dc_json { /* does not care about syntax, only purpose is to detect objects for libcjson */ + char * buf; /* internal buffer */ + size_t bufcap; /* internal buffer capacity */ + size_t nest; /* internal nesting depth of whatevery type: object or array */ + size_t instr; /* internal if we are currently in a string */ + size_t start; /* internal starting offset in buffer of first byte of object - { */ + char backup; /* internal we store byte we overwrote with \0 when we were ready */ + int ready; /* internal we indicate to the next call that we were ready previous time */ +}; /* note that no memory is transfered. in is copied and return mustn't be freed. */ +char * dc_json (struct dc_json * j, char * in) { /* detects start/end of a cat objects JSON stream */ + size_t i; /* input a null terminated string - a chunk of the json stream */ + if (!j->buf) + (j->buf = malloc((j->bufcap = 1024) * sizeof(char)))[0] = '\0'; + if (j->ready) { + if (j->ready > 0) + memmove(j->buf, j->buf+j->ready, strlen(j->buf+j->ready)+1); + j->buf[0] = j->backup; + } + size_t bufstrlen = strlen(j->buf); /* could optimize and cache it into the struct */ + size_t instrlen = strlen(in); + i = bufstrlen; + if (bufstrlen + instrlen > j->bufcap) + j->buf = realloc(j->buf, (j->bufcap=(bufstrlen+instrlen)*DC_REALLOC_K)*sizeof(char)); + strcpy(j->buf+bufstrlen, in); + bufstrlen += instrlen; + while (i < bufstrlen) { + if (j->instr) { + if (j->buf[i] == '"') { + int escaped = 0; + int index = 0; + while (j->buf[i-++index] == '\\') { + if (escaped) + escaped = 0; + else + escaped++; + } + if (!escaped) { + j->instr = 0; + fprintf(stderr, "dc_json: j->instr = 0\n"); + } else + fprintf(stderr, "dc_json: escaped\n"); + } + goto next; + } + switch (j->buf[i]) { + case '{': + case '[': + if (!j->nest++) + j->start = i; + break; + case '"': + j->instr++; + fprintf(stderr, "dc_json: j->instr++\n"); + break; + case '}': + case ']': + if (!--j->nest) { + j->backup = j->buf[++i]; + j->ready = i; + if (!j->backup) + j->ready = -1; + j->buf[i] = '\0'; + return j->buf+j->start; + } + break; + default: + break; + } +next: + i++; + } + return NULL; +} /* returns pointer to null terminated string when there's an object to be parsed or NULL. */ +void dc_json_free (struct dc_json * s) { + free(s->buf); + free(s); +} -- cgit v1.2.3