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

Generated by: LCOV version 1.15