#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); }