Loading...
Searching...
No Matches
scheme-inl.h
Go to the documentation of this file.
#ifndef ADA_SCHEME_INL_H
#define ADA_SCHEME_INL_H
#include "ada/scheme.h"
namespace ada::scheme {
namespace details {
// for use with is_special and get_special_port
// Spaces, if present, are removed from URL.
constexpr std::string_view is_special_list[] = {"http", " ", "https", "ws",
"ftp", "wss", "file", " "};
// for use with get_special_port
constexpr uint16_t special_ports[] = {80, 0, 443, 80, 21, 443, 0, 0};
// @private
// convert a string_view to a 64-bit integer key for fast comparison
constexpr uint64_t make_key(std::string_view sv) {
uint64_t val = 0;
for (size_t i = 0; i < sv.size(); i++)
val |= (uint64_t)(uint8_t)sv[i] << (i * 8);
return val;
}
// precomputed keys for the special schemes, indexed by a hash of the input
// string
constexpr uint64_t scheme_keys[] = {
make_key("http"), // 0: HTTP
0, // 1: sentinel
make_key("https"), // 2: HTTPS
make_key("ws"), // 3: WS
make_key("ftp"), // 4: FTP
make_key("wss"), // 5: WSS
make_key("file"), // 6: FILE
0, // 7: sentinel
};
// @private
// branchless load of up to 5 characters into a uint64_t, padding with zeros if
// n < 5
inline uint64_t branchless_load5(const char *p, size_t n) {
uint64_t input = (uint8_t)p[0];
input |= ((uint64_t)(uint8_t)p[n > 1] << 8) & (0 - (uint64_t)(n > 1));
input |= ((uint64_t)(uint8_t)p[(n > 2) * 2] << 16) & (0 - (uint64_t)(n > 2));
input |= ((uint64_t)(uint8_t)p[(n > 3) * 3] << 24) & (0 - (uint64_t)(n > 3));
input |= ((uint64_t)(uint8_t)p[(n > 4) * 4] << 32) & (0 - (uint64_t)(n > 4));
return input;
}
} // namespace details
ada_really_inline constexpr bool is_special(std::string_view scheme) {
if (scheme.empty()) {
return false;
}
int hash_value = (2 * scheme.size() + (unsigned)(scheme[0])) & 7;
const std::string_view target = details::is_special_list[hash_value];
return (target[0] == scheme[0]) && (target.substr(1) == scheme.substr(1));
}
constexpr uint16_t get_special_port(std::string_view scheme) noexcept {
if (scheme.empty()) {
return 0;
}
int hash_value = (2 * scheme.size() + (unsigned)(scheme[0])) & 7;
const std::string_view target = details::is_special_list[hash_value];
if (scheme.size() == target.size() &&
details::branchless_load5(scheme.data(), scheme.size()) ==
details::scheme_keys[hash_value]) {
return details::special_ports[hash_value];
} else {
return 0;
}
}
constexpr uint16_t get_special_port(ada::scheme::type type) noexcept {
return details::special_ports[int(type)];
}
constexpr ada::scheme::type get_scheme_type(std::string_view scheme) noexcept {
if (scheme.empty()) {
return ada::scheme::NOT_SPECIAL;
}
int hash_value = (2 * scheme.size() + (unsigned)(scheme[0])) & 7;
const std::string_view target = details::is_special_list[hash_value];
if (scheme.size() == target.size() &&
details::branchless_load5(scheme.data(), scheme.size()) ==
details::scheme_keys[hash_value]) {
return ada::scheme::type(hash_value);
} else {
return ada::scheme::NOT_SPECIAL;
}
}
} // namespace ada::scheme
#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.