retdec
conversion.h
Go to the documentation of this file.
1 
7 #ifndef RETDEC_UTILS_CONVERSION_H
8 #define RETDEC_UTILS_CONVERSION_H
9 
10 #include <iomanip>
11 #include <ios>
12 #include <limits>
13 #include <sstream>
14 #include <string>
15 #include <type_traits>
16 #include <vector>
17 
18 namespace retdec {
19 namespace utils {
20 
23 
24 char* byteToHexString(uint8_t b, bool uppercase = true);
25 
37 template<typename N> void bytesToHexString(
38  const N *data,
39  std::size_t dataSize,
40  std::string &result,
41  std::size_t offset = 0,
42  std::size_t size = 0,
43  bool uppercase = true,
44  bool spacing = false)
45 {
46  if (data == nullptr || offset >= dataSize)
47  {
48  return;
49  }
50 
51  size = (size == 0 || offset + size > dataSize)
52  ? dataSize - offset
53  : size;
54 
55  std::size_t hexIndex = 0;
56 
57  std::size_t sz = spacing ? (size * 3 - 1) : (size * 2);
58  result.resize(sz);
59 
60  for (std::size_t i = 0; i < size; ++i)
61  {
62  if (spacing && hexIndex > 0)
63  {
64  result[hexIndex++] = ' ';
65  }
66  auto res = byteToHexString(data[offset + i], uppercase);
67  result[hexIndex++] = res[0];
68  result[hexIndex++] = res[1];
69  }
70 }
71 
82 template<typename N> void bytesToHexString(
83  const std::vector<N> &bytes,
84  std::string &result,
85  std::size_t offset = 0,
86  std::size_t size = 0,
87  bool uppercase = true,
88  bool spacing = false)
89 {
91  bytes.data(),
92  bytes.size(),
93  result,
94  offset,
95  size,
96  uppercase,
97  spacing
98  );
99 }
100 
111 template<typename I>
112 std::string intToHexString(I w, bool addBase = false, unsigned fillToN = 0)
113 {
114  static const char* digits = "0123456789abcdef";
115 
116  size_t hex_len = sizeof(I)<<1;
117 
118  std::string rc(hex_len,'0');
119  for (size_t i = 0, j = (hex_len-1)*4 ; i < hex_len; ++i, j -= 4)
120  {
121  rc[i] = digits[(w>>j) & 0x0f];
122  }
123 
124  bool started = false;
125  std::string res;
126  size_t j = 0;
127  if (addBase)
128  {
129  res.resize(rc.size() + 2);
130  res[0] = '0';
131  res[1] = 'x';
132  j = 2;
133  }
134  else
135  {
136  res.resize(rc.size());
137  }
138  for (size_t i = 0; i < rc.size(); ++i)
139  {
140  if (started)
141  {
142  res[j++] = rc[i];
143  }
144  else if (rc[i] != '0' || (rc.size() - i <= fillToN) || (i == rc.size() - 1))
145  {
146  res[j++] = rc[i];
147  started = true;
148  }
149  }
150  res.resize(j);
151 
152  return res;
153 }
154 
155 std::vector<uint8_t> hexStringToBytes(const std::string& hexIn);
156 
168 template<typename N>
169 inline bool strToNum(const std::string &str, N &number,
170  std::ios_base &(* format)(std::ios_base &) = std::dec) {
171  std::istringstream strStream(str);
172  N convNumber = 0;
173  strStream >> format >> convNumber;
174  if (strStream.fail() || !strStream.eof()) {
175  return false;
176  }
177 
178  // The above checks do not detect conversion of a negative number into an
179  // unsigned integer. We have to perform an additional check here.
180  if (std::is_unsigned<N>::value && str[0] == '-') {
181  return false;
182  }
183 
184  number = convNumber;
185  return true;
186 }
187 
188 namespace
189 {
190  const std::size_t BITS_IN_BYTE = 8;
191 }
192 
201 template<typename N>
202 std::string bytesToBits(const N *data, std::size_t dataSize) {
203  if(!data) {
204  dataSize = 0;
205  }
206 
207  std::string result;
208  result.reserve(dataSize * BITS_IN_BYTE);
209 
210  for (std::size_t i = 0; i < dataSize; ++i) {
211  auto& item = data[i];
212 
213  for(std::size_t j = 0; j < BITS_IN_BYTE; ++j) {
214  // 0x80 = 0b10000000
215  result += ((item << j) & 0x80) ? '1' : '0';
216  }
217  }
218 
219  return result;
220 }
221 
229 template<typename N>
230 std::string bytesToBits(const std::vector<N> &bytes) {
231  return bytesToBits(bytes.data(), bytes.size());
232 }
242 template<typename N> void bytesToString(
243  const N *data,
244  std::size_t dataSize,
245  std::string &result,
246  std::size_t offset = 0,
247  std::size_t size = 0)
248 {
249  if(!data)
250  {
251  dataSize = 0;
252  }
253 
254  if(offset >= dataSize)
255  {
256  size = 0;
257  }
258  else
259  {
260  size = (size == 0 || offset + size > dataSize)
261  ? dataSize - offset
262  : size;
263  }
264 
265  result.clear();
266  result.reserve(size);
267  result = std::string(reinterpret_cast<const char*>(data + offset), size);
268 }
269 
278 template<typename N> void bytesToString(
279  const std::vector<N> &bytes,
280  std::string &result,
281  std::size_t offset = 0,
282  std::size_t size = 0)
283 {
284  bytesToString(bytes.data(), bytes.size(), result, offset, size);
285 }
286 
287 void double10ToDouble8(std::vector<unsigned char> &dest,
288  const std::vector<unsigned char> &src);
289 
290 unsigned short byteSwap16(unsigned short val);
291 unsigned int byteSwap32(unsigned int val);
292 std::string byteSwap16(const std::string &val);
293 std::string byteSwap32(const std::string &val);
294 
296 
297 } // namespace utils
298 } // namespace retdec
299 
300 #endif
void bytesToString(const N *data, std::size_t dataSize, std::string &result, std::size_t offset=0, std::size_t size=0)
Definition: conversion.h:242
bool strToNum(const std::string &str, N &number, std::ios_base &(*format)(std::ios_base &)=std::dec)
Converts the given string into a number.
Definition: conversion.h:169
std::vector< uint8_t > hexStringToBytes(const std::string &hexIn)
Definition: conversion.cpp:170
void double10ToDouble8(std::vector< unsigned char > &dest, const std::vector< unsigned char > &src)
Convert 80-bit (10-byte) long double binary data (byte array) into 64-bit (8-byte) double binary data...
Definition: conversion.cpp:72
char * byteToHexString(uint8_t b, bool uppercase=true)
Definition: conversion.cpp:19
std::string intToHexString(I w, bool addBase=false, unsigned fillToN=0)
Converts the given integer into its hexadecimal representation.
Definition: conversion.h:112
std::string bytesToBits(const N *data, std::size_t dataSize)
Converts the given array of numbers into a bits.
Definition: conversion.h:202
unsigned short byteSwap16(unsigned short val)
Swap bytes for Intel x86 16-bit little-endian immediate.
Definition: conversion.cpp:118
unsigned int byteSwap32(unsigned int val)
Swap bytes for Intel x86 32-bit little-endian immediate.
Definition: conversion.cpp:129
void bytesToHexString(const N *data, std::size_t dataSize, std::string &result, std::size_t offset=0, std::size_t size=0, bool uppercase=true, bool spacing=false)
Definition: conversion.h:37
Definition: archive_wrapper.h:19