100.00% Lines (30/30) 100.00% Functions (4/4)
TLA Baseline Branch
Line Hits Code Line Hits Code
1   // 1   //
2   // Copyright (c) 2021 Vinnie Falco (vinnie dot falco at gmail dot com) 2   // Copyright (c) 2021 Vinnie Falco (vinnie dot falco at gmail dot com)
3   // 3   //
4   // Distributed under the Boost Software License, Version 1.0. (See accompanying 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) 5   // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
6   // 6   //
7   // Official repository: https://github.com/boostorg/url 7   // Official repository: https://github.com/boostorg/url
8   // 8   //
9   9  
10   #ifndef BOOST_URL_GRAMMAR_HEXDIG_CHARS_HPP 10   #ifndef BOOST_URL_GRAMMAR_HEXDIG_CHARS_HPP
11   #define BOOST_URL_GRAMMAR_HEXDIG_CHARS_HPP 11   #define BOOST_URL_GRAMMAR_HEXDIG_CHARS_HPP
12   12  
13   #include <boost/url/detail/config.hpp> 13   #include <boost/url/detail/config.hpp>
14   #include <boost/url/grammar/detail/charset.hpp> 14   #include <boost/url/grammar/detail/charset.hpp>
15   15  
16   namespace boost { 16   namespace boost {
17   namespace urls { 17   namespace urls {
18   namespace grammar { 18   namespace grammar {
19   namespace implementation_defined { 19   namespace implementation_defined {
20   struct hexdig_chars_t 20   struct hexdig_chars_t
21   { 21   {
22   /** Determine if a character is a hexadecimal digit 22   /** Determine if a character is a hexadecimal digit
23   23  
24   @param c The character to test 24   @param c The character to test
25   @return `true` if `c` is a hexadecimal digit. 25   @return `true` if `c` is a hexadecimal digit.
26   */ 26   */
27   constexpr 27   constexpr
28   bool 28   bool
HITCBC 29   4124 operator()(char c) const noexcept 29   4124 operator()(char c) const noexcept
30   { 30   {
31   return 31   return
HITCBC 32   4124 (c >= '0' && c <= '9') || 32   4124 (c >= '0' && c <= '9') ||
HITCBC 33   8777 (c >= 'A' && c <= 'F') || 33   8777 (c >= 'A' && c <= 'F') ||
HITCBC 34   4653 (c >= 'a' && c <= 'f'); 34   4653 (c >= 'a' && c <= 'f');
35   } 35   }
36   36  
37   #ifdef BOOST_URL_USE_SSE2 37   #ifdef BOOST_URL_USE_SSE2
38   char const* 38   char const*
HITCBC 39   256 find_if( 39   256 find_if(
40   char const* first, 40   char const* first,
41   char const* last) const noexcept 41   char const* last) const noexcept
42   { 42   {
HITCBC 43   256 return detail::find_if_pred( 43   256 return detail::find_if_pred(
HITCBC 44   256 *this, first, last); 44   256 *this, first, last);
45   } 45   }
46   46  
47   char const* 47   char const*
HITCBC 48   272 find_if_not( 48   272 find_if_not(
49   char const* first, 49   char const* first,
50   char const* last) const noexcept 50   char const* last) const noexcept
51   { 51   {
HITCBC 52   272 return detail::find_if_not_pred( 52   272 return detail::find_if_not_pred(
HITCBC 53   272 *this, first, last); 53   272 *this, first, last);
54   } 54   }
55   #endif 55   #endif
56   }; 56   };
57   } 57   }
58   58  
59   /** The set of hexadecimal digits 59   /** The set of hexadecimal digits
60   60  
61   @par Example 61   @par Example
62   Character sets are used with rules and the 62   Character sets are used with rules and the
63   functions @ref find_if and @ref find_if_not. 63   functions @ref find_if and @ref find_if_not.
64   @code 64   @code
65   system::result< core::string_view > rv = parse( "8086FC19", token_rule( hexdig_chars ) ); 65   system::result< core::string_view > rv = parse( "8086FC19", token_rule( hexdig_chars ) );
66   @endcode 66   @endcode
67   67  
68   @par BNF 68   @par BNF
69   @code 69   @code
70   HEXDIG = DIGIT 70   HEXDIG = DIGIT
71   / "A" / "B" / "C" / "D" / "E" / "F" 71   / "A" / "B" / "C" / "D" / "E" / "F"
72   / "a" / "b" / "c" / "d" / "e" / "f" 72   / "a" / "b" / "c" / "d" / "e" / "f"
73   @endcode 73   @endcode
74   74  
75   @note The RFCs are inconsistent on the case 75   @note The RFCs are inconsistent on the case
76   sensitivity of hexadecimal digits. Existing 76   sensitivity of hexadecimal digits. Existing
77   uses suggest case-insensitivity is a de-facto 77   uses suggest case-insensitivity is a de-facto
78   standard. 78   standard.
79   79  
80   @par Specification 80   @par Specification
81   @li <a href="https://datatracker.ietf.org/doc/html/rfc5234#appendix-B.1" 81   @li <a href="https://datatracker.ietf.org/doc/html/rfc5234#appendix-B.1"
82   >B.1. Core Rules (rfc5234)</a> 82   >B.1. Core Rules (rfc5234)</a>
83   @li <a href="https://datatracker.ietf.org/doc/html/rfc7230#section-1.2" 83   @li <a href="https://datatracker.ietf.org/doc/html/rfc7230#section-1.2"
84   >1.2. Syntax Notation (rfc7230)</a> 84   >1.2. Syntax Notation (rfc7230)</a>
85   @li <a href="https://datatracker.ietf.org/doc/html/rfc5952#section-2.3" 85   @li <a href="https://datatracker.ietf.org/doc/html/rfc5952#section-2.3"
86   >2.3. Uppercase or Lowercase (rfc5952)</a> 86   >2.3. Uppercase or Lowercase (rfc5952)</a>
87   @li <a href="https://datatracker.ietf.org/doc/html/rfc5952#section-4.3" 87   @li <a href="https://datatracker.ietf.org/doc/html/rfc5952#section-4.3"
88   >4.3. Lowercase (rfc5952)</a> 88   >4.3. Lowercase (rfc5952)</a>
89   89  
90   @see 90   @see
91   @ref find_if, 91   @ref find_if,
92   @ref find_if_not, 92   @ref find_if_not,
93   @ref hexdig_value, 93   @ref hexdig_value,
94   @ref parse, 94   @ref parse,
95   @ref token_rule. 95   @ref token_rule.
96   */ 96   */
97   constexpr implementation_defined::hexdig_chars_t hexdig_chars{}; 97   constexpr implementation_defined::hexdig_chars_t hexdig_chars{};
98   98  
99   /** Return the decimal value of a hex character 99   /** Return the decimal value of a hex character
100   100  
101   This function returns the decimal 101   This function returns the decimal
102   value of a hexadecimal character, 102   value of a hexadecimal character,
103   or -1 if the argument is not a 103   or -1 if the argument is not a
104   valid hexadecimal digit. 104   valid hexadecimal digit.
105   105  
106   @par BNF 106   @par BNF
107   @code 107   @code
108   HEXDIG = DIGIT 108   HEXDIG = DIGIT
109   / "A" / "B" / "C" / "D" / "E" / "F" 109   / "A" / "B" / "C" / "D" / "E" / "F"
110   / "a" / "b" / "c" / "d" / "e" / "f" 110   / "a" / "b" / "c" / "d" / "e" / "f"
111   @endcode 111   @endcode
112   112  
113   @param ch The character to check 113   @param ch The character to check
114   114  
115   @return The decimal value or -1 115   @return The decimal value or -1
116   */ 116   */
117   inline 117   inline
118   signed char 118   signed char
HITCBC 119   907275 hexdig_value(char ch) noexcept 119   907683 hexdig_value(char ch) noexcept
120   { 120   {
121   // Idea for a switch statement to 121   // Idea for a switch statement to
122   // minimize emitted assembly from 122   // minimize emitted assembly from
123   // Glen Fernandes 123   // Glen Fernandes
124   signed char res; 124   signed char res;
HITCBC 125   907275 switch(ch) 125   907683 switch(ch)
126   { 126   {
HITCBC 127   1253 default: res = -1; break; 127   1253 default: res = -1; break;
HITCBC 128   121866 case '0': res = 0; break; 128   121898 case '0': res = 0; break;
HITCBC 129   917 case '1': res = 1; break; 129   917 case '1': res = 1; break;
HITCBC 130   147423 case '2': res = 2; break; 130   147567 case '2': res = 2; break;
HITCBC 131   93389 case '3': res = 3; break; 131   93505 case '3': res = 3; break;
HITCBC 132   482 case '4': res = 4; break; 132   482 case '4': res = 4; break;
HITCBC 133   117872 case '5': res = 5; break; 133   117872 case '5': res = 5; break;
HITCBC 134   23825 case '6': res = 6; break; 134   23881 case '6': res = 6; break;
HITCBC 135   69834 case '7': res = 7; break; 135   69834 case '7': res = 7; break;
HITCBC 136   373 case '8': res = 8; break; 136   373 case '8': res = 8; break;
HITCBC 137   23244 case '9': res = 9; break; 137   23244 case '9': res = 9; break;
HITCBC 138   23684 case 'a': case 'A': res = 10; break; 138   23684 case 'a': case 'A': res = 10; break;
HITCBC 139   47023 case 'b': case 'B': res = 11; break; 139   47023 case 'b': case 'B': res = 11; break;
HITCBC 140   68883 case 'c': case 'C': res = 12; break; 140   68883 case 'c': case 'C': res = 12; break;
HITCBC 141   69721 case 'd': case 'D': res = 13; break; 141   69781 case 'd': case 'D': res = 13; break;
HITCBC 142   46830 case 'e': case 'E': res = 14; break; 142   46830 case 'e': case 'E': res = 14; break;
HITCBC 143   50656 case 'f': case 'F': res = 15; break; 143   50656 case 'f': case 'F': res = 15; break;
144   } 144   }
HITCBC 145   907275 return res; 145   907683 return res;
146   } 146   }
147   147  
148   } // grammar 148   } // grammar
149   } // urls 149   } // urls
150   } // boost 150   } // boost
151   151  
152   #endif 152   #endif