129 lines
2.7 KiB
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;
|
|
}
|