LCOV - code coverage report
Current view: top level - libs/url/src/grammar - ci_string.cpp (source / functions) Hit Total Coverage
Test: coverage_filtered.info Lines: 57 58 98.3 %
Date: 2024-02-29 20:02:55 Functions: 4 4 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             : #ifndef BOOST_URL_GRAMMAR_IMPL_CI_STRING_IPP
      11             : #define BOOST_URL_GRAMMAR_IMPL_CI_STRING_IPP
      12             : 
      13             : #include <boost/url/detail/config.hpp>
      14             : #include <boost/url/grammar/ci_string.hpp>
      15             : 
      16             : namespace boost {
      17             : namespace urls {
      18             : namespace grammar {
      19             : 
      20             : namespace detail {
      21             : 
      22             : //------------------------------------------------
      23             : 
      24             : // https://lemire.me/blog/2020/04/30/for-case-insensitive-string-comparisons-avoid-char-by-char-functions/
      25             : // https://github.com/lemire/Code-used-on-Daniel-Lemire-s-blog/blob/master/2020/04/30/tolower.cpp
      26             : 
      27             : bool
      28           7 : ci_is_equal(
      29             :     core::string_view s0,
      30             :     core::string_view s1) noexcept
      31             : {
      32           7 :     auto n = s0.size();
      33           7 :     auto p1 = s0.data();
      34           7 :     auto p2 = s1.data();
      35             :     char a, b;
      36             :     // fast loop
      37          11 :     while(n--)
      38             :     {
      39           8 :         a = *p1++;
      40           8 :         b = *p2++;
      41           8 :         if(a != b)
      42           4 :             goto slow;
      43             :     }
      44           3 :     return true;
      45          12 : slow:
      46           8 :     do
      47             :     {
      48          24 :         if( to_lower(a) !=
      49          12 :             to_lower(b))
      50           0 :             return false;
      51          12 :         a = *p1++;
      52          12 :         b = *p2++;
      53             :     }
      54          12 :     while(n--);
      55           4 :     return true;
      56             : }
      57             : 
      58             : //------------------------------------------------
      59             : 
      60             : bool
      61           5 : ci_is_less(
      62             :     core::string_view s0,
      63             :     core::string_view s1) noexcept
      64             : {
      65           5 :     auto p1 = s0.data();
      66           5 :     auto p2 = s1.data();
      67          18 :     for(auto n = s0.size();n--;)
      68             :     {
      69          15 :         auto c1 = to_lower(*p1++);
      70          15 :         auto c2 = to_lower(*p2++);
      71          15 :         if(c1 != c2)
      72           2 :             return c1 < c2;
      73             :     }
      74             :     // equal
      75           3 :     return false;
      76             : }
      77             : 
      78             : } // detail
      79             : 
      80             : //------------------------------------------------
      81             : 
      82             : int
      83          21 : ci_compare(
      84             :     core::string_view s0,
      85             :     core::string_view s1) noexcept
      86             : {
      87             :     int bias;
      88             :     std::size_t n;
      89          42 :     if( s0.size() <
      90          21 :         s1.size())
      91             :     {
      92           2 :         bias = -1;
      93           2 :         n = s0.size();
      94             :     }
      95             :     else
      96             :     {
      97          38 :         if( s0.size() >
      98          19 :             s1.size())
      99           2 :             bias = 1;
     100             :         else
     101          17 :             bias = 0;
     102          19 :         n = s1.size();
     103             :     }
     104          21 :     auto it0 = s0.data();
     105          21 :     auto it1 = s1.data();
     106          38 :     while(n--)
     107             :     {
     108             :         auto c0 =
     109          29 :             to_lower(*it0++);
     110             :         auto c1 =
     111          29 :             to_lower(*it1++);
     112          29 :         if(c0 == c1)
     113          17 :             continue;
     114          12 :         if(c0 < c1)
     115           8 :             return -1;
     116           4 :         return 1;
     117             :     }
     118           9 :     return bias;
     119             : }
     120             : 
     121             : //------------------------------------------------
     122             : 
     123             : std::size_t
     124          18 : ci_digest(
     125             :     core::string_view s) noexcept
     126             : {
     127             :     // Only 4 and 8 byte sizes are supported
     128             :     static_assert(
     129             :         sizeof(std::size_t) == 4 ||
     130             :         sizeof(std::size_t) == 8, "");
     131          18 :     constexpr std::size_t prime = (
     132             :         sizeof(std::size_t) == 8) ?
     133             :             0x100000001B3ULL :
     134             :             0x01000193UL;
     135          18 :     constexpr std::size_t hash0 = (
     136             :         sizeof(std::size_t) == 8) ?
     137             :             0xcbf29ce484222325ULL :
     138             :             0x811C9DC5UL;
     139          18 :     auto hash = hash0;
     140          18 :     auto p = s.data();
     141          18 :     auto n = s.size();
     142          56 :     for(;n--;++p)
     143             :     {
     144             :         // VFALCO NOTE Consider using a lossy
     145             :         // to_lower which works 4 or 8 chars at a time.
     146          38 :         hash = (to_lower(*p) ^ hash) * prime;
     147             :     }
     148          18 :     return hash;
     149             : }
     150             : 
     151             : } // grammar
     152             : } // urls
     153             : } // boost
     154             : 
     155             : #endif

Generated by: LCOV version 1.15