GCC Code Coverage Report


Directory: libs/http_proto/
File: boost/http_proto/rfc/impl/list_rule.hpp
Date: 2024-08-30 20:13:36
Exec Total Coverage
Lines: 56 57 98.2%
Functions: 15 15 100.0%
Branches: 25 26 96.2%

Line Branch Exec Source
1 //
2 // Copyright (c) 2021 Vinnie Falco (vinnie.falco@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/cppalliance/http_proto
8 //
9
10 #ifndef BOOST_HTTP_PROTO_RFC_IMPL_LIST_RULE_HPP
11 #define BOOST_HTTP_PROTO_RFC_IMPL_LIST_RULE_HPP
12
13 #include <boost/url/grammar/parse.hpp>
14 #include <boost/url/grammar/range_rule.hpp>
15 #include <boost/core/empty_value.hpp>
16 #include <type_traits>
17
18 namespace boost {
19 namespace http_proto {
20
21 namespace detail {
22
23 /* Peter:
24
25 So, to put everything together, this is what I propose
26
27 - make range2_rule that takes first and next with
28 value types of optional<E> rather than E like the current rule
29 - make variant_rule produce an optional<X> when otherwise
30 the value type would have been variant<void, void, X, void>
31 - add operators for combining the rules so that one can
32 write *( OWS >> !literal(",") >> -( OWS >> element ) )
33 - profit
34 */
35
36 // *( OWS "," )
37 struct ows_comma_t
38 {
39 using value_type = void;
40
41 auto
42 99 parse(
43 char const*& it,
44 char const* end) const noexcept ->
45 system::result<value_type>
46 {
47 99 auto it1 = it;
48
2/2
✓ Branch 0 taken 232 times.
✓ Branch 1 taken 15 times.
247 while(it != end)
49 {
50 // SP / HT
51
2/2
✓ Branch 0 taken 176 times.
✓ Branch 1 taken 56 times.
232 if( *it == ' ' ||
52
2/2
✓ Branch 0 taken 2 times.
✓ Branch 1 taken 174 times.
176 *it == '\t')
53 {
54 58 ++it;
55 58 continue;
56 }
57
2/2
✓ Branch 0 taken 84 times.
✓ Branch 1 taken 90 times.
174 if(*it != ',')
58 84 break;
59 // ","
60 90 it1 = ++it;
61 }
62 99 it = it1;
63 99 return {};
64 }
65 };
66
67 constexpr ows_comma_t ows_comma{};
68
69 } // detail
70
71 /*
72 #element => [ ( "," / element ) *( OWS "," [ OWS element ] ) ]
73
74 #element => first *next
75 first => [ element / ( "," *( OWS "," ) [ OWS element ] ) ]
76 next => "" / ( 1*( OWS "," ) [ OWS element ] )
77 */
78
79 template<class Rule>
80 struct list_rule_t<Rule>::
81 first_rule : empty_value<Rule>
82 {
83 using value_type =
84 typename Rule::value_type;
85
86 constexpr
87 explicit
88 8736 first_rule(
89 Rule const& r) noexcept
90 : empty_value<Rule>(
91 8736 empty_init, r)
92 {
93 8736 }
94
95 auto
96 17406 parse(
97 char const*& it,
98 char const* end) const ->
99 system::result<value_type>
100 {
101 // first => [ element / ( "," *( OWS "," ) [ OWS element ] ) ]
102
103
2/2
✓ Branch 0 taken 5 times.
✓ Branch 1 taken 8889 times.
17406 if(it == end)
104 5 return grammar::error::end_of_range;
105 {
106 // element
107 17401 auto it0 = it;
108 17401 auto rv = this->get().parse(it, end);
109
2/2
✓ Branch 1 taken 8862 times.
✓ Branch 2 taken 27 times.
17401 if(rv)
110 17370 return std::move(*rv);
111 31 it = it0;
112
2/2
✓ Branch 1 taken 5 times.
✓ Branch 2 taken 8499 times.
16976 }
113 // ","
114
2/2
✓ Branch 0 taken 14 times.
✓ Branch 1 taken 13 times.
31 if(*it != ',')
115 18 return grammar::error::end_of_range;
116 13 ++it;
117 // *( OWS "," )
118 13 detail::ows_comma.parse(it, end);
119 13 auto it1 = it;
120 // OWS
121 13 it = grammar::find_if_not(
122 it, end, detail::ws);
123 // element
124 13 auto rv = this->get().parse(it, end);
125
2/2
✓ Branch 1 taken 6 times.
✓ Branch 2 taken 7 times.
13 if(rv)
126 6 return std::move(*rv);
127 7 it = it1;
128 7 return grammar::error::end_of_range;
129 }
130 };
131
132 template<class Rule>
133 struct list_rule_t<Rule>::
134 next_rule : empty_value<Rule>
135 {
136 using value_type =
137 typename Rule::value_type;
138
139 constexpr
140 explicit
141 8736 next_rule(
142 Rule const& r) noexcept
143 : empty_value<Rule>(
144 8736 empty_init, r)
145 {
146 8736 }
147
148 auto
149 17428 parse(
150 char const*& it,
151 char const* end) const ->
152 system::result<value_type>
153 {
154 // next => "" / ( 1*( OWS "," ) [ OWS element ] )
155
156 // ""
157
2/2
✓ Branch 0 taken 8832 times.
✓ Branch 1 taken 86 times.
17428 if(it == end)
158 17321 return grammar::error::end_of_range;
159
160 // 1*( OWS "," )
161 {
162 107 auto it0 = it;
163 107 detail::ows_comma.parse(it, end);
164
2/2
✓ Branch 0 taken 7 times.
✓ Branch 1 taken 79 times.
107 if(it == it0)
165 9 return grammar::error::end_of_range;
166 }
167 98 auto it1 = it;
168 // OWS
169 98 it = grammar::find_if_not(
170 it, end, detail::ws);
171 98 auto rv = this->get().parse(it, end);
172
2/2
✓ Branch 1 taken 70 times.
✓ Branch 2 taken 9 times.
98 if(rv)
173 88 return std::move(*rv);
174 10 it = it1;
175 10 return grammar::error::end_of_range;
176 47 }
177 };
178
179 template<class Rule>
180 auto
181 4474 list_rule_t<Rule>::
182 parse(
183 char const*& it,
184 char const* end) const ->
185 system::result<value_type>
186 {
187 return grammar::parse(it, end,
188 8948 grammar::range_rule(
189 first_rule{this->get()},
190 next_rule{this->get()},
191
1/2
✓ Branch 2 taken 212 times.
✗ Branch 3 not taken.
13422 n_, m_));
192 }
193
194 } // http_proto
195 } // boost
196
197 #endif
198