From fe660cdff59aa3a939479ed60172e5c0803552b2 Mon Sep 17 00:00:00 2001 From: Daniel Wilhelm Date: Sun, 8 Jan 2017 18:21:23 +0100 Subject: 8.7 --- zen/string_tools.h | 52 +++++++++++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 51 insertions(+), 1 deletion(-) (limited to 'zen/string_tools.h') diff --git a/zen/string_tools.h b/zen/string_tools.h index 9b8e7328..5292dfc6 100644 --- a/zen/string_tools.h +++ b/zen/string_tools.h @@ -24,6 +24,7 @@ namespace zen { template bool isWhiteSpace(Char ch); template bool isDigit (Char ch); //not exactly the same as "std::isdigit" -> we consider '0'-'9' only! +template bool isHexDigit (Char ch); template bool isAlpha (Char ch); template bool startsWith(const S& str, const T& prefix); // @@ -51,6 +52,9 @@ template S replaceCpy(const S& str, const T& oldT template S numberTo(const Num& number); template Num stringTo(const S& str); +std::pair hexify (unsigned char c, bool upperCase = true); +char unhexify(char high, char low); + template S printNumber(const T& format, const Num& number); //format a single number using std::snprintf() //string to string conversion: converts string-like type into char-compatible target string class @@ -101,6 +105,16 @@ bool isDigit(Char ch) //similar to implmenetation of std::::isdigit()! } +template inline +bool isHexDigit(Char c) +{ + static_assert(IsSameType::value || IsSameType::value, ""); + return (static_cast('0') <= c && c <= static_cast('9')) || + (static_cast('A') <= c && c <= static_cast('F')) || + (static_cast('a') <= c && c <= static_cast('f')); +} + + template <> bool isAlpha(char ch) = delete; //probably not a good idea with UTF-8 anyway... template <> inline bool isAlpha(wchar_t ch) { return std::iswalpha(ch) != 0; } @@ -297,7 +311,7 @@ S replaceCpy(const S& str, const T& oldTerm, const U& newTerm, bool replaceAll) return str; const auto* const newBegin = strBegin(newTerm); - const auto* const newEnd = newBegin + strLength(newTerm); + const auto* const newEnd = newBegin + strLength(newTerm); S output; for (;;) @@ -658,6 +672,42 @@ Num stringTo(const S& str) return impl::stringTo(str, TypeTag()); } + + +inline //hexify beats "printNumber("%02X", c)" by a nice factor of 3! +std::pair hexify(unsigned char c, bool upperCase) +{ + auto hexifyDigit = [upperCase](int num) -> char //input [0, 15], output 0-9, A-F + { + assert(0 <= num&& num <= 15); //guaranteed by design below! + if (num <= 9) + return static_cast('0' + num); //no signed/unsigned char problem here! + + if (upperCase) + return static_cast('A' + (num - 10)); + else + return static_cast('a' + (num - 10)); + }; + return std::make_pair(hexifyDigit(c / 16), hexifyDigit(c % 16)); +} + + +inline //unhexify beats "::sscanf(&it[3], "%02X", &tmp)" by a factor of 3000 for ~250000 calls!!! +char unhexify(char high, char low) +{ + auto unhexifyDigit = [](char hex) -> int //input 0-9, a-f, A-F; output range: [0, 15] + { + if ('0' <= hex && hex <= '9') //no signed/unsigned char problem here! + return hex - '0'; + else if ('A' <= hex && hex <= 'F') + return (hex - 'A') + 10; + else if ('a' <= hex && hex <= 'f') + return (hex - 'a') + 10; + assert(false); + return 0; + }; + return static_cast(16 * unhexifyDigit(high) + unhexifyDigit(low)); //[!] convert to unsigned char first, then to char (which may be signed) +} } #endif //STRING_TOOLS_H_213458973046 -- cgit