include/boost/url/rfc/detail/query_part_rule.hpp

100.0% Lines (31/31) 100.0% Functions (1/1) 95.0% Branches (19/20)
include/boost/url/rfc/detail/query_part_rule.hpp
Line Branch Hits Source Code
1 //
2 // Copyright (c) 2016-2019 Vinnie Falco (vinnie dot falco at gmail dot com)
3 // Copyright (c) 2023 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_RFC_DETAIL_QUERY_PART_RULE_HPP
12 #define BOOST_URL_RFC_DETAIL_QUERY_PART_RULE_HPP
13
14 #include "boost/url/detail/config.hpp"
15 #include "boost/url/error_types.hpp"
16 #include "boost/url/pct_string_view.hpp"
17 #include <boost/url/rfc/detail/charsets.hpp>
18 #include <boost/url/grammar/hexdig_chars.hpp>
19 #include <cstdlib>
20
21 namespace boost {
22 namespace urls {
23 namespace detail {
24
25 /** Rule for query-part
26
27 @par BNF
28 @code
29 query-part = [ "?" query ]
30 @endcode
31 */
32 struct query_part_rule_t
33 {
34 struct value_type
35 {
36 pct_string_view query;
37 std::size_t count = 0;
38 bool has_query = false;
39 };
40
41 BOOST_URL_CXX14_CONSTEXPR
42 auto
43 3729 parse(
44 char const*& it,
45 char const* end
46 ) const noexcept ->
47 system::result<value_type>
48 {
49
2/2
✓ Branch 0 taken 724 times.
✓ Branch 1 taken 3005 times.
3729 if( it == end ||
50
2/2
✓ Branch 0 taken 237 times.
✓ Branch 1 taken 487 times.
724 *it != '?')
51 3242 return {};
52 487 ++it;
53 487 auto const it0 = it;
54 487 std::size_t dn = 0;
55 487 std::size_t nparam = 1;
56
2/2
✓ Branch 0 taken 4718 times.
✓ Branch 1 taken 301 times.
5019 while(it != end)
57 {
58
2/2
✓ Branch 0 taken 292 times.
✓ Branch 1 taken 4426 times.
4718 if(*it == '&')
59 {
60 292 ++nparam;
61 292 ++it;
62 292 continue;
63 }
64
2/2
✓ Branch 1 taken 4119 times.
✓ Branch 2 taken 307 times.
4426 if(detail::query_chars(*it))
65 {
66 4119 ++it;
67 4119 continue;
68 }
69
2/2
✓ Branch 0 taken 123 times.
✓ Branch 1 taken 184 times.
307 if(*it == '%')
70 {
71
4/4
✓ Branch 0 taken 122 times.
✓ Branch 1 taken 1 time.
✓ Branch 2 taken 2 times.
✓ Branch 3 taken 121 times.
245 if(end - it < 3 ||
72
2/2
✓ Branch 1 taken 121 times.
✓ Branch 2 taken 1 time.
122 (!grammar::hexdig_chars(it[1]) ||
73
1/2
✗ Branch 1 not taken.
✓ Branch 2 taken 121 times.
121 !grammar::hexdig_chars(it[2])))
74 2 break;
75 121 it += 3;
76 121 dn += 2;
77 121 continue;
78 }
79 184 break;
80 }
81 487 std::size_t const n(it - it0);
82 487 value_type t;
83 487 t.query = make_pct_string_view_unsafe(
84 it0, n, n - dn);
85 487 t.count = nparam;
86 487 t.has_query = true;
87 487 return t;
88 }
89 };
90
91 constexpr query_part_rule_t query_part_rule{};
92
93 } // detail
94 } // urls
95 } // boost
96
97 #endif
98