File indexing completed on 2024-04-28 04:40:01

0001 #ifndef LEINPUT_H
0002 #define LEINPUT_H
0003 
0004 #include <QtCore/QtEndian>
0005 #include <QtCore/QByteArray>
0006 #include <QtCore/QDebug>
0007 
0008 template <typename T>
0009 const T*
0010 toPtr(const T& t) {
0011     return (t.isValid()) ?&t :0;
0012 }
0013 
0014 class FixedSizeParsedObject {
0015 private:
0016     const char* _data;
0017 protected:
0018     explicit FixedSizeParsedObject() :_data(0) {}
0019     inline void init(const char* data) {
0020         _data = data;
0021     }
0022 public:
0023     inline const char* getData() const { return _data; }
0024     inline bool isValid() const { return _data; }
0025     inline bool operator==(const FixedSizeParsedObject& o) {
0026         return _data && o._data && _data == o._data;
0027     }
0028 };
0029 
0030 class ParsedObject : public FixedSizeParsedObject {
0031 private:
0032     quint32 _size;
0033 protected:
0034     explicit ParsedObject() :FixedSizeParsedObject(), _size(0) {}
0035     inline void init(const char* data, quint32 size) {
0036         FixedSizeParsedObject::init(data);
0037         _size = size;
0038     }
0039 public:
0040     inline quint32 getSize() const { return _size; }
0041 };
0042 
0043 template <typename T>
0044 class MSOCastArray {
0045 private:
0046     const T* _data;
0047     quint32 _count;
0048 public:
0049     explicit MSOCastArray() :_data(0), _count(0) {}
0050     explicit MSOCastArray(const T* data, qint32 count) :_data(data), _count(count) {}
0051     inline const T* getData() const { return _data; }
0052     QByteArray mid(int pos, int len = -1) const {
0053         if (pos > _count) return QByteArray();
0054         if (len < 0 || len > _count - pos) {
0055             len = _count - pos;
0056         }
0057         return QByteArray(_data + pos, len);
0058     }
0059     inline int getCount() const { return _count; }
0060     inline T operator[](int pos) const { return _data[pos]; }
0061     inline bool operator!=(const QByteArray& b) {
0062         return QByteArray::fromRawData(_data, _count) != b;
0063     }
0064     inline operator QByteArray() const { return QByteArray(_data, _count); }
0065 };
0066 template <typename T> class MSOArray;
0067 template <typename T>
0068 class MSOconst_iterator {
0069 private:
0070     T currentItem;
0071     const MSOArray<T>& c;
0072     quint32 offset;
0073 public:
0074     explicit MSOconst_iterator(const MSOArray<T>& c_, int o) :c(c_), offset(o) {
0075         currentItem = T(c.getData(), c.getSize());
0076     }
0077     inline bool operator!=(const MSOconst_iterator &o) const {
0078         return offset != o.offset;
0079     }
0080     inline void operator++() {
0081         offset += currentItem.getSize();
0082         currentItem = T(c.getData() + offset, c.getSize() - offset);
0083     }
0084     inline const T& operator*() const {
0085         return currentItem;
0086     }
0087 };
0088 template <typename T>
0089 class MSONullable {
0090 private:
0091     T t;
0092 public:
0093     MSONullable() {}
0094     MSONullable(const T& data) :t(data) {}
0095     inline bool isPresent() const { return t.isValid(); }
0096     inline quint32 getSize() const { return t.getSize(); }
0097     inline const T& operator * () const { return t; }
0098 };
0099 template <typename T>
0100 class MSOBasicNullable {
0101 private:
0102     T _value;
0103     bool _set;
0104 public:
0105     explicit MSOBasicNullable() :_value(0), _set(false) {}
0106     MSOBasicNullable(T value) :_value(value), _set(true) {}
0107     inline bool isPresent() const { return _set; }
0108     inline T operator * () const { return _value; }
0109 };
0110 template <typename T>
0111 class MSOArray : public ParsedObject {
0112 friend class MSOconst_iterator<T>;
0113 private:
0114     quint32 _count;
0115 public:
0116     typedef MSOconst_iterator<T> const_iterator;
0117     MSOArray() :_count(0) {}
0118     MSOArray(const char* d, quint32 maxsize) :_count(0) {
0119         quint32 msize = 0;
0120         quint32 mcount = 0;
0121         while (msize < maxsize) {
0122             T v(d + msize, maxsize - msize);
0123             if (!v.isValid()) {
0124                 break;
0125             }
0126             msize += v.getSize();
0127             mcount++;
0128         }
0129         ParsedObject::init(d, msize);
0130         _count = mcount;
0131     }
0132     MSOArray(const char* d, quint32 maxsize, quint32 mcount) :_count(0) {
0133         quint32 msize = 0;
0134         for (quint32 i = 0; i < mcount; ++i) {
0135             T v(d + msize, maxsize - msize);
0136             if (!v.isValid()) {
0137                 return;
0138             }
0139             msize += v.getSize();
0140             if (msize > maxsize) {
0141                 return;
0142             }
0143         }
0144         ParsedObject::init(d, msize);
0145         _count = mcount;
0146     }
0147     inline quint32 getCount() const {
0148         return _count;
0149     }
0150     inline MSOconst_iterator<T> begin() const {
0151         return MSOconst_iterator<T>(*this, 0);
0152     }
0153     inline MSOconst_iterator<T> end() const {
0154         return MSOconst_iterator<T>(*this, getSize());
0155     }
0156     T operator[](quint32 pos) const {
0157         T t(ParsedObject::getData(), ParsedObject::getSize());
0158         quint32 i = 0;
0159         quint32 offset = 0;
0160         while (i < pos && t.isValid()) {
0161             offset += t.getSize();
0162             t = T(ParsedObject::getData() + offset,
0163                   ParsedObject::getSize() - offset);
0164             ++i;
0165         }
0166         return t;
0167     }
0168 };
0169 
0170 inline quint8 readuint8(const char* d) {
0171     return *d;
0172 }
0173 inline quint16 readuint16(const char* d) {
0174     return qFromLittleEndian<quint16>((const unsigned char*)d);
0175 }
0176 inline qint16 readint16(const char* d) {
0177     return qFromLittleEndian<qint16>((const unsigned char*)d);
0178 }
0179 inline quint32 readuint32(const char* d) {
0180     return qFromLittleEndian<quint32>((const unsigned char*)d);
0181 }
0182 inline qint32 readint32(const char* d) {
0183     return qFromLittleEndian<qint32>((const unsigned char*)d);
0184 }
0185 
0186 inline bool readbit(const char* d) {
0187     return *d & 0x01;
0188 }
0189 inline bool readbit_1(const char* d) {
0190     return *d >> 1 & 0x01;
0191 }
0192 inline bool readbit_2(const char* d) {
0193     return *d >> 2 & 0x01;
0194 }
0195 inline bool readbit_3(const char* d) {
0196     return *d >> 3 & 0x01;
0197 }
0198 inline bool readbit_4(const char* d) {
0199     return *d >> 4 & 0x01;
0200 }
0201 inline bool readbit_5(const char* d) {
0202     return *d >> 5 & 0x01;
0203 }
0204 inline bool readbit_6(const char* d) {
0205     return *d >> 6 & 0x01;
0206 }
0207 inline bool readbit_7(const char* d) {
0208     return *d >> 7 & 0x01;
0209 }
0210 inline quint8 readuint2(const char* d) {
0211     return *d & 0x03;
0212 }
0213 inline quint8 readuint2_2(const char* d) {
0214     return *d >> 2 & 0x03;
0215 }
0216 inline quint8 readuint2_4(const char* d) {
0217     return *d >> 4 & 0x03;
0218 }
0219 inline quint8 readuint2_6(const char* d) {
0220     return *d >> 6 & 0x03;
0221 }
0222 inline quint8 readuint3(const char* d) {
0223     return *d & 0x07;
0224 }
0225 inline quint8 readuint3_2(const char* d) {
0226     return *d >> 2 & 0x07;
0227 }
0228 inline quint8 readuint3_5(const char* d) {
0229     return *d >> 5 & 0x07;
0230 }
0231 inline quint8 readuint4(const char* d) {
0232     return *d & 0x0F;
0233 }
0234 inline quint8 readuint4_2(const char* d) {
0235     return *d >> 2 & 0x0F;
0236 }
0237 inline quint8 readuint4_4(const char* d) {
0238     return *d >> 4 & 0x0F;
0239 }
0240 inline quint8 readuint5(const char* d) {
0241     return *d & 0x1F;
0242 }
0243 inline quint8 readuint5_3(const char* d) {
0244     return *d >> 3 & 0x1F;
0245 }
0246 inline quint8 readuint6(const char* d) {
0247     return *d & 0x3F;
0248 }
0249 inline quint8 readuint6_2(const char* d) {
0250     return *d >> 2 & 0x3F;
0251 }
0252 inline quint8 readuint7(const char* d) {
0253     return *d & 0x7F;
0254 }
0255 inline quint8 readuint7_1(const char* d) {
0256     return *d >> 1 & 0x7F;
0257 }
0258 inline quint16 readuint9(const char* d) {
0259     return readuint16(d) & 0x01FF;
0260 }
0261 inline quint16 readuint12_4(const char* d) {
0262     return readuint16(d) >> 4 & 0x0FFF;
0263 }
0264 inline quint16 readuint13_3(const char* d) {
0265     return readuint16(d) >> 3 & 0x1FFF;
0266 }
0267 inline quint16 readuint14(const char* d) {
0268     return readuint16(d) & 0x3FFF;
0269 }
0270 inline quint16 readuint14_2(const char* d) {
0271     return readuint16(d) >> 2 & 0x3FFF;
0272 }
0273 inline quint16 readuint15_1(const char* d) {
0274     return readuint16(d) >> 1 & 0x7FFF;
0275 }
0276 inline quint32 readuint20(const char* d) {
0277     return readuint32(d) & 0x0FFFFF;
0278 }
0279 inline quint32 readuint20_4(const char* d) {
0280     return readuint32(d) >> 4 & 0x0FFFFF;
0281 }
0282 inline quint32 readuint30(const char* d) {
0283     return readuint32(d) & 0x3FFFFFFF;
0284 }
0285 
0286 #endif