2 # -*- coding: utf-8 -*-
4 # This script reads Huffman Code table [1] and generates symbol table
5 # and decoding tables in C language. The resulting code is used in
6 # lib/nghttp2_hd_huffman.h and lib/nghttp2_hd_huffman_data.c
8 # [1] http://http2.github.io/http2-spec/compression.html
10 from __future__ import unicode_literals
15 def __init__(self, term = None):
25 for i in range(0, len(s), 8):
31 a += ord(x[j]) - ord('0')
32 res.append(a) #chr(a))
37 def insert(node, sym, bits):
47 if node.right is None:
50 insert(child, sym, bits[1:])
52 def traverse(node, bits, syms, start_node, root, depth):
57 start_node.trans.append((node, bits, syms))
60 if node.term is not None:
67 if node.term is not None:
68 nsyms.append(node.term)
69 traverse(node, nbits, nsyms, start_node, root, depth + 1)
76 def dfs_setid(node, prefix):
77 if node.term is not None:
79 if len(prefix) <= 7 and [1] * len(prefix) == prefix:
84 dfs_setid(node.left, prefix + [0])
85 dfs_setid(node.right, prefix + [1])
90 traverse(node, [], [], node, root, 0)
94 NGHTTP2_HUFF_ACCEPTED = 1
95 NGHTTP2_HUFF_SYM = 1 << 1
96 NGHTTP2_HUFF_FAIL = 1 << 2
99 if node.term is not None:
101 print '/* {} */'.format(node.id)
103 for nd, bits, syms in node.trans:
111 flags |= NGHTTP2_HUFF_SYM
114 flags |= NGHTTP2_HUFF_FAIL
118 # if nd.id is None, it is a leaf node
120 flags |= NGHTTP2_HUFF_ACCEPTED
122 flags |= NGHTTP2_HUFF_ACCEPTED
123 print ' {{{}, 0x{:02x}, {}}},'.format(id, flags, out)
126 dfs_print(node.right)
128 symbol_tbl = [(None, 0) for i in range(257)]
133 for line in sys.stdin:
134 m = re.match(r'.*\(\s*(\d+)\)\s+([|01]+)\s+(\S+)\s+\[\s*(\d+)\].*', line)
136 #print m.group(1), m.group(2), m.group(4)
137 if len(m.group(3)) > 8:
138 raise Error('Code is more than 4 bytes long')
139 sym = int(m.group(1))
140 bits = re.sub(r'\|', '', m.group(2))
141 nbits = int(m.group(4))
142 assert(len(bits) == nbits)
143 binpat = to_bin(bits)
144 assert(len(binpat) == (nbits+7)/8)
145 symbol_tbl[sym] = (binpat, nbits, m.group(3))
146 #print "Inserting", sym
147 insert(root, sym, bits)
160 const nghttp2_huff_sym huff_sym_table[] = {'''
162 pat = list(symbol_tbl[i][0])
163 pat += [0]*(4 - len(pat))
166 '''.format(symbol_tbl[i][1], symbol_tbl[i][2], ',' if i < 256 else '')
172 NGHTTP2_HUFF_ACCEPTED = {},
173 NGHTTP2_HUFF_SYM = {},
174 NGHTTP2_HUFF_FAIL = {},
175 }} nghttp2_huff_decode_flag;
176 '''.format(NGHTTP2_HUFF_ACCEPTED, NGHTTP2_HUFF_SYM, NGHTTP2_HUFF_FAIL)
183 } nghttp2_huff_decode;
187 const nghttp2_huff_decode huff_decode_table[][16] = {'''