C++ Utilities  4.6.1
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 <memory>
6 #include <sstream>
7 #include <cstring>
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 
38  m_stream(other.m_stream),
39  m_ownership(false)
40 {}
41 
46 {
47  if(m_ownership) {
48  delete m_stream;
49  }
50 }
51 
64 {
65  if(m_ownership) {
66  delete m_stream;
67  }
68  if(stream) {
69  m_stream = stream;
70  m_ownership = giveOwnership;
71  } else {
72  m_stream = nullptr;
73  m_ownership = false;
74  }
75 }
76 
84 istream::pos_type BinaryReader::readStreamsize()
85 {
86  istream::pos_type cp = m_stream->tellg();
87  m_stream->seekg(0, ios_base::end);
88  const auto streamsize = m_stream->tellg();
89  m_stream->seekg(cp);
90  return streamsize;
91 }
92 
100 {
101  static const int maxPrefixLength = 4;
102  int prefixLength = 1;
103  const byte beg = static_cast<byte>(m_stream->peek());
104  byte mask = 0x80;
105  while(prefixLength <= maxPrefixLength && (beg & mask) == 0) {
106  ++prefixLength;
107  mask >>= 1;
108  }
109  if(prefixLength > maxPrefixLength) {
110  throw ConversionException("Length denotation of length-prefixed string exceeds maximum.");
111  }
112  memset(m_buffer, 0, maxPrefixLength);
113  m_stream->read(m_buffer + (maxPrefixLength - prefixLength), prefixLength);
114  *(m_buffer + (maxPrefixLength - prefixLength)) ^= mask;
115  uint32 prefix = BE::toUInt32(m_buffer);
116  return readString(prefix);
117 }
118 
122 string BinaryReader::readString(size_t length)
123 {
124  string res;
125  res.resize(length);
126  m_stream->read(&res[0], length);
127  return res;
128 }
129 
138 {
139  stringstream ss(ios_base::in | ios_base::out | ios_base::binary);
140  ss.exceptions(ios_base::badbit | ios_base::failbit);
141  m_stream->get(*ss.rdbuf(), termination); // delim byte is not extracted from the stream
142  m_stream->seekg(1, ios_base::cur); // "extract" delim byte manually
143  return ss.str();
144 }
145 
155 string BinaryReader::readTerminatedString(size_t maxBytesToRead, byte termination)
156 {
157  unique_ptr<char []> buff = make_unique<char []>(maxBytesToRead);
158  for(char *i = buff.get(), *end = i + maxBytesToRead; i < end; ++i) {
159  m_stream->get(*i);
160  if(*(reinterpret_cast<byte *>(i)) == termination) {
161  return string(buff.get(), i - buff.get());
162  }
163  }
164  return string(buff.get(), maxBytesToRead);
165 }
166 
175 {
176  stringstream ss(ios_base::in | ios_base::out | ios_base::binary);
177  ss.exceptions(ios_base::badbit | ios_base::failbit);
178  char *delimChars = m_buffer, *buff = m_buffer + 2;
179  ConversionUtilities::BE::getBytes(termination, delimChars);
180  do {
181  m_stream->get(buff[0]);
182  m_stream->get(buff[1]);
183  } while(!((buff[0] == delimChars[0]) && (buff[1] == delimChars[1])));
184  return ss.str();
185 }
186 
195 {
196  stringstream ss(ios_base::in | ios_base::out | ios_base::binary);
197  ss.exceptions(ios_base::badbit | ios_base::failbit);
198  char *delimChars = m_buffer, *buff = m_buffer + 2;
199  ConversionUtilities::LE::getBytes(termination, delimChars);
200  do {
201  m_stream->get(buff[0]);
202  m_stream->get(buff[1]);
203  } while(!((buff[0] == delimChars[0]) && (buff[1] == delimChars[1])));
204  return ss.str();
205 }
206 
216 string BinaryReader::readMultibyteTerminatedStringBE(std::size_t maxBytesToRead, uint16 termination)
217 {
218  unique_ptr<char []> buff = make_unique<char []>(maxBytesToRead);
219  char *delimChars = m_buffer;
220  ConversionUtilities::BE::getBytes(termination, delimChars);
221  for(char *i = buff.get(), *end = i + maxBytesToRead; (i + 1) < end; i += 2) {
222  m_stream->get(*i);
223  m_stream->get(*(i + 1));
224  if((*i == delimChars[0]) && (*(i + 1) == delimChars[1])) {
225  return string(buff.get(), i - buff.get());
226  }
227  }
228  return string(buff.get(), maxBytesToRead);
229 }
230 
240 string BinaryReader::readMultibyteTerminatedStringLE(std::size_t maxBytesToRead, uint16 termination)
241 {
242  unique_ptr<char []> buff = make_unique<char []>(maxBytesToRead);
243  char *delimChars = m_buffer;
244  ConversionUtilities::LE::getBytes(termination, delimChars);
245  for(char *i = buff.get(), *end = i + maxBytesToRead; (i + 1) < end; i += 2) {
246  m_stream->get(*i);
247  m_stream->get(*(i + 1));
248  if((*i == delimChars[0]) && (*(i + 1) == delimChars[1])) {
249  return string(buff.get(), i - buff.get());
250  }
251  }
252  return string(buff.get(), maxBytesToRead);
253 }
254 
264 {
265  uint32 crc = 0x00;
266  for(uint32 i = 0; i < length; ++i) {
267  crc = (crc << 8) ^ crc32Table[((crc >> 24) & 0xff) ^ static_cast<byte>(m_stream->get())];
268  }
269  return crc;
270 }
271 
280 uint32 BinaryReader::computeCrc32(const char *buffer, size_t length)
281 {
282  uint32 crc = 0x00;
283  for(const char *i = buffer, *end = buffer + length; i != end; ++i) {
284  crc = (crc << 8) ^ crc32Table[((crc >> 24) & 0xff) ^ static_cast<byte>(*i)];
285  }
286  return crc;
287 }
288 
295  0x00000000, 0x04c11db7, 0x09823b6e, 0x0d4326d9, 0x130476dc, 0x17c56b6b,
296  0x1a864db2, 0x1e475005, 0x2608edb8, 0x22c9f00f, 0x2f8ad6d6, 0x2b4bcb61,
297  0x350c9b64, 0x31cd86d3, 0x3c8ea00a, 0x384fbdbd, 0x4c11db70, 0x48d0c6c7,
298  0x4593e01e, 0x4152fda9, 0x5f15adac, 0x5bd4b01b, 0x569796c2, 0x52568b75,
299  0x6a1936c8, 0x6ed82b7f, 0x639b0da6, 0x675a1011, 0x791d4014, 0x7ddc5da3,
300  0x709f7b7a, 0x745e66cd, 0x9823b6e0, 0x9ce2ab57, 0x91a18d8e, 0x95609039,
301  0x8b27c03c, 0x8fe6dd8b, 0x82a5fb52, 0x8664e6e5, 0xbe2b5b58, 0xbaea46ef,
302  0xb7a96036, 0xb3687d81, 0xad2f2d84, 0xa9ee3033, 0xa4ad16ea, 0xa06c0b5d,
303  0xd4326d90, 0xd0f37027, 0xddb056fe, 0xd9714b49, 0xc7361b4c, 0xc3f706fb,
304  0xceb42022, 0xca753d95, 0xf23a8028, 0xf6fb9d9f, 0xfbb8bb46, 0xff79a6f1,
305  0xe13ef6f4, 0xe5ffeb43, 0xe8bccd9a, 0xec7dd02d, 0x34867077, 0x30476dc0,
306  0x3d044b19, 0x39c556ae, 0x278206ab, 0x23431b1c, 0x2e003dc5, 0x2ac12072,
307  0x128e9dcf, 0x164f8078, 0x1b0ca6a1, 0x1fcdbb16, 0x018aeb13, 0x054bf6a4,
308  0x0808d07d, 0x0cc9cdca, 0x7897ab07, 0x7c56b6b0, 0x71159069, 0x75d48dde,
309  0x6b93dddb, 0x6f52c06c, 0x6211e6b5, 0x66d0fb02, 0x5e9f46bf, 0x5a5e5b08,
310  0x571d7dd1, 0x53dc6066, 0x4d9b3063, 0x495a2dd4, 0x44190b0d, 0x40d816ba,
311  0xaca5c697, 0xa864db20, 0xa527fdf9, 0xa1e6e04e, 0xbfa1b04b, 0xbb60adfc,
312  0xb6238b25, 0xb2e29692, 0x8aad2b2f, 0x8e6c3698, 0x832f1041, 0x87ee0df6,
313  0x99a95df3, 0x9d684044, 0x902b669d, 0x94ea7b2a, 0xe0b41de7, 0xe4750050,
314  0xe9362689, 0xedf73b3e, 0xf3b06b3b, 0xf771768c, 0xfa325055, 0xfef34de2,
315  0xc6bcf05f, 0xc27dede8, 0xcf3ecb31, 0xcbffd686, 0xd5b88683, 0xd1799b34,
316  0xdc3abded, 0xd8fba05a, 0x690ce0ee, 0x6dcdfd59, 0x608edb80, 0x644fc637,
317  0x7a089632, 0x7ec98b85, 0x738aad5c, 0x774bb0eb, 0x4f040d56, 0x4bc510e1,
318  0x46863638, 0x42472b8f, 0x5c007b8a, 0x58c1663d, 0x558240e4, 0x51435d53,
319  0x251d3b9e, 0x21dc2629, 0x2c9f00f0, 0x285e1d47, 0x36194d42, 0x32d850f5,
320  0x3f9b762c, 0x3b5a6b9b, 0x0315d626, 0x07d4cb91, 0x0a97ed48, 0x0e56f0ff,
321  0x1011a0fa, 0x14d0bd4d, 0x19939b94, 0x1d528623, 0xf12f560e, 0xf5ee4bb9,
322  0xf8ad6d60, 0xfc6c70d7, 0xe22b20d2, 0xe6ea3d65, 0xeba91bbc, 0xef68060b,
323  0xd727bbb6, 0xd3e6a601, 0xdea580d8, 0xda649d6f, 0xc423cd6a, 0xc0e2d0dd,
324  0xcda1f604, 0xc960ebb3, 0xbd3e8d7e, 0xb9ff90c9, 0xb4bcb610, 0xb07daba7,
325  0xae3afba2, 0xaafbe615, 0xa7b8c0cc, 0xa379dd7b, 0x9b3660c6, 0x9ff77d71,
326  0x92b45ba8, 0x9675461f, 0x8832161a, 0x8cf30bad, 0x81b02d74, 0x857130c3,
327  0x5d8a9099, 0x594b8d2e, 0x5408abf7, 0x50c9b640, 0x4e8ee645, 0x4a4ffbf2,
328  0x470cdd2b, 0x43cdc09c, 0x7b827d21, 0x7f436096, 0x7200464f, 0x76c15bf8,
329  0x68860bfd, 0x6c47164a, 0x61043093, 0x65c52d24, 0x119b4be9, 0x155a565e,
330  0x18197087, 0x1cd86d30, 0x029f3d35, 0x065e2082, 0x0b1d065b, 0x0fdc1bec,
331  0x3793a651, 0x3352bbe6, 0x3e119d3f, 0x3ad08088, 0x2497d08d, 0x2056cd3a,
332  0x2d15ebe3, 0x29d4f654, 0xc5a92679, 0xc1683bce, 0xcc2b1d17, 0xc8ea00a0,
333  0xd6ad50a5, 0xd26c4d12, 0xdf2f6bcb, 0xdbee767c, 0xe3a1cbc1, 0xe760d676,
334  0xea23f0af, 0xeee2ed18, 0xf0a5bd1d, 0xf464a0aa, 0xf9278673, 0xfde69bc4,
335  0x89b8fd09, 0x8d79e0be, 0x803ac667, 0x84fbdbd0, 0x9abc8bd5, 0x9e7d9662,
336  0x933eb0bb, 0x97ffad0c, 0xafb010b1, 0xab710d06, 0xa6322bdf, 0xa2f33668,
337  0xbcb4666d, 0xb8757bda, 0xb5365d03, 0xb1f740b4
338 };
339 
Reads primitive data types from a std::istream.
Definition: binaryreader.h:12
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:81
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:128
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:104
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