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) 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_DETAIL_IMPL_ANY_PARAMS_ITER_HPP
11  
#ifndef BOOST_URL_DETAIL_IMPL_ANY_PARAMS_ITER_HPP
12  
#define BOOST_URL_DETAIL_IMPL_ANY_PARAMS_ITER_HPP
12  
#define BOOST_URL_DETAIL_IMPL_ANY_PARAMS_ITER_HPP
13  

13  

14  
#include <boost/url/encode.hpp>
14  
#include <boost/url/encode.hpp>
15  
#include <boost/url/rfc/detail/charsets.hpp>
15  
#include <boost/url/rfc/detail/charsets.hpp>
16  
#include <boost/assert.hpp>
16  
#include <boost/assert.hpp>
17  

17  

18  
namespace boost {
18  
namespace boost {
19  
namespace urls {
19  
namespace urls {
20  
namespace detail {
20  
namespace detail {
21  

21  

22  
/*
22  
/*
23  
    When a string is transformed into a range of
23  
    When a string is transformed into a range of
24  
    params, the empty string becomes ambiguous:
24  
    params, the empty string becomes ambiguous:
25  
    it can be an empty range, or a range with
25  
    it can be an empty range, or a range with
26  
    one param. The value `not_empty` is used on
26  
    one param. The value `not_empty` is used on
27  
    construction to inform the transformation
27  
    construction to inform the transformation
28  
    that the empty string should be treated as
28  
    that the empty string should be treated as
29  
    a one-element range. This simplifies
29  
    a one-element range. This simplifies
30  
    edit_params().
30  
    edit_params().
31  
*/
31  
*/
32  

32  

33  
//------------------------------------------------
33  
//------------------------------------------------
34  
//
34  
//
35  
// any_params_iter
35  
// any_params_iter
36  
//
36  
//
37  
//------------------------------------------------
37  
//------------------------------------------------
38  

38  

39  
inline
39  
inline
40  
any_params_iter::
40  
any_params_iter::
41  
~any_params_iter() noexcept = default;
41  
~any_params_iter() noexcept = default;
42  

42  

43  
//------------------------------------------------
43  
//------------------------------------------------
44  
//
44  
//
45  
// query_iter
45  
// query_iter
46  
//
46  
//
47  
//------------------------------------------------
47  
//------------------------------------------------
48  

48  

49  
inline
49  
inline
50  
query_string_iter::
50  
query_string_iter::
51  
query_string_iter(
51  
query_string_iter(
52  
    core::string_view s,
52  
    core::string_view s,
53  
    bool ne) noexcept
53  
    bool ne) noexcept
54  
    : any_params_iter(
54  
    : any_params_iter(
55  
        s.empty() && ! ne, s)
55  
        s.empty() && ! ne, s)
56  
{
56  
{
57  
    rewind();
57  
    rewind();
58  
}
58  
}
59  

59  

60  
inline
60  
inline
61  
void
61  
void
62  
query_string_iter::
62  
query_string_iter::
63  
rewind() noexcept
63  
rewind() noexcept
64  
{
64  
{
65  
    if(empty)
65  
    if(empty)
66  
    {
66  
    {
67  
        at_end_ = true;
67  
        at_end_ = true;
68  
        return;
68  
        return;
69  
    }
69  
    }
70  
    p_ = s0.begin();
70  
    p_ = s0.begin();
71  
    if(! s0.empty())
71  
    if(! s0.empty())
72  
    {
72  
    {
73  
        auto pos =
73  
        auto pos =
74  
            s0.find_first_of('&');
74  
            s0.find_first_of('&');
75  
        if(pos != core::string_view::npos)
75  
        if(pos != core::string_view::npos)
76  
            n_ = pos;
76  
            n_ = pos;
77  
        else
77  
        else
78  
            n_ = s0.size();
78  
            n_ = s0.size();
79  
    }
79  
    }
80  
    else
80  
    else
81  
    {
81  
    {
82  
        n_ = 0;
82  
        n_ = 0;
83  
    }
83  
    }
84  
    at_end_ = false;
84  
    at_end_ = false;
85  
}
85  
}
86  

86  

87  
inline
87  
inline
88  
bool
88  
bool
89  
query_string_iter::
89  
query_string_iter::
90  
measure(
90  
measure(
91  
    std::size_t& n) noexcept
91  
    std::size_t& n) noexcept
92  
{
92  
{
93  
    if(at_end_)
93  
    if(at_end_)
94  
        return false;
94  
        return false;
95  
    // When interacting with the query as
95  
    // When interacting with the query as
96  
    // an intact string, we do not treat
96  
    // an intact string, we do not treat
97  
    // the plus sign as an encoded space.
97  
    // the plus sign as an encoded space.
98  
    encoding_opts opt;
98  
    encoding_opts opt;
99  
    opt.space_as_plus = false;
99  
    opt.space_as_plus = false;
100  
    n += encoded_size(
100  
    n += encoded_size(
101  
        core::string_view(p_, n_),
101  
        core::string_view(p_, n_),
102  
        query_chars,
102  
        query_chars,
103  
        opt);
103  
        opt);
104  
    increment();
104  
    increment();
105  
    return true;
105  
    return true;
106  
}
106  
}
107  

107  

108  
inline
108  
inline
109  
void
109  
void
110  
query_string_iter::
110  
query_string_iter::
111  
copy(
111  
copy(
112  
    char*& dest,
112  
    char*& dest,
113  
    char const* end) noexcept
113  
    char const* end) noexcept
114  
{
114  
{
115  
    BOOST_ASSERT(! at_end_);
115  
    BOOST_ASSERT(! at_end_);
116  
    // When interacting with the query as
116  
    // When interacting with the query as
117  
    // an intact string, we do not treat
117  
    // an intact string, we do not treat
118  
    // the plus sign as an encoded space.
118  
    // the plus sign as an encoded space.
119  
    encoding_opts opt;
119  
    encoding_opts opt;
120  
    opt.space_as_plus = false;
120  
    opt.space_as_plus = false;
121  
    dest += encode_unsafe(
121  
    dest += encode_unsafe(
122  
        dest,
122  
        dest,
123  
        end - dest,
123  
        end - dest,
124  
        core::string_view(p_, n_),
124  
        core::string_view(p_, n_),
125  
        query_chars,
125  
        query_chars,
126  
        opt);
126  
        opt);
127  
    increment();
127  
    increment();
128  
}
128  
}
129  

129  

130  
inline
130  
inline
131  
void
131  
void
132  
query_string_iter::
132  
query_string_iter::
133  
increment() noexcept
133  
increment() noexcept
134  
{
134  
{
135  
    p_ += n_;
135  
    p_ += n_;
136  
    if(p_ == s0.end())
136  
    if(p_ == s0.end())
137  
    {
137  
    {
138  
        at_end_ = true;
138  
        at_end_ = true;
139  
        return;
139  
        return;
140  
    }
140  
    }
141  
    ++p_;
141  
    ++p_;
142  
    core::string_view s(p_, s0.end() - p_);
142  
    core::string_view s(p_, s0.end() - p_);
143  
    auto pos = s.find_first_of('&');
143  
    auto pos = s.find_first_of('&');
144  
    if(pos != core::string_view::npos)
144  
    if(pos != core::string_view::npos)
145  
        n_ = pos;
145  
        n_ = pos;
146  
    else
146  
    else
147  
        n_ = s.size();
147  
        n_ = s.size();
148  
}
148  
}
149  

149  

150  
//------------------------------------------------
150  
//------------------------------------------------
151  
//
151  
//
152  
// param_iter
152  
// param_iter
153  
//
153  
//
154  
//------------------------------------------------
154  
//------------------------------------------------
155  

155  

156  
inline
156  
inline
157  
single_param_iter::
157  
single_param_iter::
158  
single_param_iter(
158  
single_param_iter(
159  
    param_view const& p,
159  
    param_view const& p,
160  
    bool space_as_plus) noexcept
160  
    bool space_as_plus) noexcept
161  
    : any_params_iter(
161  
    : any_params_iter(
162  
        false,
162  
        false,
163  
        p.key,
163  
        p.key,
164  
        p.value)
164  
        p.value)
165  
    , has_value_(p.has_value)
165  
    , has_value_(p.has_value)
166  
    , space_as_plus_(space_as_plus)
166  
    , space_as_plus_(space_as_plus)
167  
{
167  
{
168  
}
168  
}
169  

169  

170  
inline
170  
inline
171  
void
171  
void
172  
single_param_iter::
172  
single_param_iter::
173  
rewind() noexcept
173  
rewind() noexcept
174  
{
174  
{
175  
    at_end_ = false;
175  
    at_end_ = false;
176  
}
176  
}
177  

177  

178  
inline
178  
inline
179  
bool
179  
bool
180  
single_param_iter::
180  
single_param_iter::
181  
measure(std::size_t& n) noexcept
181  
measure(std::size_t& n) noexcept
182  
{
182  
{
183  
    if(at_end_)
183  
    if(at_end_)
184  
        return false;
184  
        return false;
185  
    encoding_opts opt;
185  
    encoding_opts opt;
186  
    opt.space_as_plus = space_as_plus_;
186  
    opt.space_as_plus = space_as_plus_;
187  
    n += encoded_size(
187  
    n += encoded_size(
188  
        s0,
188  
        s0,
189  
        detail::param_key_chars,
189  
        detail::param_key_chars,
190  
        opt);
190  
        opt);
191  
    if(has_value_)
191  
    if(has_value_)
192  
    {
192  
    {
193  
        ++n; // '='
193  
        ++n; // '='
194  
        n += encoded_size(
194  
        n += encoded_size(
195  
            s1,
195  
            s1,
196  
            detail::param_value_chars,
196  
            detail::param_value_chars,
197  
            opt);
197  
            opt);
198  
    }
198  
    }
199  
    at_end_ = true;
199  
    at_end_ = true;
200  
    return true;
200  
    return true;
201  
}
201  
}
202  

202  

203  
inline
203  
inline
204  
void
204  
void
205  
single_param_iter::
205  
single_param_iter::
206  
copy(
206  
copy(
207  
    char*& dest,
207  
    char*& dest,
208  
    char const* end) noexcept
208  
    char const* end) noexcept
209  
{
209  
{
210  
    BOOST_ASSERT(! at_end_);
210  
    BOOST_ASSERT(! at_end_);
211  
    encoding_opts opt;
211  
    encoding_opts opt;
212  
    opt.space_as_plus = space_as_plus_;
212  
    opt.space_as_plus = space_as_plus_;
213  
    dest += encode(
213  
    dest += encode(
214  
        dest,
214  
        dest,
215  
        end - dest,
215  
        end - dest,
216  
        s0,
216  
        s0,
217  
        detail::param_key_chars,
217  
        detail::param_key_chars,
218  
        opt);
218  
        opt);
219  
    if (has_value_)
219  
    if (has_value_)
220  
    {
220  
    {
221  
        *dest++ = '=';
221  
        *dest++ = '=';
222  
        dest += encode(
222  
        dest += encode(
223  
            dest,
223  
            dest,
224  
            end - dest,
224  
            end - dest,
225  
            s1,
225  
            s1,
226  
            detail::param_value_chars,
226  
            detail::param_value_chars,
227  
            opt);
227  
            opt);
228  
    }
228  
    }
229  
}
229  
}
230  

230  

231  
//------------------------------------------------
231  
//------------------------------------------------
232  
//
232  
//
233  
// params_iter_base
233  
// params_iter_base
234  
//
234  
//
235  
//------------------------------------------------
235  
//------------------------------------------------
236  

236  

237  
inline
237  
inline
238  
void
238  
void
239  
params_iter_base::
239  
params_iter_base::
240  
measure_impl(
240  
measure_impl(
241  
    std::size_t& n,
241  
    std::size_t& n,
242  
    param_view const& p) noexcept
242  
    param_view const& p) noexcept
243  
{
243  
{
244  
    encoding_opts opt;
244  
    encoding_opts opt;
245  
    opt.space_as_plus = space_as_plus_;
245  
    opt.space_as_plus = space_as_plus_;
246  
    n += encoded_size(
246  
    n += encoded_size(
247  
        p.key,
247  
        p.key,
248  
        detail::param_key_chars,
248  
        detail::param_key_chars,
249  
        opt);
249  
        opt);
250  
    if(p.has_value)
250  
    if(p.has_value)
251  
    {
251  
    {
252  
        ++n; // '='
252  
        ++n; // '='
253  
        n += encoded_size(
253  
        n += encoded_size(
254  
            p.value,
254  
            p.value,
255  
            detail::param_value_chars,
255  
            detail::param_value_chars,
256  
            opt);
256  
            opt);
257  
    }
257  
    }
258  
}
258  
}
259  

259  

260  
inline
260  
inline
261  
void
261  
void
262  
params_iter_base::
262  
params_iter_base::
263  
copy_impl(
263  
copy_impl(
264  
    char*& dest,
264  
    char*& dest,
265  
    char const* end,
265  
    char const* end,
266  
    param_view const& p) noexcept
266  
    param_view const& p) noexcept
267  
{
267  
{
268  
    encoding_opts opt;
268  
    encoding_opts opt;
269  
    opt.space_as_plus = space_as_plus_;
269  
    opt.space_as_plus = space_as_plus_;
270  
    dest += encode(
270  
    dest += encode(
271  
        dest,
271  
        dest,
272  
        end - dest,
272  
        end - dest,
273  
        p.key,
273  
        p.key,
274  
        detail::param_key_chars,
274  
        detail::param_key_chars,
275  
        opt);
275  
        opt);
276  
    if(p.has_value)
276  
    if(p.has_value)
277  
    {
277  
    {
278  
        *dest++ = '=';
278  
        *dest++ = '=';
279  
        dest += encode(
279  
        dest += encode(
280  
            dest,
280  
            dest,
281  
            end - dest,
281  
            end - dest,
282  
            p.value,
282  
            p.value,
283  
            detail::param_value_chars,
283  
            detail::param_value_chars,
284  
            opt);
284  
            opt);
285  
    }
285  
    }
286  
}
286  
}
287  

287  

288  
//------------------------------------------------
288  
//------------------------------------------------
289  
//
289  
//
290  
// param_encoded_iter
290  
// param_encoded_iter
291  
//
291  
//
292  
//------------------------------------------------
292  
//------------------------------------------------
293  

293  

294  
inline
294  
inline
295  
param_encoded_iter::
295  
param_encoded_iter::
296  
param_encoded_iter(
296  
param_encoded_iter(
297  
    param_pct_view const& p) noexcept
297  
    param_pct_view const& p) noexcept
298  
    : any_params_iter(
298  
    : any_params_iter(
299  
        false,
299  
        false,
300  
        p.key,
300  
        p.key,
301  
        p.value)
301  
        p.value)
302  
    , has_value_(p.has_value)
302  
    , has_value_(p.has_value)
303  
{
303  
{
304  
}
304  
}
305  

305  

306  
inline
306  
inline
307  
void
307  
void
308  
param_encoded_iter::
308  
param_encoded_iter::
309  
rewind() noexcept
309  
rewind() noexcept
310  
{
310  
{
311  
    at_end_ = false;
311  
    at_end_ = false;
312  
}
312  
}
313  

313  

314  
inline
314  
inline
315  
bool
315  
bool
316  
param_encoded_iter::
316  
param_encoded_iter::
317  
measure(std::size_t& n) noexcept
317  
measure(std::size_t& n) noexcept
318  
{
318  
{
319  
    if(at_end_)
319  
    if(at_end_)
320  
        return false;
320  
        return false;
321  
    n += detail::re_encoded_size_unsafe(
321  
    n += detail::re_encoded_size_unsafe(
322  
        s0,
322  
        s0,
323  
        detail::param_key_chars);
323  
        detail::param_key_chars);
324  
    if(has_value_)
324  
    if(has_value_)
325  
        n += detail::re_encoded_size_unsafe(
325  
        n += detail::re_encoded_size_unsafe(
326  
            s1,
326  
            s1,
327  
            detail::param_value_chars) + 1; // for '='
327  
            detail::param_value_chars) + 1; // for '='
328  
    at_end_ = true;
328  
    at_end_ = true;
329  
    return true;
329  
    return true;
330  
}
330  
}
331  

331  

332  
inline
332  
inline
333  
void
333  
void
334  
param_encoded_iter::
334  
param_encoded_iter::
335  
copy(
335  
copy(
336  
    char*& dest,
336  
    char*& dest,
337  
    char const* end) noexcept
337  
    char const* end) noexcept
338  
{
338  
{
339  
    detail::re_encode_unsafe(
339  
    detail::re_encode_unsafe(
340  
        dest,
340  
        dest,
341  
        end,
341  
        end,
342  
        s0,
342  
        s0,
343  
        detail::param_key_chars);
343  
        detail::param_key_chars);
344  
    if(has_value_)
344  
    if(has_value_)
345  
    {
345  
    {
346  
        *dest++ = '=';
346  
        *dest++ = '=';
347  
        detail::re_encode_unsafe(
347  
        detail::re_encode_unsafe(
348  
            dest,
348  
            dest,
349  
            end,
349  
            end,
350  
            s1,
350  
            s1,
351  
            detail::param_value_chars);
351  
            detail::param_value_chars);
352  
    }
352  
    }
353  
}
353  
}
354  

354  

355  

355  

356  
//------------------------------------------------
356  
//------------------------------------------------
357  
//
357  
//
358  
// params_encoded_iter_base
358  
// params_encoded_iter_base
359  
//
359  
//
360  
//------------------------------------------------
360  
//------------------------------------------------
361  

361  

362  
inline
362  
inline
363  
void
363  
void
364  
params_encoded_iter_base::
364  
params_encoded_iter_base::
365  
measure_impl(
365  
measure_impl(
366  
    std::size_t& n,
366  
    std::size_t& n,
367  
    param_view const& p) noexcept
367  
    param_view const& p) noexcept
368  
{
368  
{
369  
    n += detail::re_encoded_size_unsafe(
369  
    n += detail::re_encoded_size_unsafe(
370  
        p.key,
370  
        p.key,
371  
        detail::param_key_chars);
371  
        detail::param_key_chars);
372  
    if(p.has_value)
372  
    if(p.has_value)
373  
        n += detail::re_encoded_size_unsafe(
373  
        n += detail::re_encoded_size_unsafe(
374  
            p.value,
374  
            p.value,
375  
            detail::param_value_chars) + 1; // for '='
375  
            detail::param_value_chars) + 1; // for '='
376  
}
376  
}
377  

377  

378  
inline
378  
inline
379  
void
379  
void
380  
params_encoded_iter_base::
380  
params_encoded_iter_base::
381  
copy_impl(
381  
copy_impl(
382  
    char*& dest,
382  
    char*& dest,
383  
    char const* end,
383  
    char const* end,
384  
    param_view const& p) noexcept
384  
    param_view const& p) noexcept
385  
{
385  
{
386  
    detail::re_encode_unsafe(
386  
    detail::re_encode_unsafe(
387  
        dest,
387  
        dest,
388  
        end,
388  
        end,
389  
        p.key,
389  
        p.key,
390  
        detail::param_key_chars);
390  
        detail::param_key_chars);
391  
    if(p.has_value)
391  
    if(p.has_value)
392  
    {
392  
    {
393  
        *dest++ = '=';
393  
        *dest++ = '=';
394  
        detail::re_encode_unsafe(
394  
        detail::re_encode_unsafe(
395  
            dest,
395  
            dest,
396  
            end,
396  
            end,
397  
            p.value,
397  
            p.value,
398  
            detail::param_value_chars);
398  
            detail::param_value_chars);
399  
    }
399  
    }
400  
}
400  
}
401  

401  

402  
//------------------------------------------------
402  
//------------------------------------------------
403  
//
403  
//
404  
// param_value_iter
404  
// param_value_iter
405  
//
405  
//
406  
//------------------------------------------------
406  
//------------------------------------------------
407  

407  

408  
inline
408  
inline
409  
void
409  
void
410  
param_value_iter::
410  
param_value_iter::
411  
rewind() noexcept
411  
rewind() noexcept
412  
{
412  
{
413  
    at_end_ = false;
413  
    at_end_ = false;
414  
}
414  
}
415  

415  

416  
inline
416  
inline
417  
bool
417  
bool
418  
param_value_iter::
418  
param_value_iter::
419  
measure(
419  
measure(
420  
    std::size_t& n) noexcept
420  
    std::size_t& n) noexcept
421  
{
421  
{
422  
    if(at_end_)
422  
    if(at_end_)
423  
        return false;
423  
        return false;
424  
    n += nk_; // skip key
424  
    n += nk_; // skip key
425  
    if(has_value_)
425  
    if(has_value_)
426  
    {
426  
    {
427  
        encoding_opts opt;
427  
        encoding_opts opt;
428  
        opt.space_as_plus = false;
428  
        opt.space_as_plus = false;
429  
        n += encoded_size(
429  
        n += encoded_size(
430  
            s0,
430  
            s0,
431  
            detail::param_value_chars,
431  
            detail::param_value_chars,
432  
            opt) + 1; // for '='
432  
            opt) + 1; // for '='
433  
    }
433  
    }
434  
    at_end_ = true;
434  
    at_end_ = true;
435  
    return true;
435  
    return true;
436  
}
436  
}
437  

437  

438  
inline
438  
inline
439  
void
439  
void
440  
param_value_iter::
440  
param_value_iter::
441  
copy(char*& it, char const* end) noexcept
441  
copy(char*& it, char const* end) noexcept
442  
{
442  
{
443  
    it += nk_; // skip key
443  
    it += nk_; // skip key
444  
    if(! has_value_)
444  
    if(! has_value_)
445  
        return;
445  
        return;
446  
    *it++ = '=';
446  
    *it++ = '=';
447  
    encoding_opts opt;
447  
    encoding_opts opt;
448  
    opt.space_as_plus = false;
448  
    opt.space_as_plus = false;
449  
    it += encode(
449  
    it += encode(
450  
        it,
450  
        it,
451  
        end - it,
451  
        end - it,
452  
        s0,
452  
        s0,
453  
        detail::param_value_chars,
453  
        detail::param_value_chars,
454  
        opt);
454  
        opt);
455  
}
455  
}
456  

456  

457  
//------------------------------------------------
457  
//------------------------------------------------
458  
//
458  
//
459  
// param_encoded_value_iter
459  
// param_encoded_value_iter
460  
//
460  
//
461  
//------------------------------------------------
461  
//------------------------------------------------
462  

462  

463  
inline
463  
inline
464  
void
464  
void
465  
param_encoded_value_iter::
465  
param_encoded_value_iter::
466  
rewind() noexcept
466  
rewind() noexcept
467  
{
467  
{
468  
    at_end_ = false;
468  
    at_end_ = false;
469  
}
469  
}
470  

470  

471  
inline
471  
inline
472  
bool
472  
bool
473  
param_encoded_value_iter::
473  
param_encoded_value_iter::
474  
measure(
474  
measure(
475  
    std::size_t& n) noexcept
475  
    std::size_t& n) noexcept
476  
{
476  
{
477  
    if(at_end_)
477  
    if(at_end_)
478  
        return false;
478  
        return false;
479  
    n += nk_; // skip key
479  
    n += nk_; // skip key
480  
    if(has_value_)
480  
    if(has_value_)
481  
    {
481  
    {
482  
        n += detail::re_encoded_size_unsafe(
482  
        n += detail::re_encoded_size_unsafe(
483  
            s0,
483  
            s0,
484  
            detail::param_value_chars) + 1; // for '='
484  
            detail::param_value_chars) + 1; // for '='
485  
    }
485  
    }
486  
    at_end_ = true;
486  
    at_end_ = true;
487  
    return true;
487  
    return true;
488  
}
488  
}
489  

489  

490  
inline
490  
inline
491  
void
491  
void
492  
param_encoded_value_iter::
492  
param_encoded_value_iter::
493  
copy(
493  
copy(
494  
    char*& dest,
494  
    char*& dest,
495  
    char const* end) noexcept
495  
    char const* end) noexcept
496  
{
496  
{
497  
    dest += nk_; // skip key
497  
    dest += nk_; // skip key
498  
    if(! has_value_)
498  
    if(! has_value_)
499  
        return;
499  
        return;
500  
    *dest++ = '=';
500  
    *dest++ = '=';
501  
    detail::re_encode_unsafe(
501  
    detail::re_encode_unsafe(
502  
        dest,
502  
        dest,
503  
        end,
503  
        end,
504  
        s0,
504  
        s0,
505  
        detail::param_value_chars);
505  
        detail::param_value_chars);
506  
}
506  
}
507  

507  

508  
} // detail
508  
} // detail
509  
} // urls
509  
} // urls
510  
} // boost
510  
} // boost
511  

511  

512  
#endif
512  
#endif