aboutsummaryrefslogtreecommitdiff
path: root/src/common
diff options
context:
space:
mode:
Diffstat (limited to 'src/common')
-rw-r--r--src/common/array.c5
-rw-r--r--src/common/better_string.c10
-rw-r--r--src/common/hash_table.c140
-rw-r--r--src/common/helpers.c13
-rw-r--r--src/common/list.c78
-rw-r--r--src/common/protocol.c20
6 files changed, 253 insertions, 13 deletions
diff --git a/src/common/array.c b/src/common/array.c
index 4ebb67e..9648f5a 100644
--- a/src/common/array.c
+++ b/src/common/array.c
@@ -39,9 +39,10 @@ array_t *array_reverse(array_t *a) {
void array_free(void *x, void (*freefunc)(void *)) {
array_t *a = (array_t *)x;
- for (int i = 0; i < a->size; i++) {
+ if (!x)
+ return;
+ for (int i = 0; i < a->size; i++)
freefunc(a->items[i]);
- }
free(a->items);
free(a);
}
diff --git a/src/common/better_string.c b/src/common/better_string.c
index 366dda6..7863da0 100644
--- a/src/common/better_string.c
+++ b/src/common/better_string.c
@@ -18,11 +18,12 @@ string_t *init_string(const char *src) {
}
void string_push(string_t *s, char c) {
- if (s->len >= s->size - 2) {
+ if (s->len >= s->size - 3) {
s->size *= 2;
s->buf = safe_realloc(s->buf, s->size);
}
s->buf[s->len] = c;
+ s->buf[s->len + 1] = '\0';
s->len++;
}
@@ -33,9 +34,8 @@ char string_pop(string_t *s) {
}
void string_concat_const(string_t *s1, const char *s2) {
- for (int i = 0; i < strlen(s2); i++) {
+ for (int i = 0; i < strlen(s2); i++)
string_push(s1, s2[i]);
- }
}
void string_concat(string_t *s1, string_t *s2) {
@@ -46,6 +46,10 @@ void string_concat(string_t *s1, string_t *s2) {
void string_free(void *x) {
string_t *s = x;
+
+ if (!x)
+ return;
+
free(s->buf);
free(s);
}
diff --git a/src/common/hash_table.c b/src/common/hash_table.c
index 2f66d45..6b4c014 100644
--- a/src/common/hash_table.c
+++ b/src/common/hash_table.c
@@ -1,12 +1,148 @@
#include "../include/hash_table.h"
#include "../include/helpers.h"
-
+#include "../include/list.h"
#include <stdlib.h>
+#include <string.h>
+
+pair_t *init_pair(char *key, void *v) {
+ pair_t *pair = safe_calloc(1, sizeof(pair_t));
+ pair->key = key;
+ pair->v = v;
+ return pair;
+}
+
+void *bucket_pop(list_t *b, char *key) {
+ node_t *cur = b->head;
+ node_t *prev;
+ pair_t *cur_pair;
+ node_t *tmp;
+
+ if (b->size == 0)
+ return NULL;
+
+ while (cur) {
+ cur_pair = cur->item;
+ if (strcmp(cur_pair->key, key) == 0) {
+ prev = cur->prev;
+ if (prev) {
+ tmp = cur->next;
+ prev->next = tmp;
+
+ if (tmp)
+ tmp->prev = prev;
+ else {
+ b->tail = prev;
+ }
+
+ b->size--;
+
+ if (b->size <= 1)
+ b->head = b->tail;
+
+ return cur;
+ } else {
+ tmp = cur->next;
+ if (tmp)
+ tmp->prev = NULL;
+
+ b->head = tmp;
+ b->size--;
+
+ if (b->size <= 1)
+ b->tail = b->head;
+
+ return cur;
+ }
+ }
+ }
+ return NULL;
+}
+
+void *bucket_get(list_t *b, char *key) {
+ node_t *cur = b->head;
+ pair_t *cur_pair;
+
+ while (cur) {
+ cur_pair = cur->item;
+ if (strcmp(key, cur_pair->key) == 0) {
+ return cur_pair->v;
+ }
+ }
+ return NULL;
+}
+
+void bucket_free(void *x, void (*freefunc)(void *)) {
+ list_t *b = x;
+ node_t *cur = b->head;
+ node_t *tmp;
+ pair_t *cur_pair;
+
+ if (!x)
+ return;
+
+ while (cur) {
+ cur_pair = cur->item;
+
+ freefunc(cur_pair->v);
+ free(cur_pair->key);
+ free(cur_pair);
+
+ tmp = cur->next;
+ free(cur);
+ cur = tmp;
+ }
+ free(b);
+}
ht_t *init_ht(size_t size) {
ht_t *ht = safe_calloc(1, sizeof(size));
size_t realsize = size == 0 ? DEFAULT_HT_SIZE : size;
- ht->buckets = safe_calloc(realsize, sizeof(sll_t *));
+ ht->buckets = safe_calloc(realsize, sizeof(list_t *));
ht->size = realsize;
return ht;
}
+
+void ht_insert(ht_t *ht, char *key, void *value) {
+ unsigned long bn = hash(key) % ht->size;
+ list_t *bucket = ht->buckets[bn];
+ if (!bucket)
+ ht->buckets[bn] = init_list();
+
+ list_push_back(bucket, init_pair(key, value));
+}
+
+void *ht_pop(ht_t *ht, char *key) {
+ unsigned long bn = hash(key) % ht->size;
+ list_t *bucket = ht->buckets[bn];
+ if (!bucket)
+ return NULL;
+ return bucket_pop(bucket, key);
+}
+
+void *ht_get(ht_t *ht, char *key) {
+ unsigned long bn = hash(key) % ht->size;
+ list_t *bucket = ht->buckets[bn];
+ if (!bucket)
+ return NULL;
+ return bucket_get(bucket, key);
+}
+
+void ht_free(void *x, void (*freefunc)(void *)) {
+ ht_t *ht = x;
+ for (int i = 0; i < ht->size; i++)
+ bucket_free(ht->buckets[i], freefunc);
+
+ free(ht->buckets);
+ free(ht);
+}
+
+/* DJB2 hash function */
+unsigned long hash(char *str) {
+ unsigned long hash = 5381;
+ int c;
+
+ while ((c = *str++))
+ hash = ((hash << 5) + hash) + c; /* hash * 33 + c */
+
+ return hash;
+}
diff --git a/src/common/helpers.c b/src/common/helpers.c
index 4bf7301..4a3606a 100644
--- a/src/common/helpers.c
+++ b/src/common/helpers.c
@@ -4,9 +4,8 @@
#include <string.h>
void die_lz(int code, const char *msg) {
- if (code < 0) {
+ if (code < 0)
die(msg);
- }
}
void die(const char *msg) {
@@ -17,17 +16,19 @@ void die(const char *msg) {
void *safe_calloc(unsigned int i, size_t size) {
void *x = calloc(i, size);
- if (x == NULL) {
+
+ if (x == NULL)
die("abort: calloc()");
- }
+
return x;
}
void *safe_realloc(void *x, size_t size) {
void *p = realloc(x, size);
- if (x == NULL) {
+
+ if (x == NULL)
die("abort: realloc()");
- }
+
return p;
}
diff --git a/src/common/list.c b/src/common/list.c
new file mode 100644
index 0000000..00c18ee
--- /dev/null
+++ b/src/common/list.c
@@ -0,0 +1,78 @@
+#include "../include/list.h"
+#include "../include/helpers.h"
+
+node_t *init_node(void *x) {
+ node_t *n = safe_calloc(1, sizeof(node_t));
+ n->item = x;
+ n->next = NULL;
+ n->prev = NULL;
+ return n;
+}
+
+list_t *init_list() {
+ list_t *l = safe_calloc(1, sizeof(list_t));
+ l->head = NULL;
+ l->tail = NULL;
+ l->size = 0;
+ return l;
+}
+
+void *list_pop_front(list_t *l) {
+ node_t *front = l->head;
+ if (!front)
+ return NULL;
+
+ node_t *new = front->next;
+ l->head = new;
+
+ if (!new)
+ l->tail = NULL;
+
+ l->size--;
+ return front;
+}
+
+void list_push_back(list_t *l, void *x) {
+ node_t *back = l->tail;
+ node_t *new = init_node(x);
+ if (!back) {
+ l->head = new;
+ l->tail = l->head;
+ } else {
+ back->next = new;
+ new->prev = back;
+ l->tail = new;
+ }
+ l->size++;
+}
+
+void list_push_front(list_t *l, void *x) {
+ node_t *front = l->head;
+ node_t *new = init_node(x);
+ if (!front) {
+ l->tail = new;
+ l->head = l->tail;
+ } else {
+ front->prev = new;
+ new->next = front;
+ l->head = new;
+ }
+ l->size++;
+}
+
+void list_free(void *x, void (*freefunc)(void *)) {
+ list_t *l = x;
+ node_t *cur = l->head;
+ node_t *tmp;
+
+ if (!x)
+ return;
+
+ while (cur) {
+ freefunc(cur->item);
+ tmp = cur->next;
+ free(cur);
+ cur = tmp;
+ }
+ free(l);
+}
diff --git a/src/common/protocol.c b/src/common/protocol.c
new file mode 100644
index 0000000..9be3bcf
--- /dev/null
+++ b/src/common/protocol.c
@@ -0,0 +1,20 @@
+#include "../include/protocol.h"
+#include "../include/better_string.h"
+
+#include <stdlib.h>
+#include <stdbool.h>
+#include <time.h>
+
+string_t *date_str() {
+ char dateStr[11];
+ time_t t = time(NULL);
+ struct tm *tm_info = localtime(&t);
+
+ strftime(dateStr, sizeof(dateStr), "%d-%m-%Y", tm_info);
+ return init_string(dateStr);
+}
+
+bool same_day(struct tm *date1, struct tm *date2) {
+ return (date1->tm_year == date2->tm_year && date1->tm_mon == date2->tm_mon &&
+ date1->tm_mday == date2->tm_mday);
+}