BinaryReader.cpp
Go to the documentation of this file.00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023 #include "Qt.h"
00024 #include "BinaryReader.h"
00025 #include <algorithm>
00026
00027 using Utils::Encodings::BinaryReader;
00028
00030
00034 BinaryReader::BinaryReader (const QByteArray &rawData, ByteOrder byteOrder)
00035 : d()
00036 {
00037 d.rawData = rawData;
00038 d.readOrigin = ReadFromStart;
00039 d.dataStart = d.rawData.data();
00040 d.dataEnd = d.dataStart + d.rawData.size();
00041
00042 setByteOrder (byteOrder);
00043 }
00044
00046
00054 void BinaryReader::doRead (char *destination, size_t count)
00055 {
00056
00057 if (canRead (count)) {
00058 if (const char* start = getRangePtrs (count))
00059 copyBytes (start, start+count, destination);
00060 }
00061 bumpPtrs (count);
00062 }
00063
00065
00073 const char* BinaryReader::getRangePtrs (size_t count)
00074 {
00075 Q_ASSERT (canRead (count));
00076 if (d.readOrigin == ReadFromEnd)
00077 return d.dataEnd - count;
00078 else
00079 return d.dataStart;
00080 }
00081
00083
00087 void BinaryReader::copyBytes (const char *beg, const char *end, char *dest)
00088 {
00089 if (d.swapBytes)
00090 while (beg != end) *dest++ = *--end;
00091 else
00092 std::copy (beg, end, dest);
00093 }
00094
00096
00100 void BinaryReader::bumpPtrs (size_t count)
00101 {
00102 if (d.readOrigin == ReadFromStart)
00103 d.dataStart += count;
00104 else
00105 d.dataEnd -= count;
00106 }
00108
00118 uchar BinaryReader::lookAhead (const int count)
00119 {
00120 Q_ASSERT (count > 0);
00121 uchar res = 0;
00122
00123 if (canRead (count)) {
00124 if (d.readOrigin == ReadFromEnd) {
00125 res = *(d.dataEnd - count);
00126 } else {
00127 res = *(d.dataStart + count - 1);
00128 }
00129 }
00130 return res;
00131 }
00132
00134
00136 bool BinaryReader::canRead (const int count)
00137 {
00138 return d.dataStart + count <= d.dataEnd;
00139 }
00140
00142
00150 uchar BinaryReader::readByte()
00151 {
00152 uchar res = 0;
00153 doRead (reinterpret_cast <char *> (&res), sizeof (res));
00154 return res;
00155 }
00156
00158
00166 quint16 BinaryReader::readUInt16()
00167 {
00168 quint16 res = 0;
00169 doRead (reinterpret_cast <char *> (&res), sizeof (res));
00170 return res;
00171 }
00172
00174
00182 quint32 BinaryReader::readUInt32()
00183 {
00184 quint32 res = 0;
00185 doRead (reinterpret_cast <char *> (&res), sizeof (res));
00186 return res;
00187 }
00188
00190
00198 quint64 BinaryReader::readUInt64()
00199 {
00200 quint64 res = 0;
00201 doRead (reinterpret_cast <char *> (&res), sizeof (res));
00202 return res;
00203 }
00204
00206 QByteArray BinaryReader::readAll()
00207 {
00208 if (d.dataEnd <= d.dataStart)
00209 return QByteArray();
00210 else
00211 return readBytes (d.dataEnd - d.dataStart);
00212 }
00213
00215
00224 QByteArray BinaryReader::readBytes (size_t count)
00225 {
00226 QByteArray res (count, '\0');
00227 if (canRead(count)) {
00228 const char* start = getRangePtrs (count);
00229 std::copy (start, start+count, res.data());
00230 }
00231 bumpPtrs (count);
00232 return res;
00233 }
00234
00236
00260 QByteArray BinaryReader::getSharedBytes (size_t count)
00261 {
00262 QByteArray res;
00263 if (canRead (count)) {
00264 if (d.readOrigin == ReadFromStart)
00265 res = QByteArray::fromRawData (d.dataStart, count);
00266 else
00267 res = QByteArray::fromRawData (d.dataEnd - count, count);
00268 } else {
00269 res = QByteArray (count, '\0');
00270 }
00271 bumpPtrs (count);
00272 return res;
00273 }
00274
00276
00290 QByteArray BinaryReader::readString (char terminator)
00291 {
00292 QByteArray res;
00293 if (d.readOrigin == ReadFromStart) {
00294 char *pos = d.dataStart;
00295 while (pos < d.dataEnd && *pos != terminator)
00296 res.append (*pos++);
00297
00298 d.dataStart = ++pos;
00299 } else {
00300 char *pos = d.dataEnd;
00301 --pos;
00302 while (pos >= d.dataStart && *pos != terminator)
00303 res.prepend (*pos--);
00304 d.dataEnd = pos;
00305 }
00306 return res;
00307 }
00308
00310
00314 void BinaryReader::setByteOrder (ByteOrder byteOrder)
00315 {
00316 d.byteOrder = byteOrder;
00317 if (byteOrder == LittleEndian)
00318 d.swapBytes = QSysInfo::ByteOrder != QSysInfo::LittleEndian;
00319 else if (byteOrder == BigEndian)
00320 d.swapBytes = QSysInfo::ByteOrder != QSysInfo::BigEndian;
00321 else
00322 Q_ASSERT (false);
00323 }
00324
00326
00335 void BinaryReader::setReadOrigin (ReadOrigin readOrigin)
00336 {
00337 Q_ASSERT (d.readOrigin == ReadFromStart || d.readOrigin == ReadFromEnd);
00338 d.readOrigin = readOrigin;
00339 }
00340
00342
00349 bool BinaryReader::hasReadPastEnd() const
00350 {
00351 return d.dataStart > d.dataEnd;
00352 }
00353
00355
00363 bool BinaryReader::hasReadAll() const
00364 {
00365 return d.dataStart >= d.dataEnd;
00366 }