ext-boost/boost/url/impl/decode_view.ipp
2023-05-22 18:45:02 +10:00

234 lines
3.9 KiB
C++

//
// Copyright (c) 2022 Alan de Freitas (alandefreitas@gmail.com)
//
// Distributed under the Boost Software License, Version 1.0. (See accompanying
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
//
// Official repository: https://github.com/boostorg/url
//
#ifndef BOOST_URL_IMPL_DECODE_VIEW_IPP
#define BOOST_URL_IMPL_DECODE_VIEW_IPP
#include <boost/url/decode_view.hpp>
#include <ostream>
namespace boost {
namespace urls {
namespace detail {
template <class T>
int
decoded_strcmp(decode_view s0, T s1)
{
auto const n0 = s0.size();
auto const n1 = s1.size();
auto n = (std::min)(n0, n1);
auto it0 = s0.begin();
auto it1 = s1.begin();
while (n--)
{
const char c0 = *it0++;
const char c1 = *it1++;
if (c0 == c1)
continue;
return 1 - 2 * (static_cast<unsigned char>(c0)
< static_cast<unsigned char>(c1));
}
return 1 - (n0 == n1) - 2 * (n0 < n1);
}
} // detail
//------------------------------------------------
auto
decode_view::
iterator::
operator*() const noexcept ->
reference
{
if (space_as_plus_ &&
*pos_ == '+')
return ' ';
if (*pos_ != '%')
return *pos_;
auto d0 = grammar::hexdig_value(pos_[1]);
auto d1 = grammar::hexdig_value(pos_[2]);
return static_cast<char>(
((static_cast<
unsigned char>(d0) << 4) +
(static_cast<
unsigned char>(d1))));
}
// unchecked constructor
decode_view::
decode_view(
string_view s,
std::size_t n,
encoding_opts opt) noexcept
: p_(s.data())
, n_(s.size())
, dn_(n)
, space_as_plus_(
opt.space_as_plus)
{
}
int
decode_view::
compare(string_view other) const noexcept
{
return detail::decoded_strcmp(*this, other);
}
int
decode_view::
compare(decode_view other) const noexcept
{
return detail::decoded_strcmp(*this, other);
}
void
decode_view::
write(std::ostream& os) const
{
auto it = begin();
auto const end_ = end();
while(it != end_)
os.put(*it++);
}
void
decode_view::
remove_prefix( size_type n )
{
auto it = begin();
auto n0 = n;
while (n)
{
++it;
--n;
}
n_ -= (it.base() - begin().base());
dn_ -= n0;
p_ = it.base();
}
void
decode_view::
remove_suffix( size_type n )
{
auto it = end();
auto n0 = n;
while (n)
{
--it;
--n;
}
n_ -= (end().base() - it.base());
dn_ -= n0;
}
bool
decode_view::
starts_with( string_view s ) const noexcept
{
if (s.size() > size())
return false;
auto it0 = begin();
auto it1 = s.begin();
std::size_t n = s.size();
while (n)
{
if (*it0 != *it1)
return false;
++it0;
++it1;
--n;
}
return true;
}
bool
decode_view::
ends_with( string_view s ) const noexcept
{
if (s.size() > size())
return false;
auto it0 = end();
auto it1 = s.end();
std::size_t n = s.size();
--it0;
--it1;
while (n - 1)
{
if (*it0 != *it1)
return false;
--it0;
--it1;
--n;
}
return *it0 == *it1;
}
bool
decode_view::
starts_with( char ch ) const noexcept
{
return
!empty() &&
front() == ch;
}
bool
decode_view::
ends_with( char ch ) const noexcept
{
return
!empty() &&
back() == ch;
}
decode_view::const_iterator
decode_view::
find( char ch ) const noexcept
{
auto it = begin();
auto end = this->end();
while (it != end)
{
if (*it == ch)
return it;
++it;
}
return it;
}
decode_view::const_iterator
decode_view::
rfind( char ch ) const noexcept
{
if (empty())
return end();
auto it = end();
auto begin = this->begin();
--it;
while (it != begin)
{
if (*it == ch)
return it;
--it;
}
if (*it == ch)
return it;
return end();
}
} // urls
} // boost
#endif