LCOV - code coverage report
Current view: top level - libs/url/src/detail - decode.cpp (source / functions) Hit Total Coverage
Test: coverage_filtered.info Lines: 46 46 100.0 %
Date: 2024-04-08 19:38:36 Functions: 7 7 100.0 %

          Line data    Source code
       1             : //
       2             : // Copyright (c) 2019 Vinnie Falco (vinnie.falco@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 "decode.hpp"
      13             : #include <boost/url/grammar/charset.hpp>
      14             : #include <boost/url/grammar/hexdig_chars.hpp>
      15             : #include <memory>
      16             : 
      17             : namespace boost {
      18             : namespace urls {
      19             : namespace detail {
      20             : 
      21             : char
      22         794 : decode_one(
      23             :     char const* const it) noexcept
      24             : {
      25         794 :     auto d0 = grammar::hexdig_value(it[0]);
      26         794 :     auto d1 = grammar::hexdig_value(it[1]);
      27             :     return static_cast<char>(
      28         794 :         ((static_cast<
      29         794 :             unsigned char>(d0) << 4) +
      30         794 :         (static_cast<
      31         794 :             unsigned char>(d1))));
      32             : }
      33             : 
      34             : std::size_t
      35        1977 : decode_bytes_unsafe(
      36             :     core::string_view s) noexcept
      37             : {
      38        1977 :     auto p = s.begin();
      39        1977 :     auto const end = s.end();
      40        1977 :     std::size_t dn = 0;
      41        1977 :     if(s.size() >= 3)
      42             :     {
      43         826 :         auto const safe_end = end - 2;
      44        7303 :         while(p < safe_end)
      45             :         {
      46        6477 :             if(*p != '%')
      47        6218 :                 p += 1;
      48             :             else
      49         259 :                 p += 3;
      50        6477 :             ++dn;
      51             :         }
      52             :     }
      53        1977 :     dn += end - p;
      54        1977 :     return dn;
      55             : }
      56             : 
      57             : template <bool SpaceAsPlus>
      58             : std::size_t
      59             : decode_unsafe_is_plus_impl(char c);
      60             : 
      61             : template <>
      62             : std::size_t
      63        4247 : decode_unsafe_is_plus_impl<true>(char c)
      64             : {
      65        4247 :     return c == '+';
      66             : }
      67             : 
      68             : template <>
      69             : std::size_t
      70       10648 : decode_unsafe_is_plus_impl<false>(char)
      71             : {
      72       10648 :     return false;
      73             : }
      74             : 
      75             : 
      76             : template <bool SpaceAsPlus>
      77             : std::size_t
      78        2711 : decode_unsafe_impl(
      79             :     char* const dest0,
      80             :     char const* end,
      81             :     core::string_view s) noexcept
      82             : {
      83        2711 :     auto it = s.data();
      84        2711 :     auto const last = it + s.size();
      85        2711 :     auto dest = dest0;
      86             : 
      87       17606 :     while(it != last)
      88             :     {
      89             :         // LCOV_EXCL_START
      90             :         if(dest == end)
      91             :         {
      92             :             /*
      93             :              * dest too small: unreachable
      94             :              * public functions always pass
      95             :              * a buffer of sufficient size
      96             :              */
      97             :             return dest - dest0;
      98             :         }
      99             :         // LCOV_EXCL_STOP
     100       14895 :         if(decode_unsafe_is_plus_impl<SpaceAsPlus>(*it))
     101             :         {
     102             :             // plus to space
     103           5 :             *dest++ = ' ';
     104           5 :             ++it;
     105           5 :             continue;
     106             :         }
     107       14890 :         if(*it == '%')
     108             :         {
     109             :             // escaped
     110         686 :             ++it;
     111             :             // LCOV_EXCL_START
     112             :             if(last - it < 2)
     113             :             {
     114             :                 // `%` not followed by two hex digits
     115             :                 // invalid input: unreachable
     116             :                 // public functions always pass
     117             :                 // a valid string_view.
     118             :                 // initialize output
     119             :                 std::memset(dest,
     120             :                     0, end - dest);
     121             :                 return dest - dest0;
     122             :             }
     123             :             // LCOV_EXCL_STOP
     124         686 :             *dest++ = decode_one(it);
     125         686 :             it += 2;
     126         686 :             continue;
     127             :         }
     128             :         // unescaped
     129       14204 :         *dest++ = *it++;
     130             :     }
     131        2711 :     return dest - dest0;
     132             : }
     133             : 
     134             : std::size_t
     135        2711 : decode_unsafe(
     136             :     char* const dest0,
     137             :     char const* end,
     138             :     core::string_view s,
     139             :     encoding_opts opt) noexcept
     140             : {
     141        2711 :     if(opt.space_as_plus)
     142             :     {
     143         709 :         return decode_unsafe_impl<true>(
     144         709 :             dest0, end, s);
     145             :     }
     146        2002 :     return decode_unsafe_impl<false>(
     147        2002 :         dest0, end, s);
     148             : }
     149             : 
     150             : } // detail
     151             : } // urls
     152             : } // boost
     153             : 

Generated by: LCOV version 1.15