GCC Code Coverage Report


Directory: libs/url/
File: libs/url/src/detail/pct_format.cpp
Date: 2024-08-20 18:28:39
Exec Total Coverage
Lines: 80 80 100.0%
Functions: 2 2 100.0%
Branches: 61 76 80.3%

Line Branch Exec Source
1 //
2 // Copyright (c) 2022 Alan de Freitas (alandefreitas@gmail.com)
3 //
4 // Distributed under the Boost Software License, Version 1.0. (See accompanying
5 // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
6 //
7 // Official repository: https://github.com/boostorg/url
8 //
9
10
11 #include <boost/url/detail/config.hpp>
12 #include "pct_format.hpp"
13 #include <boost/url/grammar/parse.hpp>
14 #include <boost/url/grammar/unsigned_rule.hpp>
15
16 namespace boost {
17 namespace urls {
18 namespace detail {
19
20 std::size_t
21 225 pct_vmeasure(
22 grammar::lut_chars const& cs,
23 format_parse_context& pctx,
24 measure_context& mctx)
25 {
26 225 auto it0 = pctx.begin();
27 225 auto end = pctx.end();
28
2/2
✓ Branch 0 taken 266 times.
✓ Branch 1 taken 171 times.
437 while( it0 != end )
29 {
30 // look for replacement id
31 266 char const* it1 = it0;
32 266 while(
33
2/2
✓ Branch 0 taken 644 times.
✓ Branch 1 taken 52 times.
696 it1 != end &&
34
2/2
✓ Branch 0 taken 430 times.
✓ Branch 1 taken 214 times.
644 *it1 != '{' )
35 {
36 430 ++it1;
37 }
38
39 // output literal prefix
40
2/2
✓ Branch 0 taken 107 times.
✓ Branch 1 taken 159 times.
266 if( it0 != it1 )
41 {
42
2/2
✓ Branch 0 taken 430 times.
✓ Branch 1 taken 107 times.
537 for (char const* i = it0; i != it1; ++i)
43 430 mctx.advance_to( mctx.out() + measure_one(*i, cs));
44 }
45
46 // over
47
2/2
✓ Branch 0 taken 52 times.
✓ Branch 1 taken 214 times.
266 if( it1 == end )
48 {
49 52 break;
50 }
51
52 // enter replacement id
53 214 ++it1;
54
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 214 times.
214 BOOST_ASSERT(it1 != end);
55
56 // handle escaped replacement (second '{')
57 // there's no "{{" in URL templates because
58 // '{'s are not allowed in URLs
59
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 214 times.
214 BOOST_ASSERT(*it1 != '{');
60 /*
61 if( *it1 == '{' )
62 {
63 mctx.advance_to( mctx.out() + measure_one('{', cs));
64 ++it1;
65 // this was not a real replacement,
66 // so we just keep moving
67 continue;
68 }
69 */
70
71
72 // parse {id} or {id:specs}
73 214 char const* id_start = it1;
74 214 while (it1 != end &&
75
3/4
✓ Branch 0 taken 344 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 303 times.
✓ Branch 3 taken 41 times.
344 *it1 != ':' &&
76
2/2
✓ Branch 0 taken 130 times.
✓ Branch 1 taken 173 times.
303 *it1 != '}')
77 {
78 130 ++it1;
79 }
80 214 core::string_view id(id_start, it1);
81
82 // move to specs start
83
1/2
✓ Branch 0 taken 214 times.
✗ Branch 1 not taken.
214 if (it1 != end &&
84
2/2
✓ Branch 0 taken 41 times.
✓ Branch 1 taken 173 times.
214 *it1 == ':')
85 41 ++it1;
86 214 pctx.advance_to( it1 );
87
88 // get format_arg to use
89 214 auto idv = grammar::parse(
90 214 id, grammar::unsigned_rule<std::size_t>{});
91
2/2
✓ Branch 1 taken 21 times.
✓ Branch 2 taken 193 times.
214 if (idv)
92 {
93
1/2
✓ Branch 3 taken 21 times.
✗ Branch 4 not taken.
21 mctx.arg( *idv ).measure( pctx, mctx, cs );
94 }
95
2/2
✓ Branch 1 taken 20 times.
✓ Branch 2 taken 173 times.
193 else if (!id.empty())
96 {
97
1/2
✓ Branch 2 taken 20 times.
✗ Branch 3 not taken.
20 mctx.arg( id ).measure( pctx, mctx, cs );
98 }
99 else
100 {
101 173 std::size_t arg_id = pctx.next_arg_id();
102
2/2
✓ Branch 2 taken 171 times.
✓ Branch 3 taken 2 times.
173 mctx.arg( arg_id ).measure( pctx, mctx, cs );
103 }
104
105
106 212 it1 = pctx.begin();
107
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 212 times.
212 BOOST_ASSERT(*it1 == '}');
108 212 it0 = it1 + 1;
109 }
110
111 223 return mctx.out();
112 }
113
114 char*
115 220 pct_vformat(
116 grammar::lut_chars const& cs,
117 format_parse_context& pctx,
118 format_context& fctx)
119 {
120 220 auto it0 = pctx.begin();
121 220 auto end = pctx.end();
122
2/2
✓ Branch 0 taken 261 times.
✓ Branch 1 taken 169 times.
430 while( it0 != end )
123 {
124 // look for replacement id
125 261 char const* it1 = it0;
126 261 while(
127
2/2
✓ Branch 0 taken 631 times.
✓ Branch 1 taken 51 times.
682 it1 != end &&
128
2/2
✓ Branch 0 taken 421 times.
✓ Branch 1 taken 210 times.
631 *it1 != '{' )
129 {
130 421 ++it1;
131 }
132
133 // output literal prefix
134
2/2
✓ Branch 0 taken 106 times.
✓ Branch 1 taken 155 times.
261 if( it0 != it1 )
135 {
136
2/2
✓ Branch 0 taken 421 times.
✓ Branch 1 taken 106 times.
527 for (char const* i = it0; i != it1; ++i)
137 {
138 421 char* o = fctx.out();
139 421 encode_one(o, *i, cs);
140 421 fctx.advance_to(o);
141 }
142 }
143
144 // over
145
2/2
✓ Branch 0 taken 51 times.
✓ Branch 1 taken 210 times.
261 if( it1 == end )
146 {
147 51 break;
148 }
149
150 // enter replacement id
151 210 ++it1;
152
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 210 times.
210 BOOST_ASSERT(it1 != end);
153
154 // handle escaped replacement (second '{')
155 // there's no "{{" in URL templates because
156 // '{'s are not allowed in URLs
157
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 210 times.
210 BOOST_ASSERT(*it1 != '{');
158 /*
159 if( *it1 == '{' )
160 {
161 char* o = fctx.out();
162 encode_one(o, '{', cs);
163 fctx.advance_to(o);
164 ++it1;
165 // this was not a real replacement,
166 // so we just keep moving
167 continue;
168 }
169 */
170
171 // parse {id} or {id:specs}
172 210 char const* id_start = it1;
173 210 while (it1 != end &&
174
3/4
✓ Branch 0 taken 340 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 301 times.
✓ Branch 3 taken 39 times.
340 *it1 != ':' &&
175
2/2
✓ Branch 0 taken 130 times.
✓ Branch 1 taken 171 times.
301 *it1 != '}')
176 {
177 130 ++it1;
178 }
179 210 core::string_view id(id_start, it1);
180
181 // move to specs part
182
1/2
✓ Branch 0 taken 210 times.
✗ Branch 1 not taken.
210 if (it1 != end &&
183
2/2
✓ Branch 0 taken 39 times.
✓ Branch 1 taken 171 times.
210 *it1 == ':')
184 39 ++it1;
185 210 pctx.advance_to( it1 );
186
187 // get format_arg to use
188 210 auto idv = grammar::parse(
189 210 id, grammar::unsigned_rule<std::size_t>{});
190
2/2
✓ Branch 1 taken 21 times.
✓ Branch 2 taken 189 times.
210 if (idv)
191 {
192
1/2
✓ Branch 3 taken 21 times.
✗ Branch 4 not taken.
21 fctx.arg( *idv ).format( pctx, fctx, cs );
193 }
194
2/2
✓ Branch 1 taken 20 times.
✓ Branch 2 taken 169 times.
189 else if (!id.empty())
195 {
196
1/2
✓ Branch 2 taken 20 times.
✗ Branch 3 not taken.
20 fctx.arg( id ).format( pctx, fctx, cs );
197 }
198 else
199 {
200 169 std::size_t arg_id = pctx.next_arg_id();
201
1/2
✓ Branch 2 taken 169 times.
✗ Branch 3 not taken.
169 fctx.arg( arg_id ).format( pctx, fctx, cs );
202 }
203
204 210 it1 = pctx.begin();
205
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 210 times.
210 BOOST_ASSERT(*it1 == '}');
206 210 it0 = it1 + 1;
207 }
208
209 220 return fctx.out();
210 }
211
212 } // detail
213 } // urls
214 } // boost
215
216