1#ifndef NEFORCE_NETWORK_HTTP_RADIX_ROUTER_HPP__
2#define NEFORCE_NETWORK_HTTP_RADIX_ROUTER_HPP__
15NEFORCE_BEGIN_NAMESPACE__
40 bool has_handler =
false;
47 route_trie() =
default;
54 void insert(
const string& pattern, handler_type handler) {
55 if (pattern.
empty() || pattern.
front() !=
'/') {
62 while (pos <= pattern.
length()) {
63 size_t slash = pattern.
find(
'/', pos);
71 if (segment.
empty()) {
75 if (segment[0] ==
':') {
76 string pname(segment.
substr(1));
78 nodes_[node_idx].param_index = nodes_.size();
79 nodes_.emplace_back();
80 nodes_.back().segment = pname;
82 node_idx = nodes_[node_idx].param_index;
83 nodes_[node_idx].param_name = pname;
84 }
else if (segment[0] ==
'*' && segment.
length() == 1) {
86 nodes_[node_idx].wildcard_index = nodes_.size();
87 nodes_.emplace_back();
88 nodes_.back().segment =
"*";
90 node_idx = nodes_[node_idx].wildcard_index;
93 auto& children = nodes_[node_idx].children;
94 auto it = children.find(seg);
95 if (it == children.end()) {
96 children[seg] = nodes_.size();
97 nodes_.emplace_back();
98 nodes_.back().segment = seg;
99 node_idx = nodes_.
size() - 1;
101 node_idx = it->second;
106 nodes_[node_idx].handler =
move(handler);
107 nodes_[node_idx].has_handler =
true;
117 NEFORCE_NODISCARD handler_type
match(
const string&
path,
bool case_sensitive,
120 return handler_type{};
126 while (pos <=
path.length()) {
127 size_t slash =
path.find(
'/', pos);
129 slash =
path.length();
135 if (segment.
empty()) {
139 const node& current = nodes_[node_idx];
141 const string seg_key(segment);
142 if (!case_sensitive) {
144 for (
const auto& child: current.children) {
145 string key_lower = child.first;
147 node_idx = child.second;
156 auto it = current.children.find(seg_key);
157 if (it != current.children.end()) {
158 node_idx = it->second;
164 params.emplace_back(nodes_[current.param_index].param_name,
string(segment));
165 node_idx = current.param_index;
172 remaining.
append(segment);
173 if (slash <
path.length()) {
176 params.emplace_back(
"*", remaining);
177 node_idx = current.wildcard_index;
181 return handler_type{};
184 if (nodes_[node_idx].has_handler) {
185 return nodes_[node_idx].handler;
187 return handler_type{};
201 while (pos <=
path.length()) {
202 size_t slash =
path.find(
'/', pos);
204 slash =
path.length();
210 if (segment.
empty()) {
214 const node& current = nodes_[node_idx];
216 string seg_key(segment);
217 if (!case_sensitive) {
220 for (
const auto& child: current.children) {
221 string key_lower = child.first;
223 node_idx = child.second;
232 auto it = current.children.find(seg_key);
233 if (it != current.children.end()) {
234 node_idx = it->second;
240 node_idx = current.param_index;
251 return nodes_[node_idx].has_handler;
257 nodes_.emplace_back();
261 NEFORCE_NODISCARD
size_t size() const noexcept {
return nodes_.size(); }
267NEFORCE_END_NAMESPACE__
constexpr size_type length() const noexcept
获取字符串长度
constexpr bool empty() const noexcept
检查是否为空
constexpr basic_string_view substr(const size_type off=0, const size_type count=npos) const
获取子视图
constexpr view_type view() const noexcept
获取字符串视图
constexpr size_type length() const noexcept
获取字符串长度
constexpr size_type find(const basic_string &other, const size_type n=0) const noexcept
查找子串
constexpr bool empty() const noexcept
检查是否为空
constexpr basic_string & append(size_type n, value_type value)
追加多个相同字符
constexpr size_type size() const noexcept
获取字符数
constexpr basic_string & lowercase() noexcept(noexcept(_NEFORCE transform(begin(), end(), begin(), _NEFORCE to_lowercase< CharT >)))
转换为小写
static constexpr size_type npos
constexpr void reserve(const size_type n)
预留容量
constexpr reference front() noexcept
访问第一个字符
handler_type match(const string &path, bool case_sensitive, vector< pair< string, string > > ¶ms)
匹配路径
size_t size() const noexcept
获取 trie 节点总数
bool contains_path(const string &path, bool case_sensitive) const
检查路径是否存在
void insert(const string &pattern, handler_type handler)
插入路由规则
static constexpr T max() noexcept
获取类型的最大值
string_view view() const noexcept
获取路径字符串视图
bool empty() const noexcept
检查路径是否为空
http_server_response http_response
HTTP响应类型别名
http_server_request http_request
HTTP请求类型别名
constexpr Iterator2 move(Iterator1 first, Iterator1 last, Iterator2 result) noexcept(noexcept(inner::__move_aux(first, last, result)))
移动范围元素
basic_string_view< char > string_view
字符字符串视图