Line data Source code
1 : //
2 : // Copyright (c) 2019 Vinnie Falco (vinnie.falco@gmail.com)
3 : // Copyright (c) 2022 Alan de Freitas (alandefreitas@gmail.com)
4 : //
5 : // Distributed under the Boost Software License, Version 1.0. (See accompanying
6 : // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
7 : //
8 : // Official repository: https://github.com/boostorg/url
9 : //
10 :
11 :
12 : #include <boost/url/detail/config.hpp>
13 : #include <boost/url/decode_view.hpp>
14 : #include <boost/url/params_base.hpp>
15 : #include <boost/url/grammar/ci_string.hpp>
16 : #include <ostream>
17 :
18 : namespace boost {
19 : namespace urls {
20 :
21 : //------------------------------------------------
22 :
23 291 : params_base::
24 : iterator::
25 : iterator(
26 : detail::query_ref const& ref,
27 291 : encoding_opts opt) noexcept
28 : : it_(ref)
29 291 : , space_as_plus_(opt.space_as_plus)
30 : {
31 291 : }
32 :
33 223 : params_base::
34 : iterator::
35 : iterator(
36 : detail::query_ref const& ref,
37 : encoding_opts opt,
38 223 : int) noexcept
39 : : it_(ref, 0)
40 223 : , space_as_plus_(opt.space_as_plus)
41 : {
42 223 : }
43 :
44 :
45 : auto
46 758 : params_base::
47 : iterator::
48 : operator*() const ->
49 : reference
50 :
51 : {
52 758 : encoding_opts opt;
53 758 : opt.space_as_plus =
54 758 : space_as_plus_;
55 : param_pct_view p =
56 758 : it_.dereference();
57 : return reference(
58 1516 : p.key.decode(opt),
59 1516 : p.value.decode(opt),
60 3790 : p.has_value);
61 : }
62 :
63 : //------------------------------------------------
64 : //
65 : // params_base
66 : //
67 : //------------------------------------------------
68 :
69 1 : params_base::
70 1 : params_base() noexcept
71 : // space_as_plus = true
72 1 : : opt_(true, false, false)
73 : {
74 1 : }
75 :
76 : bool
77 28 : params_base::
78 : contains(
79 : core::string_view key,
80 : ignore_case_param ic) const noexcept
81 : {
82 28 : return find(
83 28 : begin(),key, ic) != end();
84 : }
85 :
86 : auto
87 40 : params_base::
88 : find(
89 : core::string_view key,
90 : ignore_case_param ic) const noexcept ->
91 : iterator
92 : {
93 : return iterator(
94 40 : find_impl(
95 80 : begin().it_, key, ic),
96 40 : opt_);
97 : }
98 :
99 : auto
100 60 : params_base::
101 : find(
102 : iterator it,
103 : core::string_view key,
104 : ignore_case_param ic) const noexcept ->
105 : iterator
106 : {
107 : return iterator(
108 60 : find_impl(
109 60 : it.it_, key, ic),
110 60 : opt_);
111 : }
112 :
113 : auto
114 4 : params_base::
115 : find_last(
116 : core::string_view key,
117 : ignore_case_param ic) const noexcept ->
118 : iterator
119 : {
120 : return iterator(
121 4 : find_last_impl(
122 8 : end().it_, key, ic),
123 4 : opt_);
124 : }
125 :
126 : auto
127 9 : params_base::
128 : find_last(
129 : iterator it,
130 : core::string_view key,
131 : ignore_case_param ic) const noexcept ->
132 : iterator
133 : {
134 : return iterator(
135 9 : find_last_impl(
136 9 : it.it_, key, ic),
137 9 : opt_);
138 : }
139 :
140 272 : params_base::
141 : params_base(
142 : detail::query_ref const& ref,
143 272 : encoding_opts opt) noexcept
144 : : ref_(ref)
145 272 : , opt_(opt)
146 : {
147 272 : }
148 :
149 : pct_string_view
150 13 : params_base::
151 : buffer() const noexcept
152 : {
153 13 : return ref_.buffer();
154 : }
155 :
156 : bool
157 5 : params_base::
158 : empty() const noexcept
159 : {
160 5 : return ref_.nparam() == 0;
161 : }
162 :
163 : std::size_t
164 196 : params_base::
165 : size() const noexcept
166 : {
167 196 : return ref_.nparam();
168 : }
169 :
170 : auto
171 291 : params_base::
172 : begin() const noexcept ->
173 : iterator
174 : {
175 291 : return iterator(ref_, opt_);
176 : }
177 :
178 : auto
179 223 : params_base::
180 : end() const noexcept ->
181 : iterator
182 : {
183 223 : return iterator(ref_, opt_, 0);
184 : }
185 :
186 : //------------------------------------------------
187 :
188 : std::size_t
189 29 : params_base::
190 : count(
191 : core::string_view key,
192 : ignore_case_param ic) const noexcept
193 : {
194 29 : std::size_t n = 0;
195 29 : auto it = find(key, ic);
196 29 : auto const end_ = end();
197 57 : while(it != end_)
198 : {
199 28 : ++n;
200 28 : ++it;
201 28 : it = find(it, key, ic);
202 : }
203 29 : return n;
204 : }
205 :
206 : //------------------------------------------------
207 : //
208 : // (implementation)
209 : //
210 : //------------------------------------------------
211 :
212 : detail::params_iter_impl
213 100 : params_base::
214 : find_impl(
215 : detail::params_iter_impl it,
216 : core::string_view key,
217 : ignore_case_param ic) const noexcept
218 : {
219 100 : detail::params_iter_impl end_(ref_, 0);
220 100 : if(! ic)
221 : {
222 : for(;;)
223 : {
224 301 : if(it.equal(end_))
225 31 : return it;
226 270 : if(*it.key() == key)
227 32 : return it;
228 238 : it.increment();
229 : }
230 : }
231 : for(;;)
232 : {
233 128 : if(it.equal(end_))
234 10 : return it;
235 118 : if( grammar::ci_is_equal(
236 236 : *it.key(), key))
237 27 : return it;
238 91 : it.increment();
239 : }
240 : }
241 :
242 : detail::params_iter_impl
243 13 : params_base::
244 : find_last_impl(
245 : detail::params_iter_impl it,
246 : core::string_view key,
247 : ignore_case_param ic) const noexcept
248 : {
249 13 : detail::params_iter_impl begin_(ref_);
250 13 : if(! ic)
251 : {
252 : for(;;)
253 : {
254 13 : if(it.equal(begin_))
255 2 : return { ref_, 0 };
256 11 : it.decrement();
257 11 : if(*it.key() == key)
258 5 : return it;
259 : }
260 : }
261 : for(;;)
262 : {
263 9 : if(it.equal(begin_))
264 1 : return { ref_, 0 };
265 8 : it.decrement();
266 8 : if(grammar::ci_is_equal(
267 16 : *it.key(), key))
268 5 : return it;
269 : }
270 : }
271 :
272 : //------------------------------------------------
273 :
274 : std::ostream&
275 1 : operator<<(
276 : std::ostream& os,
277 : params_base const& qp)
278 : {
279 1 : os << qp.buffer();
280 1 : return os;
281 : }
282 :
283 : } // urls
284 : } // boost
285 :
|