LCOV - code coverage report
Current view: top level - /jenkins/workspace/boost-root/libs/url/src/grammar - ci_string.cpp (source / functions) Coverage Total Hit Missed
Test: coverage_remapped.info Lines: 98.4 % 64 63 1
Test Date: 2026-05-13 14:18:01 Functions: 100.0 % 4 4

           TLA  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                 : // FNV-1a (in ci_digest below) relies on modular multiplication
      15                 : // of unsigned values, which Clang's -fsanitize=integer flags as
      16                 : // overflow. Suppress the check for that function only. GCC has
      17                 : // no equivalent sanitizer (it does not flag unsigned overflow),
      18                 : // so the annotation is Clang-only — applying it on GCC produces
      19                 : // "attribute directive ignored" under -Werror=attributes.
      20                 : #if defined(__clang__) && defined(__has_attribute)
      21                 : # if __has_attribute(no_sanitize)
      22                 : #  define BOOST_URL_NO_SANITIZE_INT_OVERFLOW \
      23                 :     __attribute__((no_sanitize("unsigned-integer-overflow")))
      24                 : # endif
      25                 : #endif
      26                 : #ifndef BOOST_URL_NO_SANITIZE_INT_OVERFLOW
      27                 : # define BOOST_URL_NO_SANITIZE_INT_OVERFLOW
      28                 : #endif
      29                 : 
      30                 : namespace boost {
      31                 : namespace urls {
      32                 : namespace grammar {
      33                 : 
      34                 : namespace detail {
      35                 : 
      36                 : //------------------------------------------------
      37                 : 
      38                 : // https://lemire.me/blog/2020/04/30/for-case-insensitive-string-comparisons-avoid-char-by-char-functions/
      39                 : // https://github.com/lemire/Code-used-on-Daniel-Lemire-s-blog/blob/master/2020/04/30/tolower.cpp
      40                 : 
      41                 : bool
      42 HIT           8 : ci_is_equal(
      43                 :     core::string_view s0,
      44                 :     core::string_view s1) noexcept
      45                 : {
      46               8 :     auto n = s0.size();
      47               8 :     auto p1 = s0.data();
      48               8 :     auto p2 = s1.data();
      49                 :     char a, b;
      50                 :     // fast loop
      51              13 :     while(n != 0)
      52                 :     {
      53              10 :         --n;
      54              10 :         a = *p1++;
      55              10 :         b = *p2++;
      56              10 :         if(a != b)
      57               5 :             goto slow;
      58                 :     }
      59               3 :     return true;
      60                 :     for(;;)
      61                 :     {
      62               8 :         a = *p1++;
      63               8 :         b = *p2++;
      64              13 :     slow:
      65              26 :         if( to_lower(a) !=
      66              13 :             to_lower(b))
      67 MIS           0 :             return false;
      68 HIT          13 :         if(n == 0)
      69               5 :             break;
      70               8 :         --n;
      71                 :     }
      72               5 :     return true;
      73                 : }
      74                 : 
      75                 : //------------------------------------------------
      76                 : 
      77                 : bool
      78               5 : ci_is_less(
      79                 :     core::string_view s0,
      80                 :     core::string_view s1) noexcept
      81                 : {
      82               5 :     auto p1 = s0.data();
      83               5 :     auto p2 = s1.data();
      84               5 :     auto n = s0.size() < s1.size()
      85               5 :         ? s0.size() : s1.size();
      86              18 :     while(n != 0)
      87                 :     {
      88              15 :         --n;
      89              15 :         auto c1 = to_lower(*p1++);
      90              15 :         auto c2 = to_lower(*p2++);
      91              15 :         if(c1 != c2)
      92               2 :             return c1 < c2;
      93                 :     }
      94               3 :     return s0.size() < s1.size();
      95                 : }
      96                 : 
      97                 : } // detail
      98                 : 
      99                 : //------------------------------------------------
     100                 : 
     101                 : int
     102              21 : ci_compare(
     103                 :     core::string_view s0,
     104                 :     core::string_view s1) noexcept
     105                 : {
     106                 :     int bias;
     107                 :     std::size_t n;
     108              42 :     if( s0.size() <
     109              21 :         s1.size())
     110                 :     {
     111               2 :         bias = -1;
     112               2 :         n = s0.size();
     113                 :     }
     114                 :     else
     115                 :     {
     116              38 :         if( s0.size() >
     117              19 :             s1.size())
     118               2 :             bias = 1;
     119                 :         else
     120              17 :             bias = 0;
     121              19 :         n = s1.size();
     122                 :     }
     123              21 :     auto it0 = s0.data();
     124              21 :     auto it1 = s1.data();
     125              38 :     while(n != 0)
     126                 :     {
     127              29 :         --n;
     128                 :         auto c0 =
     129              29 :             to_lower(*it0++);
     130                 :         auto c1 =
     131              29 :             to_lower(*it1++);
     132              29 :         if(c0 == c1)
     133              17 :             continue;
     134              12 :         if(c0 < c1)
     135               8 :             return -1;
     136               4 :         return 1;
     137                 :     }
     138               9 :     return bias;
     139                 : }
     140                 : 
     141                 : //------------------------------------------------
     142                 : 
     143                 : BOOST_URL_NO_SANITIZE_INT_OVERFLOW
     144                 : std::size_t
     145              18 : ci_digest(
     146                 :     core::string_view s) noexcept
     147                 : {
     148                 :     // Only 4 and 8 byte sizes are supported
     149                 :     static_assert(
     150                 :         sizeof(std::size_t) == 4 ||
     151                 :         sizeof(std::size_t) == 8, "");
     152              18 :     constexpr std::size_t prime = (
     153                 :         sizeof(std::size_t) == 8) ?
     154                 :             0x100000001B3ULL :
     155                 :             0x01000193UL;
     156              18 :     constexpr std::size_t hash0 = (
     157                 :         sizeof(std::size_t) == 8) ?
     158                 :             0xcbf29ce484222325ULL :
     159                 :             0x811C9DC5UL;
     160              18 :     auto hash = hash0;
     161              18 :     auto p = s.data();
     162              18 :     auto n = s.size();
     163              56 :     for(; n != 0; --n, ++p)
     164                 :     {
     165                 :         // VFALCO NOTE Consider using a lossy
     166                 :         // to_lower which works 4 or 8 chars at a time.
     167              38 :         hash = (to_lower(*p) ^ hash) * prime;
     168                 :     }
     169              18 :     return hash;
     170                 : }
     171                 : 
     172                 : } // grammar
     173                 : } // urls
     174                 : } // boost
     175                 : 
        

Generated by: LCOV version 2.3