1
#ifndef LEINPUT_H
2
#define LEINPUT_H
3
4
#include <QtCore/QtEndian>
5
#include <QtCore/QByteArray>
6
#include <QtCore/QDebug>
7
8
template <typename T>
9
const T*
10
toPtr(const T& t) {
11
    return (t.isValid()) ?&t :0;
12
}
13
14
class FixedSizeParsedObject {
15
private:
16
    const char* _data;
17
protected:
18
    explicit FixedSizeParsedObject() :_data(0) {}
19
    inline void init(const char* data) {
20
        _data = data;
21
    }
22
public:
23
    inline const char* getData() const { return _data; }
24
    inline bool isValid() const { return _data; }
25
    inline bool operator==(const FixedSizeParsedObject& o) {
26
        return _data && o._data && _data == o._data;
27
    }
28
};
29
30
class ParsedObject : public FixedSizeParsedObject {
31
private:
32
    quint32 _size;
33
protected:
34
    explicit ParsedObject() :FixedSizeParsedObject(), _size(0) {}
35
    inline void init(const char* data, quint32 size) {
36
        FixedSizeParsedObject::init(data);
37
        _size = size;
38
    }
39
public:
40
    inline quint32 getSize() const { return _size; }
41
};
42
43
template <typename T>
44
class MSOCastArray {
45
private:
46
    const T* _data;
47
    quint32 _count;
48
public:
49
    explicit MSOCastArray() :_data(0), _count(0) {}
50
    explicit MSOCastArray(const T* data, qint32 count) :_data(data), _count(count) {}
51
    inline const T* getData() const { return _data; }
52
    QByteArray mid(int pos, int len = -1) const {
53
        if (pos > _count) return QByteArray();
54
        if (len < 0 || len > _count - pos) {
55
            len = _count - pos;
56
        }
57
        return QByteArray(_data + pos, len);
58
    }
59
    inline int getCount() const { return _count; }
60
    inline T operator[](int pos) const { return _data[pos]; }
61
    inline bool operator!=(const QByteArray& b) {
62
        return QByteArray::fromRawData(_data, _count) != b;
63
    }
64
    inline operator QByteArray() const { return QByteArray(_data, _count); }
65
};
66
template <typename T> class MSOArray;
67
template <typename T>
68
class MSOconst_iterator {
69
private:
70
    T currentItem;
71
    const MSOArray<T>& c;
72
    quint32 offset;
73
public:
74
    explicit MSOconst_iterator(const MSOArray<T>& c_, int o) :c(c_), offset(o) {
75
        currentItem = T(c.getData(), c.getSize());
76
    }
77
    inline bool operator!=(const MSOconst_iterator &o) const {
78
        return offset != o.offset;
79
    }
80
    inline void operator++() {
81
        offset += currentItem.getSize();
82
        currentItem = T(c.getData() + offset, c.getSize() - offset);
83
    }
84
    inline const T& operator*() const {
85
        return currentItem;
86
    }
87
};
88
template <typename T>
89
class MSONullable {
90
private:
91
    T t;
92
public:
93
    MSONullable() {}
94
    MSONullable(const T& data) :t(data) {}
95
    inline bool isPresent() const { return t.isValid(); }
96
    inline quint32 getSize() const { return t.getSize(); }
97
    inline const T& operator * () const { return t; }
98
};
99
template <typename T>
100
class MSOBasicNullable {
101
private:
102
    T _value;
103
    bool _set;
104
public:
105
    explicit MSOBasicNullable() :_value(0), _set(false) {}
106
    MSOBasicNullable(T value) :_value(value), _set(true) {}
107
    inline bool isPresent() const { return _set; }
108
    inline T operator * () const { return _value; }
109
};
110
template <typename T>
111
class MSOArray : public ParsedObject {
112
friend class MSOconst_iterator<T>;
113
private:
114
    quint32 _count;
115
public:
116
    typedef MSOconst_iterator<T> const_iterator;
117
    MSOArray() :_count(0) {}
118
    MSOArray(const char* d, quint32 maxsize) :_count(0) {
119
        quint32 msize = 0;
120
        quint32 mcount = 0;
121
        while (msize < maxsize) {
122
            T v(d + msize, maxsize - msize);
123
            if (!v.isValid()) {
124
                break;
125
            }
126
            msize += v.getSize();
127
            mcount++;
128
        }
129
        ParsedObject::init(d, msize);
130
        _count = mcount;
131
    }
132
    MSOArray(const char* d, quint32 maxsize, quint32 mcount) :_count(0) {
133
        quint32 msize = 0;
134
        for (quint32 i = 0; i < mcount; ++i) {
135
            T v(d + msize, maxsize - msize);
136
            if (!v.isValid()) {
137
                return;
138
            }
139
            msize += v.getSize();
140
            if (msize > maxsize) {
141
                return;
142
            }
143
        }
144
        ParsedObject::init(d, msize);
145
        _count = mcount;
146
    }
147
    inline quint32 getCount() const {
148
        return _count;
149
    }
150
    inline MSOconst_iterator<T> begin() const {
151
        return MSOconst_iterator<T>(*this, 0);
152
    }
153
    inline MSOconst_iterator<T> end() const {
154
        return MSOconst_iterator<T>(*this, getSize());
155
    }
156
    T operator[](quint32 pos) const {
157
        T t(ParsedObject::getData(), ParsedObject::getSize());
158
        quint32 i = 0;
159
        quint32 offset = 0;
160
        while (i < pos && t.isValid()) {
161
            offset += t.getSize();
162
            t = T(ParsedObject::getData() + offset,
163
                  ParsedObject::getSize() - offset);
164
            ++i;
165
        }
166
        return t;
167
    }
168
};
169
170
inline quint8 readuint8(const char* d) {
171
    return *d;
172
}
173
inline quint16 readuint16(const char* d) {
174
    return qFromLittleEndian<quint16>((const unsigned char*)d);
175
}
176
inline qint16 readint16(const char* d) {
177
    return qFromLittleEndian<qint16>((const unsigned char*)d);
178
}
179
inline quint32 readuint32(const char* d) {
180
    return qFromLittleEndian<quint32>((const unsigned char*)d);
181
}
182
inline qint32 readint32(const char* d) {
183
    return qFromLittleEndian<qint32>((const unsigned char*)d);
184
}
185
186
inline bool readbit(const char* d) {
187
    return *d & 0x01;
188
}
189
inline bool readbit_1(const char* d) {
190
    return *d >> 1 & 0x01;
191
}
192
inline bool readbit_2(const char* d) {
193
    return *d >> 2 & 0x01;
194
}
195
inline bool readbit_3(const char* d) {
196
    return *d >> 3 & 0x01;
197
}
198
inline bool readbit_4(const char* d) {
199
    return *d >> 4 & 0x01;
200
}
201
inline bool readbit_5(const char* d) {
202
    return *d >> 5 & 0x01;
203
}
204
inline bool readbit_6(const char* d) {
205
    return *d >> 6 & 0x01;
206
}
207
inline bool readbit_7(const char* d) {
208
    return *d >> 7 & 0x01;
209
}
210
inline quint8 readuint2(const char* d) {
211
    return *d & 0x03;
212
}
213
inline quint8 readuint2_2(const char* d) {
214
    return *d >> 2 & 0x03;
215
}
216
inline quint8 readuint2_4(const char* d) {
217
    return *d >> 4 & 0x03;
218
}
219
inline quint8 readuint2_6(const char* d) {
220
    return *d >> 6 & 0x03;
221
}
222
inline quint8 readuint3(const char* d) {
223
    return *d & 0x07;
224
}
225
inline quint8 readuint3_2(const char* d) {
226
    return *d >> 2 & 0x07;
227
}
228
inline quint8 readuint3_5(const char* d) {
229
    return *d >> 5 & 0x07;
230
}
231
inline quint8 readuint4(const char* d) {
232
    return *d & 0x0F;
233
}
234
inline quint8 readuint4_2(const char* d) {
235
    return *d >> 2 & 0x0F;
236
}
237
inline quint8 readuint4_4(const char* d) {
238
    return *d >> 4 & 0x0F;
239
}
240
inline quint8 readuint5(const char* d) {
241
    return *d & 0x1F;
242
}
243
inline quint8 readuint5_3(const char* d) {
244
    return *d >> 3 & 0x1F;
245
}
246
inline quint8 readuint6(const char* d) {
247
    return *d & 0x3F;
248
}
249
inline quint8 readuint6_2(const char* d) {
250
    return *d >> 2 & 0x3F;
251
}
252
inline quint8 readuint7(const char* d) {
253
    return *d & 0x7F;
254
}
255
inline quint8 readuint7_1(const char* d) {
256
    return *d >> 1 & 0x7F;
257
}
258
inline quint16 readuint9(const char* d) {
259
    return readuint16(d) & 0x01FF;
260
}
261
inline quint16 readuint12_4(const char* d) {
262
    return readuint16(d) >> 4 & 0x0FFF;
263
}
264
inline quint16 readuint13_3(const char* d) {
265
    return readuint16(d) >> 3 & 0x1FFF;
266
}
267
inline quint16 readuint14(const char* d) {
268
    return readuint16(d) & 0x3FFF;
269
}
270
inline quint16 readuint14_2(const char* d) {
271
    return readuint16(d) >> 2 & 0x3FFF;
272
}
273
inline quint16 readuint15_1(const char* d) {
274
    return readuint16(d) >> 1 & 0x7FFF;
275
}
276
inline quint32 readuint20(const char* d) {
277
    return readuint32(d) & 0x0FFFFF;
278
}
279
inline quint32 readuint20_4(const char* d) {
280
    return readuint32(d) >> 4 & 0x0FFFFF;
281
}
282
inline quint32 readuint30(const char* d) {
283
    return readuint32(d) & 0x3FFFFFFF;
284
}
285
286
#endif