summaryrefslogtreecommitdiffstats
path: root/src/json.c
diff options
context:
space:
mode:
authorAnton Luka Šijanec <anton@sijanec.eu>2022-02-14 23:05:01 +0100
committerAnton Luka Šijanec <anton@sijanec.eu>2022-02-14 23:05:01 +0100
commitb99dcd6c3b1494f44f67229b5435e629fc566b1a (patch)
tree203d4442a82bd4427a101c986f01043748f20967 /src/json.c
parenta commit just in case. read description. (diff)
downloaddiscord.c-b99dcd6c3b1494f44f67229b5435e629fc566b1a.tar
discord.c-b99dcd6c3b1494f44f67229b5435e629fc566b1a.tar.gz
discord.c-b99dcd6c3b1494f44f67229b5435e629fc566b1a.tar.bz2
discord.c-b99dcd6c3b1494f44f67229b5435e629fc566b1a.tar.lz
discord.c-b99dcd6c3b1494f44f67229b5435e629fc566b1a.tar.xz
discord.c-b99dcd6c3b1494f44f67229b5435e629fc566b1a.tar.zst
discord.c-b99dcd6c3b1494f44f67229b5435e629fc566b1a.zip
Diffstat (limited to '')
-rw-r--r--src/json.c80
1 files changed, 80 insertions, 0 deletions
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);
+}