Line data Source code
1 : //
2 : // Copyright (c) 2019 Vinnie Falco (vinnie.falco@gmail.com)
3 : // Copyright (c) 2022 Alan de Freitas (alandefreitas@gmail.com)
4 : //
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)
7 : //
8 : // Official repository: https://github.com/boostorg/url
9 : //
10 :
11 :
12 : #include <boost/url/detail/config.hpp>
13 : #include <boost/url/decode_view.hpp>
14 : #include <boost/url/params_ref.hpp>
15 : #include <boost/url/params_view.hpp>
16 : #include <boost/url/url_base.hpp>
17 : #include <boost/url/grammar/ci_string.hpp>
18 : #include <boost/assert.hpp>
19 : #include <utility>
20 :
21 : namespace boost {
22 : namespace urls {
23 :
24 : //------------------------------------------------
25 : //
26 : // Special Members
27 : //
28 : //------------------------------------------------
29 :
30 : auto
31 1 : params_ref::
32 : operator=(params_ref const& other) ->
33 : params_ref&
34 : {
35 1 : if (!ref_.alias_of(other.ref_))
36 1 : assign(other.begin(), other.end());
37 1 : return *this;
38 : }
39 :
40 63 : params_ref::
41 : operator
42 : params_view() const noexcept
43 : {
44 63 : return { ref_, opt_ };
45 : }
46 :
47 : //------------------------------------------------
48 : //
49 : // Modifiers
50 : //
51 : //------------------------------------------------
52 :
53 : void
54 5 : params_ref::
55 : assign(
56 : std::initializer_list<
57 : param_view> init)
58 : {
59 5 : assign(init.begin(), init.end());
60 5 : }
61 :
62 : auto
63 11 : params_ref::
64 : insert(
65 : iterator before,
66 : param_view const& p) ->
67 : iterator
68 : {
69 : return iterator(
70 11 : u_->edit_params(
71 : before.it_,
72 : before.it_,
73 22 : detail::param_iter(p)),
74 22 : opt_);
75 : }
76 :
77 : auto
78 15 : params_ref::
79 : insert(
80 : iterator before,
81 : std::initializer_list<
82 : param_view> init) ->
83 : iterator
84 : {
85 15 : return insert(
86 : before,
87 : init.begin(),
88 15 : init.end());
89 : }
90 :
91 : std::size_t
92 2 : params_ref::
93 : erase(
94 : core::string_view key,
95 : ignore_case_param ic) noexcept
96 : {
97 : // end() can't be fully cached,
98 : // since erase invalidates it.
99 2 : iterator it;
100 : {
101 2 : auto const end_ = end();
102 2 : it = find_last(end_, key, ic);
103 2 : if(it == end_)
104 0 : return 0;
105 : }
106 2 : std::size_t n = 0;
107 : for(;;)
108 : {
109 5 : ++n;
110 : // Use it->key instead of key,
111 : // to handle self-intersection
112 5 : auto prev = find_last(it, (*it).key, ic);
113 5 : if(prev == end())
114 2 : break;
115 3 : erase(it);
116 3 : it = prev;
117 3 : }
118 2 : erase(it);
119 2 : return n;
120 : }
121 :
122 : auto
123 6 : params_ref::
124 : replace(
125 : iterator pos,
126 : param_view const& p) ->
127 : iterator
128 : {
129 : return iterator(
130 6 : u_->edit_params(
131 : pos.it_,
132 6 : std::next(pos).it_,
133 12 : detail::param_iter(p)),
134 12 : opt_);
135 : }
136 :
137 : auto
138 2 : params_ref::
139 : replace(
140 : iterator from,
141 : iterator to,
142 : std::initializer_list<
143 : param_view> init) ->
144 : iterator
145 : {
146 2 : return replace(
147 : from,
148 : to,
149 : init.begin(),
150 2 : init.end());
151 : }
152 :
153 : auto
154 4 : params_ref::
155 : unset(
156 : iterator pos) noexcept ->
157 : iterator
158 : {
159 4 : BOOST_ASSERT(pos.it_.nk > 0);
160 4 : core::string_view s;
161 : return iterator(
162 4 : u_->edit_params(
163 : pos.it_,
164 4 : pos.it_.next(),
165 4 : detail::param_value_iter(
166 4 : pos.it_.nk - 1, s, false)),
167 4 : opt_);
168 : }
169 :
170 : auto
171 5 : params_ref::
172 : set(
173 : iterator pos,
174 : core::string_view value) ->
175 : iterator
176 : {
177 5 : BOOST_ASSERT(pos.it_.nk > 0);
178 : return iterator(
179 5 : u_->edit_params(
180 : pos.it_,
181 5 : pos.it_.next(),
182 5 : detail::param_value_iter(
183 5 : pos.it_.nk - 1, value, true)),
184 10 : opt_);
185 : }
186 :
187 : auto
188 1 : params_ref::
189 : set(
190 : core::string_view key,
191 : core::string_view value,
192 : ignore_case_param ic) ->
193 : iterator
194 : {
195 : // VFALCO we can't cache end() here
196 : // because it is invalidated
197 : // every time we set or erase.
198 1 : auto it0 = find(key, ic);
199 1 : if(it0 == end())
200 0 : return append({key, value});
201 1 : it0 = set(it0, value);
202 1 : auto it = end();
203 : for(;;)
204 : {
205 2 : it = find_last(it, key, ic);
206 2 : if(it == it0)
207 1 : return it0;
208 1 : it = erase(it);
209 : }
210 : }
211 :
212 : auto
213 9 : params_ref::
214 : erase(
215 : iterator pos) noexcept ->
216 : iterator
217 : {
218 9 : return erase(
219 : pos,
220 9 : std::next(pos));
221 : }
222 :
223 : auto
224 11 : params_ref::
225 : erase(
226 : iterator first,
227 : iterator last) noexcept ->
228 : iterator
229 : {
230 11 : core::string_view s("", 0);
231 : return iterator(
232 11 : u_->edit_params(
233 : first.it_,
234 : last.it_,
235 22 : detail::query_iter(s)),
236 11 : opt_);
237 : }
238 :
239 : } // urls
240 : } // boost
241 :
|