C++ Utilities  4.11.0
Common C++ classes and routines used by my applications such as argument parser, IO and conversion utilities
binaryreader.cpp
Go to the documentation of this file.
1 #include "./binaryreader.h"
2 
3 #include "../conversion/conversionexception.h"
4 
5 #include <cstring>
6 #include <memory>
7 #include <sstream>
8 
9 using namespace std;
10 using namespace IoUtilities;
11 using namespace ConversionUtilities;
12 
28 BinaryReader::BinaryReader(istream *stream)
29  : m_stream(stream)
30  , m_ownership(false)
31 {
32 }
33 
39  : m_stream(other.m_stream)
40  , m_ownership(false)
41 {
42 }
43 
48 {
49  if (m_ownership) {
50  delete m_stream;
51  }
52 }
53 
66 {
67  if (m_ownership) {
68  delete m_stream;
69  }
70  if (stream) {
71  m_stream = stream;
72  m_ownership = giveOwnership;
73  } else {
74  m_stream = nullptr;
75  m_ownership = false;
76  }
77 }
78 
86 istream::pos_type BinaryReader::readStreamsize()
87 {
88  istream::pos_type cp = m_stream->tellg();
89  m_stream->seekg(0, ios_base::end);
90  const auto streamsize = m_stream->tellg();
91  m_stream->seekg(cp);
92  return streamsize;
93 }
94 
102 {
103  static constexpr int maxPrefixLength = 8;
104  int prefixLength = 1;
105  const byte beg = static_cast<byte>(m_stream->peek());
106  byte mask = 0x80;
107  while (prefixLength <= maxPrefixLength && (beg & mask) == 0) {
108  ++prefixLength;
109  mask >>= 1;
110  }
111  if (prefixLength > maxPrefixLength) {
112  throw ConversionException("Length denotation of length-prefixed string exceeds maximum.");
113  }
114  memset(m_buffer, 0, maxPrefixLength);
115  m_stream->read(m_buffer + (maxPrefixLength - prefixLength), prefixLength);
116  *(m_buffer + (maxPrefixLength - prefixLength)) ^= mask;
117  return readString(BE::toUInt64(m_buffer));
118 }
119 
123 string BinaryReader::readString(size_t length)
124 {
125  string res;
126  res.resize(length);
127  m_stream->read(&res[0], length);
128  return res;
129 }
130 
139 {
140  stringstream ss(ios_base::in | ios_base::out | ios_base::binary);
141  ss.exceptions(ios_base::badbit | ios_base::failbit);
142  m_stream->get(*ss.rdbuf(), termination); // delim byte is not extracted from the stream
143  m_stream->seekg(1, ios_base::cur); // "extract" delim byte manually
144  return ss.str();
145 }
146 
156 string BinaryReader::readTerminatedString(size_t maxBytesToRead, byte termination)
157 {
158  unique_ptr<char[]> buff = make_unique<char[]>(maxBytesToRead);
159  for (char *i = buff.get(), *end = i + maxBytesToRead; i < end; ++i) {
160  m_stream->get(*i);
161  if (*(reinterpret_cast<byte *>(i)) == termination) {
162  return string(buff.get(), i - buff.get());
163  }
164  }
165  return string(buff.get(), maxBytesToRead);
166 }
167 
176 {
177  stringstream ss(ios_base::in | ios_base::out | ios_base::binary);
178  ss.exceptions(ios_base::badbit | ios_base::failbit);
179  char *delimChars = m_buffer, *buff = m_buffer + 2;
180  ConversionUtilities::BE::getBytes(termination, delimChars);
181  do {
182  m_stream->get(buff[0]);
183  m_stream->get(buff[1]);
184  } while (!((buff[0] == delimChars[0]) && (buff[1] == delimChars[1])));
185  return ss.str();
186 }
187 
196 {
197  stringstream ss(ios_base::in | ios_base::out | ios_base::binary);
198  ss.exceptions(ios_base::badbit | ios_base::failbit);
199  char *delimChars = m_buffer, *buff = m_buffer + 2;
200  ConversionUtilities::LE::getBytes(termination, delimChars);
201  do {
202  m_stream->get(buff[0]);
203  m_stream->get(buff[1]);
204  } while (!((buff[0] == delimChars[0]) && (buff[1] == delimChars[1])));
205  return ss.str();
206 }
207 
217 string BinaryReader::readMultibyteTerminatedStringBE(std::size_t maxBytesToRead, uint16 termination)
218 {
219  unique_ptr<char[]> buff = make_unique<char[]>(maxBytesToRead);
220  char *delimChars = m_buffer;
221  ConversionUtilities::BE::getBytes(termination, delimChars);
222  for (char *i = buff.get(), *end = i + maxBytesToRead; (i + 1) < end; i += 2) {
223  m_stream->get(*i);
224  m_stream->get(*(i + 1));
225  if ((*i == delimChars[0]) && (*(i + 1) == delimChars[1])) {
226  return string(buff.get(), i - buff.get());
227  }
228  }
229  return string(buff.get(), maxBytesToRead);
230 }
231 
241 string BinaryReader::readMultibyteTerminatedStringLE(std::size_t maxBytesToRead, uint16 termination)
242 {
243  unique_ptr<char[]> buff = make_unique<char[]>(maxBytesToRead);
244  char *delimChars = m_buffer;
245  ConversionUtilities::LE::getBytes(termination, delimChars);
246  for (char *i = buff.get(), *end = i + maxBytesToRead; (i + 1) < end; i += 2) {
247  m_stream->get(*i);
248  m_stream->get(*(i + 1));
249  if ((*i == delimChars[0]) && (*(i + 1) == delimChars[1])) {
250  return string(buff.get(), i - buff.get());
251  }
252  }
253  return string(buff.get(), maxBytesToRead);
254 }
255 
265 {
266  uint32 crc = 0x00;
267  for (uint32 i = 0; i < length; ++i) {
268  crc = (crc << 8) ^ crc32Table[((crc >> 24) & 0xff) ^ static_cast<byte>(m_stream->get())];
269  }
270  return crc;
271 }
272 
281 uint32 BinaryReader::computeCrc32(const char *buffer, size_t length)
282 {
283  uint32 crc = 0x00;
284  for (const char *i = buffer, *end = buffer + length; i != end; ++i) {
285  crc = (crc << 8) ^ crc32Table[((crc >> 24) & 0xff) ^ static_cast<byte>(*i)];
286  }
287  return crc;
288 }
289 
295 const uint32 BinaryReader::crc32Table[] = { 0x00000000, 0x04c11db7, 0x09823b6e, 0x0d4326d9, 0x130476dc, 0x17c56b6b, 0x1a864db2, 0x1e475005,
296  0x2608edb8, 0x22c9f00f, 0x2f8ad6d6, 0x2b4bcb61, 0x350c9b64, 0x31cd86d3, 0x3c8ea00a, 0x384fbdbd, 0x4c11db70, 0x48d0c6c7, 0x4593e01e, 0x4152fda9,
297  0x5f15adac, 0x5bd4b01b, 0x569796c2, 0x52568b75, 0x6a1936c8, 0x6ed82b7f, 0x639b0da6, 0x675a1011, 0x791d4014, 0x7ddc5da3, 0x709f7b7a, 0x745e66cd,
298  0x9823b6e0, 0x9ce2ab57, 0x91a18d8e, 0x95609039, 0x8b27c03c, 0x8fe6dd8b, 0x82a5fb52, 0x8664e6e5, 0xbe2b5b58, 0xbaea46ef, 0xb7a96036, 0xb3687d81,
299  0xad2f2d84, 0xa9ee3033, 0xa4ad16ea, 0xa06c0b5d, 0xd4326d90, 0xd0f37027, 0xddb056fe, 0xd9714b49, 0xc7361b4c, 0xc3f706fb, 0xceb42022, 0xca753d95,
300  0xf23a8028, 0xf6fb9d9f, 0xfbb8bb46, 0xff79a6f1, 0xe13ef6f4, 0xe5ffeb43, 0xe8bccd9a, 0xec7dd02d, 0x34867077, 0x30476dc0, 0x3d044b19, 0x39c556ae,
301  0x278206ab, 0x23431b1c, 0x2e003dc5, 0x2ac12072, 0x128e9dcf, 0x164f8078, 0x1b0ca6a1, 0x1fcdbb16, 0x018aeb13, 0x054bf6a4, 0x0808d07d, 0x0cc9cdca,
302  0x7897ab07, 0x7c56b6b0, 0x71159069, 0x75d48dde, 0x6b93dddb, 0x6f52c06c, 0x6211e6b5, 0x66d0fb02, 0x5e9f46bf, 0x5a5e5b08, 0x571d7dd1, 0x53dc6066,
303  0x4d9b3063, 0x495a2dd4, 0x44190b0d, 0x40d816ba, 0xaca5c697, 0xa864db20, 0xa527fdf9, 0xa1e6e04e, 0xbfa1b04b, 0xbb60adfc, 0xb6238b25, 0xb2e29692,
304  0x8aad2b2f, 0x8e6c3698, 0x832f1041, 0x87ee0df6, 0x99a95df3, 0x9d684044, 0x902b669d, 0x94ea7b2a, 0xe0b41de7, 0xe4750050, 0xe9362689, 0xedf73b3e,
305  0xf3b06b3b, 0xf771768c, 0xfa325055, 0xfef34de2, 0xc6bcf05f, 0xc27dede8, 0xcf3ecb31, 0xcbffd686, 0xd5b88683, 0xd1799b34, 0xdc3abded, 0xd8fba05a,
306  0x690ce0ee, 0x6dcdfd59, 0x608edb80, 0x644fc637, 0x7a089632, 0x7ec98b85, 0x738aad5c, 0x774bb0eb, 0x4f040d56, 0x4bc510e1, 0x46863638, 0x42472b8f,
307  0x5c007b8a, 0x58c1663d, 0x558240e4, 0x51435d53, 0x251d3b9e, 0x21dc2629, 0x2c9f00f0, 0x285e1d47, 0x36194d42, 0x32d850f5, 0x3f9b762c, 0x3b5a6b9b,
308  0x0315d626, 0x07d4cb91, 0x0a97ed48, 0x0e56f0ff, 0x1011a0fa, 0x14d0bd4d, 0x19939b94, 0x1d528623, 0xf12f560e, 0xf5ee4bb9, 0xf8ad6d60, 0xfc6c70d7,
309  0xe22b20d2, 0xe6ea3d65, 0xeba91bbc, 0xef68060b, 0xd727bbb6, 0xd3e6a601, 0xdea580d8, 0xda649d6f, 0xc423cd6a, 0xc0e2d0dd, 0xcda1f604, 0xc960ebb3,
310  0xbd3e8d7e, 0xb9ff90c9, 0xb4bcb610, 0xb07daba7, 0xae3afba2, 0xaafbe615, 0xa7b8c0cc, 0xa379dd7b, 0x9b3660c6, 0x9ff77d71, 0x92b45ba8, 0x9675461f,
311  0x8832161a, 0x8cf30bad, 0x81b02d74, 0x857130c3, 0x5d8a9099, 0x594b8d2e, 0x5408abf7, 0x50c9b640, 0x4e8ee645, 0x4a4ffbf2, 0x470cdd2b, 0x43cdc09c,
312  0x7b827d21, 0x7f436096, 0x7200464f, 0x76c15bf8, 0x68860bfd, 0x6c47164a, 0x61043093, 0x65c52d24, 0x119b4be9, 0x155a565e, 0x18197087, 0x1cd86d30,
313  0x029f3d35, 0x065e2082, 0x0b1d065b, 0x0fdc1bec, 0x3793a651, 0x3352bbe6, 0x3e119d3f, 0x3ad08088, 0x2497d08d, 0x2056cd3a, 0x2d15ebe3, 0x29d4f654,
314  0xc5a92679, 0xc1683bce, 0xcc2b1d17, 0xc8ea00a0, 0xd6ad50a5, 0xd26c4d12, 0xdf2f6bcb, 0xdbee767c, 0xe3a1cbc1, 0xe760d676, 0xea23f0af, 0xeee2ed18,
315  0xf0a5bd1d, 0xf464a0aa, 0xf9278673, 0xfde69bc4, 0x89b8fd09, 0x8d79e0be, 0x803ac667, 0x84fbdbd0, 0x9abc8bd5, 0x9e7d9662, 0x933eb0bb, 0x97ffad0c,
316  0xafb010b1, 0xab710d06, 0xa6322bdf, 0xa2f33668, 0xbcb4666d, 0xb8757bda, 0xb5365d03, 0xb1f740b4 };
Reads primitive data types from a std::istream.
Definition: binaryreader.h:11
The ConversionException class is thrown by the various conversion functions of this library when a co...
STL namespace.
static const uint32 crc32Table[]
CRC-32 table.
Definition: binaryreader.h:79
BinaryReader(std::istream *stream)
Constructs a new BinaryReader.
uint32 readCrc32(std::size_t length)
Reads length bytes from the stream and computes the CRC-32 for that block of data.
Contains utility classes helping to read and write streams.
Definition: binaryreader.h:10
Contains several functions providing conversions between different data types.
std::istream::pos_type readStreamsize()
Returns the size of the assigned stream.
std::uint32_t uint32
unsigned 32-bit integer
Definition: types.h:44
void giveOwnership()
The reader will take ownership over the assigned stream.
Definition: binaryreader.h:126
void setStream(std::istream *stream, bool giveOwnership=false)
Assigns the stream the reader will read from when calling one of the read-methods.
std::string readTerminatedString(byte termination=0)
Reads a terminated string from the current stream.
const std::istream * stream() const
Returns a pointer to the stream the reader will read from when calling one of the read-methods...
Definition: binaryreader.h:102
std::uint8_t byte
unsigned byte
Definition: types.h:14
static uint32 computeCrc32(const char *buffer, std::size_t length)
Reads length bytes from the buffer and computes the CRC-32 for that block of data.
std::string readMultibyteTerminatedStringLE(uint16 termination=0)
Reads a multibyte-terminated string from the current stream.
std::string readLengthPrefixedString()
Reads a length prefixed string from the current stream.
~BinaryReader()
Destroys the BinaryReader.
std::string readMultibyteTerminatedStringBE(uint16 termination=0)
Reads a multibyte-terminated string from the current stream.
std::string readString(std::size_t length)
Reads a string from the current stream of the given length from the stream and advances the current p...
std::uint16_t uint16
unsigned 16-bit integer
Definition: types.h:39