GCC Code Coverage Report


Directory: libs/url/
File: libs/url/src/detail/pct_format.cpp
Date: 2024-02-29 20:02:56
Exec Total Coverage
Lines: 78 78 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 #ifndef BOOST_URL_DETAIL_IMPL_PCT_FORMAT_IPP
11 #define BOOST_URL_DETAIL_IMPL_PCT_FORMAT_IPP
12
13 #include <boost/url/detail/config.hpp>
14 #include "pct_format.hpp"
15 #include <boost/url/grammar/parse.hpp>
16 #include <boost/url/grammar/unsigned_rule.hpp>
17
18 namespace boost {
19 namespace urls {
20 namespace detail {
21
22 std::size_t
23 250 pct_vmeasure(
24 grammar::lut_chars const& cs,
25 format_parse_context& pctx,
26 measure_context& mctx)
27 {
28 250 auto it0 = pctx.begin();
29 250 auto end = pctx.end();
30
2/2
✓ Branch 0 taken 295 times.
✓ Branch 1 taken 193 times.
488 while( it0 != end )
31 {
32 // look for replacement id
33 295 char const* it1 = it0;
34 467 while(
35
2/2
✓ Branch 0 taken 707 times.
✓ Branch 1 taken 55 times.
762 it1 != end &&
36
2/2
✓ Branch 0 taken 467 times.
✓ Branch 1 taken 240 times.
707 *it1 != '{' )
37 {
38 467 ++it1;
39 }
40
41 // output literal prefix
42
2/2
✓ Branch 0 taken 117 times.
✓ Branch 1 taken 178 times.
295 if( it0 != it1 )
43 {
44
2/2
✓ Branch 0 taken 467 times.
✓ Branch 1 taken 117 times.
584 for (char const* i = it0; i != it1; ++i)
45 467 mctx.advance_to( mctx.out() + measure_one(*i, cs));
46 }
47
48 // over
49
2/2
✓ Branch 0 taken 55 times.
✓ Branch 1 taken 240 times.
295 if( it1 == end )
50 {
51 55 break;
52 }
53
54 // enter replacement id
55 240 ++it1;
56
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 240 times.
240 BOOST_ASSERT(it1 != end);
57
58 // handle escaped replacement (second '{')
59 // there's no "{{" in URL templates because
60 // '{'s are not allowed in URLs
61
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 240 times.
240 BOOST_ASSERT(*it1 != '{');
62 /*
63 if( *it1 == '{' )
64 {
65 mctx.advance_to( mctx.out() + measure_one('{', cs));
66 ++it1;
67 // this was not a real replacement,
68 // so we just keep moving
69 continue;
70 }
71 */
72
73
74 // parse {id} or {id:specs}
75 240 char const* id_start = it1;
76 570 while (it1 != end &&
77
3/4
✓ Branch 0 taken 405 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 364 times.
✓ Branch 3 taken 41 times.
405 *it1 != ':' &&
78
2/2
✓ Branch 0 taken 165 times.
✓ Branch 1 taken 199 times.
364 *it1 != '}')
79 {
80 165 ++it1;
81 }
82 240 core::string_view id(id_start, it1);
83
84 // move to specs start
85
1/2
✓ Branch 0 taken 240 times.
✗ Branch 1 not taken.
240 if (it1 != end &&
86
2/2
✓ Branch 0 taken 41 times.
✓ Branch 1 taken 199 times.
240 *it1 == ':')
87 41 ++it1;
88 240 pctx.advance_to( it1 );
89
90 // get format_arg to use
91 auto idv = grammar::parse(
92 240 id, grammar::unsigned_rule<std::size_t>{});
93
2/2
✓ Branch 1 taken 27 times.
✓ Branch 2 taken 213 times.
240 if (idv)
94 {
95
1/2
✓ Branch 3 taken 27 times.
✗ Branch 4 not taken.
27 mctx.arg( *idv ).measure( pctx, mctx, cs );
96 }
97
2/2
✓ Branch 1 taken 26 times.
✓ Branch 2 taken 187 times.
213 else if (!id.empty())
98 {
99
1/2
✓ Branch 2 taken 26 times.
✗ Branch 3 not taken.
26 mctx.arg( id ).measure( pctx, mctx, cs );
100 }
101 else
102 {
103 187 std::size_t arg_id = pctx.next_arg_id();
104
2/2
✓ Branch 2 taken 185 times.
✓ Branch 3 taken 2 times.
187 mctx.arg( arg_id ).measure( pctx, mctx, cs );
105 }
106
107
108 238 it1 = pctx.begin();
109
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 238 times.
238 BOOST_ASSERT(*it1 == '}');
110 238 it0 = it1 + 1;
111 }
112
113 248 return mctx.out();
114 }
115
116 char*
117 245 pct_vformat(
118 grammar::lut_chars const& cs,
119 format_parse_context& pctx,
120 format_context& fctx)
121 {
122 245 auto it0 = pctx.begin();
123 245 auto end = pctx.end();
124
2/2
✓ Branch 0 taken 290 times.
✓ Branch 1 taken 191 times.
481 while( it0 != end )
125 {
126 // look for replacement id
127 290 char const* it1 = it0;
128 458 while(
129
2/2
✓ Branch 0 taken 694 times.
✓ Branch 1 taken 54 times.
748 it1 != end &&
130
2/2
✓ Branch 0 taken 458 times.
✓ Branch 1 taken 236 times.
694 *it1 != '{' )
131 {
132 458 ++it1;
133 }
134
135 // output literal prefix
136
2/2
✓ Branch 0 taken 116 times.
✓ Branch 1 taken 174 times.
290 if( it0 != it1 )
137 {
138
2/2
✓ Branch 0 taken 458 times.
✓ Branch 1 taken 116 times.
574 for (char const* i = it0; i != it1; ++i)
139 {
140 458 char* o = fctx.out();
141 458 encode_one(o, *i, cs);
142 458 fctx.advance_to(o);
143 }
144 }
145
146 // over
147
2/2
✓ Branch 0 taken 54 times.
✓ Branch 1 taken 236 times.
290 if( it1 == end )
148 {
149 54 break;
150 }
151
152 // enter replacement id
153 236 ++it1;
154
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 236 times.
236 BOOST_ASSERT(it1 != end);
155
156 // handle escaped replacement (second '{')
157 // there's no "{{" in URL templates because
158 // '{'s are not allowed in URLs
159
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 236 times.
236 BOOST_ASSERT(*it1 != '{');
160 /*
161 if( *it1 == '{' )
162 {
163 char* o = fctx.out();
164 encode_one(o, '{', cs);
165 fctx.advance_to(o);
166 ++it1;
167 // this was not a real replacement,
168 // so we just keep moving
169 continue;
170 }
171 */
172
173 // parse {id} or {id:specs}
174 236 char const* id_start = it1;
175 566 while (it1 != end &&
176
3/4
✓ Branch 0 taken 401 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 362 times.
✓ Branch 3 taken 39 times.
401 *it1 != ':' &&
177
2/2
✓ Branch 0 taken 165 times.
✓ Branch 1 taken 197 times.
362 *it1 != '}')
178 {
179 165 ++it1;
180 }
181 236 core::string_view id(id_start, it1);
182
183 // move to specs part
184
1/2
✓ Branch 0 taken 236 times.
✗ Branch 1 not taken.
236 if (it1 != end &&
185
2/2
✓ Branch 0 taken 39 times.
✓ Branch 1 taken 197 times.
236 *it1 == ':')
186 39 ++it1;
187 236 pctx.advance_to( it1 );
188
189 // get format_arg to use
190 auto idv = grammar::parse(
191 236 id, grammar::unsigned_rule<std::size_t>{});
192
2/2
✓ Branch 1 taken 27 times.
✓ Branch 2 taken 209 times.
236 if (idv)
193 {
194
1/2
✓ Branch 3 taken 27 times.
✗ Branch 4 not taken.
27 fctx.arg( *idv ).format( pctx, fctx, cs );
195 }
196
2/2
✓ Branch 1 taken 26 times.
✓ Branch 2 taken 183 times.
209 else if (!id.empty())
197 {
198
1/2
✓ Branch 2 taken 26 times.
✗ Branch 3 not taken.
26 fctx.arg( id ).format( pctx, fctx, cs );
199 }
200 else
201 {
202 183 std::size_t arg_id = pctx.next_arg_id();
203
1/2
✓ Branch 2 taken 183 times.
✗ Branch 3 not taken.
183 fctx.arg( arg_id ).format( pctx, fctx, cs );
204 }
205
206 236 it1 = pctx.begin();
207
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 236 times.
236 BOOST_ASSERT(*it1 == '}');
208 236 it0 = it1 + 1;
209 }
210
211 245 return fctx.out();
212 }
213
214 } // detail
215 } // urls
216 } // boost
217
218 #endif
219