lsqpack 0.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +7 -0
- data/Gemfile +19 -0
- data/Gemfile.lock +82 -0
- data/LICENSE +21 -0
- data/README.md +36 -0
- data/Rakefile +19 -0
- data/Steepfile +6 -0
- data/ext/lsqpack/extconf.rb +18 -0
- data/ext/lsqpack/lsqpack.c +426 -0
- data/ext/lsqpack/lsqpack.h +6 -0
- data/lib/lsqpack/version.rb +5 -0
- data/lib/lsqpack.rb +30 -0
- data/ls-qpack/.appveyor.yml +14 -0
- data/ls-qpack/.cirrus.yml +6 -0
- data/ls-qpack/.travis.yml +32 -0
- data/ls-qpack/CMakeLists.txt +66 -0
- data/ls-qpack/LICENSE +21 -0
- data/ls-qpack/README.md +65 -0
- data/ls-qpack/bin/CMakeLists.txt +21 -0
- data/ls-qpack/bin/encode-int.c +87 -0
- data/ls-qpack/bin/fuzz-decode.c +247 -0
- data/ls-qpack/bin/interop-decode.c +433 -0
- data/ls-qpack/bin/interop-encode.c +554 -0
- data/ls-qpack/deps/xxhash/xxhash.c +941 -0
- data/ls-qpack/deps/xxhash/xxhash.h +160 -0
- data/ls-qpack/fuzz/decode/a/README +3 -0
- data/ls-qpack/fuzz/decode/a/preamble +0 -0
- data/ls-qpack/fuzz/decode/a/test-cases/id_000000,sig_06,src_000390,op_havoc,rep_4 +0 -0
- data/ls-qpack/fuzz/decode/a/test-cases/id_000000,sig_06,src_000579,op_flip1,pos_14 +0 -0
- data/ls-qpack/fuzz/decode/a/test-cases/id_000000,src_000000,op_flip2,pos_12 +0 -0
- data/ls-qpack/fuzz/decode/a/test-cases/id_000001,sig_11,src_000579,op_havoc,rep_4 +0 -0
- data/ls-qpack/fuzz/decode/a/test-cases/id_000002,sig_11,src_000481,op_int16,pos_15,val_-1 +0 -0
- data/ls-qpack/fuzz/decode/a/test-cases/id_000002,src_000000,op_havoc,rep_8 +0 -0
- data/ls-qpack/fuzz/decode/a/test-cases/id_000006,src_000285,op_flip2,pos_14 +0 -0
- data/ls-qpack/fuzz/decode/a/test-cases/id_000008,src_000285,op_flip2,pos_20 +0 -0
- data/ls-qpack/fuzz/decode/a/test-cases/id_000010,src_000306,op_flip2,pos_75 +0 -0
- data/ls-qpack/fuzz/decode/a/test-cases/id_000011,src_000344,op_havoc,rep_2 +0 -0
- data/ls-qpack/fuzz/decode/a/test-cases/id_000014,src_000366,op_flip2,pos_28 +0 -0
- data/ls-qpack/fuzz/decode/b/README +1 -0
- data/ls-qpack/fuzz/decode/b/preamble +0 -0
- data/ls-qpack/fuzz/decode/b/test-cases/seed +0 -0
- data/ls-qpack/fuzz/decode/c/setup.sh +3 -0
- data/ls-qpack/fuzz/decode/c/test-cases/fb-req.qif.proxygen.out.256.100.0-chopped +0 -0
- data/ls-qpack/fuzz/decode/d/preamble +0 -0
- data/ls-qpack/fuzz/decode/d/setup.sh +3 -0
- data/ls-qpack/fuzz/decode/d/test-cases/fb-resp.minhq.256.128.0.ack +0 -0
- data/ls-qpack/fuzz/input/256.100.1/fb-req.out.256.100.1 +0 -0
- data/ls-qpack/fuzz/input/256.100.1/fb-resp.out.256.100.1 +0 -0
- data/ls-qpack/fuzz/input/256.100.1/netbsd.out.256.100.1 +0 -0
- data/ls-qpack/huff-tables.h +136247 -0
- data/ls-qpack/lsqpack.c +5547 -0
- data/ls-qpack/lsqpack.h +768 -0
- data/ls-qpack/test/CMakeLists.txt +76 -0
- data/ls-qpack/test/lsqpack-test.h +43 -0
- data/ls-qpack/test/qifs/fb-req.qif +4917 -0
- data/ls-qpack/test/qifs/fb-resp.qif +5982 -0
- data/ls-qpack/test/qifs/long-codes.qif +5984 -0
- data/ls-qpack/test/qifs/netbsd.qif +235 -0
- data/ls-qpack/test/run-qif.pl +97 -0
- data/ls-qpack/test/run-scenario.sh +68 -0
- data/ls-qpack/test/scenarios/0.95-reset.sce +10 -0
- data/ls-qpack/test/scenarios/cancel-stream.sce +22 -0
- data/ls-qpack/test/scenarios/drain-2.sce +37 -0
- data/ls-qpack/test/scenarios/drain.sce +37 -0
- data/ls-qpack/test/scenarios/end-dst-2.sce +14 -0
- data/ls-qpack/test/scenarios/end-dst.sce +14 -0
- data/ls-qpack/test/scenarios/incl-name.sce +13 -0
- data/ls-qpack/test/scenarios/multi-byte-int-dyn-ref-1.sce +110 -0
- data/ls-qpack/test/scenarios/multi-byte-int-dyn-ref-2.sce +161 -0
- data/ls-qpack/test/scenarios/post-base-1.sce +10 -0
- data/ls-qpack/test/scenarios/post-base-2.sce +13 -0
- data/ls-qpack/test/scenarios/post-base-nr.sce +10 -0
- data/ls-qpack/test/scenarios/set-max-cap.sce +15 -0
- data/ls-qpack/test/test_enc_str.c +139 -0
- data/ls-qpack/test/test_get_stx_id.c +144 -0
- data/ls-qpack/test/test_huff_dec.c +399 -0
- data/ls-qpack/test/test_int.c +220 -0
- data/ls-qpack/test/test_qpack.c +856 -0
- data/ls-qpack/test/test_read_enc_stream.c +256 -0
- data/ls-qpack/tools/har2qif.pl +139 -0
- data/ls-qpack/tools/randomize-cookies.pl +41 -0
- data/ls-qpack/tools/sort-qif.pl +31 -0
- data/ls-qpack/wincompat/getopt.c +758 -0
- data/ls-qpack/wincompat/getopt.h +131 -0
- data/ls-qpack/wincompat/getopt1.c +188 -0
- data/ls-qpack/wincompat/sys/queue.h +859 -0
- data/lsqpack.gemspec +39 -0
- data/sig/lsqpack.rbs +29 -0
- metadata +135 -0
@@ -0,0 +1,433 @@
|
|
1
|
+
/*
|
2
|
+
* QPACK Interop -- decode from intermediate format and output QIF
|
3
|
+
*
|
4
|
+
* https://github.com/quicwg/base-drafts/wiki/QPACK-Offline-Interop
|
5
|
+
*/
|
6
|
+
|
7
|
+
#include <assert.h>
|
8
|
+
|
9
|
+
#if defined(__FreeBSD__) || defined(__DragonFly__) || defined(__NetBSD__)
|
10
|
+
#include <sys/endian.h>
|
11
|
+
#define bswap_16 bswap16
|
12
|
+
#define bswap_32 bswap32
|
13
|
+
#define bswap_64 bswap64
|
14
|
+
#elif defined(__APPLE__)
|
15
|
+
#include <libkern/OSByteOrder.h>
|
16
|
+
#define bswap_16 OSSwapInt16
|
17
|
+
#define bswap_32 OSSwapInt32
|
18
|
+
#define bswap_64 OSSwapInt64
|
19
|
+
#elif defined(WIN32)
|
20
|
+
#define bswap_16 _byteswap_ushort
|
21
|
+
#define bswap_32 _byteswap_ulong
|
22
|
+
#define bswap_64 _byteswap_uint64
|
23
|
+
#else
|
24
|
+
#include <byteswap.h>
|
25
|
+
#endif
|
26
|
+
|
27
|
+
#include <errno.h>
|
28
|
+
#include <inttypes.h>
|
29
|
+
#include <stdio.h>
|
30
|
+
#include <stdlib.h>
|
31
|
+
#include <string.h>
|
32
|
+
#ifdef WIN32
|
33
|
+
#include "getopt.h"
|
34
|
+
#else
|
35
|
+
#include <unistd.h>
|
36
|
+
#endif
|
37
|
+
#include <sys/queue.h>
|
38
|
+
#include <sys/types.h>
|
39
|
+
#include <sys/stat.h>
|
40
|
+
#include <fcntl.h>
|
41
|
+
|
42
|
+
#include "lsqpack.h"
|
43
|
+
|
44
|
+
static size_t s_max_read_size = SIZE_MAX;
|
45
|
+
|
46
|
+
static int s_verbose;
|
47
|
+
|
48
|
+
static FILE *s_out;
|
49
|
+
|
50
|
+
#define MIN(a, b) ((a) < (b) ? (a) : (b))
|
51
|
+
|
52
|
+
static void
|
53
|
+
usage (const char *name)
|
54
|
+
{
|
55
|
+
fprintf(stderr,
|
56
|
+
"Usage: %s [options] [-i input] [-o output]\n"
|
57
|
+
"\n"
|
58
|
+
"Options:\n"
|
59
|
+
" -i FILE Input file. If not specified or set to `-', the input is\n"
|
60
|
+
" read from stdin.\n"
|
61
|
+
" -o FILE Output file. If not spepcified or set to `-', the output\n"
|
62
|
+
" is written to stdout.\n"
|
63
|
+
" -r FILE Recipe file. Without a recipe, buffers are processed in\n"
|
64
|
+
" order.\n"
|
65
|
+
" -s NUMBER Maximum number of risked streams. Defaults to %u.\n"
|
66
|
+
" -t NUMBER Dynamic table size. Defaults to %u.\n"
|
67
|
+
" -m NUMBER Maximum read size. Defaults to %zu.\n"
|
68
|
+
" -v Verbose: print headers and table state to stderr.\n"
|
69
|
+
"\n"
|
70
|
+
" -h Print this help screen and exit\n"
|
71
|
+
, name, LSQPACK_DEF_MAX_RISKED_STREAMS, LSQPACK_DEF_DYN_TABLE_SIZE, SIZE_MAX);
|
72
|
+
}
|
73
|
+
|
74
|
+
|
75
|
+
struct buf
|
76
|
+
{
|
77
|
+
TAILQ_ENTRY(buf) next_buf;
|
78
|
+
struct lsqpack_dec *dec;
|
79
|
+
uint64_t stream_id; /* Zero means encoder stream */
|
80
|
+
size_t size;
|
81
|
+
size_t off;
|
82
|
+
size_t file_off;
|
83
|
+
unsigned char buf[0];
|
84
|
+
};
|
85
|
+
|
86
|
+
|
87
|
+
TAILQ_HEAD(, buf) bufs = TAILQ_HEAD_INITIALIZER(bufs);
|
88
|
+
|
89
|
+
|
90
|
+
static void
|
91
|
+
hblock_unblocked (void *buf_p)
|
92
|
+
{
|
93
|
+
struct buf *buf = buf_p;
|
94
|
+
TAILQ_INSERT_HEAD(&bufs, buf, next_buf);
|
95
|
+
}
|
96
|
+
|
97
|
+
|
98
|
+
static void
|
99
|
+
header_block_done (const struct buf *buf, struct lsqpack_header_list *set)
|
100
|
+
{
|
101
|
+
unsigned n;
|
102
|
+
|
103
|
+
if (!set)
|
104
|
+
{
|
105
|
+
fprintf(stderr, "Stream %"PRIu64" has empty header list\n", buf->stream_id);
|
106
|
+
return;
|
107
|
+
}
|
108
|
+
|
109
|
+
if (s_verbose)
|
110
|
+
{
|
111
|
+
fprintf(stderr, "Have headers for stream %"PRIu64":\n", buf->stream_id);
|
112
|
+
for (n = 0; n < set->qhl_count; ++n)
|
113
|
+
fprintf(stderr, " %.*s: %.*s\n",
|
114
|
+
set->qhl_headers[n]->qh_name_len, set->qhl_headers[n]->qh_name,
|
115
|
+
set->qhl_headers[n]->qh_value_len, set->qhl_headers[n]->qh_value);
|
116
|
+
fprintf(stderr, "\n");
|
117
|
+
}
|
118
|
+
|
119
|
+
fprintf(s_out, "# stream %"PRIu64"\n", buf->stream_id);
|
120
|
+
fprintf(s_out, "# (stream ID above is used for sorting)\n");
|
121
|
+
for (n = 0; n < set->qhl_count; ++n)
|
122
|
+
fprintf(s_out, "%.*s\t%.*s\n",
|
123
|
+
set->qhl_headers[n]->qh_name_len, set->qhl_headers[n]->qh_name,
|
124
|
+
set->qhl_headers[n]->qh_value_len, set->qhl_headers[n]->qh_value);
|
125
|
+
fprintf(s_out, "\n");
|
126
|
+
|
127
|
+
lsqpack_dec_destroy_header_list(set);
|
128
|
+
}
|
129
|
+
|
130
|
+
|
131
|
+
int
|
132
|
+
main (int argc, char **argv)
|
133
|
+
{
|
134
|
+
FILE *in = stdin;
|
135
|
+
FILE *recipe = NULL;
|
136
|
+
int opt;
|
137
|
+
unsigned dyn_table_size = LSQPACK_DEF_DYN_TABLE_SIZE,
|
138
|
+
max_risked_streams = LSQPACK_DEF_MAX_RISKED_STREAMS;
|
139
|
+
struct lsqpack_dec decoder;
|
140
|
+
const struct lsqpack_dec_err *err;
|
141
|
+
const unsigned char *p;
|
142
|
+
ssize_t nr;
|
143
|
+
int r;
|
144
|
+
uint64_t stream_id;
|
145
|
+
uint32_t size;
|
146
|
+
size_t off; /* For debugging */
|
147
|
+
size_t file_off;
|
148
|
+
struct buf *buf;
|
149
|
+
unsigned lineno;
|
150
|
+
char *line, *end;
|
151
|
+
enum lsqpack_read_header_status rhs;
|
152
|
+
struct lsqpack_header_list *hlist;
|
153
|
+
char command[0x100];
|
154
|
+
char line_buf[0x100];
|
155
|
+
|
156
|
+
while (-1 != (opt = getopt(argc, argv, "i:o:r:s:t:m:hv")))
|
157
|
+
{
|
158
|
+
switch (opt)
|
159
|
+
{
|
160
|
+
case 'i':
|
161
|
+
if (0 != strcmp(optarg, "-"))
|
162
|
+
{
|
163
|
+
in = fopen(optarg, "rb");
|
164
|
+
if (!in)
|
165
|
+
{
|
166
|
+
fprintf(stderr, "cannot open `%s' for reading: %s\n",
|
167
|
+
optarg, strerror(errno));
|
168
|
+
exit(EXIT_FAILURE);
|
169
|
+
}
|
170
|
+
}
|
171
|
+
break;
|
172
|
+
case 'o':
|
173
|
+
if (0 != strcmp(optarg, "-"))
|
174
|
+
{
|
175
|
+
s_out = fopen(optarg, "w");
|
176
|
+
if (!s_out)
|
177
|
+
{
|
178
|
+
fprintf(stderr, "cannot open `%s' for writing: %s\n",
|
179
|
+
optarg, strerror(errno));
|
180
|
+
exit(EXIT_FAILURE);
|
181
|
+
}
|
182
|
+
}
|
183
|
+
break;
|
184
|
+
case 'r':
|
185
|
+
if (0 == strcmp(optarg, "-"))
|
186
|
+
recipe = stdin;
|
187
|
+
else
|
188
|
+
{
|
189
|
+
recipe = fopen(optarg, "r");
|
190
|
+
if (!recipe)
|
191
|
+
{
|
192
|
+
fprintf(stderr, "cannot open `%s' for reading: %s\n",
|
193
|
+
optarg, strerror(errno));
|
194
|
+
exit(EXIT_FAILURE);
|
195
|
+
}
|
196
|
+
}
|
197
|
+
break;
|
198
|
+
case 's':
|
199
|
+
max_risked_streams = atoi(optarg);
|
200
|
+
break;
|
201
|
+
case 't':
|
202
|
+
dyn_table_size = atoi(optarg);
|
203
|
+
break;
|
204
|
+
case 'm':
|
205
|
+
s_max_read_size = atoi(optarg);
|
206
|
+
break;
|
207
|
+
case 'h':
|
208
|
+
usage(argv[0]);
|
209
|
+
exit(EXIT_SUCCESS);
|
210
|
+
case 'v':
|
211
|
+
++s_verbose;
|
212
|
+
break;
|
213
|
+
default:
|
214
|
+
exit(EXIT_FAILURE);
|
215
|
+
}
|
216
|
+
}
|
217
|
+
|
218
|
+
if (!s_out)
|
219
|
+
s_out = stdout;
|
220
|
+
|
221
|
+
lsqpack_dec_init(&decoder, s_verbose ? stderr : NULL, dyn_table_size,
|
222
|
+
max_risked_streams, hblock_unblocked);
|
223
|
+
|
224
|
+
off = 0;
|
225
|
+
while (1)
|
226
|
+
{
|
227
|
+
file_off = off;
|
228
|
+
nr = fread(&stream_id, 1, sizeof(stream_id), in);
|
229
|
+
if (nr == 0)
|
230
|
+
break;
|
231
|
+
if (nr != sizeof(stream_id))
|
232
|
+
{
|
233
|
+
fprintf(stderr, "could not read %zu bytes (stream id) at "
|
234
|
+
"offset %zu: %s\n", sizeof(stream_id), off, strerror(errno));
|
235
|
+
goto read_err;
|
236
|
+
}
|
237
|
+
off += nr;
|
238
|
+
nr = fread(&size, 1, sizeof(size), in);
|
239
|
+
if (nr != sizeof(size))
|
240
|
+
{
|
241
|
+
fprintf(stderr, "could not read %zu bytes (size) at "
|
242
|
+
"offset %zu: %s\n", sizeof(size), off, strerror(errno));
|
243
|
+
goto read_err;
|
244
|
+
}
|
245
|
+
off += nr;
|
246
|
+
#if __BYTE_ORDER == __LITTLE_ENDIAN
|
247
|
+
stream_id = bswap_64(stream_id);
|
248
|
+
size = bswap_32(size);
|
249
|
+
#endif
|
250
|
+
if (stream_id == 0 && size == 0)
|
251
|
+
continue;
|
252
|
+
buf = malloc(sizeof(*buf) + size);
|
253
|
+
if (!buf)
|
254
|
+
{
|
255
|
+
perror("malloc");
|
256
|
+
exit(EXIT_FAILURE);
|
257
|
+
}
|
258
|
+
memset(buf, 0, sizeof(*buf));
|
259
|
+
nr = fread(buf->buf, 1, size, in);
|
260
|
+
if (nr != (ssize_t) size)
|
261
|
+
{
|
262
|
+
fprintf(stderr, "could not read %"PRIu32" bytes (buffer) at "
|
263
|
+
"offset %zu: %s\n", size, off, strerror(errno));
|
264
|
+
goto read_err;
|
265
|
+
}
|
266
|
+
off += nr;
|
267
|
+
buf->dec = &decoder;
|
268
|
+
buf->stream_id = stream_id;
|
269
|
+
buf->size = size;
|
270
|
+
buf->file_off = file_off;
|
271
|
+
if (buf->size == 0)
|
272
|
+
exit(EXIT_FAILURE);
|
273
|
+
TAILQ_INSERT_TAIL(&bufs, buf, next_buf);
|
274
|
+
}
|
275
|
+
|
276
|
+
if (recipe)
|
277
|
+
{
|
278
|
+
lineno = 0;
|
279
|
+
while (line = fgets(line_buf, sizeof(line_buf), recipe), line != NULL)
|
280
|
+
{
|
281
|
+
++lineno;
|
282
|
+
end = strchr(line, '\n');
|
283
|
+
if (!end)
|
284
|
+
{
|
285
|
+
fprintf(stderr, "no newline on line %u\n", lineno);
|
286
|
+
exit(EXIT_FAILURE);
|
287
|
+
}
|
288
|
+
*end = '\0';
|
289
|
+
|
290
|
+
if (*line == '#')
|
291
|
+
continue;
|
292
|
+
|
293
|
+
if (3 == sscanf(line, " %[s] %"PRIu64" %"PRIu32" ", command, &stream_id, &size))
|
294
|
+
{
|
295
|
+
TAILQ_FOREACH(buf, &bufs, next_buf)
|
296
|
+
if (stream_id == buf->stream_id)
|
297
|
+
break;
|
298
|
+
if (!buf)
|
299
|
+
{
|
300
|
+
fprintf(stderr, "stream %"PRIu64" not found (recipe line %u)\n",
|
301
|
+
stream_id, lineno);
|
302
|
+
exit(EXIT_FAILURE);
|
303
|
+
}
|
304
|
+
p = buf->buf;
|
305
|
+
rhs = lsqpack_dec_header_in(&decoder, buf, stream_id,
|
306
|
+
buf->size, &p,
|
307
|
+
buf->size /* FIXME: this should be `size' */,
|
308
|
+
&hlist, NULL, NULL);
|
309
|
+
switch (rhs)
|
310
|
+
{
|
311
|
+
case LQRHS_DONE:
|
312
|
+
assert(p == buf->buf + buf->size);
|
313
|
+
header_block_done(buf, hlist);
|
314
|
+
if (s_verbose)
|
315
|
+
fprintf(stderr, "compression ratio: %.3f\n",
|
316
|
+
lsqpack_dec_ratio(&decoder));
|
317
|
+
TAILQ_REMOVE(&bufs, buf, next_buf);
|
318
|
+
free(buf);
|
319
|
+
break;
|
320
|
+
case LQRHS_BLOCKED:
|
321
|
+
buf->off += (unsigned) (p - buf->buf);
|
322
|
+
TAILQ_REMOVE(&bufs, buf, next_buf);
|
323
|
+
break;
|
324
|
+
case LQRHS_NEED:
|
325
|
+
buf->off += (unsigned) (p - buf->buf);
|
326
|
+
break;
|
327
|
+
default:
|
328
|
+
assert(rhs == LQRHS_ERROR);
|
329
|
+
fprintf(stderr, "recipe line %u: stream %"PRIu64": "
|
330
|
+
"header_in error\n", lineno, stream_id);
|
331
|
+
exit(EXIT_FAILURE);
|
332
|
+
}
|
333
|
+
}
|
334
|
+
else if (2 == sscanf(line, " %[z] %u ", command, &size))
|
335
|
+
{
|
336
|
+
s_max_read_size = size;
|
337
|
+
}
|
338
|
+
else
|
339
|
+
{
|
340
|
+
perror("sscanf");
|
341
|
+
exit(EXIT_FAILURE);
|
342
|
+
}
|
343
|
+
}
|
344
|
+
fclose(recipe);
|
345
|
+
}
|
346
|
+
|
347
|
+
while (buf = TAILQ_FIRST(&bufs), buf != NULL)
|
348
|
+
{
|
349
|
+
TAILQ_REMOVE(&bufs, buf, next_buf);
|
350
|
+
if (buf->stream_id == 0)
|
351
|
+
{
|
352
|
+
r = lsqpack_dec_enc_in(&decoder, buf->buf, buf->size - buf->off);
|
353
|
+
if (r != 0)
|
354
|
+
{
|
355
|
+
err = lsqpack_dec_get_err_info(buf->dec);
|
356
|
+
fprintf(stderr, "encoder_in error; off %"PRIu64", line %d\n",
|
357
|
+
err->off, err->line);
|
358
|
+
exit(EXIT_FAILURE);
|
359
|
+
}
|
360
|
+
if (s_verbose)
|
361
|
+
lsqpack_dec_print_table(&decoder, stderr);
|
362
|
+
free(buf);
|
363
|
+
}
|
364
|
+
else
|
365
|
+
{
|
366
|
+
dec_header:
|
367
|
+
p = buf->buf + buf->off;
|
368
|
+
if (buf->off == 0)
|
369
|
+
rhs = lsqpack_dec_header_in(&decoder, buf, buf->stream_id,
|
370
|
+
buf->size, &p, MIN(s_max_read_size, buf->size),
|
371
|
+
&hlist, NULL, NULL);
|
372
|
+
else
|
373
|
+
rhs = lsqpack_dec_header_read(buf->dec, buf, &p,
|
374
|
+
MIN(s_max_read_size, (buf->size - buf->off)),
|
375
|
+
&hlist, NULL, NULL);
|
376
|
+
switch (rhs)
|
377
|
+
{
|
378
|
+
case LQRHS_DONE:
|
379
|
+
assert(p == buf->buf + buf->size);
|
380
|
+
header_block_done(buf, hlist);
|
381
|
+
if (s_verbose)
|
382
|
+
fprintf(stderr, "compression ratio: %.3f\n",
|
383
|
+
lsqpack_dec_ratio(&decoder));
|
384
|
+
free(buf);
|
385
|
+
break;
|
386
|
+
case LQRHS_BLOCKED:
|
387
|
+
buf->off = (unsigned) (p - buf->buf);
|
388
|
+
break;
|
389
|
+
case LQRHS_NEED:
|
390
|
+
buf->off = (unsigned) (p - buf->buf);
|
391
|
+
goto dec_header;
|
392
|
+
default:
|
393
|
+
assert(rhs == LQRHS_ERROR);
|
394
|
+
fprintf(stderr, "stream %"PRIu64": header block error "
|
395
|
+
"starting at off %zu\n", buf->stream_id, buf->off);
|
396
|
+
err = lsqpack_dec_get_err_info(&decoder);
|
397
|
+
fprintf(stderr, "encoder_in error; off %"PRIu64", line %d\n",
|
398
|
+
err->off, err->line);
|
399
|
+
exit(EXIT_FAILURE);
|
400
|
+
}
|
401
|
+
}
|
402
|
+
}
|
403
|
+
|
404
|
+
if (!TAILQ_EMPTY(&bufs))
|
405
|
+
{
|
406
|
+
fprintf(stderr, "some streams reamain\n");
|
407
|
+
exit(EXIT_FAILURE);
|
408
|
+
}
|
409
|
+
/* TODO: check if decoder has any stream references. That would be
|
410
|
+
* an error.
|
411
|
+
*/
|
412
|
+
|
413
|
+
if (s_verbose)
|
414
|
+
lsqpack_dec_print_table(&decoder, stderr);
|
415
|
+
|
416
|
+
lsqpack_dec_cleanup(&decoder);
|
417
|
+
|
418
|
+
assert(TAILQ_EMPTY(&bufs));
|
419
|
+
|
420
|
+
if (s_out)
|
421
|
+
(void) fclose(s_out);
|
422
|
+
|
423
|
+
exit(EXIT_SUCCESS);
|
424
|
+
|
425
|
+
read_err:
|
426
|
+
if (nr < 0)
|
427
|
+
perror("read");
|
428
|
+
else if (nr == 0)
|
429
|
+
fprintf(stderr, "unexpected EOF\n");
|
430
|
+
else
|
431
|
+
fprintf(stderr, "not enough bytes read (%zu)\n", (size_t) nr);
|
432
|
+
exit(EXIT_FAILURE);
|
433
|
+
}
|