GCC Code Coverage Report


Directory: libs/url/
File: libs/url/src/params_ref.cpp
Date: 2023-12-15 15:31:49
Exec Total Coverage
Lines: 68 98 69.4%
Functions: 13 15 86.7%
Branches: 14 46 30.4%

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