1 /* vim: set expandtab ts=4 sw=4: */
2 /*
3 * You may redistribute this program and/or modify it under the terms of
4 * the GNU General Public License as published by the Free Software Foundation,
5 * either version 3 of the License, or (at your option) any later version.
6 *
7 * This program is distributed in the hope that it will be useful,
8 * but WITHOUT ANY WARRANTY; without even the implied warranty of
9 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
10 * GNU General Public License for more details.
11 *
12 * You should have received a copy of the GNU General Public License
13 * along with this program. If not, see <https://www.gnu.org/licenses/>.
14 */
15 #include "memory/MallocAllocator.h"
16 #include "crypto/random/Random.h"
17 #include "util/VarInt.h"
18 #include "util/Assert.h"
19 #include "util/Bits.h"
20
21 #include <stdio.h>
22
23 #define BUF_SZ 1024
24
fidelityTest()25 static void fidelityTest()
26 {
27 struct Allocator* alloc = MallocAllocator_new(1<<20);
28 struct Random* rand = Random_new(alloc, NULL, NULL);
29 uint64_t* buf = Allocator_malloc(alloc, BUF_SZ*8);
30 Random_bytes(rand, (uint8_t*) buf, BUF_SZ*8);
31
32 // make a mix of different size numbers
33 for (int i = 0; i < BUF_SZ; i++) {
34 uint64_t x = buf[i];
35 switch (x & 3) {
36 case 3: break;
37 case 2: buf[i] = x >> 32; break;
38 case 1: buf[i] = x >> 48; break;
39 case 0: buf[i] = x >> 56; break;
40 }
41 }
42
43 uint8_t* buf2 = Allocator_malloc(alloc, BUF_SZ*8);
44 struct VarInt_Iter iter;
45 VarInt_mk(&iter, buf2, BUF_SZ*8);
46 VarInt_toEnd(&iter);
47
48 for (int i = 0; i < BUF_SZ; i++) { Assert_true(!VarInt_push(&iter, buf[i])); }
49 Assert_true(iter.ptr > buf2);
50
51 for (int i = BUF_SZ - 1; i >= 0; i--) {
52 uint64_t x = ~0;
53 Assert_true(!VarInt_pop(&iter, &x));
54 Assert_true(buf[i] == x);
55 }
56
57 Assert_true(iter.ptr == iter.end);
58
59 Allocator_free(alloc);
60 }
61
test(uint8_t * bytes,int len,uint64_t num,uint8_t * buf)62 static inline void test(uint8_t* bytes, int len, uint64_t num, uint8_t* buf)
63 {
64 struct VarInt_Iter iter = { .ptr = bytes, .end = &bytes[len], .start = bytes };
65 uint64_t out = ~0;
66 Assert_true(!VarInt_pop(&iter, &out));
67 Assert_true(out == num);
68 Assert_true(iter.ptr == iter.end);
69
70 buf[0] = buf[len+1] = 0xee;
71 struct VarInt_Iter iter2 = { .ptr = &buf[len+1], .end = &buf[len+1], .start = &buf[1] };
72 if (len < 9) { Assert_true(VarInt_push(&iter2, 0xf000000000000000ull)); }
73 if (len < 5) { Assert_true(VarInt_push(&iter2, 0xf0000000)); }
74 if (len < 3) { Assert_true(VarInt_push(&iter2, 0xf000)); }
75 Assert_true(!VarInt_push(&iter2, num));
76 Assert_true(iter2.ptr == iter2.start);
77 Assert_true(buf[0] == 0xee);
78 Assert_true(buf[len+1] == 0xee);
79 }
80 #define TEST(bytes, num) do { \
81 uint8_t data[sizeof(bytes)+1] = {0}; \
82 test(bytes, sizeof(bytes)-1, num, data); \
83 } while (0)
84 // CHECKFILES_IGNORE expecting a ;
85
simpleTest()86 static void simpleTest()
87 {
88 TEST("\x00", 0x00);
89 TEST("\xAC", 0xAC);
90 TEST("\xFD\xAB\xCD", 0xABCD);
91 TEST("\xFE\xAB\xCD\xEF\x01", 0xABCDEF01);
92 TEST("\xFF\xAB\xCD\xEF\x01\x23\x45\x67\x89", 0xABCDEF0123456789ull);
93 }
94
main()95 int main()
96 {
97 simpleTest();
98 fidelityTest();
99 return 0;
100 }