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