13c795f78SDmitri Tikhonov/*
23c795f78SDmitri Tikhonov * Read encoder stream
33c795f78SDmitri Tikhonov */
43c795f78SDmitri Tikhonov
53c795f78SDmitri Tikhonov#include <assert.h>
63c795f78SDmitri Tikhonov#include <stdlib.h>
73c795f78SDmitri Tikhonov#include <string.h>
83c795f78SDmitri Tikhonov
93c795f78SDmitri Tikhonov#include "lsqpack.h"
103c795f78SDmitri Tikhonov
11a7f0eb00SDmitri Tikhonov#define MIN(a, b) ((a) < (b) ? (a) : (b))
12a7f0eb00SDmitri Tikhonov
133c795f78SDmitri Tikhonov/* Dynamic table entry: */
143c795f78SDmitri Tikhonovstruct lsqpack_dec_table_entry
153c795f78SDmitri Tikhonov{
163c795f78SDmitri Tikhonov    unsigned    dte_name_len;
173c795f78SDmitri Tikhonov    unsigned    dte_val_len;
183c795f78SDmitri Tikhonov    unsigned    dte_refcnt;
19439cd37dSDmitri Tikhonov    unsigned    dte_pad[4];     /* name hash, nameval hash, name idx, flags */
203c795f78SDmitri Tikhonov    char        dte_buf[0];     /* Contains both name and value */
213c795f78SDmitri Tikhonov};
223c795f78SDmitri Tikhonov
233c795f78SDmitri Tikhonov#define DTE_NAME(dte) ((dte)->dte_buf)
243c795f78SDmitri Tikhonov#define DTE_VALUE(dte) (&(dte)->dte_buf[(dte)->dte_name_len])
253c795f78SDmitri Tikhonov
263c795f78SDmitri Tikhonov
273c795f78SDmitri Tikhonovstruct test_read_encoder_stream
283c795f78SDmitri Tikhonov{
293c795f78SDmitri Tikhonov    int             lineno;
303c795f78SDmitri Tikhonov
313c795f78SDmitri Tikhonov    /* Input */
323c795f78SDmitri Tikhonov    unsigned char   input[0x100];
333c795f78SDmitri Tikhonov    size_t          input_sz;
343c795f78SDmitri Tikhonov
353c795f78SDmitri Tikhonov    /* Output */
363c795f78SDmitri Tikhonov    unsigned        n_entries;
373c795f78SDmitri Tikhonov    struct {
383c795f78SDmitri Tikhonov        const char *name, *value;
393c795f78SDmitri Tikhonov    }               dyn_table[10];
403c795f78SDmitri Tikhonov};
413c795f78SDmitri Tikhonov
423c795f78SDmitri Tikhonov
433c795f78SDmitri Tikhonovstatic const struct test_read_encoder_stream tests[] =
443c795f78SDmitri Tikhonov{
453c795f78SDmitri Tikhonov
463c795f78SDmitri Tikhonov    {   __LINE__,
47c0da112cSDmitri Tikhonov        "\xc0\x8b\xf1\xe3\xc2\xf5\x15\x31\xa2\x45\xcf\x64\xdf",
483c795f78SDmitri Tikhonov        13,
493c795f78SDmitri Tikhonov        1,
503c795f78SDmitri Tikhonov        {
513c795f78SDmitri Tikhonov            { ":authority", "www.netbsd.org", },
523c795f78SDmitri Tikhonov        },
533c795f78SDmitri Tikhonov    },
543c795f78SDmitri Tikhonov
55608798c5SDmitri Tikhonov    {   __LINE__,
56582aa904SStephen Petrides        "\xc0\x00",
57582aa904SStephen Petrides        2,
58582aa904SStephen Petrides        1,
59582aa904SStephen Petrides        {
60582aa904SStephen Petrides            { ":authority", "", },
61582aa904SStephen Petrides        },
62582aa904SStephen Petrides    },
63582aa904SStephen Petrides
64582aa904SStephen Petrides    {   __LINE__,
65c0da112cSDmitri Tikhonov        "\xc0\x8b\xf1\xe3\xc2\xf5\x15\x31\xa2\x45\xcf\x64\xdf\x00",
66608798c5SDmitri Tikhonov        14,
67608798c5SDmitri Tikhonov        2,
68608798c5SDmitri Tikhonov        {
69608798c5SDmitri Tikhonov            { ":authority", "www.netbsd.org", },
70608798c5SDmitri Tikhonov            { ":authority", "www.netbsd.org", },
71608798c5SDmitri Tikhonov        },
72608798c5SDmitri Tikhonov    },
73608798c5SDmitri Tikhonov
748aab2f7dSDmitri Tikhonov    {   __LINE__,
75c0da112cSDmitri Tikhonov        "\xc0\x8b\xf1\xe3\xc2\xf5\x15\x31\xa2\x45\xcf\x64\xdf\x00\x20",
768aab2f7dSDmitri Tikhonov        15,
778aab2f7dSDmitri Tikhonov        0,
788aab2f7dSDmitri Tikhonov        {
79205a2804SDmitri Tikhonov            { NULL, NULL, },
808aab2f7dSDmitri Tikhonov        },
818aab2f7dSDmitri Tikhonov    },
828aab2f7dSDmitri Tikhonov
8341f1e588SDmitri Tikhonov    {   __LINE__,
84c0da112cSDmitri Tikhonov        "\xc0\x15" "Respect my authorata!",
85c3d72583SDmitri Tikhonov        2 + sizeof("Respect my authorata!") - 1,
86c3d72583SDmitri Tikhonov        1,
87c3d72583SDmitri Tikhonov        {
88c3d72583SDmitri Tikhonov            { ":authority", "Respect my authorata!", },
89c3d72583SDmitri Tikhonov        },
90c3d72583SDmitri Tikhonov    },
91c3d72583SDmitri Tikhonov
92c3d72583SDmitri Tikhonov    {   __LINE__,
9341f1e588SDmitri Tikhonov        "\x63\x92\xd9\x0b\x8c\xe5\x39\x6c\x2a\x86\x42\x94\xfa\x50\x83\xb3"
9441f1e588SDmitri Tikhonov        "\xfc",
9541f1e588SDmitri Tikhonov        17,
9641f1e588SDmitri Tikhonov        1,
9741f1e588SDmitri Tikhonov        {
9841f1e588SDmitri Tikhonov            { "dude", "Where is my car?", },
9941f1e588SDmitri Tikhonov        },
10041f1e588SDmitri Tikhonov    },
10141f1e588SDmitri Tikhonov
102fabc7376SDmitri Tikhonov    {   __LINE__,
103fabc7376SDmitri Tikhonov        "\x63\x92\xd9\x0b\x03\x61\x61\x7a",
104fabc7376SDmitri Tikhonov        8,
105fabc7376SDmitri Tikhonov        1,
106fabc7376SDmitri Tikhonov        {
107fabc7376SDmitri Tikhonov            { "dude", "aaz", },
108fabc7376SDmitri Tikhonov        },
109fabc7376SDmitri Tikhonov    },
110fabc7376SDmitri Tikhonov
1111e505d17SDmitri Tikhonov    {   __LINE__,
1121e505d17SDmitri Tikhonov        "\x43\x7a\x7a\x7a\x88\xcc\x6a\x0d\x48\xea\xe8\x3b\x0f",
1131e505d17SDmitri Tikhonov        13,
1141e505d17SDmitri Tikhonov        1,
1151e505d17SDmitri Tikhonov        {
1161e505d17SDmitri Tikhonov            { "zzz", "Kilimanjaro", },
1171e505d17SDmitri Tikhonov        },
1181e505d17SDmitri Tikhonov    },
1191e505d17SDmitri Tikhonov
1201e505d17SDmitri Tikhonov    {   __LINE__,
1211e505d17SDmitri Tikhonov        "\x43\x7a\x7a\x7a\x03\x61\x61\x7a",
1221e505d17SDmitri Tikhonov        8,
1231e505d17SDmitri Tikhonov        1,
1241e505d17SDmitri Tikhonov        {
1251e505d17SDmitri Tikhonov            { "zzz", "aaz", },
1261e505d17SDmitri Tikhonov        },
1271e505d17SDmitri Tikhonov    },
1281e505d17SDmitri Tikhonov
129f888f77cSStephen Petrides    {   __LINE__,
130582aa904SStephen Petrides        "\x43\x7a\x7a\x7a\x03\x61\x61\x61\x80\x03\x61\x61\x7a",
131582aa904SStephen Petrides        13,
132582aa904SStephen Petrides        2,
133582aa904SStephen Petrides        {
134582aa904SStephen Petrides            { "zzz", "aaa", },
135582aa904SStephen Petrides            { "zzz", "aaz", },
136582aa904SStephen Petrides        },
137582aa904SStephen Petrides    },
138582aa904SStephen Petrides
139582aa904SStephen Petrides    {   __LINE__,
140f888f77cSStephen Petrides        "\x40\x88\xcc\x6a\x0d\x48\xea\xe8\x3b\x0f",
141f888f77cSStephen Petrides        10,
142f888f77cSStephen Petrides        1,
143f888f77cSStephen Petrides        {
144f888f77cSStephen Petrides            { "", "Kilimanjaro", },
145f888f77cSStephen Petrides        },
146f888f77cSStephen Petrides    },
147f888f77cSStephen Petrides
148f888f77cSStephen Petrides    {   __LINE__,
149f888f77cSStephen Petrides        "\x43\x7a\x7a\x7a\x00",
150f888f77cSStephen Petrides        5,
151f888f77cSStephen Petrides        1,
152f888f77cSStephen Petrides        {
153f888f77cSStephen Petrides            { "zzz", "", },
154f888f77cSStephen Petrides        },
155f888f77cSStephen Petrides    },
156f888f77cSStephen Petrides
157f888f77cSStephen Petrides    {   __LINE__,
158f888f77cSStephen Petrides        "\x40\x00",
159f888f77cSStephen Petrides        2,
160f888f77cSStephen Petrides        1,
161f888f77cSStephen Petrides        {
162f888f77cSStephen Petrides            { "", "", },
163f888f77cSStephen Petrides        },
164f888f77cSStephen Petrides    },
165f888f77cSStephen Petrides
1663c795f78SDmitri Tikhonov};
1673c795f78SDmitri Tikhonov
1683c795f78SDmitri Tikhonov
16911fc5170SDmitri Tikhonovstruct ringbuf_iter
17011fc5170SDmitri Tikhonov{
17111fc5170SDmitri Tikhonov    const struct lsqpack_ringbuf *rbuf;
17211fc5170SDmitri Tikhonov    unsigned next, end;
17311fc5170SDmitri Tikhonov};
17411fc5170SDmitri Tikhonov
17511fc5170SDmitri Tikhonov
17611fc5170SDmitri Tikhonov#if LSQPACK_DEVEL_MODE
17711fc5170SDmitri Tikhonovunsigned
17811fc5170SDmitri Tikhonovringbuf_count (const struct lsqpack_ringbuf *rbuf);
17911fc5170SDmitri Tikhonov
18011fc5170SDmitri Tikhonovvoid *
18111fc5170SDmitri Tikhonovringbuf_iter_next (struct ringbuf_iter *iter);
18211fc5170SDmitri Tikhonov
18311fc5170SDmitri Tikhonovvoid *
18411fc5170SDmitri Tikhonovringbuf_iter_first (struct ringbuf_iter *iter,
18511fc5170SDmitri Tikhonov                                        const struct lsqpack_ringbuf *rbuf);
18611fc5170SDmitri Tikhonov
1873c795f78SDmitri Tikhonovstatic void
1883c795f78SDmitri Tikhonovverify_dyn_table (const struct lsqpack_dec *dec,
1893c795f78SDmitri Tikhonov                            const struct test_read_encoder_stream *test)
1903c795f78SDmitri Tikhonov{
1913c795f78SDmitri Tikhonov    const struct lsqpack_dec_table_entry *entry;
1923c795f78SDmitri Tikhonov    unsigned n;
19311fc5170SDmitri Tikhonov    struct ringbuf_iter riter;
1943c795f78SDmitri Tikhonov
19511fc5170SDmitri Tikhonov    assert(ringbuf_count(&dec->qpd_dyn_table) == test->n_entries);
1963c795f78SDmitri Tikhonov
1973c795f78SDmitri Tikhonov    for (n = 0; n < test->n_entries; ++n)
1983c795f78SDmitri Tikhonov    {
19911fc5170SDmitri Tikhonov        if (n == 0)
20011fc5170SDmitri Tikhonov            entry = ringbuf_iter_first(&riter, &dec->qpd_dyn_table);
20111fc5170SDmitri Tikhonov        else
20211fc5170SDmitri Tikhonov            entry = ringbuf_iter_next(&riter);
20311fc5170SDmitri Tikhonov        assert(entry);
2043c795f78SDmitri Tikhonov        assert(entry->dte_name_len == strlen(test->dyn_table[n].name));
2053c795f78SDmitri Tikhonov        assert(entry->dte_val_len == strlen(test->dyn_table[n].value));
2063c795f78SDmitri Tikhonov        assert(0 == memcmp(DTE_NAME(entry), test->dyn_table[n].name, entry->dte_name_len));
2073c795f78SDmitri Tikhonov        assert(0 == memcmp(DTE_VALUE(entry), test->dyn_table[n].value, entry->dte_val_len));
2083c795f78SDmitri Tikhonov    }
2093c795f78SDmitri Tikhonov}
21011fc5170SDmitri Tikhonov#else
21111fc5170SDmitri Tikhonovstatic void
21211fc5170SDmitri Tikhonovverify_dyn_table (const struct lsqpack_dec *dec,
21311fc5170SDmitri Tikhonov                            const struct test_read_encoder_stream *test)
21411fc5170SDmitri Tikhonov{
21511fc5170SDmitri Tikhonov    fprintf(stderr, "LSQPACK_DEVEL_MODE is not compiled: cannot verify dynamic table\n");
21611fc5170SDmitri Tikhonov}
21711fc5170SDmitri Tikhonov#endif
2183c795f78SDmitri Tikhonov
2193c795f78SDmitri Tikhonov
2203c795f78SDmitri Tikhonovstatic void
2213c795f78SDmitri Tikhonovrun_test (const struct test_read_encoder_stream *test)
2223c795f78SDmitri Tikhonov{
2233c795f78SDmitri Tikhonov    struct lsqpack_dec dec;
224a7f0eb00SDmitri Tikhonov    size_t chunk_sz, off;
2253c795f78SDmitri Tikhonov    int r;
2263c795f78SDmitri Tikhonov
227a7f0eb00SDmitri Tikhonov    for (chunk_sz = 1; chunk_sz <= test->input_sz; ++chunk_sz)
228a7f0eb00SDmitri Tikhonov    {
22960620859SDmitri Tikhonov        lsqpack_dec_init(&dec, NULL, 0x1000, 100, (void *) 1 /* hset */,
23060620859SDmitri Tikhonov                                                    LSQPACK_DEC_OPT_HTTP1X);
2313c795f78SDmitri Tikhonov
232a7f0eb00SDmitri Tikhonov        off = 0;
233a7f0eb00SDmitri Tikhonov        do
234a7f0eb00SDmitri Tikhonov        {
235a7f0eb00SDmitri Tikhonov            r = lsqpack_dec_enc_in(&dec, test->input + off,
236a7f0eb00SDmitri Tikhonov                                        MIN(chunk_sz, test->input_sz - off));
237a7f0eb00SDmitri Tikhonov            assert(r == 0);
238a7f0eb00SDmitri Tikhonov            off += MIN(chunk_sz, test->input_sz - off);
239a7f0eb00SDmitri Tikhonov        }
240a7f0eb00SDmitri Tikhonov        while (off < test->input_sz);
2413c795f78SDmitri Tikhonov
242a7f0eb00SDmitri Tikhonov        verify_dyn_table(&dec, test);
2433c795f78SDmitri Tikhonov
244a7f0eb00SDmitri Tikhonov        lsqpack_dec_cleanup(&dec);
245a7f0eb00SDmitri Tikhonov    }
2463c795f78SDmitri Tikhonov}
2473c795f78SDmitri Tikhonov
2483c795f78SDmitri Tikhonov
2493c795f78SDmitri Tikhonovint
2503c795f78SDmitri Tikhonovmain (void)
2513c795f78SDmitri Tikhonov{
2523c795f78SDmitri Tikhonov    const struct test_read_encoder_stream *test;
2533c795f78SDmitri Tikhonov
2543c795f78SDmitri Tikhonov    for (test = tests; test < tests + sizeof(tests) / sizeof(tests[0]); ++test)
2553c795f78SDmitri Tikhonov        run_test(test);
2568fd5df69SDmitri Tikhonov
2578fd5df69SDmitri Tikhonov    return 0;
2583c795f78SDmitri Tikhonov}
259