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_IMPL_QUERY_RULE_HPP
11  
#ifndef BOOST_URL_RFC_IMPL_QUERY_RULE_HPP
12  
#define BOOST_URL_RFC_IMPL_QUERY_RULE_HPP
12  
#define BOOST_URL_RFC_IMPL_QUERY_RULE_HPP
13  

13  

14  
#include <boost/url/detail/config.hpp>
14  
#include <boost/url/detail/config.hpp>
15  
#include <boost/url/rfc/detail/charsets.hpp>
15  
#include <boost/url/rfc/detail/charsets.hpp>
16  
#include <boost/url/error.hpp>
16  
#include <boost/url/error.hpp>
17  
#include <boost/url/grammar/hexdig_chars.hpp>
17  
#include <boost/url/grammar/hexdig_chars.hpp>
18  

18  

19  
namespace boost {
19  
namespace boost {
20  
namespace urls {
20  
namespace urls {
21  

21  

22  
inline
22  
inline
23  
auto
23  
auto
24  
implementation_defined::query_rule_t::
24  
implementation_defined::query_rule_t::
25  
parse(
25  
parse(
26  
    char const*& it,
26  
    char const*& it,
27  
    char const* end
27  
    char const* end
28  
        ) const noexcept ->
28  
        ) const noexcept ->
29  
    system::result<value_type>
29  
    system::result<value_type>
30  
{
30  
{
31  
    if(it == end)
31  
    if(it == end)
32  
    {
32  
    {
33  
        // empty string = 1 param
33  
        // empty string = 1 param
34  
        core::string_view str(it, 0);
34  
        core::string_view str(it, 0);
35  
        return params_encoded_view(
35  
        return params_encoded_view(
36  
            detail::query_ref(str, 0, 1));
36  
            detail::query_ref(str, 0, 1));
37  
    }
37  
    }
38  
    auto const it0 = it;
38  
    auto const it0 = it;
39  
    std::size_t dn = 0;
39  
    std::size_t dn = 0;
40  
    std::size_t nparam = 1;
40  
    std::size_t nparam = 1;
41  
    while(it != end)
41  
    while(it != end)
42  
    {
42  
    {
43  
        if(*it == '&')
43  
        if(*it == '&')
44  
        {
44  
        {
45  
            ++nparam;
45  
            ++nparam;
46  
            ++it;
46  
            ++it;
47  
            continue;
47  
            continue;
48  
        }
48  
        }
49  
        if(detail::query_chars(*it))
49  
        if(detail::query_chars(*it))
50  
        {
50  
        {
51  
            ++it;
51  
            ++it;
52  
            continue;
52  
            continue;
53  
        }
53  
        }
54  
        if(*it == '%')
54  
        if(*it == '%')
55  
        {
55  
        {
56  
            if(end - it < 3 ||
56  
            if(end - it < 3 ||
57  
                (!grammar::hexdig_chars(it[1]) ||
57  
                (!grammar::hexdig_chars(it[1]) ||
58  
                 !grammar::hexdig_chars(it[2])))
58  
                 !grammar::hexdig_chars(it[2])))
59  
            {
59  
            {
60  
                // missing valid HEXDIG
60  
                // missing valid HEXDIG
61  
                break;
61  
                break;
62  
            }
62  
            }
63  
            it += 3;
63  
            it += 3;
64  
            dn += 2;
64  
            dn += 2;
65  
            continue;
65  
            continue;
66  
        }
66  
        }
67  
        // got reserved character
67  
        // got reserved character
68  
        break;
68  
        break;
69  
    }
69  
    }
70  
    std::size_t const n(it - it0);
70  
    std::size_t const n(it - it0);
71  
    core::string_view str(it0, n);
71  
    core::string_view str(it0, n);
72  
    return params_encoded_view(
72  
    return params_encoded_view(
73  
        detail::query_ref(
73  
        detail::query_ref(
74  
            str, n - dn, nparam));
74  
            str, n - dn, nparam));
75  
}
75  
}
76  

76  

77  
} // urls
77  
} // urls
78  
} // boost
78  
} // boost
79  

79  

80  

80  

81  
#endif
81  
#endif