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  
//
3  
//
4  
// Distributed under the Boost Software License, Version 1.0. (See accompanying
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)
5  
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
6  
//
6  
//
7  
// Official repository: https://github.com/boostorg/url
7  
// Official repository: https://github.com/boostorg/url
8  
//
8  
//
9  

9  

10  
#include <boost/url/detail/config.hpp>
10  
#include <boost/url/detail/config.hpp>
11  
#include <boost/url/rfc/query_rule.hpp>
11  
#include <boost/url/rfc/query_rule.hpp>
12  
#include "detail/charsets.hpp"
12  
#include "detail/charsets.hpp"
13  
#include <boost/url/error.hpp>
13  
#include <boost/url/error.hpp>
14  
#include <boost/url/grammar/hexdig_chars.hpp>
14  
#include <boost/url/grammar/hexdig_chars.hpp>
15  

15  

16  
namespace boost {
16  
namespace boost {
17  
namespace urls {
17  
namespace urls {
18  

18  

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

72  

73  
} // urls
73  
} // urls
74  
} // boost
74  
} // boost
75  

75