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

Generated by: LCOV version 1.15