1#!/usr/bin/env python3 2# -*- coding: utf-8 -*- 3 4# This scripts reads static table entries [1] and generates 5# token_stable and stable. This table is used in lib/nghttp3_qpack.c. 6# 7# [1] https://quicwg.org/base-drafts/draft-ietf-quic-qpack.html#name-static-table-2 8 9import re, sys 10 11def hd_map_hash(name): 12 h = 2166136261 13 14 # FNV hash variant: http://isthe.com/chongo/tech/comp/fnv/ 15 for c in name: 16 h ^= ord(c) 17 h *= 16777619 18 h &= 0xffffffff 19 20 return h 21 22class Header: 23 def __init__(self, idx, name, value): 24 self.idx = idx 25 self.name = name 26 self.value = value 27 self.token = -1 28 29entries = [] 30for line in sys.stdin: 31 m = re.match(r'(\d+)\s+(\S+)\s+(\S.*)?', line) 32 val = m.group(3).strip() if m.group(3) else '' 33 entries.append(Header(int(m.group(1)), m.group(2), val)) 34 35token_entries = sorted(entries, key=lambda ent: ent.name) 36 37token = 0 38seq = 0 39name = token_entries[0].name 40for i, ent in enumerate(token_entries): 41 if name != ent.name: 42 name = ent.name 43 token = seq 44 seq += 1 45 ent.token = token 46 47def to_enum_hd(k): 48 res = 'NGHTTP3_QPACK_TOKEN_' 49 for c in k.upper(): 50 if c == ':' or c == '-': 51 res += '_' 52 continue 53 res += c 54 return res 55 56def gen_enum(entries): 57 used = {} 58 print('typedef enum nghttp3_qpack_token {') 59 for ent in entries: 60 if ent.name in used: 61 continue 62 used[ent.name] = True 63 enumname = to_enum_hd(ent.name) 64 print('''\ 65 /** 66 * :enum:`{enumname}` is a token for ``{name}``. 67 */'''.format(enumname=enumname, name=ent.name)) 68 if ent.token is None: 69 print(' {},'.format(enumname)) 70 else: 71 print(' {} = {},'.format(enumname, ent.token)) 72 print('} nghttp3_qpack_token;') 73 74gen_enum(entries) 75 76print() 77 78print('static nghttp3_qpack_static_entry token_stable[] = {') 79for i, ent in enumerate(token_entries): 80 print('MAKE_STATIC_ENT({}, {}, {}u),'\ 81 .format(ent.idx, to_enum_hd(ent.name), hd_map_hash(ent.name))) 82print('};') 83 84print() 85 86print('static nghttp3_qpack_static_header stable[] = {') 87for ent in entries: 88 print('MAKE_STATIC_HD("{}", "{}", {}),'\ 89 .format(ent.name, ent.value, to_enum_hd(ent.name))) 90print('};') 91