1 | /* |
2 | SPDX-FileCopyrightText: 2025 Stefan BrĂ¼ns <stefan.bruens@rwth-aachen.de> |
3 | SPDX-License-Identifier: LGPL-2.1-or-later |
4 | */ |
5 | |
6 | #include "../lib/bitreader_p.h" |
7 | |
8 | #include <QTest> |
9 | |
10 | using namespace Mobipocket; |
11 | |
12 | class BitReaderTest : public QObject |
13 | { |
14 | Q_OBJECT |
15 | public: |
16 | void setLocalized(bool); |
17 | |
18 | private Q_SLOTS: |
19 | void testRead_1(); |
20 | void testRead_2(); |
21 | void testRead1Bit(); |
22 | void testRead8Bit(); |
23 | void testRead16Bit(); |
24 | void testRead12Bit(); |
25 | void benchmarkInit(); |
26 | void benchmarkInitSlice(); |
27 | void benchmarkRead(); |
28 | void benchmarkRead_data(); |
29 | }; |
30 | |
31 | void BitReaderTest::testRead_1() |
32 | { |
33 | QByteArray data(1, '\x01'); |
34 | |
35 | BitReader r(data); |
36 | |
37 | QCOMPARE(r.left(), 8); |
38 | QCOMPARE(r.read(), 0x01000000); |
39 | QVERIFY(r.eat(4)); |
40 | |
41 | QCOMPARE(r.left(), 4); |
42 | QCOMPARE(r.read(), 0x10000000); |
43 | QVERIFY(r.eat(2)); |
44 | |
45 | QCOMPARE(r.left(), 2); |
46 | QCOMPARE(r.read(), 0x40000000); |
47 | QVERIFY(r.eat(1)); |
48 | |
49 | QCOMPARE(r.left(), 1); |
50 | QCOMPARE(r.read(), 0x80000000); |
51 | QVERIFY(r.eat(1)); |
52 | |
53 | QCOMPARE(r.left(), 0); |
54 | QCOMPARE(r.read(), 0x00000000); |
55 | QVERIFY(!r.eat(1)); |
56 | } |
57 | |
58 | void BitReaderTest::testRead_2() |
59 | { |
60 | QByteArray data("\x01\xff\xaa\x81" , 4); |
61 | |
62 | BitReader r(data); |
63 | |
64 | QCOMPARE(r.left(), 32); |
65 | QCOMPARE(r.read(), 0x01ffaa81); |
66 | QVERIFY(r.eat(4)); |
67 | |
68 | QCOMPARE(r.left(), 28); |
69 | QCOMPARE(r.read(), 0x1ffaa810); |
70 | QVERIFY(r.eat(2)); |
71 | |
72 | QCOMPARE(r.left(), 26); |
73 | QCOMPARE(r.read(), 0x7feaa040); |
74 | QVERIFY(r.eat(1)); |
75 | |
76 | QCOMPARE(r.left(), 25); |
77 | QCOMPARE(r.read(), 0xffd54080); |
78 | QVERIFY(r.eat(1)); |
79 | |
80 | QCOMPARE(r.left(), 24); |
81 | QCOMPARE(r.read(), 0xffaa8100); |
82 | QVERIFY(r.eat(16)); |
83 | |
84 | QCOMPARE(r.left(), 8); |
85 | QCOMPARE(r.read(), 0x81000000); |
86 | QVERIFY(r.eat(4)); |
87 | |
88 | QCOMPARE(r.left(), 4); |
89 | QCOMPARE(r.read(), 0x10000000); |
90 | QVERIFY(r.eat(3)); |
91 | |
92 | QCOMPARE(r.left(), 1); |
93 | QCOMPARE(r.read(), 0x80000000); |
94 | QVERIFY(r.eat(1)); |
95 | |
96 | QCOMPARE(r.left(), 0); |
97 | QCOMPARE(r.read(), 0x00000000); |
98 | QVERIFY(!r.eat(1)); |
99 | } |
100 | |
101 | void BitReaderTest::testRead1Bit() |
102 | { |
103 | QByteArray data(128, '\x01'); |
104 | |
105 | size_t count = 0; |
106 | BitReader r(data); |
107 | while (r.left()) { |
108 | count++; |
109 | r.read(); |
110 | r.eat(n: 1); |
111 | } |
112 | QCOMPARE(count, 1024); |
113 | |
114 | QCOMPARE(r.left(), 0); |
115 | QCOMPARE(r.read(), 0x00000000); |
116 | QVERIFY(!r.eat(1)); |
117 | } |
118 | |
119 | void BitReaderTest::testRead8Bit() |
120 | { |
121 | QByteArray data(1024, '\x01'); |
122 | |
123 | size_t count = 0; |
124 | BitReader r(data); |
125 | while (r.left() > 24) { |
126 | count++; |
127 | auto t = r.read(); |
128 | QCOMPARE(t, 0x01010101); |
129 | r.eat(n: 8); |
130 | } |
131 | QCOMPARE(count, 1021); |
132 | |
133 | QCOMPARE(r.read(), 0x01010100); |
134 | QVERIFY(r.eat(8)); |
135 | QCOMPARE(r.read(), 0x01010000); |
136 | QVERIFY(r.eat(8)); |
137 | QCOMPARE(r.read(), 0x01000000); |
138 | QVERIFY(r.eat(8)); |
139 | QCOMPARE(r.left(), 0); |
140 | QCOMPARE(r.read(), 0x00000000); |
141 | QVERIFY(!r.eat(1)); |
142 | } |
143 | |
144 | void BitReaderTest::testRead16Bit() |
145 | { |
146 | QByteArray data(1024, '\x01'); |
147 | |
148 | size_t count = 0; |
149 | BitReader r(data); |
150 | while (r.left() > 24) { |
151 | count++; |
152 | auto t = r.read(); |
153 | QCOMPARE(t, 0x01010101); |
154 | r.eat(n: 16); |
155 | } |
156 | QCOMPARE(count, 511); |
157 | |
158 | QCOMPARE(r.read(), 0x01010000); |
159 | QVERIFY(r.eat(16)); |
160 | QCOMPARE(r.left(), 0); |
161 | QCOMPARE(r.read(), 0x00000000); |
162 | QVERIFY(!r.eat(1)); |
163 | } |
164 | |
165 | void BitReaderTest::testRead12Bit() |
166 | { |
167 | QByteArray data(304, '\x01'); |
168 | |
169 | BitReader r(data); |
170 | |
171 | size_t count = 0; |
172 | while (r.left() > 36) { |
173 | count++; |
174 | auto t = r.read(); |
175 | QCOMPARE(t, 0x01010101); |
176 | QVERIFY(r.eat(12)); |
177 | t = r.read(); |
178 | QCOMPARE(t, 0x10101010); |
179 | QVERIFY(r.eat(12)); |
180 | } |
181 | QCOMPARE(count, 100); |
182 | |
183 | QCOMPARE(r.left(), 32); |
184 | QCOMPARE(r.read(), 0x01010101); |
185 | QVERIFY(r.eat(12)); |
186 | QCOMPARE(r.left(), 20); |
187 | QCOMPARE(r.read(), 0x10101000); |
188 | QVERIFY(r.eat(12)); |
189 | QCOMPARE(r.left(), 8); |
190 | QCOMPARE(r.read(), 0x01000000); |
191 | QVERIFY(r.eat(8)); |
192 | QVERIFY(!r.eat(1)); |
193 | } |
194 | |
195 | void BitReaderTest::benchmarkInit() |
196 | { |
197 | QByteArray data(1024, '\0'); |
198 | |
199 | QBENCHMARK { |
200 | BitReader r(data); |
201 | } |
202 | } |
203 | |
204 | void BitReaderTest::benchmarkInitSlice() |
205 | { |
206 | QByteArray data(1024, '\0'); |
207 | |
208 | QBENCHMARK { |
209 | BitReader r(data.mid(index: 1)); |
210 | } |
211 | } |
212 | |
213 | void BitReaderTest::benchmarkRead() |
214 | { |
215 | QFETCH(QByteArray, data); |
216 | QFETCH(int, count); |
217 | |
218 | qint64 t = 0; |
219 | QBENCHMARK { |
220 | BitReader r(data); |
221 | while (r.left() > 0) { |
222 | t += r.read(); |
223 | r.eat(n: count); |
224 | } |
225 | } |
226 | QVERIFY(t > (data.size() / count)); |
227 | } |
228 | |
229 | void BitReaderTest::benchmarkRead_data() |
230 | { |
231 | QTest::addColumn<QByteArray>(name: "data" ); |
232 | QTest::addColumn<int>(name: "count" ); |
233 | |
234 | QTest::addRow(format: "1" ) << QByteArray(1024, '\x01') << 1; |
235 | QTest::addRow(format: "4" ) << QByteArray(1024, '\x01') << 4; |
236 | QTest::addRow(format: "8" ) << QByteArray(1024, '\x01') << 8; |
237 | QTest::addRow(format: "12" ) << QByteArray(1024, '\x01') << 12; |
238 | QTest::addRow(format: "7" ) << QByteArray(1024, '\x01') << 7; |
239 | } |
240 | |
241 | QTEST_GUILESS_MAIN(BitReaderTest) |
242 | |
243 | #include "bitreadertest.moc" |
244 | |