1  
//
1  
//
2  
// Copyright (c) 2016-2019 Vinnie Falco (vinnie dot falco at gmail dot com)
2  
// Copyright (c) 2016-2019 Vinnie Falco (vinnie dot falco at gmail dot com)
3  
// Copyright (c) 2023 Alan de Freitas (alandefreitas@gmail.com)
3  
// Copyright (c) 2023 Alan de Freitas (alandefreitas@gmail.com)
4  
//
4  
//
5  
// Distributed under the Boost Software License, Version 1.0. (See accompanying
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)
6  
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
7  
//
7  
//
8  
// Official repository: https://github.com/boostorg/url
8  
// Official repository: https://github.com/boostorg/url
9  
//
9  
//
10  

10  

11  
#ifndef BOOST_URL_RFC_DETAIL_QUERY_PART_RULE_HPP
11  
#ifndef BOOST_URL_RFC_DETAIL_QUERY_PART_RULE_HPP
12  
#define BOOST_URL_RFC_DETAIL_QUERY_PART_RULE_HPP
12  
#define BOOST_URL_RFC_DETAIL_QUERY_PART_RULE_HPP
13  

13  

14  
#include <boost/url/detail/config.hpp>
14  
#include <boost/url/detail/config.hpp>
15  
#include <boost/url/error_types.hpp>
15  
#include <boost/url/error_types.hpp>
16  
#include <boost/url/pct_string_view.hpp>
16  
#include <boost/url/pct_string_view.hpp>
17  
#include <boost/url/rfc/detail/charsets.hpp>
17  
#include <boost/url/rfc/detail/charsets.hpp>
18  
#include <boost/url/grammar/hexdig_chars.hpp>
18  
#include <boost/url/grammar/hexdig_chars.hpp>
19  
#include <cstdlib>
19  
#include <cstdlib>
20  

20  

21  
namespace boost {
21  
namespace boost {
22  
namespace urls {
22  
namespace urls {
23  
namespace detail {
23  
namespace detail {
24  

24  

25  
/** Rule for query-part
25  
/** Rule for query-part
26  

26  

27  
    @par BNF
27  
    @par BNF
28  
    @code
28  
    @code
29  
    query-part    = [ "?" query ]
29  
    query-part    = [ "?" query ]
30  
    @endcode
30  
    @endcode
31  
*/
31  
*/
32  
struct query_part_rule_t
32  
struct query_part_rule_t
33  
{
33  
{
34  
    struct value_type
34  
    struct value_type
35  
    {
35  
    {
36  
        pct_string_view query;
36  
        pct_string_view query;
37  
        std::size_t count = 0;
37  
        std::size_t count = 0;
38  
        bool has_query = false;
38  
        bool has_query = false;
39  
    };
39  
    };
40  

40  

41  
    BOOST_URL_CXX14_CONSTEXPR
41  
    BOOST_URL_CXX14_CONSTEXPR
42  
    auto
42  
    auto
43  
    parse(
43  
    parse(
44  
        char const*& it,
44  
        char const*& it,
45  
        char const* end
45  
        char const* end
46  
            ) const noexcept ->
46  
            ) const noexcept ->
47  
        system::result<value_type>
47  
        system::result<value_type>
48  
    {
48  
    {
49  
        if( it == end ||
49  
        if( it == end ||
50  
            *it != '?')
50  
            *it != '?')
51  
            return {};
51  
            return {};
52  
        ++it;
52  
        ++it;
53  
        auto const it0 = it;
53  
        auto const it0 = it;
54  
        std::size_t dn = 0;
54  
        std::size_t dn = 0;
55  
        std::size_t nparam = 1;
55  
        std::size_t nparam = 1;
56  
        while(it != end)
56  
        while(it != end)
57  
        {
57  
        {
58  
            if(*it == '&')
58  
            if(*it == '&')
59  
            {
59  
            {
60  
                ++nparam;
60  
                ++nparam;
61  
                ++it;
61  
                ++it;
62  
                continue;
62  
                continue;
63  
            }
63  
            }
64  
            if(detail::query_chars(*it))
64  
            if(detail::query_chars(*it))
65  
            {
65  
            {
66  
                ++it;
66  
                ++it;
67  
                continue;
67  
                continue;
68  
            }
68  
            }
69  
            if(*it == '%')
69  
            if(*it == '%')
70  
            {
70  
            {
71  
                if(end - it < 3 ||
71  
                if(end - it < 3 ||
72  
                    (!grammar::hexdig_chars(it[1]) ||
72  
                    (!grammar::hexdig_chars(it[1]) ||
73  
                     !grammar::hexdig_chars(it[2])))
73  
                     !grammar::hexdig_chars(it[2])))
74  
                    break;
74  
                    break;
75  
                it += 3;
75  
                it += 3;
76  
                dn += 2;
76  
                dn += 2;
77  
                continue;
77  
                continue;
78  
            }
78  
            }
79  
            break;
79  
            break;
80  
        }
80  
        }
81  
        std::size_t const n(it - it0);
81  
        std::size_t const n(it - it0);
82  
        value_type t;
82  
        value_type t;
83  
        t.query = make_pct_string_view_unsafe(
83  
        t.query = make_pct_string_view_unsafe(
84  
            it0, n, n - dn);
84  
            it0, n, n - dn);
85  
        t.count = nparam;
85  
        t.count = nparam;
86  
        t.has_query = true;
86  
        t.has_query = true;
87  
        return t;
87  
        return t;
88  
    }
88  
    }
89  
};
89  
};
90  

90  

91  
constexpr query_part_rule_t query_part_rule{};
91  
constexpr query_part_rule_t query_part_rule{};
92  

92  

93  
} // detail
93  
} // detail
94  
} // urls
94  
} // urls
95  
} // boost
95  
} // boost
96  

96  

97  
#endif
97  
#endif