GCC Code Coverage Report


Directory: libs/url/
File: src/detail/segments_iter_impl.cpp
Date: 2025-10-23 13:40:33
Exec Total Coverage
Lines: 97 97 100.0%
Functions: 6 6 100.0%
Branches: 32 40 80.0%

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
12 #include <boost/url/detail/config.hpp>
13 #include "path.hpp"
14 #include <boost/url/detail/segments_iter_impl.hpp>
15 #include "boost/url/rfc/detail/path_rules.hpp"
16 #include <boost/assert.hpp>
17
18 namespace boost {
19 namespace urls {
20 namespace detail {
21
22 // begin
23 2280 segments_iter_impl::
24 segments_iter_impl(
25 2280 detail::path_ref const& ref_) noexcept
26 2280 : ref(ref_)
27 {
28 2280 pos = path_prefix(ref.buffer());
29 2280 update();
30 2280 }
31
32 // end
33 1852 segments_iter_impl::
34 segments_iter_impl(
35 detail::path_ref const& ref_,
36 1852 int) noexcept
37 1852 : ref(ref_)
38 1852 , pos(ref.size())
39 1852 , next(ref.size())
40 1852 , index(ref.nseg())
41 {
42 1852 }
43
44 595 segments_iter_impl::
45 segments_iter_impl(
46 url_impl const& u_,
47 std::size_t pos_,
48 595 std::size_t index_) noexcept
49 595 : ref(u_)
50 595 , pos(pos_)
51 595 , index(index_)
52 {
53
2/2
✓ Branch 0 taken 272 times.
✓ Branch 1 taken 323 times.
595 if(index == 0)
54 {
55 272 pos = path_prefix(ref.buffer());
56 }
57
2/2
✓ Branch 1 taken 199 times.
✓ Branch 2 taken 124 times.
323 else if(pos != ref.size())
58 {
59
1/2
✗ Branch 1 not taken.
✓ Branch 2 taken 199 times.
199 BOOST_ASSERT(
60 ref.data()[pos] == '/');
61 199 ++pos; // skip '/'
62 }
63 595 update();
64 595 }
65
66 void
67 2875 segments_iter_impl::
68 update() noexcept
69 {
70 2875 auto const end = ref.end();
71 char const* const p0 =
72 2875 ref.data() + pos;
73 2875 dn = 0;
74 2875 auto p = p0;
75
2/2
✓ Branch 0 taken 9310 times.
✓ Branch 1 taken 1291 times.
10601 while(p != end)
76 {
77
2/2
✓ Branch 0 taken 1584 times.
✓ Branch 1 taken 7726 times.
9310 if(*p == '/')
78 1584 break;
79
2/2
✓ Branch 0 taken 7358 times.
✓ Branch 1 taken 368 times.
7726 if(*p != '%')
80 {
81 7358 ++p;
82 7358 continue;
83 }
84 368 p += 3;
85 368 dn += 2;
86 }
87 2875 next = p - ref.data();
88 2875 dn = p - p0 - dn;
89 2875 s_ = make_pct_string_view_unsafe(
90 2875 p0, p - p0, dn);
91 2875 }
92
93 void
94 2795 segments_iter_impl::
95 increment() noexcept
96 {
97
1/2
✗ Branch 1 not taken.
✓ Branch 2 taken 2795 times.
2795 BOOST_ASSERT(
98 index != ref.nseg());
99 2795 ++index;
100 2795 pos = next;
101
2/2
✓ Branch 1 taken 1142 times.
✓ Branch 2 taken 1653 times.
2795 if(index == ref.nseg())
102 1142 return;
103 // "/" segment
104 1653 auto const end = ref.end();
105 1653 auto p = ref.data() + pos;
106
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 1653 times.
1653 BOOST_ASSERT(p != end);
107
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 1653 times.
1653 BOOST_ASSERT(*p == '/');
108 1653 dn = 0;
109 1653 ++p; // skip '/'
110 1653 auto const p0 = p;
111
2/2
✓ Branch 0 taken 6507 times.
✓ Branch 1 taken 704 times.
7211 while(p != end)
112 {
113
2/2
✓ Branch 0 taken 949 times.
✓ Branch 1 taken 5558 times.
6507 if(*p == '/')
114 949 break;
115
2/2
✓ Branch 0 taken 5446 times.
✓ Branch 1 taken 112 times.
5558 if(*p != '%')
116 {
117 5446 ++p;
118 5446 continue;
119 }
120 112 p += 3;
121 112 dn += 2;
122 }
123 1653 next = p - ref.data();
124 1653 dn = p - p0 - dn;
125 1653 s_ = make_pct_string_view_unsafe(
126 1653 p0, p - p0, dn);
127 }
128
129 void
130 1584 segments_iter_impl::
131 decrement() noexcept
132 {
133
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 1584 times.
1584 BOOST_ASSERT(index != 0);
134 1584 --index;
135
2/2
✓ Branch 0 taken 549 times.
✓ Branch 1 taken 1035 times.
1584 if(index == 0)
136 {
137 549 next = pos;
138 549 pos = path_prefix(ref.buffer());
139 549 s_ = core::string_view(
140 549 ref.data() + pos,
141 549 next - pos);
142
1/2
✗ Branch 1 not taken.
✓ Branch 2 taken 549 times.
549 BOOST_ASSERT(! s_.ends_with('/'));
143 549 return;
144 }
145 1035 auto const begin = ref.data() +
146 1035 path_prefix(ref.buffer());
147 1035 next = pos;
148 1035 auto p = ref.data() + next;
149 1035 auto const p1 = p;
150
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 1035 times.
1035 BOOST_ASSERT(p != begin);
151 1035 dn = 0;
152
1/2
✓ Branch 0 taken 3188 times.
✗ Branch 1 not taken.
3188 while(p != begin)
153 {
154 3188 --p;
155
2/2
✓ Branch 0 taken 1035 times.
✓ Branch 1 taken 2153 times.
3188 if(*p == '/')
156 {
157 1035 ++dn;
158 1035 break;
159 }
160
2/2
✓ Branch 0 taken 28 times.
✓ Branch 1 taken 2125 times.
2153 if(*p == '%')
161 28 dn += 2;
162 }
163 1035 dn = p1 - p - dn;
164 1035 pos = p - ref.data();
165 1035 s_ = make_pct_string_view_unsafe(
166 1035 p + 1, p1 - p - 1, dn);
167 }
168
169 } // detail
170 } // url
171 } // boost
172
173