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_ref.hpp>
14  
#include <boost/url/params_ref.hpp>
15  
#include <boost/url/params_view.hpp>
15  
#include <boost/url/params_view.hpp>
16  
#include <boost/url/url_base.hpp>
16  
#include <boost/url/url_base.hpp>
17  
#include <boost/url/grammar/ci_string.hpp>
17  
#include <boost/url/grammar/ci_string.hpp>
18  
#include <boost/assert.hpp>
18  
#include <boost/assert.hpp>
19  
#include <utility>
19  
#include <utility>
20  

20  

21  
namespace boost {
21  
namespace boost {
22  
namespace urls {
22  
namespace urls {
23  

23  

24  
//------------------------------------------------
24  
//------------------------------------------------
25  
//
25  
//
26  
// Special Members
26  
// Special Members
27  
//
27  
//
28  
//------------------------------------------------
28  
//------------------------------------------------
29  

29  

 
30 +
params_ref::
 
31 +
params_ref(
 
32 +
    url_base& u,
 
33 +
    encoding_opts opt) noexcept
 
34 +
    : params_base(u.impl_, opt)
 
35 +
    , u_(&u)
 
36 +
{
 
37 +
}
 
38 +

 
39 +
params_ref::
 
40 +
params_ref(
 
41 +
    params_ref const& other,
 
42 +
    encoding_opts opt) noexcept
 
43 +
    : params_base(other.u_->impl_, opt)
 
44 +
    , u_(other.u_)
 
45 +
{
 
46 +
}
 
47 +

30  
auto
48  
auto
31  
params_ref::
49  
params_ref::
32  
operator=(params_ref const& other) ->
50  
operator=(params_ref const& other) ->
33  
    params_ref&
51  
    params_ref&
34  
{
52  
{
35  
    if (!ref_.alias_of(other.ref_))
53  
    if (!ref_.alias_of(other.ref_))
36  
        assign(other.begin(), other.end());
54  
        assign(other.begin(), other.end());
37  
    return *this;
55  
    return *this;
38  
}
56  
}
39  

57  

 
58 +
auto
 
59 +
params_ref::
 
60 +
operator=(std::initializer_list<
 
61 +
    param_view> init) ->
 
62 +
        params_ref&
 
63 +
{
 
64 +
    assign(init);
 
65 +
    return *this;
 
66 +
}
 
67 +

40  
params_ref::
68  
params_ref::
41  
operator
69  
operator
42  
params_view() const noexcept
70  
params_view() const noexcept
43  
{
71  
{
44  
    return { ref_, opt_ };
72  
    return { ref_, opt_ };
45  
}
73  
}
46  

74  

47  
//------------------------------------------------
75  
//------------------------------------------------
48  
//
76  
//
49  
// Modifiers
77  
// Modifiers
50  
//
78  
//
51  
//------------------------------------------------
79  
//------------------------------------------------
52  

80  

53  
void
81  
void
54  
params_ref::
82  
params_ref::
 
83 +
clear() noexcept
 
84 +
{
 
85 +
    u_->remove_query();
 
86 +
}
 
87 +

 
88 +
void
 
89 +
params_ref::
55  
assign(
90  
assign(
56  
    std::initializer_list<
91  
    std::initializer_list<
57  
        param_view> init)
92  
        param_view> init)
58  
{
93  
{
59  
    assign(init.begin(), init.end());
94  
    assign(init.begin(), init.end());
60  
}
95  
}
61  

96  

62  
auto
97  
auto
63  
params_ref::
98  
params_ref::
64  
insert(
99  
insert(
65  
    iterator before,
100  
    iterator before,
66  
    param_view const& p) ->
101  
    param_view const& p) ->
67  
        iterator
102  
        iterator
68  
{
103  
{
69  
    return {
104  
    return {
70  
        u_->edit_params(
105  
        u_->edit_params(
71  
            before.it_,
106  
            before.it_,
72  
            before.it_,
107  
            before.it_,
73  
            detail::single_param_iter(p, opt_.space_as_plus)),
108  
            detail::single_param_iter(p, opt_.space_as_plus)),
74  
        opt_};
109  
        opt_};
75  
}
110  
}
76  

111  

77  
auto
112  
auto
78  
params_ref::
113  
params_ref::
79  
insert(
114  
insert(
80  
    iterator before,
115  
    iterator before,
81  
    std::initializer_list<
116  
    std::initializer_list<
82  
        param_view> init) ->
117  
        param_view> init) ->
83  
    iterator
118  
    iterator
84  
{
119  
{
85  
    return insert(
120  
    return insert(
86  
        before,
121  
        before,
87  
        init.begin(),
122  
        init.begin(),
88  
        init.end());
123  
        init.end());
89  
}
124  
}
90  

125  

 
126 +
auto
 
127 +
params_ref::
 
128 +
append(
 
129 +
    param_view const& p) ->
 
130 +
        iterator
 
131 +
{
 
132 +
    return insert(end(), p);
 
133 +
}
 
134 +

 
135 +
auto
 
136 +
params_ref::
 
137 +
append(
 
138 +
    std::initializer_list<
 
139 +
        param_view> init) ->
 
140 +
    iterator
 
141 +
{
 
142 +
    return insert(end(), init);
 
143 +
}
 
144 +

91  
std::size_t
145  
std::size_t
92  
params_ref::
146  
params_ref::
93  
erase(
147  
erase(
94  
    core::string_view key,
148  
    core::string_view key,
95  
    ignore_case_param ic) noexcept
149  
    ignore_case_param ic) noexcept
96  
{
150  
{
97  
    // end() can't be fully cached,
151  
    // end() can't be fully cached,
98  
    // since erase invalidates it.
152  
    // since erase invalidates it.
99  
    iterator it;
153  
    iterator it;
100  
    {
154  
    {
101  
        auto const end_ = end();
155  
        auto const end_ = end();
102  
        it = find_last(end_, key, ic);
156  
        it = find_last(end_, key, ic);
103  
        if(it == end_)
157  
        if(it == end_)
104  
            return 0;
158  
            return 0;
105  
    }
159  
    }
106  
    std::size_t n = 0;
160  
    std::size_t n = 0;
107  
    for(;;)
161  
    for(;;)
108  
    {
162  
    {
109  
        ++n;
163  
        ++n;
110  
        // Use it->key instead of key,
164  
        // Use it->key instead of key,
111  
        // to handle self-intersection
165  
        // to handle self-intersection
112  
        auto prev = find_last(it, (*it).key, ic);
166  
        auto prev = find_last(it, (*it).key, ic);
113  
        if(prev == end())
167  
        if(prev == end())
114  
            break;
168  
            break;
115  
        erase(it);
169  
        erase(it);
116  
        it = prev;
170  
        it = prev;
117  
    }
171  
    }
118  
    erase(it);
172  
    erase(it);
119  
    return n;
173  
    return n;
120  
}
174  
}
121  

175  

122  
auto
176  
auto
123  
params_ref::
177  
params_ref::
124  
replace(
178  
replace(
125  
    iterator pos,
179  
    iterator pos,
126  
    param_view const& p) ->
180  
    param_view const& p) ->
127  
        iterator
181  
        iterator
128  
{
182  
{
129  
    return iterator(
183  
    return iterator(
130  
        u_->edit_params(
184  
        u_->edit_params(
131  
            pos.it_,
185  
            pos.it_,
132  
            std::next(pos).it_,
186  
            std::next(pos).it_,
133  
            detail::single_param_iter(p, opt_.space_as_plus)),
187  
            detail::single_param_iter(p, opt_.space_as_plus)),
134  
        opt_);
188  
        opt_);
135  
}
189  
}
136  

190  

137  
auto
191  
auto
138  
params_ref::
192  
params_ref::
139  
replace(
193  
replace(
140  
    iterator from,
194  
    iterator from,
141  
    iterator to,
195  
    iterator to,
142  
    std::initializer_list<
196  
    std::initializer_list<
143  
        param_view> init) ->
197  
        param_view> init) ->
144  
    iterator
198  
    iterator
145  
{
199  
{
146  
    return replace(
200  
    return replace(
147  
        from,
201  
        from,
148  
        to,
202  
        to,
149  
        init.begin(),
203  
        init.begin(),
150  
        init.end());
204  
        init.end());
151  
}
205  
}
152  

206  

153  
auto
207  
auto
154  
params_ref::
208  
params_ref::
155  
unset(
209  
unset(
156  
    iterator pos) noexcept ->
210  
    iterator pos) noexcept ->
157  
        iterator
211  
        iterator
158  
{
212  
{
159  
    BOOST_ASSERT(pos.it_.nk > 0);
213  
    BOOST_ASSERT(pos.it_.nk > 0);
160  
    core::string_view s;
214  
    core::string_view s;
161  
    return iterator(
215  
    return iterator(
162  
        u_->edit_params(
216  
        u_->edit_params(
163  
            pos.it_,
217  
            pos.it_,
164  
            pos.it_.next(),
218  
            pos.it_.next(),
165  
            detail::param_value_iter(
219  
            detail::param_value_iter(
166  
                pos.it_.nk - 1, s, false)),
220  
                pos.it_.nk - 1, s, false)),
167  
        opt_);
221  
        opt_);
168  
}
222  
}
169  

223  

170  
auto
224  
auto
171  
params_ref::
225  
params_ref::
172  
set(
226  
set(
173  
    iterator pos,
227  
    iterator pos,
174  
    core::string_view value) ->
228  
    core::string_view value) ->
175  
        iterator
229  
        iterator
176  
{
230  
{
177  
    BOOST_ASSERT(pos.it_.nk > 0);
231  
    BOOST_ASSERT(pos.it_.nk > 0);
178  
    return iterator(
232  
    return iterator(
179  
        u_->edit_params(
233  
        u_->edit_params(
180  
            pos.it_,
234  
            pos.it_,
181  
            pos.it_.next(),
235  
            pos.it_.next(),
182  
            detail::param_value_iter(
236  
            detail::param_value_iter(
183  
                pos.it_.nk - 1, value, true)),
237  
                pos.it_.nk - 1, value, true)),
184  
        opt_);
238  
        opt_);
185  
}
239  
}
186  

240  

187  
auto
241  
auto
188  
params_ref::
242  
params_ref::
189  
set(
243  
set(
190  
    core::string_view key,
244  
    core::string_view key,
191  
    core::string_view value,
245  
    core::string_view value,
192  
    ignore_case_param ic) ->
246  
    ignore_case_param ic) ->
193  
        iterator
247  
        iterator
194  
{
248  
{
195  
    // VFALCO we can't cache end() here
249  
    // VFALCO we can't cache end() here
196  
    // because it is invalidated
250  
    // because it is invalidated
197  
    // every time we set or erase.
251  
    // every time we set or erase.
198  
    auto it0 = find(key, ic);
252  
    auto it0 = find(key, ic);
199  
    if(it0 == end())
253  
    if(it0 == end())
200  
        return append({key, value});
254  
        return append({key, value});
201  
    it0 = set(it0, value);
255  
    it0 = set(it0, value);
202  
    auto it = end();
256  
    auto it = end();
203  
    for(;;)
257  
    for(;;)
204  
    {
258  
    {
205  
        it = find_last(it, key, ic);
259  
        it = find_last(it, key, ic);
206  
        if(it == it0)
260  
        if(it == it0)
207  
            return it0;
261  
            return it0;
208  
        it = erase(it);
262  
        it = erase(it);
209  
    }
263  
    }
210  
}
264  
}
211  

265  

212  
auto
266  
auto
213  
params_ref::
267  
params_ref::
214  
erase(
268  
erase(
215  
    iterator pos) noexcept ->
269  
    iterator pos) noexcept ->
216  
    iterator
270  
    iterator
217  
{
271  
{
218  
    return erase(
272  
    return erase(
219  
        pos,
273  
        pos,
220  
        std::next(pos));
274  
        std::next(pos));
221  
}
275  
}
222  

276  

223  
auto
277  
auto
224  
params_ref::
278  
params_ref::
225  
erase(
279  
erase(
226  
    iterator first,
280  
    iterator first,
227  
    iterator last) noexcept ->
281  
    iterator last) noexcept ->
228  
        iterator
282  
        iterator
229  
{
283  
{
230  
    core::string_view s("", 0);
284  
    core::string_view s("", 0);
231  
    return iterator(
285  
    return iterator(
232  
        u_->edit_params(
286  
        u_->edit_params(
233  
            first.it_,
287  
            first.it_,
234  
            last.it_,
288  
            last.it_,
235  
            detail::query_string_iter(s)),
289  
            detail::query_string_iter(s)),
236  
        opt_);
290  
        opt_);
237  
}
291  
}
238  

292  

239  
} // urls
293  
} // urls
240 -

 
241  
} // boost
294  
} // boost