1  
//
1  
//
2  
// Copyright (c) 2019 Vinnie Falco (vinnie.falco@gmail.com)
2  
// Copyright (c) 2019 Vinnie Falco (vinnie.falco@gmail.com)
3  
// Copyright (c) 2022 Alan de Freitas (alandefreitas@gmail.com)
3  
// Copyright (c) 2022 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  

11  

12  
#include <boost/url/detail/config.hpp>
12  
#include <boost/url/detail/config.hpp>
13  
#include <boost/url/decode_view.hpp>
13  
#include <boost/url/decode_view.hpp>
14  
#include <boost/url/params_encoded_base.hpp>
14  
#include <boost/url/params_encoded_base.hpp>
15  
#include <boost/url/grammar/ci_string.hpp>
15  
#include <boost/url/grammar/ci_string.hpp>
16  
#include <ostream>
16  
#include <ostream>
17  

17  

18  
namespace boost {
18  
namespace boost {
19  
namespace urls {
19  
namespace urls {
20  

20  

21  
params_encoded_base::
21  
params_encoded_base::
22  
iterator::
22  
iterator::
23  
iterator(
23  
iterator(
24  
    detail::query_ref const& ref) noexcept
24  
    detail::query_ref const& ref) noexcept
25  
    : it_(ref)
25  
    : it_(ref)
26  
{
26  
{
27  
}
27  
}
28  

28  

29  
params_encoded_base::
29  
params_encoded_base::
30  
iterator::
30  
iterator::
31  
iterator(
31  
iterator(
32  
    detail::query_ref const& ref, int) noexcept
32  
    detail::query_ref const& ref, int) noexcept
33  
    : it_(ref, 0)
33  
    : it_(ref, 0)
34  
{
34  
{
35  
}
35  
}
36  

36  

37  
//------------------------------------------------
37  
//------------------------------------------------
38  
//
38  
//
39  
// params_encoded_base
39  
// params_encoded_base
40  
//
40  
//
41  
//------------------------------------------------
41  
//------------------------------------------------
42  

42  

43  
params_encoded_base::
43  
params_encoded_base::
44  
params_encoded_base(
44  
params_encoded_base(
45  
    detail::query_ref const& ref) noexcept
45  
    detail::query_ref const& ref) noexcept
46  
    : ref_(ref)
46  
    : ref_(ref)
47  
{
47  
{
48  
}
48  
}
49  

49  

50  
//------------------------------------------------
50  
//------------------------------------------------
51  
//
51  
//
52  
// Observers
52  
// Observers
53  
//
53  
//
54  
//------------------------------------------------
54  
//------------------------------------------------
55  

55  

56  
pct_string_view
56  
pct_string_view
57  
params_encoded_base::
57  
params_encoded_base::
58  
buffer() const noexcept
58  
buffer() const noexcept
59  
{
59  
{
60  
    return ref_.buffer();
60  
    return ref_.buffer();
61  
}
61  
}
62  

62  

63  
bool
63  
bool
64  
params_encoded_base::
64  
params_encoded_base::
65  
empty() const noexcept
65  
empty() const noexcept
66  
{
66  
{
67  
    return ref_.nparam() == 0;
67  
    return ref_.nparam() == 0;
68  
}
68  
}
69  

69  

70  
std::size_t
70  
std::size_t
71  
params_encoded_base::
71  
params_encoded_base::
72  
size() const noexcept
72  
size() const noexcept
73  
{
73  
{
74  
    return ref_.nparam();
74  
    return ref_.nparam();
75  
}
75  
}
76  

76  

77  
auto
77  
auto
78  
params_encoded_base::
78  
params_encoded_base::
79  
begin() const noexcept ->
79  
begin() const noexcept ->
80  
    iterator
80  
    iterator
81  
{
81  
{
82  
    return { ref_ };
82  
    return { ref_ };
83  
}
83  
}
84  

84  

85  
auto
85  
auto
86  
params_encoded_base::
86  
params_encoded_base::
87  
end() const noexcept ->
87  
end() const noexcept ->
88  
    iterator
88  
    iterator
89  
{
89  
{
90  
    return { ref_, 0 };
90  
    return { ref_, 0 };
91  
}
91  
}
92  

92  

93  
//------------------------------------------------
93  
//------------------------------------------------
94  

94  

95  
std::size_t
95  
std::size_t
96  
params_encoded_base::
96  
params_encoded_base::
97  
count(
97  
count(
98  
    pct_string_view key,
98  
    pct_string_view key,
99  
    ignore_case_param ic) const noexcept
99  
    ignore_case_param ic) const noexcept
100  
{
100  
{
101  
    std::size_t n = 0;
101  
    std::size_t n = 0;
102  
    auto it = find(key, ic);
102  
    auto it = find(key, ic);
103  
    auto const end_ = end();
103  
    auto const end_ = end();
104  
    while(it != end_)
104  
    while(it != end_)
105  
    {
105  
    {
106  
        ++n;
106  
        ++n;
107  
        ++it;
107  
        ++it;
108  
        it = find(it, key, ic);
108  
        it = find(it, key, ic);
109  
    }
109  
    }
110  
    return n;
110  
    return n;
111  
}
111  
}
112  

112  

113  
//------------------------------------------------
113  
//------------------------------------------------
114  
//
114  
//
115  
// (implementation)
115  
// (implementation)
116  
//
116  
//
117  
//------------------------------------------------
117  
//------------------------------------------------
118  

118  

119  
detail::params_iter_impl
119  
detail::params_iter_impl
120  
params_encoded_base::
120  
params_encoded_base::
121  
find_impl(
121  
find_impl(
122  
    detail::params_iter_impl it,
122  
    detail::params_iter_impl it,
123  
    pct_string_view key,
123  
    pct_string_view key,
124  
    ignore_case_param ic) const noexcept
124  
    ignore_case_param ic) const noexcept
125  
{
125  
{
126  
    detail::params_iter_impl end_(ref_, 0);
126  
    detail::params_iter_impl end_(ref_, 0);
127  
    if(! ic)
127  
    if(! ic)
128  
    {
128  
    {
129  
        for(;;)
129  
        for(;;)
130  
        {
130  
        {
131  
            if(it.equal(end_))
131  
            if(it.equal(end_))
132  
                return it;
132  
                return it;
133  
            if(*it.key() == *key)
133  
            if(*it.key() == *key)
134  
                return it;
134  
                return it;
135  
            it.increment();
135  
            it.increment();
136  
        }
136  
        }
137  
    }
137  
    }
138  
    for(;;)
138  
    for(;;)
139  
    {
139  
    {
140  
        if(it.equal(end_))
140  
        if(it.equal(end_))
141  
            return it;
141  
            return it;
142  
        if( grammar::ci_is_equal(
142  
        if( grammar::ci_is_equal(
143  
                *it.key(), *key))
143  
                *it.key(), *key))
144  
            return it;
144  
            return it;
145  
        it.increment();
145  
        it.increment();
146  
    }
146  
    }
147  
}
147  
}
148  

148  

149  
detail::params_iter_impl
149  
detail::params_iter_impl
150  
params_encoded_base::
150  
params_encoded_base::
151  
find_last_impl(
151  
find_last_impl(
152  
    detail::params_iter_impl it,
152  
    detail::params_iter_impl it,
153  
    pct_string_view key,
153  
    pct_string_view key,
154  
    ignore_case_param ic) const noexcept
154  
    ignore_case_param ic) const noexcept
155  
{
155  
{
156  
    detail::params_iter_impl begin_(ref_);
156  
    detail::params_iter_impl begin_(ref_);
157  
    if(! ic)
157  
    if(! ic)
158  
    {
158  
    {
159  
        for(;;)
159  
        for(;;)
160  
        {
160  
        {
161  
            if(it.equal(begin_))
161  
            if(it.equal(begin_))
162  
                return { ref_, 0 };
162  
                return { ref_, 0 };
163  
            it.decrement();
163  
            it.decrement();
164  
            if(*it.key() == *key)
164  
            if(*it.key() == *key)
165  
                return it;
165  
                return it;
166  
        }
166  
        }
167  
    }
167  
    }
168  
    for(;;)
168  
    for(;;)
169  
    {
169  
    {
170  
        if(it.equal(begin_))
170  
        if(it.equal(begin_))
171  
            return { ref_, 0 };
171  
            return { ref_, 0 };
172  
        it.decrement();
172  
        it.decrement();
173  
        if(grammar::ci_is_equal(
173  
        if(grammar::ci_is_equal(
174  
                *it.key(), *key))
174  
                *it.key(), *key))
175  
            return it;
175  
            return it;
176  
    }
176  
    }
177  
}
177  
}
178  

178  

179  
//------------------------------------------------
179  
//------------------------------------------------
180  

180  

181  
std::ostream&
181  
std::ostream&
182  
operator<<(
182  
operator<<(
183  
    std::ostream& os,
183  
    std::ostream& os,
184  
    params_encoded_base const& qp)
184  
    params_encoded_base const& qp)
185  
{
185  
{
186  
    os << qp.buffer();
186  
    os << qp.buffer();
187  
    return os;
187  
    return os;
188  
}
188  
}
189  

189  

190  
} // urls
190  
} // urls
191  
} // boost
191  
} // boost
192  

192