diff options
author | bpc2003 <wpesfriendnva@gmail.com> | 2025-04-30 12:20:13 -0400 |
---|---|---|
committer | bpc2003 <wpesfriendnva@gmail.com> | 2025-04-30 12:20:13 -0400 |
commit | 4ea8fe896cc333f5e7addd56e23db5668f4599b3 (patch) | |
tree | 56dd3eac6e94f26976188cd08db4ad0466fec826 | |
parent | 1eddf23c5da0faa055a5feb1bf22cf52b17011a4 (diff) |
Made readdb and writedb smaller
-rw-r--r-- | src/include/engine/file.c | 211 | ||||
-rw-r--r-- | src/main.c | 49 |
2 files changed, 132 insertions, 128 deletions
diff --git a/src/include/engine/file.c b/src/include/engine/file.c index e89dacf..13d6d3e 100644 --- a/src/include/engine/file.c +++ b/src/include/engine/file.c @@ -5,137 +5,172 @@ #include "engine.h" static int check(char **known, int len, char *str); +static void freeknown(char ***known, int len); + static long getsz(FILE *fp); -static char *makepair(char *key, char *value); +static int checkmark(char *buf, int pos); +static char *readidx(char *buf, int *i, char ***known, int *len, int *pos); -// TODO: reimplement this to read file in FI (Fast Infoset) format -// TODO: make this smaller tablist_t *readdb(char *filename) { FILE *fp; - int llen = 2, tlen = 2; - char **ktags = calloc(tlen, sizeof(char *)); - tablist_t *list = calloc(llen, sizeof(tablist_t)); - list[0].len = llen; - + int len = 2; + tablist_t *list = calloc(len, sizeof(tablist_t)); + list[0].len = len; if (filename == NULL || (fp = fopen(filename, "rb")) == NULL) return list; - long sz = getsz(fp); char *buf = calloc(sz, sizeof(char)); fread(buf, sizeof(char), sz, fp); - char *v, *k; - for (int i = 0, j = 0, id = 0; i < sz; ++i) { - if (buf[i] == '\n') - continue; - if (j >= tlen) - ktags = realloc(ktags, ++tlen * sizeof(char *)); - if (buf[i] == '<' || buf[i] == ':') { - if (buf[i] == '<') { - int t; - for (t = i + 1; buf[t] != '>'; ++t) ; - ktags[j] = calloc(t - i, sizeof(char)); - strncpy(ktags[j++], buf + i + 1, t - i - 1); - k = ktags[j - 1]; - i += t - i; - } else { - int t; - for (t = i + 1; buf[t] != '\n'; ++t) ; - v = calloc(t - i, sizeof(char)); - strncpy(v, buf + i + 1, t - i - 1); - i += t - i; - char *pair = makepair(k, v); - setkeys(&list, id, &pair, 1); - free(pair); - free(v); - } - } else { - int idx = 0; - memcpy(&idx, buf + i, sizeof(int)); - i += sizeof(int) - 1; - if (idx == 1) - id++; - k = ktags[idx]; + fclose(fp); + + int tlen, vlen, t = 0, v = 0, l = -1; + char **ktags = calloc((tlen = 2), sizeof(char *)); + char **kvalues = calloc((vlen = 2), sizeof (char *)); + char *key, *value; + for (int i = 0; i < sz; ++i) { + if (buf[i] == ':') { + ++i; + value = readidx(buf, &i, &kvalues, &vlen, &v); + char *pair = calloc(strlen(key) + strlen(value) + 2, sizeof(char)); + sprintf(pair, "%s:%s", key, value); + setkeys(&list, l, &pair, 1); + free(pair); + key = value = NULL; + } + else { + key = readidx(buf, &i, &ktags, &tlen, &t); + if (!strcmp(key, "document")) + ++l; } } - - for (int i = 0; i < tlen - 1; ++i) - free(ktags[i]); - free(ktags); + freeknown(&ktags, t); + freeknown(&kvalues, v); free(buf); - fclose(fp); return list; } -// TODO: Make this write to a file in the FI (Fast Infoset) format -// TODO: Make this smaller +static char *readidx(char *buf, int *i, char ***known, int *len, int *pos) +{ + char *r = NULL; + if (checkmark(buf, *i)) { + if (*len >= *pos) { + *len *= 2; + *known = realloc(*known, *len * sizeof(char *)); + } + *i += 4; + int nlen; + memcpy(&nlen, buf + *i, sizeof(int)); + *i += sizeof(int); + (*known)[*pos] = calloc(nlen + 1, sizeof(char)); + strncpy((*known)[(*pos)++], buf + *i, nlen); + r = (*known)[(*pos) - 1]; + *i += nlen - 1; + } else { + int idx; + memcpy(&idx, buf + *i, sizeof(int)); + *i += sizeof(int) - 1; + if (idx > *pos) + return NULL; + r = (*known)[idx]; + } + return r; +} + +static int checkmark(char *buf, int pos) +{ + int marker = 0xffffffff; + return !memcmp(buf + pos, &marker, sizeof(int)); +} + +static long getsz(FILE *fp) +{ + fseek(fp, 0, SEEK_END); + long sz = ftell(fp); + fseek(fp, 0, SEEK_SET); + return sz; +} + +static void newtag(char *tag, FILE *fp); +static void writeidx(char ***known, int *len, int *pos, char *str, FILE *fp); + void writedb(char *filename, tablist_t *list) { FILE *fp = fopen(filename, "wb"); if (fp == NULL) return; - int len = 2; - char **ktags = calloc(len, sizeof(char *)); + int tlen, vlen, t = 0, v = 0; + char **ktags = calloc((tlen = 2), sizeof(char *)); + writeidx(&ktags, &tlen, &t, "documents", fp); + writeidx(&ktags, &tlen, &t, "document", fp); - fprintf(fp, "<documents>\n"); - fprintf(fp, "<document>\n"); - ktags[0] = "documents"; - ktags[1] = "document"; + char buf[64]; + char **kvalues = calloc((vlen = 2), sizeof(char *)); tablist_t *indexes = getkeys(list, -1, NULL, 0); - for (int i = 0, j = 2; i < indexes[0].len; ++i) { - int n = 1; + for (int i = 0; i < indexes[0].len; ++i) { if (i > 0) - fwrite(&n, sizeof(int), 1, fp); - for (int k = 0; indexes[i].tab[k].flag; ++k) { - if ((n = check(ktags, len, indexes[i].tab[k].key)) >= 0) - fwrite(&n, sizeof(int), 1, fp); - else { - fprintf(fp, "<%s>", indexes[i].tab[k].key); - if (j >= len) - ktags = realloc(ktags, ++len * sizeof(char *)); - ktags[j] = calloc(strlen(indexes[i].tab[k].key) + 1, sizeof(char)); - strcpy(ktags[j++], indexes[i].tab[k].key); - } - switch (indexes[i].tab[k].flag) { + writeidx(&ktags, &tlen, &t, "document", fp); + for (int j = 0; indexes[i].tab[j].flag; ++j) { + writeidx(&ktags, &tlen, &t, indexes[i].tab[j].key, fp); + fputc(':', fp); + switch (indexes[i].tab[j].flag) { case 1: - fprintf(fp, ":%g\n", indexes[i].tab[k].value.num); + snprintf(buf, 64, "%g", indexes[i].tab[j].value.num); + writeidx(&kvalues, &vlen, &v, buf, fp); break; case 2: - fprintf(fp, ":%s\n", indexes[i].tab[k].value.boolean ? "true" : "false"); + writeidx(&kvalues, &vlen, &v, + indexes[i].tab[j].value.boolean ? "true" : "false", fp); break; case 3: - fprintf(fp, ":%s\n", indexes[i].tab[k].value.str); + writeidx(&kvalues, &vlen, &v, indexes[i].tab[j].value.str, fp); break; } } } - for (int i = 2; i < len; ++i) - free(ktags[i]); - free(ktags); + freeknown(&ktags, t); + freeknown(&kvalues, v); free(indexes); fclose(fp); } -static int check(char **known, int len, char *str) +static void newtag(char *tag, FILE *fp) { - for (int i = 0; i < len; ++i) { - if (!strcmp(str, known[i])) - return i; + int len = strlen(tag); + int marker = 0xffffffff; + fwrite(&marker, sizeof(int), 1, fp); + fwrite(&len, sizeof(int), 1, fp); + fwrite(tag, sizeof(char), len, fp); +} + +static void writeidx(char ***known, int *len, int *pos, char *str, FILE *fp) +{ + int n; + if ((n = check(*known, *pos, str)) >= 0) + fwrite(&n, sizeof(int), 1, fp); + else { + if (*pos >= *len) { + *len *= 2; + *known = realloc(*known, *len * sizeof(char *)); + } + (*known)[*pos] = calloc(strlen(str) + 1, sizeof(char)); + strcpy((*known)[*pos], str); + newtag((*known)[(*pos)++], fp); } - return -1; } -static long getsz(FILE *fp) +static void freeknown(char ***known, int pos) { - fseek(fp, 0, SEEK_END); - long sz = ftell(fp); - fseek(fp, 0, SEEK_SET); - return sz; + for (int i = 0; i < pos; ++i) + free((*known)[i]); + free(*known); } -static char *makepair(char *key, char *value) +static int check(char **known, int len, char *str) { - char *pair = calloc(strlen(key) + strlen(value) + 2, sizeof(char)); - sprintf(pair, "%s:%s", key, value); - return pair; + for (int i = 0; i < len; ++i) { + if (!strcmp(str, known[i])) + return i; + } + return -1; } @@ -7,13 +7,8 @@ #include "cmd.h" int getid(char *selector); -int printkeys(tablist_t **list, int id, char **keys, int klen); +int printkeys(tablist_t *list, int id, char **keys, int klen); void printkey(tabidx_t idx); -// TODO: rename these functions -int setkeys_main(tablist_t **list, int id, char **pairs, int plen); -int delkeys_main(tablist_t **list, int id, char **keys, int klen); -int exec(int (*tabop)(tablist_t **, int, char **, int), - tablist_t **list, int id, char **keys, int klen); int main(int argc, char **argv) { @@ -37,12 +32,15 @@ int main(int argc, char **argv) int id = getid(evaled.selector); switch (evaled.type) { case GET: - exec(printkeys, &list, id, evaled.params, evaled.plen); + printkeys(list, id, evaled.params, evaled.plen); break; case SET: + id = setkeys(&list, id, evaled.params, evaled.plen); + if (!id && filename) + writedb(filename, list); + break; case DEL: - id = exec(evaled.type == SET ? setkeys_main : delkeys_main, - &list, id, evaled.params, evaled.plen); + id = delkeys(list, id, evaled.params, evaled.plen); if (!id && filename) writedb(filename, list); break; @@ -77,9 +75,9 @@ int getid(char *selector) { return -2; } -int printkeys(tablist_t **list, int id, char **keys, int klen) +int printkeys(tablist_t *list, int id, char **keys, int klen) { - tablist_t *indexes = getkeys(*list, id, keys, klen); + tablist_t *indexes = getkeys(list, id, keys, klen); if (indexes == NULL) return 1; for (int i = 0; i < indexes[0].len; ++i) { @@ -107,32 +105,3 @@ void printkey(tabidx_t idx) break; } } - -int setkeys_main(tablist_t **list, int id, char **pairs, int plen) -{ - if (pairs == NULL || id < -1) - return 1; - if (setkeys(list, id, pairs, plen)) - return 2; - return 0; -} - -int delkeys_main(tablist_t **list, int id, char **keys, int klen) -{ - if (keys == NULL || id < -1) - return 1; - if (delkeys(*list, id, keys, klen)) - return 2; - return 0; -} - -int exec(int (*tabop)(tablist_t **, int, char **, int), - tablist_t **list, int id, char **keys, int klen) -{ - if (id >= -1) - return tabop(list, id, keys, klen); - else { - fprintf(stderr, "Invalid id\n"); - return 1; - } -} |