Ada
3.4.4
Fast spec-compliant URL parser
Toggle main menu visibility
Loading...
Searching...
No Matches
scheme-inl.h
Go to the documentation of this file.
1
5
#ifndef ADA_SCHEME_INL_H
6
#define ADA_SCHEME_INL_H
7
8
#include "
ada/scheme.h
"
9
10
namespace
ada::scheme
{
11
16
namespace
details
{
17
// for use with is_special and get_special_port
18
// Spaces, if present, are removed from URL.
19
constexpr
std::string_view
is_special_list
[] = {
"http"
,
" "
,
"https"
,
"ws"
,
20
"ftp"
,
"wss"
,
"file"
,
" "
};
21
// for use with get_special_port
22
constexpr
uint16_t
special_ports
[] = {80, 0, 443, 80, 21, 443, 0, 0};
23
24
// @private
25
// convert a string_view to a 64-bit integer key for fast comparison
26
constexpr
uint64_t
make_key
(std::string_view sv) {
27
uint64_t val = 0;
28
for
(
size_t
i = 0; i < sv.size(); i++)
29
val |= (uint64_t)(uint8_t)sv[i] << (i * 8);
30
return
val;
31
}
32
// precomputed keys for the special schemes, indexed by a hash of the input
33
// string
34
constexpr
uint64_t
scheme_keys
[] = {
35
make_key
(
"http"
),
// 0: HTTP
36
0,
// 1: sentinel
37
make_key
(
"https"
),
// 2: HTTPS
38
make_key
(
"ws"
),
// 3: WS
39
make_key
(
"ftp"
),
// 4: FTP
40
make_key
(
"wss"
),
// 5: WSS
41
make_key
(
"file"
),
// 6: FILE
42
0,
// 7: sentinel
43
};
44
45
// @private
46
// branchless load of up to 5 characters into a uint64_t, padding with zeros if
47
// n < 5
48
inline
uint64_t
branchless_load5
(
const
char
*p,
size_t
n) {
49
uint64_t input = (uint8_t)p[0];
50
input |= ((uint64_t)(uint8_t)p[n > 1] << 8) & (0 - (uint64_t)(n > 1));
51
input |= ((uint64_t)(uint8_t)p[(n > 2) * 2] << 16) & (0 - (uint64_t)(n > 2));
52
input |= ((uint64_t)(uint8_t)p[(n > 3) * 3] << 24) & (0 - (uint64_t)(n > 3));
53
input |= ((uint64_t)(uint8_t)p[(n > 4) * 4] << 32) & (0 - (uint64_t)(n > 4));
54
return
input;
55
}
56
}
// namespace details
57
58
81
82
ada_really_inline
constexpr
bool
is_special(std::string_view
scheme
) {
83
if
(
scheme
.empty()) {
84
return
false
;
85
}
86
int
hash_value = (2 * scheme.size() + (
unsigned
)(scheme[0])) & 7;
87
const
std::string_view target =
details::is_special_list
[hash_value];
88
return
(target[0] == scheme[0]) && (target.substr(1) == scheme.substr(1));
89
}
90
constexpr
uint16_t
get_special_port
(std::string_view
scheme
)
noexcept
{
91
if
(
scheme
.empty()) {
92
return
0;
93
}
94
int
hash_value = (2 *
scheme
.size() + (
unsigned
)(
scheme
[0])) & 7;
95
const
std::string_view target =
details::is_special_list
[hash_value];
96
if
(
scheme
.size() == target.size() &&
97
details::branchless_load5
(
scheme
.data(),
scheme
.size()) ==
98
details::scheme_keys
[hash_value]) {
99
return
details::special_ports
[hash_value];
100
}
else
{
101
return
0;
102
}
103
}
104
constexpr
uint16_t
get_special_port
(
ada::scheme::type
type
)
noexcept
{
105
return
details::special_ports
[int(
type
)];
106
}
107
constexpr
ada::scheme::type
get_scheme_type
(std::string_view
scheme
)
noexcept
{
108
if
(
scheme
.empty()) {
109
return
ada::scheme::NOT_SPECIAL
;
110
}
111
int
hash_value = (2 *
scheme
.size() + (
unsigned
)(
scheme
[0])) & 7;
112
const
std::string_view target =
details::is_special_list
[hash_value];
113
if
(
scheme
.size() == target.size() &&
114
details::branchless_load5
(
scheme
.data(),
scheme
.size()) ==
115
details::scheme_keys
[hash_value]) {
116
return
ada::scheme::type
(hash_value);
117
}
else
{
118
return
ada::scheme::NOT_SPECIAL
;
119
}
120
}
121
122
}
// namespace ada::scheme
123
124
#endif
// ADA_SCHEME_INL_H
ada_really_inline
#define ada_really_inline
Definition
common_defs.h:85
ada::scheme::details
Includes the definitions for scheme specific entities.
ada::scheme::details::is_special_list
constexpr std::string_view is_special_list[]
Definition
scheme-inl.h:19
ada::scheme::details::scheme_keys
constexpr uint64_t scheme_keys[]
Definition
scheme-inl.h:34
ada::scheme::details::special_ports
constexpr uint16_t special_ports[]
Definition
scheme-inl.h:22
ada::scheme::details::branchless_load5
uint64_t branchless_load5(const char *p, size_t n)
Definition
scheme-inl.h:48
ada::scheme::details::make_key
constexpr uint64_t make_key(std::string_view sv)
Definition
scheme-inl.h:26
ada::scheme
URL scheme utilities and constants.
Definition
scheme-inl.h:10
ada::scheme::get_scheme_type
constexpr ada::scheme::type get_scheme_type(std::string_view scheme) noexcept
Definition
scheme-inl.h:107
ada::scheme::type
type
Enumeration of URL scheme types.
Definition
scheme.h:41
ada::scheme::NOT_SPECIAL
@ NOT_SPECIAL
Definition
scheme.h:43
ada::scheme::get_special_port
constexpr uint16_t get_special_port(std::string_view scheme) noexcept
Definition
scheme-inl.h:90
scheme.h
URL scheme type definitions and utilities.