src/params_ref.cpp

97.8% Lines (91/93) 100.0% Functions (19/19) 68.4% Branches (13/19)
src/params_ref.cpp
Line Branch Hits 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_ref.hpp>
15 #include <boost/url/params_view.hpp>
16 #include <boost/url/url_base.hpp>
17 #include <boost/url/grammar/ci_string.hpp>
18 #include <boost/assert.hpp>
19 #include <utility>
20
21 namespace boost {
22 namespace urls {
23
24 //------------------------------------------------
25 //
26 // Special Members
27 //
28 //------------------------------------------------
29
30 100 params_ref::
31 params_ref(
32 url_base& u,
33 100 encoding_opts opt) noexcept
34 100 : params_base(u.impl_, opt)
35 100 , u_(&u)
36 {
37 100 }
38
39 1 params_ref::
40 params_ref(
41 params_ref const& other,
42 1 encoding_opts opt) noexcept
43 1 : params_base(other.u_->impl_, opt)
44 1 , u_(other.u_)
45 {
46 1 }
47
48 auto
49 1 params_ref::
50 operator=(params_ref const& other) ->
51 params_ref&
52 {
53
1/2
✓ Branch 1 taken 1 time.
✗ Branch 2 not taken.
1 if (!ref_.alias_of(other.ref_))
54 1 assign(other.begin(), other.end());
55 1 return *this;
56 }
57
58 auto
59 1 params_ref::
60 operator=(std::initializer_list<
61 param_view> init) ->
62 params_ref&
63 {
64 1 assign(init);
65 1 return *this;
66 }
67
68 63 params_ref::
69 operator
70 params_view() const noexcept
71 {
72 63 return { ref_, opt_ };
73 }
74
75 //------------------------------------------------
76 //
77 // Modifiers
78 //
79 //------------------------------------------------
80
81 void
82 3 params_ref::
83 clear() noexcept
84 {
85 3 u_->remove_query();
86 3 }
87
88 void
89 5 params_ref::
90 assign(
91 std::initializer_list<
92 param_view> init)
93 {
94 5 assign(init.begin(), init.end());
95 5 }
96
97 auto
98 16 params_ref::
99 insert(
100 iterator before,
101 param_view const& p) ->
102 iterator
103 {
104 return {
105
1/1
✓ Branch 1 taken 16 times.
16 u_->edit_params(
106 before.it_,
107 before.it_,
108 32 detail::single_param_iter(p, opt_.space_as_plus)),
109 32 opt_};
110 }
111
112 auto
113 16 params_ref::
114 insert(
115 iterator before,
116 std::initializer_list<
117 param_view> init) ->
118 iterator
119 {
120 16 return insert(
121 before,
122 init.begin(),
123 16 init.end());
124 }
125
126 auto
127 12 params_ref::
128 append(
129 param_view const& p) ->
130 iterator
131 {
132 12 return insert(end(), p);
133 }
134
135 auto
136 6 params_ref::
137 append(
138 std::initializer_list<
139 param_view> init) ->
140 iterator
141 {
142 6 return insert(end(), init);
143 }
144
145 std::size_t
146 2 params_ref::
147 erase(
148 core::string_view key,
149 ignore_case_param ic) noexcept
150 {
151 // end() can't be fully cached,
152 // since erase invalidates it.
153 2 iterator it;
154 {
155 2 auto const end_ = end();
156 2 it = find_last(end_, key, ic);
157
1/2
✗ Branch 1 not taken.
✓ Branch 2 taken 2 times.
2 if(it == end_)
158 return 0;
159 }
160 2 std::size_t n = 0;
161 for(;;)
162 {
163 5 ++n;
164 // Use it->key instead of key,
165 // to handle self-intersection
166 5 auto prev = find_last(it, (*it).key, ic);
167
2/2
✓ Branch 2 taken 2 times.
✓ Branch 3 taken 3 times.
5 if(prev == end())
168 2 break;
169 3 erase(it);
170 3 it = prev;
171 3 }
172 2 erase(it);
173 2 return n;
174 }
175
176 auto
177 8 params_ref::
178 replace(
179 iterator pos,
180 param_view const& p) ->
181 iterator
182 {
183 return iterator(
184 24 u_->edit_params(
185 pos.it_,
186
1/1
✓ Branch 1 taken 8 times.
8 std::next(pos).it_,
187 16 detail::single_param_iter(p, opt_.space_as_plus)),
188 16 opt_);
189 }
190
191 auto
192 2 params_ref::
193 replace(
194 iterator from,
195 iterator to,
196 std::initializer_list<
197 param_view> init) ->
198 iterator
199 {
200 2 return replace(
201 from,
202 to,
203 init.begin(),
204 2 init.end());
205 }
206
207 auto
208 4 params_ref::
209 unset(
210 iterator pos) noexcept ->
211 iterator
212 {
213
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 4 times.
4 BOOST_ASSERT(pos.it_.nk > 0);
214 4 core::string_view s;
215 return iterator(
216 4 u_->edit_params(
217 pos.it_,
218 4 pos.it_.next(),
219 4 detail::param_value_iter(
220 4 pos.it_.nk - 1, s, false)),
221 4 opt_);
222 }
223
224 auto
225 5 params_ref::
226 set(
227 iterator pos,
228 core::string_view value) ->
229 iterator
230 {
231
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 5 times.
5 BOOST_ASSERT(pos.it_.nk > 0);
232 return iterator(
233
1/1
✓ Branch 1 taken 5 times.
5 u_->edit_params(
234 pos.it_,
235 5 pos.it_.next(),
236 5 detail::param_value_iter(
237 5 pos.it_.nk - 1, value, true)),
238 10 opt_);
239 }
240
241 auto
242 1 params_ref::
243 set(
244 core::string_view key,
245 core::string_view value,
246 ignore_case_param ic) ->
247 iterator
248 {
249 // VFALCO we can't cache end() here
250 // because it is invalidated
251 // every time we set or erase.
252 1 auto it0 = find(key, ic);
253
1/2
✗ Branch 2 not taken.
✓ Branch 3 taken 1 time.
1 if(it0 == end())
254 return append({key, value});
255
1/1
✓ Branch 1 taken 1 time.
1 it0 = set(it0, value);
256 1 auto it = end();
257 for(;;)
258 {
259 2 it = find_last(it, key, ic);
260
2/2
✓ Branch 1 taken 1 time.
✓ Branch 2 taken 1 time.
2 if(it == it0)
261 1 return it0;
262 1 it = erase(it);
263 }
264 }
265
266 auto
267 9 params_ref::
268 erase(
269 iterator pos) noexcept ->
270 iterator
271 {
272 9 return erase(
273 pos,
274 9 std::next(pos));
275 }
276
277 auto
278 11 params_ref::
279 erase(
280 iterator first,
281 iterator last) noexcept ->
282 iterator
283 {
284 11 core::string_view s("", 0);
285 return iterator(
286 11 u_->edit_params(
287 first.it_,
288 last.it_,
289 22 detail::query_string_iter(s)),
290 11 opt_);
291 }
292
293 } // urls
294 } // boost
295