summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/file.c75
-rw-r--r--src/include/mdb.h29
-rw-r--r--src/keytab.c19
-rw-r--r--src/main.c41
-rw-r--r--src/parser.c71
5 files changed, 80 insertions, 155 deletions
diff --git a/src/file.c b/src/file.c
index ba24ed3..e3cee9d 100644
--- a/src/file.c
+++ b/src/file.c
@@ -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)
diff --git a/src/main.c b/src/main.c
index ac8f102..7dfa181 100644
--- a/src/main.c
+++ b/src/main.c
@@ -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;
-}