Ada 2.9.2
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 <ranges>
16#include <string>
17#include <string_view>
18#include <vector>
19
20namespace ada {
21
22// A default, empty url_search_params for use with empty iterators.
23template <typename T, ada::url_search_params_iter_type Type>
24url_search_params url_search_params_iter<T, Type>::EMPTY;
25
26inline void url_search_params::reset(std::string_view input) {
27 params.clear();
28 initialize(input);
29}
30
31inline void url_search_params::initialize(std::string_view input) {
32 if (!input.empty() && input.front() == '?') {
33 input.remove_prefix(1);
34 }
35
36 auto process_key_value = [&](const std::string_view current) {
37 auto equal = current.find('=');
38
39 if (equal == std::string_view::npos) {
40 std::string name(current);
41 std::ranges::replace(name, '+', ' ');
42 params.emplace_back(unicode::percent_decode(name, name.find('%')), "");
43 } else {
44 std::string name(current.substr(0, equal));
45 std::string value(current.substr(equal + 1));
46
47 std::ranges::replace(name, '+', ' ');
48 std::ranges::replace(value, '+', ' ');
49
50 params.emplace_back(unicode::percent_decode(name, name.find('%')),
51 unicode::percent_decode(value, value.find('%')));
52 }
53 };
54
55 while (!input.empty()) {
56 auto ampersand_index = input.find('&');
57
58 if (ampersand_index == std::string_view::npos) {
59 if (!input.empty()) {
60 process_key_value(input);
61 }
62 break;
63 } else if (ampersand_index != 0) {
64 process_key_value(input.substr(0, ampersand_index));
65 }
66
67 input.remove_prefix(ampersand_index + 1);
68 }
69}
70
71inline void url_search_params::append(const std::string_view key,
72 const std::string_view value) {
73 params.emplace_back(key, value);
74}
75
76inline size_t url_search_params::size() const noexcept { return params.size(); }
77
78inline std::optional<std::string_view> url_search_params::get(
79 const std::string_view key) {
80 auto entry = std::ranges::find_if(
81 params, [&key](auto &param) { return param.first == key; });
82
83 if (entry == params.end()) {
84 return std::nullopt;
85 }
86
87 return entry->second;
88}
89
90inline std::vector<std::string> url_search_params::get_all(
91 const std::string_view key) {
92 std::vector<std::string> out{};
93
94 for (auto &param : params) {
95 if (param.first == key) {
96 out.emplace_back(param.second);
97 }
98 }
99
100 return out;
101}
102
103inline bool url_search_params::has(const std::string_view key) noexcept {
104 auto entry = std::ranges::find_if(
105 params, [&key](auto &param) { return param.first == key; });
106 return entry != params.end();
107}
108
109inline bool url_search_params::has(std::string_view key,
110 std::string_view value) noexcept {
111 auto entry = std::ranges::find_if(params, [&key, &value](auto &param) {
112 return param.first == key && param.second == value;
113 });
114 return entry != params.end();
115}
116
117inline std::string url_search_params::to_string() const {
119 std::string out{};
120 for (size_t i = 0; i < params.size(); i++) {
121 auto key = ada::unicode::percent_encode(params[i].first, character_set);
122 auto value = ada::unicode::percent_encode(params[i].second, character_set);
123
124 // Performance optimization: Move this inside percent_encode.
125 std::ranges::replace(key, ' ', '+');
126 std::ranges::replace(value, ' ', '+');
127
128 if (i != 0) {
129 out += "&";
130 }
131 out.append(key);
132 out += "=";
133 out.append(value);
134 }
135 return out;
136}
137
138inline void url_search_params::set(const std::string_view key,
139 const std::string_view value) {
140 const auto find = [&key](auto &param) { return param.first == key; };
141
142 auto it = std::ranges::find_if(params, find);
143
144 if (it == params.end()) {
145 params.emplace_back(key, value);
146 } else {
147 it->second = value;
148 params.erase(std::remove_if(std::next(it), params.end(), find),
149 params.end());
150 }
151}
152
153inline void url_search_params::remove(const std::string_view key) {
154 std::erase_if(params, [&key](auto &param) { return param.first == key; });
155}
156
157inline void url_search_params::remove(const std::string_view key,
158 const std::string_view value) {
159 std::erase_if(params, [&key, &value](auto &param) {
160 return param.first == key && param.second == value;
161 });
162}
163
165 std::ranges::stable_sort(
166 params, [](const key_value_pair &lhs, const key_value_pair &rhs) {
167 return lhs.first < rhs.first;
168 });
169}
170
174
181
188
189template <typename T, url_search_params_iter_type Type>
191 return pos < params.params.size();
192}
193
194template <>
195inline std::optional<std::string_view> url_search_params_keys_iter::next() {
196 if (!has_next()) {
197 return std::nullopt;
198 }
199 return params.params[pos++].first;
200}
201
202template <>
203inline std::optional<std::string_view> url_search_params_values_iter::next() {
204 if (!has_next()) {
205 return std::nullopt;
206 }
207 return params.params[pos++].second;
208}
209
210template <>
211inline std::optional<key_value_view_pair>
213 if (!has_next()) {
214 return std::nullopt;
215 }
216 return params.params[pos++];
217}
218
219} // namespace ada
220
221#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.