1 | #pragma once |
2 | #include <string> |
3 | |
4 | |
5 | /// Maps 0..15 to 0..9A..F or 0..9a..f correspondingly. |
6 | |
7 | extern const char * const hex_digit_to_char_uppercase_table; |
8 | extern const char * const hex_digit_to_char_lowercase_table; |
9 | |
10 | inline char hexDigitUppercase(unsigned char c) |
11 | { |
12 | return hex_digit_to_char_uppercase_table[c]; |
13 | } |
14 | |
15 | inline char hexDigitLowercase(unsigned char c) |
16 | { |
17 | return hex_digit_to_char_lowercase_table[c]; |
18 | } |
19 | |
20 | |
21 | #include <cstring> |
22 | #include <cstddef> |
23 | |
24 | #include <common/Types.h> |
25 | |
26 | |
27 | /// Maps 0..255 to 00..FF or 00..ff correspondingly |
28 | |
29 | extern const char * const hex_byte_to_char_uppercase_table; |
30 | extern const char * const hex_byte_to_char_lowercase_table; |
31 | |
32 | inline void writeHexByteUppercase(UInt8 byte, void * out) |
33 | { |
34 | memcpy(out, &hex_byte_to_char_uppercase_table[static_cast<size_t>(byte) * 2], 2); |
35 | } |
36 | |
37 | inline void writeHexByteLowercase(UInt8 byte, void * out) |
38 | { |
39 | memcpy(out, &hex_byte_to_char_lowercase_table[static_cast<size_t>(byte) * 2], 2); |
40 | } |
41 | |
42 | |
43 | /// Produces hex representation of an unsigned int with leading zeros (for checksums) |
44 | template <typename TUInt> |
45 | inline void writeHexUIntImpl(TUInt uint_, char * out, const char * const table) |
46 | { |
47 | union |
48 | { |
49 | TUInt value; |
50 | UInt8 uint8[sizeof(TUInt)]; |
51 | }; |
52 | |
53 | value = uint_; |
54 | |
55 | /// Use little endian |
56 | for (size_t i = 0; i < sizeof(TUInt); ++i) |
57 | memcpy(out + i * 2, &table[static_cast<size_t>(uint8[sizeof(TUInt) - 1 - i]) * 2], 2); |
58 | } |
59 | |
60 | template <typename TUInt> |
61 | inline void writeHexUIntUppercase(TUInt uint_, char * out) |
62 | { |
63 | writeHexUIntImpl(uint_, out, hex_byte_to_char_uppercase_table); |
64 | } |
65 | |
66 | template <typename TUInt> |
67 | inline void writeHexUIntLowercase(TUInt uint_, char * out) |
68 | { |
69 | writeHexUIntImpl(uint_, out, hex_byte_to_char_lowercase_table); |
70 | } |
71 | |
72 | template <typename TUInt> |
73 | std::string getHexUIntUppercase(TUInt uint_) |
74 | { |
75 | std::string res(sizeof(TUInt) * 2, '\0'); |
76 | writeHexUIntUppercase(uint_, res.data()); |
77 | return res; |
78 | } |
79 | |
80 | template <typename TUInt> |
81 | std::string getHexUIntLowercase(TUInt uint_) |
82 | { |
83 | std::string res(sizeof(TUInt) * 2, '\0'); |
84 | writeHexUIntLowercase(uint_, res.data()); |
85 | return res; |
86 | } |
87 | |
88 | |
89 | /// Maps 0..9, A..F, a..f to 0..15. Other chars are mapped to implementation specific value. |
90 | |
91 | extern const char * const hex_char_to_digit_table; |
92 | |
93 | inline char unhex(char c) |
94 | { |
95 | return hex_char_to_digit_table[static_cast<UInt8>(c)]; |
96 | } |
97 | |
98 | inline char unhex2(const char * data) |
99 | { |
100 | return |
101 | static_cast<UInt8>(unhex(data[0])) * 0x10 |
102 | + static_cast<UInt8>(unhex(data[1])); |
103 | } |
104 | |
105 | inline UInt16 unhex4(const char * data) |
106 | { |
107 | return |
108 | static_cast<UInt16>(unhex(data[0])) * 0x1000 |
109 | + static_cast<UInt16>(unhex(data[1])) * 0x100 |
110 | + static_cast<UInt16>(unhex(data[2])) * 0x10 |
111 | + static_cast<UInt16>(unhex(data[3])); |
112 | } |
113 | |