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

            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          798 : decode_one(
      23              :     char const* const it) noexcept
      24              : {
      25          798 :     auto d0 = grammar::hexdig_value(it[0]);
      26          798 :     auto d1 = grammar::hexdig_value(it[1]);
      27              :     return static_cast<char>(
      28          798 :         ((static_cast<
      29          798 :             unsigned char>(d0) << 4) +
      30          798 :         (static_cast<
      31          798 :             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        10696 : decode_unsafe_is_plus_impl<false>(char)
      71              : {
      72        10696 :     return false;
      73              : }
      74              : 
      75              : 
      76              : template <bool SpaceAsPlus>
      77              : std::size_t
      78         2715 : decode_unsafe_impl(
      79              :     char* const dest0,
      80              :     char const* end,
      81              :     core::string_view s) noexcept
      82              : {
      83         2715 :     auto it = s.data();
      84         2715 :     auto const last = it + s.size();
      85         2715 :     auto dest = dest0;
      86              : 
      87        17658 :     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        14943 :         if(decode_unsafe_is_plus_impl<SpaceAsPlus>(*it))
     101              :         {
     102              :             // plus to space
     103            5 :             *dest++ = ' ';
     104            5 :             ++it;
     105            5 :             continue;
     106              :         }
     107        14938 :         if(*it == '%')
     108              :         {
     109              :             // escaped
     110          690 :             ++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          690 :             *dest++ = decode_one(it);
     125          690 :             it += 2;
     126          690 :             continue;
     127              :         }
     128              :         // unescaped
     129        14248 :         *dest++ = *it++;
     130              :     }
     131         2715 :     return dest - dest0;
     132              : }
     133              : 
     134              : std::size_t
     135         2715 : decode_unsafe(
     136              :     char* const dest0,
     137              :     char const* end,
     138              :     core::string_view s,
     139              :     encoding_opts opt) noexcept
     140              : {
     141         2715 :     if(opt.space_as_plus)
     142              :     {
     143          709 :         return decode_unsafe_impl<true>(
     144          709 :             dest0, end, s);
     145              :     }
     146         2006 :     return decode_unsafe_impl<false>(
     147         2006 :         dest0, end, s);
     148              : }
     149              : 
     150              : } // detail
     151              : } // urls
     152              : } // boost
     153              : 
        

Generated by: LCOV version 2.1