in include/ylt/standalone/cinatra/coro_radix_tree.hpp [125:224]
int insert(
const std::string &path,
std::function<void(coro_http_request &req, coro_http_response &resp)>
handler,
const std::string &method) {
auto root = this->root;
int i = 0, n = path.size(), param_count = 0, code = 0;
while (i < n) {
if (!root->indices.empty() &&
(root->indices[0] == type_asterisk || path[i] == type_asterisk ||
(path[i] != type_colon && root->indices[0] == type_colon) ||
(path[i] == type_colon && root->indices[0] != type_colon) ||
(path[i] == type_colon && root->indices[0] == type_colon &&
path.substr(i + 1, find_pos(path, type_slash, i) - i - 1) !=
root->children[0]->path))) {
code = -1;
break;
}
auto child = root->get_child(path[i]);
if (!child) {
auto p = find_pos(path, type_colon, i);
if (p == n) {
p = find_pos(path, type_asterisk, i);
root = root->insert_child(path[i], std::make_shared<radix_tree_node>(
path.substr(i, p - i)));
if (p < n) {
root = root->insert_child(
type_asterisk,
std::make_shared<radix_tree_node>(path.substr(p + 1)));
++param_count;
}
code = root->add_handler(handler, method);
break;
}
root = root->insert_child(
path[i], std::make_shared<radix_tree_node>(path.substr(i, p - i)));
i = find_pos(path, type_slash, p);
root = root->insert_child(
type_colon,
std::make_shared<radix_tree_node>(path.substr(p + 1, i - p - 1)));
++param_count;
if (i == n) {
code = root->add_handler(handler, method);
break;
}
}
else {
root = child;
if (path[i] == type_colon) {
++param_count;
i += root->path.size() + 1;
if (i == n) {
code = root->add_handler(handler, method);
break;
}
}
else {
auto j = 0UL;
auto m = root->path.size();
for (; i < n && j < m && path[i] == root->path[j]; ++i, ++j) {
}
if (j < m) {
std::shared_ptr<radix_tree_node> child(
std::make_shared<radix_tree_node>(root->path.substr(j)));
child->handler = root->handler;
child->indices = root->indices;
child->children = root->children;
root->path = root->path.substr(0, j);
root->handler = {};
root->indices = child->path[0];
root->children = {child};
}
if (i == n) {
code = root->add_handler(handler, method);
break;
}
}
}
}
if (param_count > this->root->max_params)
this->root->max_params = param_count;
return code;
}