netwerk/protocol/http/make_incoming_tables.py

Thu, 15 Jan 2015 21:03:48 +0100

author
Michael Schloh von Bennewitz <michael@schloh.com>
date
Thu, 15 Jan 2015 21:03:48 +0100
branch
TOR_BUG_9701
changeset 11
deefc01c0e14
permissions
-rw-r--r--

Integrate friendly tips from Tor colleagues to make (or not) 4.5 alpha 3;
This includes removal of overloaded (but unused) methods, and addition of
a overlooked call to DataStruct::SetData(nsISupports, uint32_t, bool.)

     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 ''')

mercurial