utils.hpp
1 #ifndef SWISSARMYKNIFE_BYTES_UTILS_HPP
2 #define SWISSARMYKNIFE_BYTES_UTILS_HPP
3 
4 #include <pre/detail/namespace_compatibility.hpp>
5 
6 #include <string>
7 #include <sstream>
8 #include <cctype>
9 #include <math.h>
10 #include <stdexcept>
11 #include <fstream>
12 #include <boost/shared_ptr.hpp>
13 #include <boost/cstdint.hpp>
14 #include <boost/container/vector.hpp>
15 #include <boost/container/map.hpp>
16 #include <boost/assign.hpp>
17 #include <boost/foreach.hpp>
18 
19 namespace pre { namespace bytes {
20 
24  const size_t NIBBLE_BITS = 4;
25 
29  const size_t BYTE_NIBBLES = 2;
30 
36  inline std::string to_hexstring(const boost::uint8_t *bytes, const size_t length) {
37  uint8_t ch = 0x00;
38  size_t i = 0;
39 
40  if (bytes == NULL || length <= 0)
41  return std::string("");
42 
46  const char nibbleToChar[] = {'0', '1', '2', '3', '4', '5',
47  '6', '7', '8', '9', 'a', 'b',
48  'c', 'd', 'e', 'f'};
49 
50  std::string out;
51  out.reserve(length*2);
52  while (i < length) {
53 
54  ch = (bytes[i] & 0xF0); // Strip off high nibble
55  ch = (ch >> NIBBLE_BITS); // shift the bits down
56  ch = (ch & 0x0F); // must do this is high order bit is on!
57 
58  out.push_back(nibbleToChar[ch]); // convert the nibble to a String Character
59 
60  ch = (bytes[i] & 0x0F); // Strip off low nibble
61 
62  out.push_back(nibbleToChar[ch]); // convert the nibble to a String Character
63 
64  i++;
65  }
66 
67  return out;
68  }
69 
74  inline std::string to_hexstring(const std::string& bytes) {
75  uint8_t ch = 0x00;
76  size_t i = 0;
77 
78  if (bytes.size() == 0)
79  return std::string("");
80 
84  const char nibbleToChar[] = {'0', '1', '2', '3', '4', '5',
85  '6', '7', '8', '9', 'a', 'b',
86  'c', 'd', 'e', 'f'};
87 
88  std::string out;
89  out.reserve(bytes.size()*2);
90  while (i < bytes.size()) {
91 
92  ch = (bytes[i] & 0xF0); // Strip off high nibble
93  ch = (ch >> NIBBLE_BITS); // shift the bits down
94  ch = (ch & 0x0F); // must do this is high order bit is on!
95 
96  out.push_back(nibbleToChar[ch]); // convert the nibble to a String Character
97 
98  ch = (bytes[i] & 0x0F); // Strip off low nibble
99 
100  out.push_back(nibbleToChar[ch]); // convert the nibble to a String Character
101 
102  i++;
103  }
104 
105  return out;
106  }
107 
108 
113  inline std::string to_binstring(const boost::container::vector<boost::uint8_t> &byteArray) {
114  std::stringstream bitsRepresentation;
115  const int shift = 8 * sizeof( uint8_t ) - 1;
116  const uint8_t mask = 1 << shift;
117 
118  BOOST_FOREACH(uint8_t byte, byteArray) {
119 
120  for ( size_t i = 1; i <= shift + 1; i++ ) {
121  bitsRepresentation << ( byte & mask ? '1' : '0' );
122  byte <<= 1;
123  }
124  }
125 
126  return bitsRepresentation.str();
127  }
128 
134  inline boost::uint8_t from_hexchar(char highNibbleChar, char lowNibbleChar) {
135  const boost::container::map<char, boost::uint8_t> charToNibble = boost::assign::map_list_of('0', 0)('1', 1)('2', 2)
136  ('3', 3)('4', 4)('5', 5)
137  ('6', 6)('7', 7)('8', 8)
138  ('9', 9)('a', 10)('b', 11)
139  ('c', 12)('d', 13)('e', 14)
140  ('f', 15);
141  if (!isdigit(highNibbleChar)) {
142  highNibbleChar = tolower(highNibbleChar);
143  }
144 
145  if (!isdigit(lowNibbleChar)) {
146  lowNibbleChar = tolower(lowNibbleChar);
147  }
148 
149  if ( (charToNibble.find(highNibbleChar) != charToNibble.end()) && ( charToNibble.find(lowNibbleChar) != charToNibble.end() ) ) {
150  boost::uint8_t highNibble = charToNibble.find(highNibbleChar)->second;
151  boost::uint8_t lowNibble = charToNibble.find(lowNibbleChar)->second;
152 
153  highNibble <<= NIBBLE_BITS; // make it high
154  lowNibble |= highNibble; // merge them together
155 
156  return lowNibble;
157  }
158 
159  return 0; // This is invalid
160  }
161 
167  inline boost::container::vector<boost::uint8_t> from_hexstring(const std::string &hexString) {
168  size_t nibblePaddedSize = ( (hexString.size() / BYTE_NIBBLES) + (hexString.size() % BYTE_NIBBLES) );
169 
170  if ((nibblePaddedSize & 1) != 0) {
171  ++nibblePaddedSize;
172  }
173 
174  boost::container::vector<boost::uint8_t> result;
175  result.reserve(nibblePaddedSize);
176 
177  for (std::string::const_iterator iter = hexString.begin(); iter != hexString.end(); iter += BYTE_NIBBLES) {
178 
179  if ( (iter+1) != hexString.end() ) {
180  result.push_back(from_hexchar(*iter, *(iter+1)));
181  } else {
182  result.push_back(from_hexchar(*iter, '0'));
183  break;
184  }
185  }
186 
187  return result;
188  }
189 
194  inline std::string buffer_from_hexstring(const std::string& hex) {
195  std::vector<char> bytes;
196  for (unsigned int i = 0; i < hex.length(); i += 2) {
197  std::string byteString = hex.substr(i, 2);
198  char byte = (char) strtol(byteString.c_str(), NULL, 16);
199  bytes.push_back(byte);
200  }
201  std::string bb(bytes.begin(),bytes.end());
202  return bb;
203  }
204 
210  template<typename intX_t>
211  inline intX_t from_byteArray(const boost::container::vector<boost::uint8_t> &byteArray) {
212  intX_t result = 0x0;
213 
214  for (size_t i = 0; i < sizeof(intX_t); ++i) {
215  result |= static_cast<intX_t>(byteArray[i] << (CHAR_BIT * (sizeof(intX_t) - (i+1))));
216  }
217 
218  return result;
219  }
220 
228  inline boost::shared_ptr<boost::container::vector<boost::uint8_t> > load_bytearray(const std::string binaryFilePath) {
229  boost::shared_ptr<boost::container::vector<boost::uint8_t> > bytearray;
230  std::ifstream in(binaryFilePath.data(), std::ios_base::in | std::ios::binary);
231 
232  if (in.good()) {
233  in.seekg(0, in.end);
234  std::streampos lengthToRead = in.tellg();
235  in.seekg(0, in.beg);
236 
237  bytearray.reset(new boost::container::vector<boost::uint8_t>(lengthToRead, 0x0));
238  in.read(reinterpret_cast<char*>(&bytearray->at(0)), lengthToRead);
239  in.close();
240  } else {
241  throw std::runtime_error("File " + binaryFilePath + " not found.");
242  }
243 
244  return bytearray;
245  }
246 }}
247 
248 #endif
boost::container::vector< boost::uint8_t > from_hexstring(const std::string &hexString)
This function can be used to parse a string of hexadecimal number back into bits representation. Note that it runs from left to right, putting eventually the last nibble empty if the size of the input string isn&#39;t a multiple of 2.
Definition: utils.hpp:167
const size_t BYTE_NIBBLES
Constant telling how much Nibbles are in a byte.
Definition: utils.hpp:29
std::string to_hexstring(const boost::uint8_t *bytes, const size_t length)
Convers the given byte array of the given length to a corresponding hexadecimal number in a string...
Definition: utils.hpp:36
std::string to_binstring(const boost::container::vector< boost::uint8_t > &byteArray)
Convers the given byte array of the given length to a corresponding binary number in a string...
Definition: utils.hpp:113
boost::shared_ptr< boost::container::vector< boost::uint8_t > > load_bytearray(const std::string binaryFilePath)
This methods opens up a file and parses it&#39;s bytes into a bytearray.
Definition: utils.hpp:228
const size_t NIBBLE_BITS
Constant telling how much bits there is in a nibble.
Definition: utils.hpp:24
std::string buffer_from_hexstring(const std::string &hex)
Converts a string of hexadecimal number into a binary buffer of this valeu.
Definition: utils.hpp:194
boost::uint8_t from_hexchar(char highNibbleChar, char lowNibbleChar)
Converts the given hexChars to the byte corresponding.
Definition: utils.hpp:134
intX_t from_byteArray(const boost::container::vector< boost::uint8_t > &byteArray)
This function transforms any byteArray in the chosen (u)int*_t type.
Definition: utils.hpp:211