Skip to content

Commit

Permalink
params::replace_value
Browse files Browse the repository at this point in the history
  • Loading branch information
alandefreitas authored and vinniefalco committed Mar 18, 2022
1 parent 999dbe1 commit 3f9954e
Show file tree
Hide file tree
Showing 7 changed files with 197 additions and 38 deletions.
63 changes: 63 additions & 0 deletions include/boost/url/detail/any_query_iter.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -231,6 +231,60 @@ class plain_params_iter
) noexcept override;
};

class plain_value_iter_base
{
protected:
BOOST_URL_DECL
static
void
measure_impl(
string_view key,
string_view const* value,
std::size_t& n) noexcept;

BOOST_URL_DECL
static
void
copy_impl(
string_view key,
string_view const* value,
char*& dest,
char const* end) noexcept;
};

// iterates params in a
// decoded params range
// decoding values only
template<class FwdIt>
class plain_value_iter
: public any_query_iter
, public plain_value_iter_base
{
FwdIt it_;
FwdIt end_;

public:
plain_value_iter(
FwdIt first,
FwdIt last) noexcept
: it_(first)
, end_(last)
{
}

bool
measure(
std::size_t& n,
error_code&
) noexcept override;

void
copy(
char*& dest,
char const* end
) noexcept override;
};

//------------------------------------------------

template<class FwdIt>
Expand All @@ -251,6 +305,15 @@ make_plain_params_iter(
first, last);
}

template<class FwdIt>
plain_value_iter<FwdIt>
make_plain_value_iter(
FwdIt first, FwdIt last)
{
return plain_value_iter<FwdIt>(
first, last);
}

} // detail
} // urls
} // boost
Expand Down
37 changes: 37 additions & 0 deletions include/boost/url/detail/impl/any_query_iter.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -53,6 +53,43 @@ copy(
dest, end);
}

template<class FwdIt>
bool
plain_value_iter<FwdIt>::
measure(
std::size_t& n,
error_code&) noexcept
{
if(it_ == end_)
return false;
query_param_view v(*it_++);
if(v.has_value)
measure_impl(
v.key, &v.value, n);
else
measure_impl(
v.key, nullptr, n);
return true;
}

template<class FwdIt>
void
plain_value_iter<FwdIt>::
copy(
char*& dest,
char const* end) noexcept
{
params::value_type v(*it_++);
if(v.has_value)
copy_impl(
v.key, &v.value,
dest, end);
else
copy_impl(
v.key, nullptr,
dest, end);
}

} // detail
} // urls
} // boost
Expand Down
79 changes: 53 additions & 26 deletions include/boost/url/detail/impl/any_query_iter.ipp
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@
#include <boost/url/detail/any_query_iter.hpp>
#include <boost/url/string_view.hpp>
#include <boost/url/rfc/charsets.hpp>
#include <boost/url/rfc/detail/charsets.hpp>

namespace boost {
namespace urls {
Expand Down Expand Up @@ -71,10 +72,8 @@ measure(
if(! p_)
return false;
string_view s(p_, n_);
static auto constexpr cs =
pchars + '/' + '?';
urls::validate_pct_encoding(
s, ec, {}, cs);
s, ec, {}, query_chars);
if(ec.failed())
return false;
n += s.size();
Expand Down Expand Up @@ -152,10 +151,8 @@ measure(
if(! p_)
return false;
string_view s(p_, n_);
static auto constexpr cs =
pchars + '/' + '?';
n += urls::pct_encode_bytes(
s, {}, cs);
s, {}, query_chars);
increment();
return true;
}
Expand All @@ -167,13 +164,11 @@ copy(
char const* end) noexcept
{
BOOST_ASSERT(p_ != nullptr);
static auto constexpr cs =
pchars + '/' + '?';
dest += pct_encode(
dest, end,
string_view(p_, n_),
{},
cs);
query_chars);
increment();
}

