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 | |||||