LCOV - code coverage report
Current view: top level - libs/url/src - decode_view.cpp (source / functions) Hit Total Coverage
Test: coverage_filtered.info Lines: 116 116 100.0 %
Date: 2024-02-29 20:02:55 Functions: 15 15 100.0 %

          Line data    Source code
       1             : //
       2             : // Copyright (c) 2022 Alan de Freitas (alandefreitas@gmail.com)
       3             : //
       4             : // Distributed under the Boost Software License, Version 1.0. (See accompanying
       5             : // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
       6             : //
       7             : // Official repository: https://github.com/boostorg/url
       8             : //
       9             : 
      10             : #ifndef BOOST_URL_IMPL_DECODE_VIEW_IPP
      11             : #define BOOST_URL_IMPL_DECODE_VIEW_IPP
      12             : 
      13             : #include <boost/url/detail/config.hpp>
      14             : #include <boost/url/decode_view.hpp>
      15             : #include <boost/url/grammar/hexdig_chars.hpp>
      16             : #include <ostream>
      17             : 
      18             : namespace boost {
      19             : namespace urls {
      20             : 
      21             : namespace detail {
      22             : 
      23             : template <class T>
      24             : int
      25        3238 : decoded_strcmp(decode_view s0, T s1)
      26             : {
      27        3238 :     auto const n0 = s0.size();
      28        3238 :     auto const n1 = s1.size();
      29        3238 :     auto n = (std::min)(n0, n1);
      30        3238 :     auto it0 = s0.begin();
      31        3238 :     auto it1 = s1.begin();
      32        5149 :     while (n--)
      33             :     {
      34        4218 :         const char c0 = *it0++;
      35        4218 :         const char c1 = *it1++;
      36        4218 :         if (c0 == c1)
      37        1911 :             continue;
      38        2307 :         return 1 - 2 * (static_cast<unsigned char>(c0)
      39        4614 :                       < static_cast<unsigned char>(c1));
      40             :     }
      41         931 :     return 1 - (n0 == n1) - 2 * (n0 < n1);
      42             : }
      43             : 
      44             : } // detail
      45             : 
      46             : //------------------------------------------------
      47             : 
      48             : auto
      49        6287 : decode_view::
      50             : iterator::
      51             : operator*() const noexcept ->
      52             :     reference
      53             : {
      54        6287 :     if (space_as_plus_ &&
      55          53 :         *pos_ == '+')
      56           6 :         return ' ';
      57        6281 :     if (*pos_ != '%')
      58        5917 :         return *pos_;
      59         364 :     auto d0 = grammar::hexdig_value(pos_[1]);
      60         364 :     auto d1 = grammar::hexdig_value(pos_[2]);
      61             :     return static_cast<char>(
      62         364 :         ((static_cast<
      63         364 :               unsigned char>(d0) << 4) +
      64         364 :          (static_cast<
      65         364 :              unsigned char>(d1))));
      66             : }
      67             : 
      68             : // unchecked constructor
      69        3765 : decode_view::
      70             : decode_view(
      71             :     core::string_view s,
      72             :     std::size_t n,
      73        3765 :     encoding_opts opt) noexcept
      74        3765 :     : p_(s.data())
      75        3765 :     , n_(s.size())
      76             :     , dn_(n)
      77             :     , space_as_plus_(
      78        3765 :         opt.space_as_plus)
      79             : {
      80        3765 : }
      81             : 
      82             : int
      83        2922 : decode_view::
      84             : compare(core::string_view other) const noexcept
      85             : {
      86        2922 :     return detail::decoded_strcmp(*this, other);
      87             : }
      88             : 
      89             : int
      90         316 : decode_view::
      91             : compare(decode_view other) const noexcept
      92             : {
      93         316 :     return detail::decoded_strcmp(*this, other);
      94             : }
      95             : 
      96             : void
      97           2 : decode_view::
      98             : write(std::ostream& os) const
      99             : {
     100           2 :     auto it = begin();
     101           2 :     auto const end_ = end();
     102          23 :     while(it != end_)
     103          21 :         os.put(*it++);
     104           2 : }
     105             : 
     106             : void
     107           1 : decode_view::
     108             : remove_prefix( size_type n )
     109             : {
     110           1 :     auto it = begin();
     111           1 :     auto n0 = n;
     112           3 :     while (n)
     113             :     {
     114           2 :         ++it;
     115           2 :         --n;
     116             :     }
     117           1 :     n_ -= (it.base() - begin().base());
     118           1 :     dn_ -= n0;
     119           1 :     p_ = it.base();
     120           1 : }
     121             : 
     122             : void
     123           1 : decode_view::
     124             : remove_suffix( size_type n )
     125             : {
     126           1 :     auto it = end();
     127           1 :     auto n0 = n;
     128           6 :     while (n)
     129             :     {
     130           5 :         --it;
     131           5 :         --n;
     132             :     }
     133           1 :     n_ -= (end().base() - it.base());
     134           1 :     dn_ -= n0;
     135           1 : }
     136             : 
     137             : bool
     138           3 : decode_view::
     139             : starts_with( core::string_view s ) const noexcept
     140             : {
     141           3 :     if (s.size() > size())
     142           1 :         return false;
     143           2 :     auto it0 = begin();
     144           2 :     auto it1 = s.begin();
     145           2 :     std::size_t n = s.size();
     146          11 :     while (n)
     147             :     {
     148          10 :         if (*it0 != *it1)
     149           1 :             return false;
     150           9 :         ++it0;
     151           9 :         ++it1;
     152           9 :         --n;
     153             :     }
     154           1 :     return true;
     155             : }
     156             : 
     157             : bool
     158           3 : decode_view::
     159             : ends_with( core::string_view s ) const noexcept
     160             : {
     161           3 :     if (s.size() > size())
     162           1 :         return false;
     163           2 :     auto it0 = end();
     164           2 :     auto it1 = s.end();
     165           2 :     std::size_t n = s.size();
     166           2 :     --it0;
     167           2 :     --it1;
     168          14 :     while (n - 1)
     169             :     {
     170          13 :         if (*it0 != *it1)
     171           1 :             return false;
     172          12 :         --it0;
     173          12 :         --it1;
     174          12 :         --n;
     175             :     }
     176           1 :     return *it0 == *it1;
     177             : }
     178             : 
     179             : bool
     180           1 : decode_view::
     181             : starts_with( char ch ) const noexcept
     182             : {
     183             :     return
     184           2 :         !empty() &&
     185           2 :         front() == ch;
     186             : }
     187             : 
     188             : bool
     189           1 : decode_view::
     190             : ends_with( char ch ) const noexcept
     191             : {
     192             :     return
     193           2 :         !empty() &&
     194           2 :         back() == ch;
     195             : }
     196             : 
     197             : decode_view::const_iterator
     198           2 : decode_view::
     199             : find( char ch ) const noexcept
     200             : {
     201           2 :     auto it = begin();
     202           2 :     auto end = this->end();
     203           8 :     while (it != end)
     204             :     {
     205           7 :         if (*it == ch)
     206           1 :             return it;
     207           6 :         ++it;
     208             :     }
     209           1 :     return it;
     210             : }
     211             : 
     212             : decode_view::const_iterator
     213           5 : decode_view::
     214             : rfind( char ch ) const noexcept
     215             : {
     216           5 :     if (empty())
     217           1 :         return end();
     218           4 :     auto it = end();
     219           4 :     auto begin = this->begin();
     220           4 :     --it;
     221          27 :     while (it != begin)
     222             :     {
     223          25 :         if (*it == ch)
     224           2 :             return it;
     225          23 :         --it;
     226             :     }
     227           2 :     if (*it == ch)
     228           1 :         return it;
     229           1 :     return end();
     230             : }
     231             : 
     232             : } // urls
     233             : } // boost
     234             : 
     235             : #endif

Generated by: LCOV version 1.15