/* * This Source Code Form is subject to the terms of the Mozilla Public * License, v. 2.0. If a copy of the MPL was not distributed with this * file, You can obtain one at http://mozilla.org/MPL/2.0/. * * Copyright 2016-2018 Danny Robson */ #ifndef CRUFT_UTIL_ASCII_HPP #define CRUFT_UTIL_ASCII_HPP #include "annotation.hpp" #include #include namespace util::ascii { /////////////////////////////////////////////////////////////////////////// constexpr inline bool is_digit (char c) noexcept { return c >= '0' && c <= '9'; } //------------------------------------------------------------------------- constexpr inline uint8_t to_integer (char c) { return likely (is_digit (c)) ? c - '0' : throw std::invalid_argument ("character is not a digit"); } //------------------------------------------------------------------------- constexpr inline bool is_upper (char c) noexcept { return c >= 'A' && c <= 'Z'; } //------------------------------------------------------------------------- constexpr inline bool is_lower (char c) noexcept { return c >= 'a' && c <= 'z'; } //------------------------------------------------------------------------- constexpr inline bool is_hex (const char c) noexcept { switch (c) { case '0'...'9': return true; case 'a'...'f': return true; case 'A'...'F': return true; } return false; } //------------------------------------------------------------------------- constexpr inline uint8_t from_hex (char c) { return c >= '0' && c <= '9' ? (c - '0' ) : c >= 'a' && c <= 'f' ? (c - 'a' + 10) : c >= 'A' && c <= 'F' ? (c - 'A' + 10) : throw std::invalid_argument ("character is not hexademical"); } /////////////////////////////////////////////////////////////////////////// constexpr inline char to_upper (char c) noexcept { return c - 'a' + 'A'; } //------------------------------------------------------------------------- constexpr inline char to_lower (char c) noexcept { return c - 'A' + 'a'; } /////////////////////////////////////////////////////////////////////////// constexpr inline bool is_space (char c) { switch (c) { case ' ': case '\f': case '\n': case '\r': case '\t': case '\v': return true; default: return false; } } } /////////////////////////////////////////////////////////////////////////////// #include "debug.hpp" #include /// convert an ascii string of hex digits into a vector of uint8 std::vector inline operator"" _hex2u8 (const char *str, size_t len) { CHECK_MOD (len, 2); std::vector res (len/2); for (size_t i = 0; i < len; i += 2) res[i/2] = util::ascii::from_hex (str[i]) << 4 | util::ascii::from_hex (str[i+1]); return res; }; /////////////////////////////////////////////////////////////////////////////// template constexpr auto operator"" _hex2array (void) { static_assert (sizeof ...(StrV) % 2 == 0); std::array res {}; constexpr CharT literal[] = { StrV... }; for (size_t i = 0; i < res.size (); ++i) res[i] = util::ascii::from_hex (literal[i*2+0]) << 4 | util::ascii::from_hex (literal[i*2+1]); return res; } #endif