GCC Code Coverage Report


Directory: libs/url/
File: boost/url/detail/encode.hpp
Date: 2024-02-29 20:02:56
Exec Total Coverage
Lines: 50 78 64.1%
Functions: 3 3 100.0%
Branches: 22 62 35.5%

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_DETAIL_ENCODE_HPP
12 #define BOOST_URL_DETAIL_ENCODE_HPP
13
14 #include <boost/url/encoding_opts.hpp>
15 #include <boost/url/pct_string_view.hpp>
16 #include <boost/url/grammar/hexdig_chars.hpp>
17 #include <boost/core/ignore_unused.hpp>
18 #include <cstdlib>
19
20 namespace boost {
21 namespace urls {
22 namespace detail {
23
24 constexpr
25 char const* const hexdigs[] = {
26 "0123456789ABCDEF",
27 "0123456789abcdef" };
28
29 //------------------------------------------------
30
31 // re-encode is to percent-encode a
32 // string that can already contain
33 // escapes. Characters not in the
34 // unreserved set are escaped, and
35 // escapes are passed through unchanged.
36 //
37 template<class CharSet>
38 std::size_t
39 1065 re_encoded_size_unsafe(
40 core::string_view s,
41 CharSet const& unreserved,
42 encoding_opts opt) noexcept
43 {
44 1065 std::size_t n = 0;
45 1065 auto const end = s.end();
46 1065 auto it = s.begin();
47
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 1065 times.
1065 if(opt.space_as_plus)
48 {
49 while(it != end)
50 {
51 if(*it != '%')
52 {
53 if( unreserved(*it)
54 || *it == ' ')
55 n += 1;
56 else
57 n += 3;
58 ++it;
59 }
60 else
61 {
62 BOOST_ASSERT(end - it >= 3);
63 BOOST_ASSERT(
64 grammar::hexdig_value(
65 it[1]) >= 0);
66 BOOST_ASSERT(
67 grammar::hexdig_value(
68 it[2]) >= 0);
69 n += 3;
70 it += 3;
71 }
72 }
73 }
74 else
75 {
76
2/2
✓ Branch 0 taken 3637 times.
✓ Branch 1 taken 1065 times.
4702 while(it != end)
77 {
78
2/2
✓ Branch 0 taken 3482 times.
✓ Branch 1 taken 155 times.
3637 if(*it != '%')
79 {
80
2/2
✓ Branch 1 taken 3275 times.
✓ Branch 2 taken 207 times.
3482 if(unreserved(*it))
81 3275 n += 1;
82 else
83 207 n += 3;
84 3482 ++it;
85 }
86 else
87 {
88
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 155 times.
155 BOOST_ASSERT(end - it >= 3);
89
1/2
✗ Branch 1 not taken.
✓ Branch 2 taken 155 times.
155 BOOST_ASSERT(
90 grammar::hexdig_value(
91 it[1]) >= 0);
92
1/2
✗ Branch 1 not taken.
✓ Branch 2 taken 155 times.
155 BOOST_ASSERT(
93 grammar::hexdig_value(
94 it[2]) >= 0);
95 155 n += 3;
96 155 it += 3;
97 }
98 }
99 }
100 1065 return n;
101 }
102
103 // unchecked
104 // returns decoded size
105 template<class CharSet>
106 std::size_t
107 1271 re_encode_unsafe(
108 char*& dest_,
109 char const* const end,
110 core::string_view s,
111 CharSet const& unreserved,
112 encoding_opts opt) noexcept
113 {
114 1271 char const* const hex =
115 1271 detail::hexdigs[opt.lower_case];
116 1271 auto const encode = [end, hex](
117 char*& dest,
118 char c0) noexcept
119 {
120 213 auto c = static_cast<unsigned char>(c0);
121 213 ignore_unused(end);
122 213 *dest++ = '%';
123
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 213 times.
213 BOOST_ASSERT(dest != end);
124 213 *dest++ = hex[c>>4];
125
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 213 times.
213 BOOST_ASSERT(dest != end);
126 213 *dest++ = hex[c&0xf];
127 };
128 ignore_unused(end);
129
130 1271 auto dest = dest_;
131 1271 auto const dest0 = dest;
132 1271 auto const last = s.end();
133 1271 std::size_t dn = 0;
134 1271 auto it = s.begin();
135
136
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 1271 times.
1271 if(opt.space_as_plus)
137 {
138 while(it != last)
139 {
140 BOOST_ASSERT(dest != end);
141 if(*it != '%')
142 {
143 if(*it == ' ')
144 {
145 *dest++ = '+';
146 }
147 else if(unreserved(*it))
148 {
149 *dest++ = *it;
150 }
151 else
152 {
153 encode(dest, *it);
154 dn += 2;
155 }
156 ++it;
157 }
158 else
159 {
160 *dest++ = *it++;
161 BOOST_ASSERT(dest != end);
162 *dest++ = *it++;
163 BOOST_ASSERT(dest != end);
164 *dest++ = *it++;
165 dn += 2;
166 }
167 }
168 }
169 else
170 {
171
2/2
✓ Branch 0 taken 3783 times.
✓ Branch 1 taken 1271 times.
5054 while(it != last)
172 {
173
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 3783 times.
3783 BOOST_ASSERT(dest != end);
174
2/2
✓ Branch 0 taken 3625 times.
✓ Branch 1 taken 158 times.
3783 if(*it != '%')
175 {
176
2/2
✓ Branch 1 taken 3412 times.
✓ Branch 2 taken 213 times.
3625 if(unreserved(*it))
177 {
178 3412 *dest++ = *it;
179 }
180 else
181 {
182 213 encode(dest, *it);
183 213 dn += 2;
184 }
185 3625 ++it;
186 }
187 else
188 {
189 158 *dest++ = *it++;
190
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 158 times.
158 BOOST_ASSERT(dest != end);
191 158 *dest++ = *it++;
192
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 158 times.
158 BOOST_ASSERT(dest != end);
193 158 *dest++ = *it++;
194 158 dn += 2;
195 }
196 }
197 }
198 1271 dest_ = dest;
199 1271 return dest - dest0 - dn;
200 }
201
202 } // detail
203 } // urls
204 } // boost
205
206 #endif
207