diff options
author | bpc2003 <wpesfriendnva@gmail.com> | 2025-04-25 19:19:37 -0400 |
---|---|---|
committer | bpc2003 <wpesfriendnva@gmail.com> | 2025-04-25 19:19:37 -0400 |
commit | 1eddf23c5da0faa055a5feb1bf22cf52b17011a4 (patch) | |
tree | ca70bce4e452d1cc132b8da9f9405f296b35b18d | |
parent | 2b7a3a815fb5d0b5155deec5f613730e898e4100 (diff) |
rewrite readdb and writedb to read and write in binary format
-rw-r--r-- | Makefile | 4 | ||||
-rw-r--r-- | src/include/engine/file.c | 161 | ||||
-rw-r--r-- | src/test.c | 25 |
3 files changed, 129 insertions, 61 deletions
@@ -2,7 +2,7 @@ CC = gcc BUILD = target C_FLAGS = -Wall -lmdb -std=c11 D_FLAGS = -L$(BUILD) -Wl,-rpath=$(BUILD) -O0 -L_FLAGS = -c -fPIC -Wall -Werror +L_FLAGS = -c -fPIC -Wall all: mdb mdb: lib @@ -14,7 +14,7 @@ lib: $(BUILD) test: dev_lib $(CC) src/test.c $(D_FLAGS) -g $(C_FLAGS) -o $(BUILD)/test.out - valgrind --tool=memcheck -s --log-file="mem_dbg" ./$(BUILD)/test.out + valgrind --tool=memcheck --leak-check=full --log-file="mem_dbg" ./$(BUILD)/test.out valgrind --tool=drd -s --log-file="thrd_dbg" ./$(BUILD)/test.out rm -rf $(BUILD) dev: dev_lib diff --git a/src/include/engine/file.c b/src/include/engine/file.c index 4da8b2d..e89dacf 100644 --- a/src/include/engine/file.c +++ b/src/include/engine/file.c @@ -4,95 +4,138 @@ #include "engine.h" -static char *getpair(int *c, FILE *fp); +static int check(char **known, int len, char *str); +static long getsz(FILE *fp); +static char *makepair(char *key, char *value); -// TODO: reimplement this to read file in FI format +// TODO: reimplement this to read file in FI (Fast Infoset) format +// TODO: make this smaller tablist_t *readdb(char *filename) { - int len = 2; - tablist_t *list = calloc(len, sizeof(tablist_t)); - list[0].len = len; FILE *fp; - if (filename == NULL || - (fp = fopen(filename, "rb")) == NULL) + int llen = 2, tlen = 2; + char **ktags = calloc(tlen, sizeof(char *)); + tablist_t *list = calloc(llen, sizeof(tablist_t)); + list[0].len = llen; + + if (filename == NULL || (fp = fopen(filename, "rb")) == NULL) return list; - int c, i = 0, open = 0; - char *p; - while ((c = fgetc(fp)) != EOF) { - switch (c) { - case 250: - p = getpair(&c, fp); - if (p == NULL) goto fail; - setkeys(&list, i, &p, 1); - free(p); - break; - case 251: - if (open == 1) goto fail; - open = 1; - break; - case 254: - open = 0; - i++; - break; - default: - goto fail; + 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); - return list; -fail: + for (int i = 0; i < tlen - 1; ++i) + free(ktags[i]); + free(ktags); + free(buf); fclose(fp); - delkeys(list, -1, NULL, 0); - free(list); - return NULL; + return list; } -// TODO: rewrite this function to write data in FI format +// TODO: Make this write to a file in the FI (Fast Infoset) format +// TODO: Make this smaller void writedb(char *filename, tablist_t *list) { FILE *fp = fopen(filename, "wb"); if (fp == NULL) return; - for (int i = 0; i < list[0].len; ++i) { - fputc(0xFB, fp); - tablist_t *indexes = getkeys(list, i, NULL, 0); - for (int j = 0; indexes[0].tab[j].flag; ++j) { - fprintf(fp, "\xfa%s:", indexes[0].tab[j].key); - switch (indexes[0].tab[j].flag) { + int len = 2; + char **ktags = calloc(len, sizeof(char *)); + + fprintf(fp, "<documents>\n"); + fprintf(fp, "<document>\n"); + ktags[0] = "documents"; + ktags[1] = "document"; + tablist_t *indexes = getkeys(list, -1, NULL, 0); + for (int i = 0, j = 2; i < indexes[0].len; ++i) { + int n = 1; + 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) { case 1: - fprintf(fp, "%.2lf\xfc", indexes[0].tab[j].value.num); + fprintf(fp, ":%g\n", indexes[i].tab[k].value.num); break; case 2: - fprintf(fp, "%s\xfc", indexes[0].tab[j].value.boolean ? - "true" : "false"); + fprintf(fp, ":%s\n", indexes[i].tab[k].value.boolean ? "true" : "false"); break; case 3: - fprintf(fp, "%s\xfc", indexes[0].tab[j].value.str); + fprintf(fp, ":%s\n", indexes[i].tab[k].value.str); break; } } - free(indexes); - fputc(0xFE, fp); } + for (int i = 2; i < len; ++i) + free(ktags[i]); + free(ktags); + free(indexes); fclose(fp); } -static char *getpair(int *c, FILE *fp) +static int check(char **known, int len, char *str) { - char *pair = calloc(3, sizeof(char)); - int i = 0, len = 3; - while ((*c = fgetc(fp)) != 252 && *c != EOF) { - if (i >= len) - pair = realloc(pair, ++len * sizeof(char)); - pair[i++] = *c; - } - pair = realloc(pair, ++len * sizeof(char)); - pair[i] = '\0'; - if (*c != 252) { - free(pair); - return NULL; + for (int i = 0; i < len; ++i) { + if (!strcmp(str, known[i])) + return i; } + return -1; +} + +static long getsz(FILE *fp) +{ + fseek(fp, 0, SEEK_END); + long sz = ftell(fp); + fseek(fp, 0, SEEK_SET); + return sz; +} + +static char *makepair(char *key, char *value) +{ + char *pair = calloc(strlen(key) + strlen(value) + 2, sizeof(char)); + sprintf(pair, "%s:%s", key, value); return pair; } @@ -3,6 +3,29 @@ #include "include/mdb.h" +void test_writedb(void) +{ + tablist_t *list = readdb("dbs/new.db"); + writedb("dbs/test.db", list); + delkeys(list, -1, NULL, 0); + free(list); +} + +void test_readdb(void) +{ + tablist_t *list = readdb("dbs/new.db"); + tablist_t *indices = getkeys(list, -1, NULL, 0); + for (int i = 0; i < indices[0].len; ++i) { + printf("id: %d\n", i); + for (int j = 0; indices[i].tab[j].flag; ++j) + printf("%s\n", indices[i].tab[j].key); + } + free(indices); + delkeys(list, -1, NULL, 0); + free(list); +} + + void test_setkeys(void) { tablist_t *list = readdb("dbs/test.db"); @@ -178,6 +201,8 @@ void test_getkeys(void) int main(void) { + test_writedb(); + test_readdb(); test_getkeys(); test_getkeys_multi(); test_getkeys_multi_fail(); |