Wed, 31 Dec 2014 06:09:35 +0100
Cloned upstream origin tor-browser at tor-browser-31.3.0esr-4.5-1-build1
revision ID fc1c9ff7c1b2defdbc039f12214767608f46423f for hacking purpose.
1 # This script exists to auto-generate Http2HuffmanIncoming.h from the table
2 # contained in the HPACK spec. It's pretty simple to run:
3 # python make_incoming_tables.py < http2_huffman_table.txt > Http2HuffmanIncoming.h
4 # where huff_incoming.txt is copy/pasted text from the latest version of the
5 # HPACK spec, with all non-relevant lines removed (the most recent version
6 # of huff_incoming.txt also lives in this directory as an example).
7 import sys
9 def char_cmp(x, y):
10 rv = cmp(x['nbits'], y['nbits'])
11 if not rv:
12 rv = cmp(x['bpat'], y['bpat'])
13 if not rv:
14 rv = cmp(x['ascii'], y['ascii'])
15 return rv
17 characters = []
19 for line in sys.stdin:
20 line = line.rstrip()
21 obracket = line.rfind('[')
22 nbits = int(line[obracket + 1:-1])
24 ascii = int(line[10:13].strip())
26 bar = line.find('|', 9)
27 obracket = line.find('[', bar)
28 bpat = line[bar + 1:obracket - 1].strip().rstrip('|')
30 characters.append({'ascii': ascii, 'nbits': nbits, 'bpat': bpat})
32 characters.sort(cmp=char_cmp)
33 raw_entries = []
34 for c in characters:
35 raw_entries.append((c['ascii'], c['bpat']))
37 class DefaultList(list):
38 def __init__(self, default=None):
39 self.__default = default
41 def __ensure_size(self, sz):
42 while sz > len(self):
43 self.append(self.__default)
45 def __getitem__(self, idx):
46 self.__ensure_size(idx + 1)
47 rv = super(DefaultList, self).__getitem__(idx)
48 return rv
50 def __setitem__(self, idx, val):
51 self.__ensure_size(idx + 1)
52 super(DefaultList, self).__setitem__(idx, val)
54 def expand_to_8bit(bstr):
55 while len(bstr) < 8:
56 bstr += '0'
57 return int(bstr, 2)
59 table = DefaultList()
60 for r in raw_entries:
61 ascii, bpat = r
62 ascii = int(ascii)
63 bstrs = bpat.split('|')
64 curr_table = table
65 while len(bstrs) > 1:
66 idx = expand_to_8bit(bstrs[0])
67 if curr_table[idx] is None:
68 curr_table[idx] = DefaultList()
69 curr_table = curr_table[idx]
70 bstrs.pop(0)
72 idx = expand_to_8bit(bstrs[0])
73 curr_table[idx] = {'prefix_len': len(bstrs[0]),
74 'mask': int(bstrs[0], 2),
75 'value': ascii}
78 def output_table(table, name_suffix=''):
79 max_prefix_len = 0
80 for i, t in enumerate(table):
81 if isinstance(t, dict):
82 if t['prefix_len'] > max_prefix_len:
83 max_prefix_len = t['prefix_len']
84 elif t is not None:
85 output_table(t, '%s_%s' % (name_suffix, i))
87 tablename = 'HuffmanIncoming%s' % (name_suffix if name_suffix else 'Root',)
88 entriestable = tablename.replace('HuffmanIncoming', 'HuffmanIncomingEntries')
89 sys.stdout.write('static HuffmanIncomingEntry %s[] = {\n' % (entriestable,))
90 prefix_len = 0
91 value = 0
92 ptr = 'nullptr'
93 for i in range(256):
94 t = table[i]
95 if isinstance(t, dict):
96 prefix_len = t['prefix_len']
97 value = t['value']
98 ptr = 'nullptr'
99 elif t is not None:
100 prefix_len = 0
101 value = 0
102 subtable = '%s_%s' % (name_suffix, i)
103 ptr = '&HuffmanIncoming%s' % (subtable,)
104 sys.stdout.write(' { %s, %s, %s }' %
105 (ptr, value, prefix_len))
106 if i < 255:
107 sys.stdout.write(',')
108 sys.stdout.write('\n')
109 sys.stdout.write('};\n')
110 sys.stdout.write('\n')
111 sys.stdout.write('static HuffmanIncomingTable %s = {\n' % (tablename,))
112 sys.stdout.write(' %s,\n' % (entriestable,))
113 sys.stdout.write(' %s\n' % (max_prefix_len,))
114 sys.stdout.write('};\n')
115 sys.stdout.write('\n')
117 sys.stdout.write('''/*
118 * THIS FILE IS AUTO-GENERATED. DO NOT EDIT!
119 */
120 #ifndef mozilla__net__Http2HuffmanIncoming_h
121 #define mozilla__net__Http2HuffmanIncoming_h
123 namespace mozilla {
124 namespace net {
126 struct HuffmanIncomingTable;
128 struct HuffmanIncomingEntry {
129 HuffmanIncomingTable *mPtr;
130 uint16_t mValue;
131 uint8_t mPrefixLen;
132 };
134 struct HuffmanIncomingTable {
135 HuffmanIncomingEntry *mEntries;
136 uint8_t mPrefixLen;
137 };
139 ''')
141 output_table(table)
143 sys.stdout.write('''} // namespace net
144 } // namespace mozilla
146 #endif // mozilla__net__Http2HuffmanIncoming_h
147 ''')