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 |