LCOV - code coverage report
Current view: top level - libs/url/src/grammar/ci_string.cpp (source / functions) Coverage Total Hit
Test: coverage_filtered.info Lines: 98.2 % 57 56
Test Date: 2024-08-20 16:05:53 Functions: 100.0 % 4 4

            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            4 : slow:
      44              :     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 2.1