aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorspl3g <spleefer6@yandex.ru>2025-03-16 19:41:50 +0300
committerspl3g <spleefer6@yandex.ru>2025-03-16 19:46:13 +0300
commit8ceb8fe77cb431dd4d866cbffd935cb2c101074c (patch)
tree4e7d15786113ae3f0ea04a7ef1267e558bfe44ac
parentf8dc21f52bfb47de5bcfd3fb536f99a5bd8e5ca5 (diff)
Replace push macro with da_append from tsoding
-rw-r--r--lib/arena.c21
-rw-r--r--lib/arena.h31
-rw-r--r--lib/http.c30
3 files changed, 55 insertions, 27 deletions
diff --git a/lib/arena.c b/lib/arena.c
index dd12d0c..8cd1748 100644
--- a/lib/arena.c
+++ b/lib/arena.c
@@ -10,12 +10,18 @@ region *new_region(size_t cap) {
return r;
}
+arena arena_init_cap(size_t cap) {
+ arena a = {0};
+ a.region_cap = cap;
+ return a;
+}
+
void *arena_alloc(arena *a, size_t size_bytes) {
size_t size = (size_bytes + sizeof(uintptr_t)-1)/sizeof(uintptr_t);
if (a->end == NULL) {
assert(a->beg == NULL);
- size_t capacity = ARENA_REGION_DEFAULT_CAPACITY;
+ size_t capacity = a->region_cap ? a->region_cap : ARENA_REGION_DEFAULT_CAPACITY;
if (capacity < size) capacity = size;
a->beg = new_region(capacity);
a->end = a->beg;
@@ -26,7 +32,7 @@ void *arena_alloc(arena *a, size_t size_bytes) {
}
if (a->end->len + size > a->end->cap) {
- size_t capacity = ARENA_REGION_DEFAULT_CAPACITY;
+ size_t capacity = a->region_cap ? a->region_cap : ARENA_REGION_DEFAULT_CAPACITY;
if (capacity < size) capacity = size;
a->beg = new_region(capacity);
a->end->next = new_region(capacity);
@@ -47,6 +53,17 @@ void arena_free(arena *a) {
}
}
+void *arena_realloc(arena *a, void *oldptr, size_t oldsz, size_t newsz) {
+ if (newsz <= oldsz) return oldptr;
+ void *newptr = arena_alloc(a, newsz);
+ char *newptr_char = (char*)newptr;
+ char *oldptr_char = (char*)oldptr;
+ for (size_t i = 0; i < oldsz; ++i) {
+ newptr_char[i] = oldptr_char[i];
+ }
+ return newptr;
+}
+
void grow_da(void *slice, size_t size, arena *arena) {
struct {
void *data;
diff --git a/lib/arena.h b/lib/arena.h
index 1ddddac..7535f8a 100644
--- a/lib/arena.h
+++ b/lib/arena.h
@@ -1,3 +1,5 @@
+// Most of the code is from https://github.com/tsoding/arena
+
#ifndef ARENA_H_
#define ARENA_H_
@@ -19,22 +21,31 @@ struct region {
typedef struct {
region *beg;
region *end;
+ size_t region_cap;
} arena;
+arena arena_init_cap(size_t cap);
void *arena_alloc(arena *a, size_t size);
void arena_free(arena *a);
-void grow_da(void *slice, size_t size, arena *arena);
-
+void *arena_realloc(arena *a, void *oldptr, size_t oldsz, size_t newsz);
#define new(a, t, c) (t *)arena_alloc(a, sizeof(t)*c)
-#define ARENA_REGION_DEFAULT_CAPACITY (8*1024);
-
-// from nullprogram
-#define push(slice, arena) \
- ((slice)->len >= (slice)->cap \
- ? grow_da(slice, sizeof(*(slice)->data), arena), \
- (slice)->data + (slice)->len++ \
- : (slice)->data + (slice)->len++)
+#define ARENA_REGION_DEFAULT_CAPACITY (8*1024)
+#define ARENA_DA_INIT_CAP (2)
+
+#define arena_da_append(a, da, item) \
+ do { \
+ if ((da)->len >= (da)->cap) { \
+ size_t new_cap = (da)->cap == 0 ? ARENA_DA_INIT_CAP : (da)->cap*2; \
+ (da)->data = arena_realloc( \
+ (a), (da)->data, \
+ (da)->cap*sizeof(*(da)->data), \
+ new_cap*sizeof(*(da)->data)); \
+ (da)->cap = new_cap; \
+ } \
+ \
+ (da)->data[(da)->len++] = (item); \
+ } while (0)
#endif //ARENA_H_
diff --git a/lib/http.c b/lib/http.c
index 7ae49a1..ff81e64 100644
--- a/lib/http.c
+++ b/lib/http.c
@@ -137,37 +137,37 @@ void handle_path(struct server *serv, const_string method, const_string path, ha
.func = handler,
};
- *push(&serv->handlers, serv->arena) = hand;
+ arena_da_append(serv->arena, &serv->handlers, hand);
}
-void compose_response(struct response *resp, arena *perm, arena scratch) {
+void compose_response(arena *arena, struct response *resp) {
const_string_da header_da = {0};
- *push(&header_da, &scratch) = CS("HTTP/1.1");
+ arena_da_append(arena, &header_da, CS("HTTP/1.1"));
if (resp->code != 0) {
char buf[4];
sprintf(buf, "%ld", resp->code);
- *push(&header_da, &scratch) = cs_from_cstr(buf);
- *push(&header_da, &scratch) = get_response_string(resp->code);
+ arena_da_append(arena, &header_da, cs_from_cstr(buf));
+ arena_da_append(arena, &header_da, get_response_string(resp->code));
} else {
printf("Response is handeled, but no code is given");
- *push(&header_da, &scratch) = CS("500");
- *push(&header_da, &scratch) = get_response_string(INTERNAL_SERVER_ERROR);
+ arena_da_append(arena, &header_da, CS("500"));
+ arena_da_append(arena, &header_da, get_response_string(INTERNAL_SERVER_ERROR));
}
- volatile const_string header = arena_cs_concat(&scratch, header_da, CS(" "));
+ const_string header = arena_cs_concat(arena, header_da, CS(" "));
- volatile const_string str;
+ const_string str;
if (resp->body.len != 0) {
const_string_da resp_da= {0};
- *push(&resp_da, perm) = header;
- *push(&resp_da, perm) = CS("");
- *push(&resp_da, perm) = resp->body;
+ arena_da_append(arena, &resp_da, header);
+ arena_da_append(arena, &resp_da, CS(""));
+ arena_da_append(arena, &resp_da, resp->body);
- str = arena_cs_concat(&scratch, resp_da, CS("\r\n"));
+ str = arena_cs_concat(arena, resp_da, CS("\r\n"));
} else {
- str = arena_cs_append(perm, header, CS("\r\n\r\n"));
+ str = arena_cs_append(arena, header, CS("\r\n\r\n"));
}
resp->string = str;
@@ -217,7 +217,7 @@ void process_request(struct server *serv, ssize_t inc_fd) {
header_str.data++;
header.value = header_str;
- *push(&headers, &req_arena) = header;
+ arena_da_append(arena, &headers, header);
}
cs_chop_delim(&req_str, '\n');