Line | Branch | Exec | Source |
---|---|---|---|
1 | // | ||
2 | // Copyright (c) 2021 Vinnie Falco (vinnie dot falco at gmail dot 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_HEXDIG_CHARS_HPP | ||
11 | #define BOOST_URL_GRAMMAR_HEXDIG_CHARS_HPP | ||
12 | |||
13 | #include <boost/url/detail/config.hpp> | ||
14 | #include <boost/url/grammar/detail/charset.hpp> | ||
15 | |||
16 | namespace boost { | ||
17 | namespace urls { | ||
18 | namespace grammar { | ||
19 | |||
20 | /** The set of hexadecimal digits | ||
21 | |||
22 | @par Example | ||
23 | Character sets are used with rules and the | ||
24 | functions @ref find_if and @ref find_if_not. | ||
25 | @code | ||
26 | system::result< core::string_view > rv = parse( "8086FC19", token_rule( hexdig_chars ) ); | ||
27 | @endcode | ||
28 | |||
29 | @par BNF | ||
30 | @code | ||
31 | HEXDIG = DIGIT | ||
32 | / "A" / "B" / "C" / "D" / "E" / "F" | ||
33 | / "a" / "b" / "c" / "d" / "e" / "f" | ||
34 | @endcode | ||
35 | |||
36 | @note The RFCs are inconsistent on the case | ||
37 | sensitivity of hexadecimal digits. Existing | ||
38 | uses suggest case-insensitivity is a de-facto | ||
39 | standard. | ||
40 | |||
41 | @par Specification | ||
42 | @li <a href="https://datatracker.ietf.org/doc/html/rfc5234#appendix-B.1" | ||
43 | >B.1. Core Rules (rfc5234)</a> | ||
44 | @li <a href="https://datatracker.ietf.org/doc/html/rfc7230#section-1.2" | ||
45 | >1.2. Syntax Notation (rfc7230)</a> | ||
46 | @li <a href="https://datatracker.ietf.org/doc/html/rfc5952#section-2.3" | ||
47 | >2.3. Uppercase or Lowercase (rfc5952)</a> | ||
48 | @li <a href="https://datatracker.ietf.org/doc/html/rfc5952#section-4.3" | ||
49 | >4.3. Lowercase (rfc5952)</a> | ||
50 | |||
51 | @see | ||
52 | @ref find_if, | ||
53 | @ref find_if_not, | ||
54 | @ref hexdig_value, | ||
55 | @ref parse, | ||
56 | @ref token_rule. | ||
57 | */ | ||
58 | #ifdef BOOST_URL_DOCS | ||
59 | constexpr __implementation_defined__ hexdig_chars; | ||
60 | #else | ||
61 | namespace implementation_defined { | ||
62 | struct hexdig_chars_t | ||
63 | { | ||
64 | /** Return true if c is in the character set. | ||
65 | */ | ||
66 | constexpr | ||
67 | bool | ||
68 | 3411 | operator()(char c) const noexcept | |
69 | { | ||
70 | return | ||
71 |
4/4✓ Branch 0 taken 825 times.
✓ Branch 1 taken 553 times.
✓ Branch 2 taken 782 times.
✓ Branch 3 taken 2076 times.
|
3411 | (c >= '0' && c <= '9') || |
72 |
6/6✓ Branch 0 taken 1378 times.
✓ Branch 1 taken 2033 times.
✓ Branch 2 taken 539 times.
✓ Branch 3 taken 243 times.
✓ Branch 4 taken 379 times.
✓ Branch 5 taken 2236 times.
|
7201 | (c >= 'A' && c <= 'F') || |
73 |
2/2✓ Branch 0 taken 225 times.
✓ Branch 1 taken 154 times.
|
3790 | (c >= 'a' && c <= 'f'); |
74 | } | ||
75 | |||
76 | #ifdef BOOST_URL_USE_SSE2 | ||
77 | char const* | ||
78 | 256 | find_if( | |
79 | char const* first, | ||
80 | char const* last) const noexcept | ||
81 | { | ||
82 | 256 | return detail::find_if_pred( | |
83 | 256 | *this, first, last); | |
84 | } | ||
85 | |||
86 | char const* | ||
87 | 272 | find_if_not( | |
88 | char const* first, | ||
89 | char const* last) const noexcept | ||
90 | { | ||
91 | 272 | return detail::find_if_not_pred( | |
92 | 272 | *this, first, last); | |
93 | } | ||
94 | #endif | ||
95 | }; | ||
96 | } | ||
97 | |||
98 | /** The set of hexadecimal digits | ||
99 | |||
100 | @par Example | ||
101 | Character sets are used with rules and the | ||
102 | functions @ref find_if and @ref find_if_not. | ||
103 | @code | ||
104 | system::result< core::string_view > rv = parse( "8086FC19", token_rule( hexdig_chars ) ); | ||
105 | @endcode | ||
106 | |||
107 | @par BNF | ||
108 | @code | ||
109 | HEXDIG = DIGIT | ||
110 | / "A" / "B" / "C" / "D" / "E" / "F" | ||
111 | / "a" / "b" / "c" / "d" / "e" / "f" | ||
112 | @endcode | ||
113 | |||
114 | @note The RFCs are inconsistent on the case | ||
115 | sensitivity of hexadecimal digits. Existing | ||
116 | uses suggest case-insensitivity is a de-facto | ||
117 | standard. | ||
118 | |||
119 | @par Specification | ||
120 | @li <a href="https://datatracker.ietf.org/doc/html/rfc5234#appendix-B.1" | ||
121 | >B.1. Core Rules (rfc5234)</a> | ||
122 | @li <a href="https://datatracker.ietf.org/doc/html/rfc7230#section-1.2" | ||
123 | >1.2. Syntax Notation (rfc7230)</a> | ||
124 | @li <a href="https://datatracker.ietf.org/doc/html/rfc5952#section-2.3" | ||
125 | >2.3. Uppercase or Lowercase (rfc5952)</a> | ||
126 | @li <a href="https://datatracker.ietf.org/doc/html/rfc5952#section-4.3" | ||
127 | >4.3. Lowercase (rfc5952)</a> | ||
128 | |||
129 | @see | ||
130 | @ref find_if, | ||
131 | @ref find_if_not, | ||
132 | @ref hexdig_value, | ||
133 | @ref parse, | ||
134 | @ref token_rule. | ||
135 | */ | ||
136 | constexpr implementation_defined::hexdig_chars_t hexdig_chars{}; | ||
137 | #endif | ||
138 | |||
139 | // VFALCO We can declare | ||
140 | // these later if needed | ||
141 | // | ||
142 | //struct hexdig_upper_chars; | ||
143 | //struct hexdig_lower_chars; | ||
144 | |||
145 | /** Return the decimal value of a hex character | ||
146 | |||
147 | This function returns the decimal | ||
148 | value of a hexadecimal character, | ||
149 | or -1 if the argument is not a | ||
150 | valid hexadecimal digit. | ||
151 | |||
152 | @par BNF | ||
153 | @code | ||
154 | HEXDIG = DIGIT | ||
155 | / "A" / "B" / "C" / "D" / "E" / "F" | ||
156 | / "a" / "b" / "c" / "d" / "e" / "f" | ||
157 | @endcode | ||
158 | |||
159 | @param ch The character to check | ||
160 | |||
161 | @return The decimal value or -1 | ||
162 | */ | ||
163 | inline | ||
164 | signed char | ||
165 | 8270 | hexdig_value(char ch) noexcept | |
166 | { | ||
167 | // Idea for switch statement to | ||
168 | // minimize emitted assembly from | ||
169 | // Glen Fernandes | ||
170 | signed char res; | ||
171 |
17/17✓ Branch 0 taken 954 times.
✓ Branch 1 taken 1148 times.
✓ Branch 2 taken 704 times.
✓ Branch 3 taken 1507 times.
✓ Branch 4 taken 761 times.
✓ Branch 5 taken 336 times.
✓ Branch 6 taken 256 times.
✓ Branch 7 taken 430 times.
✓ Branch 8 taken 233 times.
✓ Branch 9 taken 200 times.
✓ Branch 10 taken 84 times.
✓ Branch 11 taken 310 times.
✓ Branch 12 taken 133 times.
✓ Branch 13 taken 188 times.
✓ Branch 14 taken 194 times.
✓ Branch 15 taken 398 times.
✓ Branch 16 taken 434 times.
|
8270 | switch(ch) |
172 | { | ||
173 | 954 | default: res = -1; break; | |
174 | 1148 | case '0': res = 0; break; | |
175 | 704 | case '1': res = 1; break; | |
176 | 1507 | case '2': res = 2; break; | |
177 | 761 | case '3': res = 3; break; | |
178 | 336 | case '4': res = 4; break; | |
179 | 256 | case '5': res = 5; break; | |
180 | 430 | case '6': res = 6; break; | |
181 | 233 | case '7': res = 7; break; | |
182 | 200 | case '8': res = 8; break; | |
183 | 84 | case '9': res = 9; break; | |
184 | 310 | case 'a': case 'A': res = 10; break; | |
185 | 133 | case 'b': case 'B': res = 11; break; | |
186 | 188 | case 'c': case 'C': res = 12; break; | |
187 | 194 | case 'd': case 'D': res = 13; break; | |
188 | 398 | case 'e': case 'E': res = 14; break; | |
189 | 434 | case 'f': case 'F': res = 15; break; | |
190 | } | ||
191 | 8270 | return res; | |
192 | } | ||
193 | |||
194 | } // grammar | ||
195 | } // urls | ||
196 | } // boost | ||
197 | |||
198 | #endif | ||
199 |