1#include <assert.h>
2#include <stdint.h>
3#include <stdlib.h>
4#include <string.h>
5
6#include "lsqpack.h"
7#include "lsqpack-test.h"
8
9struct int_test
10{
11    int             it_lineno;
12    unsigned        it_prefix_bits;
13    unsigned char   it_encoded[20];
14    size_t          it_enc_sz;
15    uint64_t        it_decoded;
16    int             it_dec_retval;
17};
18
19static const struct int_test tests[] =
20{
21
22    {   .it_lineno      = __LINE__,
23        .it_prefix_bits = 7,
24        .it_encoded     = { 0x7F, 0x02, },
25        .it_enc_sz      = 2,
26        .it_decoded     = 0x81,
27        .it_dec_retval  = 0,
28    },
29
30    /* RFC 7541, Appendinx C.1.1 */
31    {   .it_lineno      = __LINE__,
32        .it_prefix_bits = 5,
33        .it_encoded     = { 0b1010, 0x02, },
34        .it_enc_sz      = 1,
35        .it_decoded     = 10,
36        .it_dec_retval  = 0,
37    },
38
39    /* RFC 7541, Appendinx C.1.2 */
40    {   .it_lineno      = __LINE__,
41        .it_prefix_bits = 5,
42        .it_encoded     = { 0b11111, 0b10011010, 0b00001010, },
43        .it_enc_sz      = 3,
44        .it_decoded     = 1337,
45        .it_dec_retval  = 0,
46    },
47
48    /* RFC 7541, Appendinx C.1.3 */
49    {   .it_lineno      = __LINE__,
50        .it_prefix_bits = 8,
51        .it_encoded     = { 0b101010, },
52        .it_enc_sz      = 1,
53        .it_decoded     = 42,
54        .it_dec_retval  = 0,
55    },
56
57    {   .it_lineno      = __LINE__,
58        .it_prefix_bits = 7,
59        .it_encoded     = { 0b01111111, 0b10000001, 0b10000010, 0b00000011, },
60        .it_enc_sz      = 4,
61                       /*     01234560123456 */
62        .it_decoded     = 0b1100000100000001    + 0b1111111,
63        .it_dec_retval  = 0,
64    },
65
66    {   .it_lineno      = __LINE__,
67        .it_prefix_bits = 7,
68        .it_encoded     = { 0b01111111, 0b10000001, 0b10000010, 0b10000011,
69                            0b00000011, },
70        .it_enc_sz      = 5,
71                       /*     012345601234560123456 */
72        .it_decoded     = 0b11000001100000100000001    + 0b1111111,
73        .it_dec_retval  = 0,
74    },
75
76    {   .it_lineno      = __LINE__,
77        .it_prefix_bits = 7,
78        .it_encoded     = { 0b01111111, 0b10000001, 0b10000010, 0b10000011,
79                            0b10000100, 0b10000101, 0b10000110, 0b10000111,
80                            0b10001000,
81                            0b00000011, },
82        .it_enc_sz      = 10,
83                       /*     01234560123456012345601234560123456012345601234560123456 */
84        .it_decoded     = 0b1100010000000111000011000001010000100000001100000100000001
85                                + 0b1111111,
86        .it_dec_retval  = 0,
87    },
88
89    {   .it_lineno      = __LINE__,
90        .it_prefix_bits = 7,
91        .it_encoded     = { 0b01111111, 0b10000001, 0b10000010, 0b10000011,
92                            0b10000100, 0b10000101, 0b10000110, 0b10000111,
93                            0b10001000, 0b10001001,
94                            0b00000001, },
95        .it_enc_sz      = 11,
96                       /*    012345601234560123456012345601234560123456012345601234560123456 */
97        .it_decoded     = 0b1000100100010000000111000011000001010000100000001100000100000001
98                                + 0b1111111,
99        .it_dec_retval  = 0,
100    },
101
102    {   .it_lineno      = __LINE__,
103        .it_prefix_bits = 7,
104        .it_encoded     = { 0b01111111, 0b10000000, 0b11111111, 0b11111111,
105                            0b11111111, 0b11111111, 0b11111111, 0b11111111,
106                            0b11111111, 0b11111111,
107                            0b00000001, },
108        .it_enc_sz      = 11,
109        .it_decoded     = UINT64_MAX,
110        .it_dec_retval  = 0,
111    },
112
113    {   .it_lineno      = __LINE__,
114        .it_prefix_bits = 7,
115            /* Same as above, but with extra bit that overflows it */
116                                      /* ----v---- */
117        .it_encoded     = { 0b01111111, 0b10010000, 0b11111111, 0b11111111,
118                            0b11111111, 0b11111111, 0b11111111, 0b11111111,
119                            0b11111111, 0b11111111,
120                            0b00000001, },
121        .it_enc_sz      = 11,
122        .it_dec_retval  = -2,
123    },
124
125    {   .it_lineno      = __LINE__,
126        .it_prefix_bits = 8,
127        .it_encoded     = { 0b11111111, 0b10000001, 0b10000010, 0b10000011,
128                            0b10000100, 0b10000101, 0b10000110, 0b10000111,
129                            0b10001000, 0b10001001, 0b00000001, },
130        .it_enc_sz      = 11,
131                       /*    012345601234560123456012345601234560123456012345601234560123456 */
132        .it_decoded     = 0b1000100100010000000111000011000001010000100000001100000100000001
133                                + 0b11111111,
134        .it_dec_retval  = 0,
135    },
136
137    {   .it_lineno      = __LINE__,
138        .it_prefix_bits = 7,
139        .it_encoded     = { 0b01111111, 0b11101111, 0b11111111, 0b11111111,
140                            0b11111111, 0b11111111, 0b11111111, 0b11111111,
141                            0b11111111, 0b11111111,
142                            0b00000001, },
143        .it_enc_sz      = 11,
144        .it_dec_retval  = -2,
145    },
146
147    {   .it_lineno      = __LINE__,
148        .it_prefix_bits = 7,
149        .it_encoded     = { 0b01111111, 0b10000001, 0b10000010, 0b10000011,
150                            0b10000100, 0b10000101, 0b10000110, 0b10000111,
151                            0b10001000, 0b10001001,
152                            0b00000011, },
153        .it_enc_sz      = 11,
154        .it_dec_retval  = -2,
155    },
156
157    {   .it_lineno      = __LINE__,
158        .it_prefix_bits = 7,
159        .it_encoded     = { 0x7F, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
160                            0xFF, 0xFF, 0xFF, },
161        .it_enc_sz      = 11,
162        .it_dec_retval  = -2,
163    },
164
165};
166
167int
168main (void)
169{
170    const struct int_test *test;
171    const unsigned char *src;
172    unsigned char *dst;
173    unsigned char buf[ sizeof(((struct int_test *) NULL)->it_encoded) ];
174    uint64_t val;
175    size_t sz;
176    int rv;
177
178    /* Test the decoder */
179    for (test = tests; test < tests + sizeof(tests) / sizeof(tests[0]); ++test)
180    {
181        struct lsqpack_dec_int_state state;
182        state.resume = 0;
183        for (sz = 0; sz < test->it_enc_sz - 1; ++sz)
184        {
185            src = test->it_encoded + sz;
186            rv = lsqpack_dec_int(&src, src + 1, test->it_prefix_bits,
187                                                                &val, &state);
188            assert(-1 == rv);
189        }
190        src = test->it_encoded + sz;
191        rv = lsqpack_dec_int(&src, src + 1, test->it_prefix_bits,
192                                                            &val, &state);
193        assert(rv == test->it_dec_retval);
194        if (0 == rv)
195            assert(val == test->it_decoded);
196    }
197
198    /* Test the encoder */
199    for (test = tests; test < tests + sizeof(tests) / sizeof(tests[0]); ++test)
200    {
201        if (test->it_dec_retval != 0)
202            continue;
203        for (sz = 1; sz < test->it_enc_sz; ++sz)
204        {
205            dst = lsqpack_enc_int(buf, buf + sz, test->it_decoded,
206                                                        test->it_prefix_bits);
207            assert(dst == buf);     /* Not enough room */
208        }
209        for (; sz <= sizeof(buf); ++sz)
210        {
211            buf[0] = '\0';
212            dst = lsqpack_enc_int(buf, buf + sz, test->it_decoded,
213                                                        test->it_prefix_bits);
214            assert(dst - buf == (intptr_t) test->it_enc_sz);
215            assert(0 == memcmp(buf, test->it_encoded, test->it_enc_sz));
216        }
217    }
218
219    return 0;
220}
221