Ada 2.8.0
Fast spec-compliant URL parser
Loading...
Searching...
No Matches
url_search_params-inl.h
Go to the documentation of this file.
1
5#ifndef ADA_URL_SEARCH_PARAMS_INL_H
6#define ADA_URL_SEARCH_PARAMS_INL_H
7
8#include "ada.h"
10#include "ada/unicode.h"
12
13#include <algorithm>
14#include <optional>
15#include <string>
16#include <string_view>
17#include <vector>
18
19namespace ada {
20
21// A default, empty url_search_params for use with empty iterators.
22template <typename T, ada::url_search_params_iter_type Type>
23url_search_params url_search_params_iter<T, Type>::EMPTY;
24
25inline void url_search_params::initialize(std::string_view input) {
26 if (!input.empty() && input.front() == '?') {
27 input.remove_prefix(1);
28 }
29
30 auto process_key_value = [&](const std::string_view current) {
31 auto equal = current.find('=');
32
33 if (equal == std::string_view::npos) {
34 std::string name(current);
35 std::replace(name.begin(), name.end(), '+', ' ');
36 params.emplace_back(unicode::percent_decode(name, name.find('%')), "");
37 } else {
38 std::string name(current.substr(0, equal));
39 std::string value(current.substr(equal + 1));
40
41 std::replace(name.begin(), name.end(), '+', ' ');
42 std::replace(value.begin(), value.end(), '+', ' ');
43
44 params.emplace_back(unicode::percent_decode(name, name.find('%')),
45 unicode::percent_decode(value, value.find('%')));
46 }
47 };
48
49 while (!input.empty()) {
50 auto ampersand_index = input.find('&');
51
52 if (ampersand_index == std::string_view::npos) {
53 if (!input.empty()) {
54 process_key_value(input);
55 }
56 break;
57 } else if (ampersand_index != 0) {
58 process_key_value(input.substr(0, ampersand_index));
59 }
60
61 input.remove_prefix(ampersand_index + 1);
62 }
63}
64
65inline void url_search_params::append(const std::string_view key,
66 const std::string_view value) {
67 params.emplace_back(key, value);
68}
69
70inline size_t url_search_params::size() const noexcept { return params.size(); }
71
72inline std::optional<std::string_view> url_search_params::get(
73 const std::string_view key) {
74 auto entry = std::find_if(params.begin(), params.end(),
75 [&key](auto &param) { return param.first == key; });
76
77 if (entry == params.end()) {
78 return std::nullopt;
79 }
80
81 return entry->second;
82}
83
84inline std::vector<std::string> url_search_params::get_all(
85 const std::string_view key) {
86 std::vector<std::string> out{};
87
88 for (auto &param : params) {
89 if (param.first == key) {
90 out.emplace_back(param.second);
91 }
92 }
93
94 return out;
95}
96
97inline bool url_search_params::has(const std::string_view key) noexcept {
98 auto entry = std::find_if(params.begin(), params.end(),
99 [&key](auto &param) { return param.first == key; });
100 return entry != params.end();
101}
102
103inline bool url_search_params::has(std::string_view key,
104 std::string_view value) noexcept {
105 auto entry =
106 std::find_if(params.begin(), params.end(), [&key, &value](auto &param) {
107 return param.first == key && param.second == value;
108 });
109 return entry != params.end();
110}
111
112inline std::string url_search_params::to_string() const {
114 std::string out{};
115 for (size_t i = 0; i < params.size(); i++) {
116 auto key = ada::unicode::percent_encode(params[i].first, character_set);
117 auto value = ada::unicode::percent_encode(params[i].second, character_set);
118
119 // Performance optimization: Move this inside percent_encode.
120 std::replace(key.begin(), key.end(), ' ', '+');
121 std::replace(value.begin(), value.end(), ' ', '+');
122
123 if (i != 0) {
124 out += "&";
125 }
126 out.append(key);
127 out += "=";
128 out.append(value);
129 }
130 return out;
131}
132
133inline void url_search_params::set(const std::string_view key,
134 const std::string_view value) {
135 const auto find = [&key](auto &param) { return param.first == key; };
136
137 auto it = std::find_if(params.begin(), params.end(), find);
138
139 if (it == params.end()) {
140 params.emplace_back(key, value);
141 } else {
142 it->second = value;
143 params.erase(std::remove_if(std::next(it), params.end(), find),
144 params.end());
145 }
146}
147
148inline void url_search_params::remove(const std::string_view key) {
149 params.erase(
150 std::remove_if(params.begin(), params.end(),
151 [&key](auto &param) { return param.first == key; }),
152 params.end());
153}
154
155inline void url_search_params::remove(const std::string_view key,
156 const std::string_view value) {
157 params.erase(std::remove_if(params.begin(), params.end(),
158 [&key, &value](auto &param) {
159 return param.first == key &&
160 param.second == value;
161 }),
162 params.end());
163}
164
166 std::stable_sort(params.begin(), params.end(),
167 [](const key_value_pair &lhs, const key_value_pair &rhs) {
168 return lhs.first < rhs.first;
169 });
170}
171
175
182
189
190template <typename T, url_search_params_iter_type Type>
192 return pos < params.params.size();
193}
194
195template <>
196inline std::optional<std::string_view> url_search_params_keys_iter::next() {
197 if (!has_next()) {
198 return std::nullopt;
199 }
200 return params.params[pos++].first;
201}
202
203template <>
204inline std::optional<std::string_view> url_search_params_values_iter::next() {
205 if (!has_next()) {
206 return std::nullopt;
207 }
208 return params.params[pos++].second;
209}
210
211template <>
212inline std::optional<key_value_view_pair>
214 if (!has_next()) {
215 return std::nullopt;
216 }
217 return params.params[pos++];
218}
219
220} // namespace ada
221
222#endif // ADA_URL_SEARCH_PARAMS_INL_H
Includes all definitions for Ada.
Definitions of the character sets used by unicode functions.
constexpr uint8_t WWW_FORM_URLENCODED_PERCENT_ENCODE[32]
Definition ada_idna.h:13
url_search_params_iter< std::string_view, url_search_params_iter_type::VALUES > url_search_params_values_iter
url_search_params_iter< key_value_view_pair, url_search_params_iter_type::ENTRIES > url_search_params_entries_iter
url_search_params_iter< std::string_view, url_search_params_iter_type::KEYS > url_search_params_keys_iter
void set(std::string_view key, std::string_view value)
std::vector< std::string > get_all(std::string_view key)
void remove(std::string_view key)
url_search_params_entries_iter get_entries()
std::string to_string() const
url_search_params_keys_iter get_keys()
size_t size() const noexcept
void append(std::string_view key, std::string_view value)
url_search_params_values_iter get_values()
std::optional< std::string_view > get(std::string_view key)
bool has(std::string_view key) noexcept
Definitions for all unicode specific functions.
Declaration for the URL Search Params.