diff options
-rw-r--r-- | src/file.c | 75 | ||||
-rw-r--r-- | src/include/mdb.h | 29 | ||||
-rw-r--r-- | src/keytab.c | 19 | ||||
-rw-r--r-- | src/main.c | 41 | ||||
-rw-r--r-- | src/parser.c | 71 |
5 files changed, 80 insertions, 155 deletions
@@ -1,53 +1,92 @@ #include <stdio.h> #include <stdlib.h> -#include <stdint.h> #include <string.h> #include "include/mdb.h" -uint8_t *readdb(char *filename) +static char *getpair(int *c, FILE *fp); + +struct keytablist *readdb(char *filename) { + int len = 2; + struct keytablist *list = calloc(len, sizeof(struct keytablist)); FILE *fp = fopen(filename, "rb"); if (fp == NULL) - return NULL; + return list; - int len = 10; - uint8_t *buf = calloc(len, sizeof(uint8_t)); - int c, i = 0; + int c, i = 0, open = 0; + char *p; while ((c = fgetc(fp)) != EOF) { - if (i >= len) { - len *= 2; - buf = realloc(buf, len * sizeof(uint8_t)); - memset(buf + i, 0, (len - i) * sizeof(uint8_t)); + switch (c) { + case 250: + p = getpair(&c, fp); + if (p == NULL) { + fprintf(stderr, "missing pair closing byte!\n"); + return NULL; + } + setkey(&list, &len, i, p); + free(p); + break; + case 251: + if (open == 1) { + fprintf(stderr, "missing object closing byte!\n"); + return NULL; + } + open = 1; + break; + case 254: + open = 0; + i++; + break; + default: + fprintf(stderr, "Unknown byte: %d\n", c); + return NULL; } - buf[i++] = c; } - fclose(fp); - return buf; + return list; } -void writedb(char *filename, struct keytablist *list, int len) +void writedb(char *filename, struct keytablist *list) { FILE *fp = fopen(filename, "wb"); - for (int i = 0; i < len; ++i) { + for (int i = 0; i < list[0].len; ++i) { fprintf(fp, "\xfb"); int *indexes = getkeys(list, i); for (int j = 0; indexes[j]; ++j) { fprintf(fp, "\xfa%s:", list[i].tab[indexes[j]].key); switch (list[i].tab[indexes[j]].flag) { case 1: - fprintf(fp, "%.2lf", list[i].tab[indexes[j]].v.num); + fprintf(fp, "%.2lf\xfc", list[i].tab[indexes[j]].v.num); break; case 2: - fprintf(fp, "%s", list[i].tab[indexes[j]].v.b == 1 ? "true" : "false"); + fprintf(fp, "%s\xfc", list[i].tab[indexes[j]].v.b == 1 ? "true" : "false"); break; case 3: - fprintf(fp, "%s", list[i].tab[indexes[j]].v.str); + fprintf(fp, "%s\xfc", list[i].tab[indexes[j]].v.str); break; } } free(indexes); fprintf(fp, "\xfe"); } + fclose(fp); +} + +static char *getpair(int *c, FILE *fp) +{ + 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; + } + return pair; } diff --git a/src/include/mdb.h b/src/include/mdb.h index 6e6fca9..49f5903 100644 --- a/src/include/mdb.h +++ b/src/include/mdb.h @@ -1,24 +1,8 @@ -#ifndef FILEOPS_H -#define FILEOPS_H +#ifndef MDB_H +#define MDB_H #define TABLEN 1024 -extern int blen; - -enum btype { - BEGIN = 1, - END, PAIR, - - ERROR -}; - -struct byte { - enum btype type; - char *value; -}; - -struct byte *parse(unsigned char *buf); - union value { char *str; double num; @@ -32,17 +16,16 @@ struct keytab { }; struct keytablist { + int len; struct keytab tab[TABLEN]; }; int *getkeys(struct keytablist *list, int id); struct keytab getkey(struct keytablist *list, int id, char *key); -void setkey(struct keytablist **list, int *len, int id, char *pair); +int setkey(struct keytablist **list, int *len, int id, char *pair); void delkey(struct keytablist *list, int id, char *key); -// TODO: integrate every header into single file -// TODO: make readdb return struct keytab list* -unsigned char *readdb(char *filename); -void writedb(char *filename, struct keytablist *list, int len); +struct keytablist *readdb(char *filename); +void writedb(char *filename, struct keytablist *list); #endif diff --git a/src/keytab.c b/src/keytab.c index b1b12d7..3cba87a 100644 --- a/src/keytab.c +++ b/src/keytab.c @@ -5,6 +5,8 @@ #include "include/mdb.h" +static const struct keytablist empty; + static int hash(char *key); int *getkeys(struct keytablist *list, int id) @@ -35,11 +37,14 @@ struct keytab getkey(struct keytablist *list, int id, char *key) return list[id].tab[idx]; } -void setkey(struct keytablist **list, int *len, int id, char *pair) +int setkey(struct keytablist **list, int *len, int id, char *pair) { if (id >= *len) { - *len += (id - *len) + 1; - *list = realloc(*list, (*len) * sizeof(struct keytablist)); + *list = realloc(*list, (id + 1) * sizeof(struct keytablist)); + for (int i = *len; i <= id; ++i) + (*list)[i] = empty; + *len = id + 1; + (*list)[0].len = *len; } char *tok = strtok(pair, ":"); char *key = calloc(strlen(tok) + 1, sizeof(char)); @@ -48,7 +53,7 @@ void setkey(struct keytablist **list, int *len, int id, char *pair) tok = strtok(NULL, ":"); if (tok == NULL) { fprintf(stderr, "Invalid key-value pair\n"); - return; + return 1; } union value v; int flag; @@ -67,11 +72,10 @@ void setkey(struct keytablist **list, int *len, int id, char *pair) int idx = hash(key); while ((*list)[id].tab[idx].key != NULL && strcmp((*list)[id].tab[idx].key, key) && - idx < TABLEN) - idx++; + idx < TABLEN) idx++; if (idx >= TABLEN) { fprintf(stderr, "No more room in table\n"); - return; + return 2; } if (!(*list)[id].tab[idx].key) (*list)[id].tab[idx].key = key; @@ -79,6 +83,7 @@ void setkey(struct keytablist **list, int *len, int id, char *pair) free(key); (*list)[id].tab[idx].v = v; (*list)[id].tab[idx].flag = flag; + return 0; } void delkey(struct keytablist *list, int id, char *key) @@ -6,45 +6,15 @@ int main(int argc, char **argv) { - int open = 0; - int len = 2; - struct keytablist *list = calloc(len, sizeof(struct keytablist)); if (argc != 2) exit(1); char *filename = argv[1]; + struct keytablist *list = readdb(filename); + if (list == NULL) + exit(2); - uint8_t *buf = readdb(filename); - if (buf == NULL) - exit(0); - struct byte *bytes = parse(buf); - free(buf); - - for (int i = 0, j = 0; i < blen; ++i) { - switch (bytes[i].type) { - case BEGIN: - if (open == 1) { - fprintf(stderr, "missing close!\n"); - free(bytes); - exit(1); - } - open = 1; - break; - case END: - open = 0; - j++; - break; - case PAIR: - setkey(&list, &len, j, bytes[i].value); - free(bytes[i].value); - break; - case ERROR: - fprintf(stderr, "%s\n", bytes[i].value); - exit(1); - } - } - - writedb(filename, list, len); - for (int i = 0; i < len; ++i) { + writedb(filename, list); + for (int i = 0; i < list[0].len; ++i) { int *indexes = getkeys(list, i); for (int j = 0; indexes[j]; ++j) { printf("%s: ", list[i].tab[indexes[j]].key); @@ -65,6 +35,5 @@ int main(int argc, char **argv) } free(list); - free(bytes); exit(0); } diff --git a/src/parser.c b/src/parser.c deleted file mode 100644 index a45c945..0000000 --- a/src/parser.c +++ /dev/null @@ -1,71 +0,0 @@ -#include <stdlib.h> -#include <stdint.h> -#include <string.h> - -#include "include/mdb.h" - -int blen; - -static void addbyte(struct byte *bytes, int *pos, enum btype type, char *value); -static char *getpair(uint8_t *buf, int *pos); - -struct byte *parse(uint8_t *buf) -{ - char *value; - int len = 2; - struct byte *bytes = calloc(len, sizeof(struct byte)); - for (int i = 0, j = 0; buf[i]; ++i) { - if (j >= len) - len *= 2; - bytes = realloc(bytes, len * sizeof(struct byte)); - switch (buf[i]) { - case 250: - value = getpair(buf, &i); - if (value == NULL) - addbyte(bytes, &j, ERROR, "Invalid Key-Value pair"); - else - addbyte(bytes, &j, PAIR, value); - break; - case 251: - addbyte(bytes, &j, BEGIN, NULL); - break; - case 254: - addbyte(bytes, &j, END, NULL); - break; - default: - addbyte(bytes, &j, ERROR, "Invalid chunk"); - } - blen = j; - } - return bytes; -} - -static void addbyte(struct byte *bytes, int *pos, enum btype type, char *value) -{ - bytes[*pos].type = type; - - if (value != NULL) { - bytes[*pos].value = value; - } - else - bytes[*pos].value = NULL; - - (*pos)++; -} - -static char *getpair(uint8_t *buf, int *pos) -{ - int i; - for (i = *pos + 1; buf[i] != 250 && buf[i] != 254 && buf[i]; ++i) - ; - if (buf[i] != 250 && buf[i] != 254) - return NULL; - - char *pair = calloc(i - *pos, sizeof(char)); - int j; - for (j = *pos + 1; j < i; ++j) - pair[j - (*pos + 1)] = buf[j]; - pair[j - (*pos + 1)] = '\0'; - *pos = i - 1; - return pair; -} |