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