1/* 2 * Read encoder stream 3 */ 4 5#include <assert.h> 6#include <stdlib.h> 7#include <string.h> 8 9#include "lsqpack.h" 10 11#define MIN(a, b) ((a) < (b) ? (a) : (b)) 12 13/* Dynamic table entry: */ 14struct lsqpack_dec_table_entry 15{ 16 unsigned dte_name_len; 17 unsigned dte_val_len; 18 unsigned dte_refcnt; 19 unsigned dte_pad[4]; /* name hash, nameval hash, name idx, flags */ 20 char dte_buf[0]; /* Contains both name and value */ 21}; 22 23#define DTE_NAME(dte) ((dte)->dte_buf) 24#define DTE_VALUE(dte) (&(dte)->dte_buf[(dte)->dte_name_len]) 25 26 27struct test_read_encoder_stream 28{ 29 int lineno; 30 31 /* Input */ 32 unsigned char input[0x100]; 33 size_t input_sz; 34 35 /* Output */ 36 unsigned n_entries; 37 struct { 38 const char *name, *value; 39 } dyn_table[10]; 40}; 41 42 43static const struct test_read_encoder_stream tests[] = 44{ 45 46 { __LINE__, 47 "\xc0\x8b\xf1\xe3\xc2\xf5\x15\x31\xa2\x45\xcf\x64\xdf", 48 13, 49 1, 50 { 51 { ":authority", "www.netbsd.org", }, 52 }, 53 }, 54 55 { __LINE__, 56 "\xc0\x00", 57 2, 58 1, 59 { 60 { ":authority", "", }, 61 }, 62 }, 63 64 { __LINE__, 65 "\xc0\x8b\xf1\xe3\xc2\xf5\x15\x31\xa2\x45\xcf\x64\xdf\x00", 66 14, 67 2, 68 { 69 { ":authority", "www.netbsd.org", }, 70 { ":authority", "www.netbsd.org", }, 71 }, 72 }, 73 74 { __LINE__, 75 "\xc0\x8b\xf1\xe3\xc2\xf5\x15\x31\xa2\x45\xcf\x64\xdf\x00\x20", 76 15, 77 0, 78 { 79 { NULL, NULL, }, 80 }, 81 }, 82 83 { __LINE__, 84 "\xc0\x15" "Respect my authorata!", 85 2 + sizeof("Respect my authorata!") - 1, 86 1, 87 { 88 { ":authority", "Respect my authorata!", }, 89 }, 90 }, 91 92 { __LINE__, 93 "\x63\x92\xd9\x0b\x8c\xe5\x39\x6c\x2a\x86\x42\x94\xfa\x50\x83\xb3" 94 "\xfc", 95 17, 96 1, 97 { 98 { "dude", "Where is my car?", }, 99 }, 100 }, 101 102 { __LINE__, 103 "\x63\x92\xd9\x0b\x03\x61\x61\x7a", 104 8, 105 1, 106 { 107 { "dude", "aaz", }, 108 }, 109 }, 110 111 { __LINE__, 112 "\x43\x7a\x7a\x7a\x88\xcc\x6a\x0d\x48\xea\xe8\x3b\x0f", 113 13, 114 1, 115 { 116 { "zzz", "Kilimanjaro", }, 117 }, 118 }, 119 120 { __LINE__, 121 "\x43\x7a\x7a\x7a\x03\x61\x61\x7a", 122 8, 123 1, 124 { 125 { "zzz", "aaz", }, 126 }, 127 }, 128 129 { __LINE__, 130 "\x43\x7a\x7a\x7a\x03\x61\x61\x61\x80\x03\x61\x61\x7a", 131 13, 132 2, 133 { 134 { "zzz", "aaa", }, 135 { "zzz", "aaz", }, 136 }, 137 }, 138 139 { __LINE__, 140 "\x40\x88\xcc\x6a\x0d\x48\xea\xe8\x3b\x0f", 141 10, 142 1, 143 { 144 { "", "Kilimanjaro", }, 145 }, 146 }, 147 148 { __LINE__, 149 "\x43\x7a\x7a\x7a\x00", 150 5, 151 1, 152 { 153 { "zzz", "", }, 154 }, 155 }, 156 157 { __LINE__, 158 "\x40\x00", 159 2, 160 1, 161 { 162 { "", "", }, 163 }, 164 }, 165 166}; 167 168 169struct ringbuf_iter 170{ 171 const struct lsqpack_ringbuf *rbuf; 172 unsigned next, end; 173}; 174 175 176#if LSQPACK_DEVEL_MODE 177unsigned 178ringbuf_count (const struct lsqpack_ringbuf *rbuf); 179 180void * 181ringbuf_iter_next (struct ringbuf_iter *iter); 182 183void * 184ringbuf_iter_first (struct ringbuf_iter *iter, 185 const struct lsqpack_ringbuf *rbuf); 186 187static void 188verify_dyn_table (const struct lsqpack_dec *dec, 189 const struct test_read_encoder_stream *test) 190{ 191 const struct lsqpack_dec_table_entry *entry; 192 unsigned n; 193 struct ringbuf_iter riter; 194 195 assert(ringbuf_count(&dec->qpd_dyn_table) == test->n_entries); 196 197 for (n = 0; n < test->n_entries; ++n) 198 { 199 if (n == 0) 200 entry = ringbuf_iter_first(&riter, &dec->qpd_dyn_table); 201 else 202 entry = ringbuf_iter_next(&riter); 203 assert(entry); 204 assert(entry->dte_name_len == strlen(test->dyn_table[n].name)); 205 assert(entry->dte_val_len == strlen(test->dyn_table[n].value)); 206 assert(0 == memcmp(DTE_NAME(entry), test->dyn_table[n].name, entry->dte_name_len)); 207 assert(0 == memcmp(DTE_VALUE(entry), test->dyn_table[n].value, entry->dte_val_len)); 208 } 209} 210#else 211static void 212verify_dyn_table (const struct lsqpack_dec *dec, 213 const struct test_read_encoder_stream *test) 214{ 215 fprintf(stderr, "LSQPACK_DEVEL_MODE is not compiled: cannot verify dynamic table\n"); 216} 217#endif 218 219 220static void 221run_test (const struct test_read_encoder_stream *test) 222{ 223 struct lsqpack_dec dec; 224 size_t chunk_sz, off; 225 int r; 226 227 for (chunk_sz = 1; chunk_sz <= test->input_sz; ++chunk_sz) 228 { 229 lsqpack_dec_init(&dec, NULL, 0x1000, 100, (void *) 1 /* hset */, 230 LSQPACK_DEC_OPT_HTTP1X); 231 232 off = 0; 233 do 234 { 235 r = lsqpack_dec_enc_in(&dec, test->input + off, 236 MIN(chunk_sz, test->input_sz - off)); 237 assert(r == 0); 238 off += MIN(chunk_sz, test->input_sz - off); 239 } 240 while (off < test->input_sz); 241 242 verify_dyn_table(&dec, test); 243 244 lsqpack_dec_cleanup(&dec); 245 } 246} 247 248 249int 250main (void) 251{ 252 const struct test_read_encoder_stream *test; 253 254 for (test = tests; test < tests + sizeof(tests) / sizeof(tests[0]); ++test) 255 run_test(test); 256 257 return 0; 258} 259