Ada 3.4.4
Fast spec-compliant URL parser
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
10namespace ada::scheme {
11
16namespace details {
17// for use with is_special and get_special_port
18// Spaces, if present, are removed from URL.
19constexpr std::string_view is_special_list[] = {"http", " ", "https", "ws",
20 "ftp", "wss", "file", " "};
21// for use with get_special_port
22constexpr 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
26constexpr 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
34constexpr 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
48inline 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
82ada_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}
90constexpr 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}
104constexpr uint16_t get_special_port(ada::scheme::type type) noexcept {
105 return details::special_ports[int(type)];
106}
107constexpr ada::scheme::type get_scheme_type(std::string_view scheme) noexcept {
108 if (scheme.empty()) {
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 {
119 }
120}
121
122} // namespace ada::scheme
123
124#endif // ADA_SCHEME_INL_H
#define ada_really_inline
Definition common_defs.h:85
Includes the definitions for scheme specific entities.
constexpr std::string_view is_special_list[]
Definition scheme-inl.h:19
constexpr uint64_t scheme_keys[]
Definition scheme-inl.h:34
constexpr uint16_t special_ports[]
Definition scheme-inl.h:22
uint64_t branchless_load5(const char *p, size_t n)
Definition scheme-inl.h:48
constexpr uint64_t make_key(std::string_view sv)
Definition scheme-inl.h:26
URL scheme utilities and constants.
Definition scheme-inl.h:10
constexpr ada::scheme::type get_scheme_type(std::string_view scheme) noexcept
Definition scheme-inl.h:107
type
Enumeration of URL scheme types.
Definition scheme.h:41
@ NOT_SPECIAL
Definition scheme.h:43
constexpr uint16_t get_special_port(std::string_view scheme) noexcept
Definition scheme-inl.h:90
URL scheme type definitions and utilities.