Expand All @@ -187,19 +182,17 @@ measure_impl(
std::size_t& n,
error_code& ec) noexcept
{
static constexpr auto cs =
pchars + '/' + '?';
pct_decode_opts opt;
opt.plus_to_space = true;
validate_pct_encoding(
key, ec, opt, cs);
key, ec, opt, query_chars);
if(ec.failed())
return false;
n += key.size();
if(value)
{
validate_pct_encoding(
*value, ec, opt, cs);
*value, ec, opt, query_chars);
if(ec.failed())
return false;
n += 1 + value->size();
Expand All @@ -217,17 +210,15 @@ copy_impl(
{
(void)end;
// avoid self-copy
std::size_t n = key.size();
BOOST_ASSERT(end - n >= dest);
if( key.data() != dest &&
key.data() != nullptr)
{
std::size_t n =
key.size();
BOOST_ASSERT(
end - n >= dest);
std::memcpy(dest,
key.data(), n);
dest += n;
}
dest += n;
if(value)
{
BOOST_ASSERT(
Expand Down Expand Up @@ -255,15 +246,13 @@ measure_impl(
string_view const* value,
std::size_t& n) noexcept
{
static constexpr auto cs =
pchars + '/' + '?';
n += pct_encode_bytes(
key, {}, cs);
key, {}, query_chars);
if(value)
{
++n; // '='
n += pct_encode_bytes(
*value, {}, cs);
*value, {}, query_chars);
}
}

Expand All @@ -275,15 +264,53 @@ copy_impl(
char*& dest,
char const* end) noexcept
{
static constexpr auto cs =
pchars + '/' + '?';
dest += pct_encode(
dest, end, key, {}, cs);
dest, end, key, {}, query_chars);
if(value)
{
*dest++ = '=';
dest += pct_encode(
dest, end, *value, {}, query_chars);
}
}

//------------------------------------------------

void
plain_value_iter_base::
measure_impl(
string_view key,
string_view const* value,
std::size_t& n) noexcept
{
n += key.size();
if(value)
{
++n; // '='
n += pct_encode_bytes(
*value, {}, query_chars);
}
}

void
plain_value_iter_base::
copy_impl(
string_view key,
string_view const* value,
char*& dest,
char const* end) noexcept
{
// avoid self-copy
std::size_t n = key.size();
BOOST_ASSERT(end - n >= dest);
// iterator for value only
BOOST_ASSERT(key.data() == dest);
dest += n;
if(value)
{
*dest++ = '=';
dest += pct_encode(
dest, end, *value, {}, cs);
dest, end, *value, {}, query_chars);
}
}

Expand Down
22 changes: 18 additions & 4 deletions include/boost/url/impl/params.ipp
Original file line number Diff line number Diff line change
Expand Up @@ -169,10 +169,24 @@ replace_value(
string_view value) ->
iterator
{
(void)pos;
(void)value;
// VFALCO TODO
return {};
auto const r =
u_->param(pos.i_);
string_view key{
u_->s_ + r.pos + 1,
r.nk - 1};
value_type v{
key, value, true };
BOOST_ASSERT(pos.u_ == u_);
using detail::
make_plain_value_iter;
u_->edit_params(
pos.i_,
pos.i_ + 1,
make_plain_value_iter(
&v, &v + 1),
make_plain_value_iter(
&v, &v + 1));
return pos;
}

auto
Expand Down
8 changes: 4 additions & 4 deletions include/boost/url/impl/params_encoded.ipp
Original file line number Diff line number Diff line change
Expand Up @@ -139,10 +139,10 @@ replace_value(
string_view value) ->
iterator
{
(void)pos;
(void)value;
// VFALCO TODO
return {};
return emplace_at(
pos,
(*pos).key,
value);
}

auto
Expand Down
13 changes: 11 additions & 2 deletions test/unit/params.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -219,9 +219,18 @@ class params_test
}

// replace_value(iterator, string_view)
// replace_value(iterator, Value)
{
// VFALCO TODO
url u = parse_uri_reference(
"/?k0=0&k%31=0&k2=#f").value();
params p = u.params(pa_.allocator());
auto it = p.replace_value(
p.begin() + 1,
"1");
BOOST_TEST(it == p.begin() + 1);
BOOST_TEST_EQ(u.encoded_query(),
"k0=0&k%31=1&k2=");
BOOST_TEST_EQ(u.string(),
"/?k0=0&k%31=1&k2=#f");
}

// emplace_at(iterator, string_view, string_view)
Expand Down
13 changes: 11 additions & 2 deletions test/unit/params_encoded.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -216,9 +216,18 @@ class params_encoded_test
}

// replace_value(iterator, string_view)
// replace_value(iterator, Value)
{
// VFALCO TODO
url u = parse_uri_reference(
"/?k0=0&k%31=0&k2=#f").value();
params_encoded p = u.encoded_params();
auto it = p.replace_value(
p.begin() + 1,
"1");
BOOST_TEST(it == p.begin() + 1);
BOOST_TEST(u.encoded_query() ==
"k0=0&k%31=1&k2=");
BOOST_TEST(u.string() ==
"/?k0=0&k%31=1&k2=#f");
}

// emplace_at(iterator, string_view, string_view)
Expand Down

0 comments on commit 3f9954e

Please sign in to comment.