-
Notifications
You must be signed in to change notification settings - Fork 2
/
Copy pathutilities.h
166 lines (151 loc) · 3.53 KB
/
utilities.h
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
#ifndef UTILITIES_H
#define UTILITIES_H
#include <iostream>
#include <iomanip>
#include <vector>
#include <string>
#include <sstream>
namespace utilities {
/**
* Print a collection as hexadecimal values.
*
* */
template <typename T>
inline void printToHex(T s)
{
for(size_t i = 0; i < s.size(); i++) {
std::cout << std::hex << std::setfill('0') << std::setw(2) << (int)s[i];
}
std::cout << std::dec << "\n";
}
/**
* Stream a collection as hexadecimal values.
*
* */
template <typename T>
inline std::ostream& streamToHex(T s, std::ostream& os)
{
for(size_t i = 0; i < s.size(); i++) {
os << std::hex << std::setfill('0') << std::setw(2) << (int)s[i];
}
os << std::dec;
return os;
}
/**
*
* */
template <typename T>
inline std::ostream& printToHex(std::ostream& os, T s)
{
for(size_t i = 0; i < s.size(); i++) {
os << std::hex << std::setfill('0') << std::setw(2) << (int)s[i];
}
os << std::dec;
return os;
}
/**
* Print collection of bytes as a hexadecimal string.
*
* */
inline void stringToHexBytes(const std::string& s, std::vector<unsigned char>& hexBytes)
{
for (size_t i = 0; i < s.size(); i++) {
if ((unsigned char)s[i] == 0xff) continue;
hexBytes.push_back(s[i]);
}
}
template <typename T>
inline void switchEndianness(T& collection)
{
size_t i = 0, j = collection.size() - 1;
while (i < collection.size() / 2) {
auto tmp = collection[i];
collection[i++] = collection[j];
collection[j--] = tmp;
}
}
inline int hexDigitToInt(char digit)
{
digit = tolower(digit);
if (digit >= '0' && digit <='9')
return (int)(digit - '0');
else if (digit >= 'a' && digit <= 'f') {
return (int)(digit - '1' - '0') + 10;
}
return -1;
}
template <typename T>
inline int hexstringToBytes(std::string const& hexstring, T& result)
{
if (hexstring.size() % 2) {
std::cerr << "The hexstring is not an even number of characters.\n";
exit(EXIT_FAILURE);
}
size_t resultLength = hexstring.size() / 2;
size_t i = 0;
for (auto it = hexstring.begin(); it != hexstring.end(); it = it + 2) {
int sixteens = hexDigitToInt(*it);
int units = hexDigitToInt(*std::next(it));
if (units == -1 || sixteens == -1) {
std::cerr << "Invalid hex character.\n";
exit(EXIT_FAILURE);
}
result.push_back((sixteens << 4) | units);
i++;
}
return resultLength;
}
template <typename T>
inline void bytesToHexstring(const T& bytes, std::string& s)
{
std::stringstream ss;
for (auto b : bytes) {
ss << std::hex << std::setfill('0') << std::setw(2) << (int)b;
}
s = ss.str();
}
inline void bytesToDecimal(const std::vector<unsigned char>& bytes, std::string& result)
{
size_t resultLen = bytes.size() * 3;
std::vector<unsigned char> decimal(resultLen, 0);
ssize_t resultIndex;
for (size_t i = 0; i < bytes.size(); i++) {
uint32_t carry = bytes[i];
resultIndex = resultLen - 1;
while (carry || resultIndex >= 0) {
carry += 256 * decimal[resultIndex];
decimal[resultIndex] = carry % 10;
carry /= 10;
resultIndex--;
}
}
std::stringstream ss;
bool leadingZero = true;
for (auto el : decimal) {
if (leadingZero && el == 0) {
continue;
}
leadingZero = false;
ss << (int)el;
}
result = ss.str();
}
/**
* Convert a container of bytes into a uint64_t
*
* Useful for Varints.
* */
template <typename T>
uint64_t toUint64(T container)
{
auto size = container.size();
assert(size < 9); // Max size for uint64_t
uint64_t num = container[0];
num <<= ((size - 1) * 8);
for (size_t i = 1; i < size; i++) {
num |= (container[i] << ((size - 1 - i) * 8));
}
return num;
}
} // utilities
#endif /* UTILITIES_H */