include/boost/url/detail/impl/url_impl.hpp

100.0% Lines (154/154) 100.0% Functions (21/21) 85.0% Branches (51/60)
include/boost/url/detail/impl/url_impl.hpp
Line Branch Hits Source Code
1 //
2 // Copyright (c) 2022 Vinnie Falco (vinnie.falco@gmail.com)
3 // Copyright (c) 2023 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_DETAIL_IMPL_URL_IMPL_HPP
12 #define BOOST_URL_DETAIL_IMPL_URL_IMPL_HPP
13
14 #include <boost/url/detail/config.hpp>
15 #include <boost/url/detail/url_impl.hpp>
16 #include <boost/url/authority_view.hpp>
17 #include <boost/url/scheme.hpp>
18 #include <boost/assert.hpp>
19 #include <cstring>
20
21 namespace boost {
22 namespace urls {
23 namespace detail {
24
25 //------------------------------------------------
26 //
27 // url_impl
28 //
29 //------------------------------------------------
30
31 inline BOOST_URL_CXX20_CONSTEXPR
32 void
33 2430 url_impl::
34 apply_scheme(
35 core::string_view s) noexcept
36 {
37 2430 scheme_ = string_to_scheme(s);
38 2430 set_size(id_scheme, s.size() + 1);
39 2430 }
40
41 inline BOOST_URL_CXX20_CONSTEXPR
42 void
43 405 url_impl::
44 apply_userinfo(
45 pct_string_view const& user,
46 pct_string_view const* pass) noexcept
47 {
48
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 405 times.
405 BOOST_ASSERT(from_ == from::authority);
49
50 405 set_size(id_user, user.size());
51 405 decoded_[id_user] =
52 405 detail::to_size_type(
53 user.decoded_size());
54
2/2
✓ Branch 0 taken 270 times.
✓ Branch 1 taken 135 times.
405 if(pass)
55 {
56 270 set_size(id_pass,
57 270 pass->size() + 2);
58 270 decoded_[id_pass] =
59 270 detail::to_size_type(
60 pass->decoded_size());
61 }
62 else
63 {
64 135 set_size(id_pass, 1 );
65 }
66 405 }
67
68 inline BOOST_URL_CXX20_CONSTEXPR
69 void
70 2021 url_impl::
71 apply_host(
72 host_type ht,
73 pct_string_view s,
74 unsigned char const* addr) noexcept
75 {
76
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 2021 times.
2021 BOOST_ASSERT(from_ == from::authority);
77
78 2021 host_type_ = ht;
79 2021 set_size(id_host, s.size());
80 2021 decoded_[id_host] =
81 2021 detail::to_size_type(
82 s.decoded_size());
83 2021 for(std::size_t i = 0;
84
2/2
✓ Branch 0 taken 32336 times.
✓ Branch 1 taken 2021 times.
34357 i < sizeof(ip_addr_); ++i)
85 32336 ip_addr_[i] = addr[i];
86 2021 }
87
88 inline BOOST_URL_CXX20_CONSTEXPR
89 void
90 284 url_impl::
91 apply_port(
92 core::string_view s,
93 unsigned short pn) noexcept
94 {
95
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 284 times.
284 BOOST_ASSERT(from_ == from::authority);
96
97 284 port_number_ = pn;
98 284 set_size(id_port, 1 + s.size());
99 284 }
100
101 inline BOOST_URL_CXX20_CONSTEXPR
102 void
103 1961 url_impl::
104 apply_authority(
105 authority_view const& a) noexcept
106 {
107
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 1961 times.
1961 BOOST_ASSERT(from_ != from::authority);
108
109 1961 set_size(id_user,
110 1961 a.u_.len(id_user) +
111
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 1961 times.
1961 (from_ == from::authority ? 0 : 2));
112 1961 set_size(id_pass, a.u_.len(id_pass));
113 1961 decoded_[id_user] = a.u_.decoded_[id_user];
114 1961 decoded_[id_pass] = a.u_.decoded_[id_pass];
115
116 1961 host_type_ = a.u_.host_type_;
117 1961 port_number_ = a.u_.port_number_;
118 1961 set_size(id_host, a.u_.len(id_host));
119 1961 set_size(id_port, a.u_.len(id_port));
120 1961 for(std::size_t i = 0;
121
2/2
✓ Branch 0 taken 31376 times.
✓ Branch 1 taken 1961 times.
33337 i < sizeof(ip_addr_); ++i)
122 31376 ip_addr_[i] = a.u_.ip_addr_[i];
123 1961 decoded_[id_host] = a.u_.decoded_[id_host];
124 1961 }
125
126 inline BOOST_URL_CXX20_CONSTEXPR
127 void
128 3729 url_impl::
129 apply_path(
130 pct_string_view s,
131 std::size_t nseg) noexcept
132 {
133 3729 set_size(id_path, s.size());
134 3729 decoded_[id_path] =
135 3729 detail::to_size_type(
136 s.decoded_size());
137 // inline path_segments logic
138 // (original in src/detail/path.hpp)
139 3729 auto const sz = s.size();
140 3729 auto const p = s.data();
141 3729 std::size_t adj = nseg;
142
4/4
✓ Branch 0 taken 1167 times.
✓ Branch 1 taken 553 times.
✓ Branch 2 taken 176 times.
✓ Branch 3 taken 1833 times.
3729 switch(sz)
143 {
144 1167 case 0:
145 1167 adj = 0;
146 1167 break;
147 553 case 1:
148 553 adj = (p[0] == '/') ? 0 : 1;
149 553 break;
150 176 case 2:
151
2/2
✓ Branch 0 taken 139 times.
✓ Branch 1 taken 37 times.
176 if(p[0] == '/')
152 139 adj = nseg;
153
4/4
✓ Branch 0 taken 19 times.
✓ Branch 1 taken 18 times.
✓ Branch 2 taken 9 times.
✓ Branch 3 taken 10 times.
37 else if(p[0] == '.' && p[1] == '/')
154 9 adj = nseg - 1;
155 else
156 28 adj = nseg;
157 176 break;
158 1833 default:
159
2/2
✓ Branch 0 taken 990 times.
✓ Branch 1 taken 843 times.
1833 if(p[0] == '/')
160 {
161
4/4
✓ Branch 0 taken 66 times.
✓ Branch 1 taken 924 times.
✓ Branch 2 taken 44 times.
✓ Branch 3 taken 22 times.
990 if(p[1] == '.' && p[2] == '/')
162 44 adj = nseg - 1;
163 else
164 946 adj = nseg;
165 }
166
4/4
✓ Branch 0 taken 74 times.
✓ Branch 1 taken 769 times.
✓ Branch 2 taken 37 times.
✓ Branch 3 taken 37 times.
843 else if(p[0] == '.' && p[1] == '/')
167 37 adj = nseg - 1;
168 else
169 806 adj = nseg;
170 1833 break;
171 }
172 3729 nseg_ = detail::to_size_type(adj);
173 3729 }
174
175 inline BOOST_URL_CXX20_CONSTEXPR
176 void
177 487 url_impl::
178 apply_query(
179 pct_string_view s,
180 std::size_t n) noexcept
181 {
182 487 nparam_ = detail::to_size_type(n);
183 487 set_size(id_query, 1 + s.size());
184 487 decoded_[id_query] =
185 487 detail::to_size_type(
186 s.decoded_size());
187 487 }
188
189 inline BOOST_URL_CXX20_CONSTEXPR
190 void
191 244 url_impl::
192 apply_frag(
193 pct_string_view s) noexcept
194 {
195 244 set_size(id_frag, s.size() + 1);
196 244 decoded_[id_frag] =
197 244 detail::to_size_type(
198 s.decoded_size());
199 244 }
200
201 // return length of [first, last)
202 inline BOOST_URL_CXX20_CONSTEXPR
203 std::size_t
204 20955 url_impl::
205 len(
206 int first,
207 int last) const noexcept
208 {
209
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 20955 times.
20955 BOOST_ASSERT(first <= last);
210
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 20955 times.
20955 BOOST_ASSERT(last <= id_end);
211 20955 return offset(last) - offset(first);
212 }
213
214 // return length of part
215 inline BOOST_URL_CXX20_CONSTEXPR
216 std::size_t
217 276563 url_impl::
218 len(int id) const noexcept
219 {
220 return id == id_end
221
1/2
✓ Branch 0 taken 276563 times.
✗ Branch 1 not taken.
553126 ? zero_
222 276563 : ( offset(id + 1) -
223 553126 offset(id) );
224 }
225
226 // return offset of id
227 inline BOOST_URL_CXX20_CONSTEXPR
228 std::size_t
229 723556 url_impl::
230 offset(int id) const noexcept
231 {
232 return
233 id == id_scheme
234
2/2
✓ Branch 0 taken 669208 times.
✓ Branch 1 taken 54348 times.
723556 ? zero_
235 723556 : offset_[id];
236 }
237
238 // return id as string
239 inline BOOST_URL_CXX20_CONSTEXPR
240 core::string_view
241 49375 url_impl::
242 get(int id) const noexcept
243 {
244 return {
245 49375 cs_ + offset(id), len(id) };
246 }
247
248 // return [first, last) as string
249 inline BOOST_URL_CXX20_CONSTEXPR
250 core::string_view
251 916 url_impl::
252 get(int first,
253 int last) const noexcept
254 {
255 916 return { cs_ + offset(first),
256 916 offset(last) - offset(first) };
257 }
258
259 // return id as pct-string
260 inline BOOST_URL_CXX20_CONSTEXPR
261 pct_string_view
262 2315 url_impl::
263 pct_get(
264 int id) const noexcept
265 {
266 2315 return make_pct_string_view_unsafe(
267 2315 cs_ + offset(id),
268 len(id),
269 4630 decoded_[id]);
270 }
271
272 // return [first, last) as pct-string
273 inline BOOST_URL_CXX20_CONSTEXPR
274 pct_string_view
275 130 url_impl::
276 pct_get(
277 int first,
278 int last) const noexcept
279 {
280 130 auto const pos = offset(first);
281 130 std::size_t n = 0;
282
2/2
✓ Branch 0 taken 290 times.
✓ Branch 1 taken 130 times.
420 for(auto i = first; i < last;)
283 290 n += decoded_[i++];
284 130 return make_pct_string_view_unsafe(
285 130 cs_ + pos,
286 130 offset(last) - pos,
287 130 n);
288 }
289
290 //------------------------------------------------
291
292 // change id to size n
293 inline BOOST_URL_CXX20_CONSTEXPR
294 void
295 20632 url_impl::
296 set_size(
297 int id,
298 std::size_t n) noexcept
299 {
300 20632 auto const cur = len(id);
301
2/2
✓ Branch 0 taken 20267 times.
✓ Branch 1 taken 365 times.
20632 if(n >= cur)
302 {
303 20267 auto const d = n - cur;
304 20267 for(auto i = id + 1;
305
2/2
✓ Branch 0 taken 103379 times.
✓ Branch 1 taken 20267 times.
123646 i <= id_end; ++i)
306 103379 offset_[i] += detail::to_size_type(d);
307 20267 return;
308 }
309 365 auto const d = cur - n;
310 365 for(auto i = id + 1;
311
2/2
✓ Branch 0 taken 1429 times.
✓ Branch 1 taken 365 times.
1794 i <= id_end; ++i)
312 1429 offset_[i] -= detail::to_size_type(d);
313 }
314
315 // trim id to size n,
316 // moving excess into id+1
317 inline BOOST_URL_CXX20_CONSTEXPR
318 void
319 891 url_impl::
320 split(
321 int id,
322 std::size_t n) noexcept
323 {
324
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 891 times.
891 BOOST_ASSERT(id < id_end - 1);
325 891 offset_[id + 1] = detail::to_size_type(
326 891 offset(id) + n);
327 891 }
328
329 // add n to [first, last]
330 inline BOOST_URL_CXX20_CONSTEXPR
331 void
332 979 url_impl::
333 adjust_right(
334 int first,
335 int last,
336 std::size_t n) noexcept
337 {
338 979 for(int i = first;
339
2/2
✓ Branch 0 taken 4741 times.
✓ Branch 1 taken 979 times.
5720 i <= last; ++i)
340 4741 offset_[i] += detail::to_size_type(n);
341 979 }
342
343 // remove n from [first, last]
344 inline BOOST_URL_CXX20_CONSTEXPR
345 void
346 721 url_impl::
347 adjust_left(
348 int first,
349 int last,
350 std::size_t n) noexcept
351 {
352 721 for(int i = first;
353
2/2
✓ Branch 0 taken 2837 times.
✓ Branch 1 taken 721 times.
3558 i <= last; ++i)
354 2837 offset_[i] -= detail::to_size_type(n);
355 721 }
356
357 // set [first, last) offset
358 inline BOOST_URL_CXX20_CONSTEXPR
359 void
360 1681 url_impl::
361 collapse(
362 int first,
363 int last,
364 std::size_t n) noexcept
365 {
366 1681 for(int i = first + 1;
367
2/2
✓ Branch 0 taken 547 times.
✓ Branch 1 taken 1681 times.
2228 i < last; ++i)
368 547 offset_[i] = detail::to_size_type(n);
369 1681 }
370
371 //------------------------------------------------
372
373 inline BOOST_URL_CXX20_CONSTEXPR
374 authority_view
375 2533 url_impl::
376 construct_authority() const noexcept
377 {
378 2533 return authority_view(*this);
379 }
380
381 // construct() is defined in url_view.hpp
382 // after the url_view type is complete
383
384 } // detail
385 } // urls
386 } // boost
387
388 #endif
389