| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233 |
- //
- // 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
|