Utilities  1
Collection of utility classes and functions used by my C++ applications.
 All Classes Namespaces Files Functions Typedefs Enumerations Enumerator Friends Macros
binaryreader.cpp
Go to the documentation of this file.
1 #include "binaryreader.h"
2 
4 
5 #include <sstream>
6 #include <memory>
7 
8 using namespace std;
9 using namespace IoUtilities;
10 using namespace ConversionUtilities;
11 
28 BinaryReader::BinaryReader(istream *stream, ByteOrder byteOrder) :
29  m_stream(stream),
30  m_ownership(false),
31  m_streamsize(0),
32  m_byteOrder(byteOrder)
33 {}
34 
41  m_stream(other.m_stream),
42  m_ownership(false),
43  m_streamsize(other.m_streamsize),
44  m_byteOrder(other.m_byteOrder)
45 {}
46 
51 {
52  if(m_stream && m_ownership)
53  delete m_stream;
54 }
55 
62 {
63  return m_stream;
64 }
65 
71 const istream *BinaryReader::stream() const
72 {
73  return m_stream;
74 }
75 
87 void BinaryReader::setStream(istream *stream, bool giveOwnership)
88 {
89  if(m_stream && m_ownership) {
90  delete m_stream;
91  }
92 
93  if(stream) {
94  m_stream = stream;
95  m_ownership = giveOwnership;
96  } else {
97  m_stream = nullptr;
98  m_ownership = false;
99  }
100 
101  m_streamsize = 0;
102 }
103 
112 {
113  return m_ownership;
114 }
115 
124 {
125  if(m_stream) {
126  m_ownership = true;
127  }
128 }
129 
138 {
139  m_ownership = false;
140 }
141 
149 {
150  return m_byteOrder;
151 }
152 
160 {
161  m_byteOrder = value;
162 }
163 
167 bool BinaryReader::fail() const
168 {
169  if(m_stream)
170  return m_stream->fail();
171  else
172  return false;
173 }
174 
178 bool BinaryReader::eof() const
179 {
180  if(m_stream)
181  return m_stream->eof();
182  else
183  return false;
184 }
185 
190 {
191  if(m_stream)
192  return !(m_stream->fail() || m_stream->eof());
193  else
194  return false;
195 }
196 
203 istream::pos_type BinaryReader::readStreamsize()
204 {
205  istream::pos_type cp = m_stream->tellg();
206  m_stream->seekg(0, ios_base::end);
207  m_streamsize = m_stream->tellg();
208  m_stream->seekg(cp);
209  return m_streamsize;
210 }
211 
215 void BinaryReader::read(char *buffer, std::streamsize length)
216 {
217  m_stream->read(buffer, length);
218 }
219 
223 void BinaryReader::read(byte *buffer, std::streamsize length)
224 {
225  m_stream->read(reinterpret_cast<char *>(buffer), length);
226 }
227 
231 void BinaryReader::read(std::vector<char> &buffer, std::streamsize length)
232 {
233  buffer.resize(length);
234  m_stream->read(buffer.data(), length);
235 }
236 
241 {
242  char buff[sizeof(int32)];
243  m_stream->read(buff, sizeof(int32));
244  return toInt32(buff, 0, m_byteOrder);
245 }
246 
251 {
252  char buff[sizeof(uint32)];
253  m_stream->read(buff, sizeof(uint32));
254  return toUInt32(buff, 0, m_byteOrder);
255 }
256 
261 {
262  char buff[sizeof(int16)];
263  m_stream->read(buff, sizeof(int16));
264  return toInt16(buff, 0, m_byteOrder);
265 }
266 
271 {
272  char buff[sizeof(uint16)];
273  m_stream->read(buff, sizeof(uint16));
274  return toUInt16(buff, 0, m_byteOrder);
275 }
276 
281 {
282  char buff[4] = {0};
283  switch(m_byteOrder) {
284  case ByteOrder::BigEndian:
285  m_stream->read(buff + 1, 3);
286  return toInt32(buff, 0, m_byteOrder);
287  case ByteOrder::LittleEndian:
288  m_stream->read(buff, 3);
289  return toInt32(buff, 0, m_byteOrder);
290  }
291  return 0;
292 }
293 
298 {
299  char buff[4] = {0};
300  switch(m_byteOrder) {
301  case ByteOrder::BigEndian:
302  m_stream->read(buff + 1, 3);
303  return toUInt32(buff, 0, m_byteOrder);
304  case ByteOrder::LittleEndian:
305  m_stream->read(buff, 3);
306  return toUInt32(buff, 0, m_byteOrder);
307  }
308  return 0;
309 }
310 
315 {
316  char buff[sizeof(int64)];
317  m_stream->read(buff, sizeof(int64));
318  return toInt64(buff, 0, m_byteOrder);
319 }
320 
325 {
326  char buff[sizeof(uint64)];
327  m_stream->read(buff, sizeof(uint64));
328  return toUInt64(buff, 0, m_byteOrder);
329 }
330 
335 {
336  char buff[sizeof(float32)];
337  m_stream->read(buff, sizeof(float32));
338  return toFloat32(buff, 0, m_byteOrder);
339 }
340 
345 {
346  char buff[sizeof(float64)];
347  m_stream->read(buff, sizeof(float64));
348  return toFloat64(buff, 0, m_byteOrder);
349 }
350 
355 {
356  char buff[1];
357  m_stream->read(buff, sizeof(buff));
358  return buff[0];
359 }
360 
365 {
366  char buff[1];
367  m_stream->read(buff, sizeof(buff));
368  return static_cast<byte>(buff[0]);
369 }
370 
375 {
376  return readByte() > 0;
377 }
378 
386 {
387  static const int maxPrefixLength = 4;
388  int prefixLength = 1;
389  byte beg = m_stream->peek();
390  byte mask = 0x80;
391  while(prefixLength <= maxPrefixLength && (beg & mask) == 0) {
392  ++prefixLength;
393  mask >>= 1;
394  }
395  if(prefixLength > maxPrefixLength) {
396  throw ConversionException("Length denotation of length-prefixed string exceeds maximum.");
397  }
398  char buff[maxPrefixLength] = {0};
399  m_stream->read(buff + (maxPrefixLength - prefixLength), prefixLength);
400  *(buff + (maxPrefixLength - prefixLength)) ^= mask;
401  uint32 prefix = toUInt32(buff, 0, ByteOrder::BigEndian);
402  return readString(prefix);
403 // if((m_streamsize <= 0)
404 // || ((m_stream->tellg() + static_cast<istream::pos_type>(length)) <= m_streamsize)) {
405 // return readString(length);
406 // } else {
407 // return string();
408 // }
409 }
410 
414 string BinaryReader::readString(size_t length)
415 {
416  unique_ptr<char []> buff(new char[length]);
417  m_stream->read(buff.get(), length);
418  string res(buff.get(), length);
419  return res;
420 }
421 
430 {
431  stringstream ss(ios_base::in | ios_base::out | ios_base::binary);
432  // thrown ios_base::failure when badbit or failbit is set
433  ss.exceptions(ios_base::badbit | ios_base::failbit);
434  m_stream->get(*ss.rdbuf(), termination); // delim byte is not extracted from the stream
435  m_stream->seekg(1, ios_base::cur); // "extract" delim byte manually
436  return ss.str();
437 }
438 
448 string BinaryReader::readTerminatedString(size_t maxBytesToRead, byte termination)
449 {
450  unique_ptr<char []> buff(new char[maxBytesToRead]);
451  for(char *i = buff.get(), *end = i + maxBytesToRead; i < end; ++i) {
452  m_stream->get(*i);
453  if(*(reinterpret_cast<byte *>(i)) == termination) {
454  return string(buff.get(), i - buff.get());
455  }
456  }
457  return string(buff.get(), maxBytesToRead);
458 }
459 
468 {
469  stringstream ss(ios_base::in | ios_base::out | ios_base::binary);
470  // thrown ios_base::failure when badbit or failbit is set
471  ss.exceptions(ios_base::badbit | ios_base::failbit);
472  char delimChars[2];
473  ConversionUtilities::getBytes(termination, delimChars, 0, m_byteOrder);
474  char buff[2];
475  ConversionUtilities::getBytes(termination, delimChars, 0, m_byteOrder);
476  do {
477  m_stream->get(buff[0]);
478  m_stream->get(buff[1]);
479  } while(!((buff[0] == delimChars[0]) && (buff[1] == delimChars[1])));
480  return ss.str();
481 }
482 
492 string BinaryReader::readMultibyteTerminatedString(size_t maxBytesToRead, uint16 termination)
493 {
494  unique_ptr<char []> buff(new char[maxBytesToRead]);
495  char delimChars[2];
496  ConversionUtilities::getBytes(termination, delimChars, 0, m_byteOrder);
497  for(char *i = buff.get(), *end = i + maxBytesToRead; (i + 1) < end; i += 2) {
498  m_stream->get(*i);
499  m_stream->get(*(i + 1));
500  if((*i == delimChars[0]) && (*(i + 1) == delimChars[1])) {
501  return string(buff.get(), i - buff.get());
502  }
503  }
504  return string(buff.get(), maxBytesToRead);
505 }
506 
515 {
517 }
518 
528 {
529  unique_ptr<char []> buff(new char[length]);
530  m_stream->read(buff.get(), length);
531  byte *block = reinterpret_cast<byte *>(&buff);
532  uint32 crc;
533  uint32 i;
534  crc = 0xFFFFFFFF;
535  for (i = 0; i < length; ++i) {
536  crc = ((crc >> 8) & 0x00FFFFFF) ^ crc32Table()[(crc ^ *block++) & 0xFF];
537  }
538  return (crc ^ 0xFFFFFFFF);
539 }
540 
549 {
550  static uint32 table[] = {
551  0x00000000, 0x04c11db7, 0x09823b6e, 0x0d4326d9, 0x130476dc, 0x17c56b6b,
552  0x1a864db2, 0x1e475005, 0x2608edb8, 0x22c9f00f, 0x2f8ad6d6, 0x2b4bcb61,
553  0x350c9b64, 0x31cd86d3, 0x3c8ea00a, 0x384fbdbd, 0x4c11db70, 0x48d0c6c7,
554  0x4593e01e, 0x4152fda9, 0x5f15adac, 0x5bd4b01b, 0x569796c2, 0x52568b75,
555  0x6a1936c8, 0x6ed82b7f, 0x639b0da6, 0x675a1011, 0x791d4014, 0x7ddc5da3,
556  0x709f7b7a, 0x745e66cd, 0x9823b6e0, 0x9ce2ab57, 0x91a18d8e, 0x95609039,
557  0x8b27c03c, 0x8fe6dd8b, 0x82a5fb52, 0x8664e6e5, 0xbe2b5b58, 0xbaea46ef,
558  0xb7a96036, 0xb3687d81, 0xad2f2d84, 0xa9ee3033, 0xa4ad16ea, 0xa06c0b5d,
559  0xd4326d90, 0xd0f37027, 0xddb056fe, 0xd9714b49, 0xc7361b4c, 0xc3f706fb,
560  0xceb42022, 0xca753d95, 0xf23a8028, 0xf6fb9d9f, 0xfbb8bb46, 0xff79a6f1,
561  0xe13ef6f4, 0xe5ffeb43, 0xe8bccd9a, 0xec7dd02d, 0x34867077, 0x30476dc0,
562  0x3d044b19, 0x39c556ae, 0x278206ab, 0x23431b1c, 0x2e003dc5, 0x2ac12072,
563  0x128e9dcf, 0x164f8078, 0x1b0ca6a1, 0x1fcdbb16, 0x018aeb13, 0x054bf6a4,
564  0x0808d07d, 0x0cc9cdca, 0x7897ab07, 0x7c56b6b0, 0x71159069, 0x75d48dde,
565  0x6b93dddb, 0x6f52c06c, 0x6211e6b5, 0x66d0fb02, 0x5e9f46bf, 0x5a5e5b08,
566  0x571d7dd1, 0x53dc6066, 0x4d9b3063, 0x495a2dd4, 0x44190b0d, 0x40d816ba,
567  0xaca5c697, 0xa864db20, 0xa527fdf9, 0xa1e6e04e, 0xbfa1b04b, 0xbb60adfc,
568  0xb6238b25, 0xb2e29692, 0x8aad2b2f, 0x8e6c3698, 0x832f1041, 0x87ee0df6,
569  0x99a95df3, 0x9d684044, 0x902b669d, 0x94ea7b2a, 0xe0b41de7, 0xe4750050,
570  0xe9362689, 0xedf73b3e, 0xf3b06b3b, 0xf771768c, 0xfa325055, 0xfef34de2,
571  0xc6bcf05f, 0xc27dede8, 0xcf3ecb31, 0xcbffd686, 0xd5b88683, 0xd1799b34,
572  0xdc3abded, 0xd8fba05a, 0x690ce0ee, 0x6dcdfd59, 0x608edb80, 0x644fc637,
573  0x7a089632, 0x7ec98b85, 0x738aad5c, 0x774bb0eb, 0x4f040d56, 0x4bc510e1,
574  0x46863638, 0x42472b8f, 0x5c007b8a, 0x58c1663d, 0x558240e4, 0x51435d53,
575  0x251d3b9e, 0x21dc2629, 0x2c9f00f0, 0x285e1d47, 0x36194d42, 0x32d850f5,
576  0x3f9b762c, 0x3b5a6b9b, 0x0315d626, 0x07d4cb91, 0x0a97ed48, 0x0e56f0ff,
577  0x1011a0fa, 0x14d0bd4d, 0x19939b94, 0x1d528623, 0xf12f560e, 0xf5ee4bb9,
578  0xf8ad6d60, 0xfc6c70d7, 0xe22b20d2, 0xe6ea3d65, 0xeba91bbc, 0xef68060b,
579  0xd727bbb6, 0xd3e6a601, 0xdea580d8, 0xda649d6f, 0xc423cd6a, 0xc0e2d0dd,
580  0xcda1f604, 0xc960ebb3, 0xbd3e8d7e, 0xb9ff90c9, 0xb4bcb610, 0xb07daba7,
581  0xae3afba2, 0xaafbe615, 0xa7b8c0cc, 0xa379dd7b, 0x9b3660c6, 0x9ff77d71,
582  0x92b45ba8, 0x9675461f, 0x8832161a, 0x8cf30bad, 0x81b02d74, 0x857130c3,
583  0x5d8a9099, 0x594b8d2e, 0x5408abf7, 0x50c9b640, 0x4e8ee645, 0x4a4ffbf2,
584  0x470cdd2b, 0x43cdc09c, 0x7b827d21, 0x7f436096, 0x7200464f, 0x76c15bf8,
585  0x68860bfd, 0x6c47164a, 0x61043093, 0x65c52d24, 0x119b4be9, 0x155a565e,
586  0x18197087, 0x1cd86d30, 0x029f3d35, 0x065e2082, 0x0b1d065b, 0x0fdc1bec,
587  0x3793a651, 0x3352bbe6, 0x3e119d3f, 0x3ad08088, 0x2497d08d, 0x2056cd3a,
588  0x2d15ebe3, 0x29d4f654, 0xc5a92679, 0xc1683bce, 0xcc2b1d17, 0xc8ea00a0,
589  0xd6ad50a5, 0xd26c4d12, 0xdf2f6bcb, 0xdbee767c, 0xe3a1cbc1, 0xe760d676,
590  0xea23f0af, 0xeee2ed18, 0xf0a5bd1d, 0xf464a0aa, 0xf9278673, 0xfde69bc4,
591  0x89b8fd09, 0x8d79e0be, 0x803ac667, 0x84fbdbd0, 0x9abc8bd5, 0x9e7d9662,
592  0x933eb0bb, 0x97ffad0c, 0xafb010b1, 0xab710d06, 0xa6322bdf, 0xa2f33668,
593  0xbcb4666d, 0xb8757bda, 0xb5365d03, 0xb1f740b4
594  };
595  return table;
596 }
597 
int32 readInt24()
Reads a 24-bit signed integer from the current stream and advances the current position of the stream...
void getBytes(int16 value, char *outputbuffer, int startIndex, ByteOrder byteOrder)
Stores the specified 16-bit signed integer value at a specified position in a char array...
void giveOwnership()
The reader will take ownership over the assigned stream.
ByteOrder
Specifies the byte order/endianness.
std::int64_t int64
signed 64-bit integer
Definition: types.h:29
float32 readFloat32()
Reads a 32-bit floating point value from the current stream and advances the current position of the ...
byte readByte()
Reads a single byte/unsigned character from the current stream and advances the current position of t...
Reads primitive data types from a std::istream using a specified ConversionUtilities::ByteOrder.
Definition: binaryreader.h:14
float64 toFloat64(const char *value, int startIndex, ByteOrder byteOrder)
Returns a 64-bit floating point number converted from eight bytes at a specified position in a char a...
bool eof() const
Returns an indication whether the end-of-stream bit of the assigned stream is set.
uint32 toNormalInt(uint32 synchsafeInt)
Returns a normal 32-bit integer converted from a 32-bit synchsafe integer.
uint32 readSynchsafeUInt32()
Reads a 32-bit synchsafe integer from the current stream and advances the current position of the str...
The exception that is thrown when an conversion error occurs.
const std::istream * stream() const
Returns a pointer to the stream the reader will read from when calling one of the read-methods...
STL namespace.
bool readBool()
Reads a boolean value from the current stream and advances the current position of the stream by one ...
int16 toInt16(const char *value, int startIndex, ByteOrder byteOrder)
Returns a 16-bit signed integer converted from two bytes at a specified position in a char array...
uint32 readUInt24()
Reads a 24-bit unsigned integer from the current stream and advances the current position of the stre...
std::uint64_t uint64
unsigned 64-bit integer
Definition: types.h:49
int32 readInt32()
Reads a 32-bit signed integer from the current stream and advances the current position of the stream...
uint64 readUInt64()
Reads a 64-bit unsigned integer from the current stream and advances the current position of the stre...
void detatchOwnership()
The reader will not take ownership over the assigned stream.
void setByteOrder(ConversionUtilities::ByteOrder value)
Sets the byte order used when converting the raw bytes read from the stream to the desired base data ...
float64 readFloat64()
Reads a 64-bit floating point value from the current stream and advances the current position of the ...
float32 toFloat32(const char *value, int startIndex, ByteOrder byteOrder)
Returns a 32-bit floating point number converted from four bytes at a specified position in a char ar...
Contains utility classes helping to read and write streams.
char readChar()
Reads a single character from the current stream and advances the current position of the stream by o...
Contains several functions providing conversions between different data types.
bool hasOwnership() const
Returns whether the reader takes ownership over the assigned stream.
std::istream::pos_type readStreamsize()
Returns the size of the assigned stream.
std::uint32_t uint32
unsigned 32-bit integer
Definition: types.h:44
BinaryReader(std::istream *stream, ConversionUtilities::ByteOrder byteOrder=ConversionUtilities::ByteOrder::LittleEndian)
Constructs a new BinaryReader.
int64 readInt64()
Reads a 64-bit signed integer from the current stream and advances the current position of the stream...
uint64 toUInt64(const char *value, int startIndex, ByteOrder byteOrder)
Returns a 64-bit unsigned integer converted from eight bytes at a specified position in a char array...
void setStream(std::istream *stream, bool giveOwnership=false)
Assigns the stream the reader will read from when calling one of the read-methods.
std::int32_t int32
signed 32-bit integer
Definition: types.h:24
int32 toInt32(const char *value, int startIndex, ByteOrder byteOrder)
Returns a 32-bit signed integer converted from four bytes at a specified position in a char array...
int16 readInt16()
Reads a 16-bit signed integer from the current stream and advances the current position of the stream...
std::string readTerminatedString(byte termination=0)
Reads a terminated string from the current stream.
static uint32 * crc32Table()
Returns a CRC-32 table.
uint32 toUInt32(const char *value, int startIndex, ByteOrder byteOrder)
Returns a 32-bit unsigned integer converted from four bytes at a specified position in a char array...
uint32 readCrc32(size_t length)
Reads length bytes from the stream an computes the CRC-32 for that block of data. ...
std::uint8_t byte
unsigned byte
Definition: types.h:14
uint32 readUInt32()
Reads a 32-bit unsigned integer from the current stream and advances the current position of the stre...
std::string readString(size_t length)
Reads a string from the current stream of the given length from the stream and advances the current p...
bool canRead() const
Returns an indication whether a stream is assigned the reader can read from.
std::int16_t int16
signed 16-bit integer
Definition: types.h:19
ConversionUtilities::ByteOrder byteOrder() const
Returns the byte order used when converting the raw bytes read from the stream to the desired base da...
uint16 toUInt16(const char *value, int startIndex, ByteOrder byteOrder)
Returns a 16-bit unsigned integer converted from two bytes at a specified position in a char array...
uint16 readUInt16()
Reads a 16-bit unsigned integer from the current stream and advances the current position of the stre...
std::string readLengthPrefixedString()
Reads a length prefixed string from the current stream.
~BinaryReader()
Destroys the BinaryReader.
bool fail() const
Returns an indication whether the fail bit of the assigned stream is set.
std::uint16_t uint16
unsigned 16-bit integer
Definition: types.h:39
void read(char *buffer, std::streamsize length)
Reads the specified number of characters from the stream in the character array.
std::string readMultibyteTerminatedString(uint16 termination=0)
Reads a multibyte-terminated string from the current stream.
int64 toInt64(const char *value, int startIndex, ByteOrder byteOrder)
Returns a 64-bit signed integer converted from eight bytes at a specified position in a char array...