1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
|
#ifndef URLUTIL_HH
#define URLUTIL_HH
#include <string>
#include <string_view>
#include <unordered_map>
namespace url {
enum class EscapeFlags : unsigned {
// Default encodes all non-unreserved characters
// (not the same as all reserved) to be safe.
DEFAULT = 0,
// Same as DEFAULT but doesn't encode SLASH, useful when the in data
// is a path.
KEEP_SLASH = 1,
};
std::string escape(std::string_view str,
EscapeFlags flags = EscapeFlags::DEFAULT);
void escape(std::string_view str, std::string& out,
EscapeFlags flags = EscapeFlags::DEFAULT);
std::string unescape(std::string_view str);
void unescape(std::string_view str, std::string& out);
constexpr EscapeFlags operator&(EscapeFlags a, EscapeFlags b) noexcept {
using utype = typename std::underlying_type<EscapeFlags>::type;
return static_cast<EscapeFlags>(
static_cast<utype>(a) & static_cast<utype>(b));
}
constexpr EscapeFlags operator|(EscapeFlags a, EscapeFlags b) noexcept {
using utype = typename std::underlying_type<EscapeFlags>::type;
return static_cast<EscapeFlags>(
static_cast<utype>(a) | static_cast<utype>(b));
}
constexpr EscapeFlags operator^(EscapeFlags a, EscapeFlags b) noexcept {
using utype = typename std::underlying_type<EscapeFlags>::type;
return static_cast<EscapeFlags>(
static_cast<utype>(a) ^ static_cast<utype>(b));
}
constexpr EscapeFlags operator~(EscapeFlags a) noexcept {
using utype = typename std::underlying_type<EscapeFlags>::type;
return static_cast<EscapeFlags>(~static_cast<utype>(a));
}
void split_and_unescape_path_and_query(
std::string_view url,
std::string& path,
std::unordered_map<std::string, std::string>& query);
std::unordered_map<std::string, std::string> expand_and_unescape_query(
std::string_view query);
} // namespace url
#endif // URLUTIL_HH
|