lnm/src/http/lnm_http_route.c

129 lines
2.7 KiB
C

#include "lnm/http/loop_internal.h"
lnm_err lnm_http_route_init(lnm_http_route **out) {
lnm_http_route *route = calloc(1, sizeof(lnm_http_route));
if (route == NULL) {
return lnm_err_failed_alloc;
}
*out = route;
return lnm_err_ok;
}
void lnm_http_route_free(lnm_http_route *route) {
if (route == NULL) {
return;
}
lnm_http_route_segment_trie_free(route->key_segments);
free(route);
}
lnm_err lnm_http_route_segment_trie_init(lnm_http_route_segment_trie **out) {
lnm_http_route_segment_trie *trie =
calloc(1, sizeof(lnm_http_route_segment_trie));
if (trie == NULL) {
return lnm_err_failed_alloc;
}
*out = trie;
return lnm_err_ok;
}
void lnm_http_route_segment_trie_free(lnm_http_route_segment_trie *trie) {
if (trie == NULL) {
return;
}
for (size_t i = 0; i < 128; i++) {
lnm_http_route_segment_trie_free(trie->children[i]);
}
free(trie);
}
lnm_err lnm_http_route_key_segment_insert(lnm_http_route *route,
const char *key, size_t key_len,
size_t index) {
if (route->key_segments == NULL) {
LNM_RES(lnm_http_route_segment_trie_init(&route->key_segments));
}
lnm_http_route_segment_trie *trie = route->key_segments;
for (size_t key_index = 0; key_index < key_len; key_index++) {
unsigned char c = key[key_index];
if (trie->children[c] == NULL) {
LNM_RES(lnm_http_route_segment_trie_init(&trie->children[c]));
}
trie = trie->children[c];
}
if (trie->represents_segment) {
return lnm_err_already_present;
}
trie->represents_segment = true;
trie->index = index;
return lnm_err_ok;
}
const lnm_http_route_match_segment *
lnm_http_route_match_get(lnm_http_route_match *match, const char *key) {
if (match->route->key_segments == NULL) {
return NULL;
}
lnm_http_route_segment_trie *trie = match->route->key_segments;
while (*key != '\0') {
trie = trie->children[(unsigned char)*key];
if (trie == NULL) {
return NULL;
}
key++;
}
if (!trie->represents_segment) {
return NULL;
}
return &match->key_segments[trie->index];
}
lnm_err lnm_http_step_init(lnm_http_step **out) {
lnm_http_step *step = calloc(1, sizeof(lnm_http_step));
if (step == NULL) {
return lnm_err_failed_alloc;
}
*out = step;
return lnm_err_ok;
}
lnm_err lnm_http_route_step_append(lnm_http_route *route, lnm_http_step_fn fn,
bool blocking) {
lnm_http_step **step_ptr = &route->step;
while (*step_ptr != NULL) {
step_ptr = &(*step_ptr)->next;
}
LNM_RES(lnm_http_step_init(step_ptr));
(*step_ptr)->fn = fn;
(*step_ptr)->blocking = blocking;
return lnm_err_ok;
}