1/* encode-int: encode an integer into HPACK varint. */
2
3#include <assert.h>
4#include <stdio.h>
5#include <stdlib.h>
6#include <stdint.h>
7
8
9static unsigned char *
10enc_int (unsigned char *dst, unsigned char *const end, uint64_t value,
11                                                        unsigned prefix_bits)
12{
13    unsigned char *const dst_orig = dst;
14
15    /* This function assumes that at least one byte is available */
16    assert(dst < end);
17    if (value < (1u << prefix_bits) - 1)
18        *dst++ |= value;
19    else
20    {
21        *dst++ |= (1 << prefix_bits) - 1;
22        value -= (1 << prefix_bits) - 1;
23        while (value >= 128)
24        {
25            if (dst < end)
26            {
27                *dst++ = 0x80 | (unsigned char) value;
28                value >>= 7;
29            }
30            else
31                return dst_orig;
32        }
33        if (dst < end)
34            *dst++ = (unsigned char) value;
35        else
36            return dst_orig;
37    }
38    return dst;
39}
40
41static unsigned
42lsqpack_val2len (uint64_t value, unsigned prefix_bits)
43{
44    uint64_t mask = (1ULL << prefix_bits) - 1;
45    return 1
46         + (value >=                 mask )
47         + (value >= ((1ULL <<  7) + mask))
48         + (value >= ((1ULL << 14) + mask))
49         + (value >= ((1ULL << 21) + mask))
50         + (value >= ((1ULL << 28) + mask))
51         + (value >= ((1ULL << 35) + mask))
52         + (value >= ((1ULL << 42) + mask))
53         + (value >= ((1ULL << 49) + mask))
54         + (value >= ((1ULL << 56) + mask))
55         + (value >= ((1ULL << 63) + mask))
56         ;
57}
58
59int
60main (int argc, char **argv)
61{
62    unsigned long long val;
63    unsigned char *p;
64    unsigned prefix_bits;
65    unsigned char buf[20];
66
67    if (argc != 3)
68    {
69        fprintf(stderr, "Usage: %s prefix_bits value\n", argv[0]);
70        exit(EXIT_FAILURE);
71    }
72
73    prefix_bits = atoi(argv[1]);
74    val = strtoull(argv[2], NULL, 10);
75
76    fprintf(stderr, "expected size: %u\n", lsqpack_val2len(val, prefix_bits));
77    buf[0] = 0;
78    p = enc_int(buf, buf + sizeof(buf), val, prefix_bits);
79
80    if (p > buf)
81    {
82        fwrite(buf, 1, p - buf, stdout);
83        exit(EXIT_SUCCESS);
84    }
85    else
86        exit(EXIT_FAILURE);
87}
88