12c593315Sopenharmony_ci#!/usr/bin/env python3
22c593315Sopenharmony_ci# -*- coding: utf-8 -*-
32c593315Sopenharmony_ci
42c593315Sopenharmony_ci# This script reads Huffman Code table [1] and generates symbol table
52c593315Sopenharmony_ci# and decoding tables in C language.  The resulting code is used in
62c593315Sopenharmony_ci# lib/nghttp2_hd_huffman.h and lib/nghttp2_hd_huffman_data.c
72c593315Sopenharmony_ci#
82c593315Sopenharmony_ci# [1] https://httpwg.org/specs/rfc7541.html
92c593315Sopenharmony_ci
102c593315Sopenharmony_ciimport re
112c593315Sopenharmony_ciimport sys
122c593315Sopenharmony_cifrom io import StringIO
132c593315Sopenharmony_ci
142c593315Sopenharmony_ci# From [1]
152c593315Sopenharmony_ciHUFFMAN_CODE_TABLE = """\
162c593315Sopenharmony_ci    (  0)  |11111111|11000                             1ff8  [13]
172c593315Sopenharmony_ci    (  1)  |11111111|11111111|1011000                7fffd8  [23]
182c593315Sopenharmony_ci    (  2)  |11111111|11111111|11111110|0010         fffffe2  [28]
192c593315Sopenharmony_ci    (  3)  |11111111|11111111|11111110|0011         fffffe3  [28]
202c593315Sopenharmony_ci    (  4)  |11111111|11111111|11111110|0100         fffffe4  [28]
212c593315Sopenharmony_ci    (  5)  |11111111|11111111|11111110|0101         fffffe5  [28]
222c593315Sopenharmony_ci    (  6)  |11111111|11111111|11111110|0110         fffffe6  [28]
232c593315Sopenharmony_ci    (  7)  |11111111|11111111|11111110|0111         fffffe7  [28]
242c593315Sopenharmony_ci    (  8)  |11111111|11111111|11111110|1000         fffffe8  [28]
252c593315Sopenharmony_ci    (  9)  |11111111|11111111|11101010               ffffea  [24]
262c593315Sopenharmony_ci    ( 10)  |11111111|11111111|11111111|111100      3ffffffc  [30]
272c593315Sopenharmony_ci    ( 11)  |11111111|11111111|11111110|1001         fffffe9  [28]
282c593315Sopenharmony_ci    ( 12)  |11111111|11111111|11111110|1010         fffffea  [28]
292c593315Sopenharmony_ci    ( 13)  |11111111|11111111|11111111|111101      3ffffffd  [30]
302c593315Sopenharmony_ci    ( 14)  |11111111|11111111|11111110|1011         fffffeb  [28]
312c593315Sopenharmony_ci    ( 15)  |11111111|11111111|11111110|1100         fffffec  [28]
322c593315Sopenharmony_ci    ( 16)  |11111111|11111111|11111110|1101         fffffed  [28]
332c593315Sopenharmony_ci    ( 17)  |11111111|11111111|11111110|1110         fffffee  [28]
342c593315Sopenharmony_ci    ( 18)  |11111111|11111111|11111110|1111         fffffef  [28]
352c593315Sopenharmony_ci    ( 19)  |11111111|11111111|11111111|0000         ffffff0  [28]
362c593315Sopenharmony_ci    ( 20)  |11111111|11111111|11111111|0001         ffffff1  [28]
372c593315Sopenharmony_ci    ( 21)  |11111111|11111111|11111111|0010         ffffff2  [28]
382c593315Sopenharmony_ci    ( 22)  |11111111|11111111|11111111|111110      3ffffffe  [30]
392c593315Sopenharmony_ci    ( 23)  |11111111|11111111|11111111|0011         ffffff3  [28]
402c593315Sopenharmony_ci    ( 24)  |11111111|11111111|11111111|0100         ffffff4  [28]
412c593315Sopenharmony_ci    ( 25)  |11111111|11111111|11111111|0101         ffffff5  [28]
422c593315Sopenharmony_ci    ( 26)  |11111111|11111111|11111111|0110         ffffff6  [28]
432c593315Sopenharmony_ci    ( 27)  |11111111|11111111|11111111|0111         ffffff7  [28]
442c593315Sopenharmony_ci    ( 28)  |11111111|11111111|11111111|1000         ffffff8  [28]
452c593315Sopenharmony_ci    ( 29)  |11111111|11111111|11111111|1001         ffffff9  [28]
462c593315Sopenharmony_ci    ( 30)  |11111111|11111111|11111111|1010         ffffffa  [28]
472c593315Sopenharmony_ci    ( 31)  |11111111|11111111|11111111|1011         ffffffb  [28]
482c593315Sopenharmony_ci' ' ( 32)  |010100                                       14  [ 6]
492c593315Sopenharmony_ci'!' ( 33)  |11111110|00                                 3f8  [10]
502c593315Sopenharmony_ci'"' ( 34)  |11111110|01                                 3f9  [10]
512c593315Sopenharmony_ci'#' ( 35)  |11111111|1010                               ffa  [12]
522c593315Sopenharmony_ci'$' ( 36)  |11111111|11001                             1ff9  [13]
532c593315Sopenharmony_ci'%' ( 37)  |010101                                       15  [ 6]
542c593315Sopenharmony_ci'&' ( 38)  |11111000                                     f8  [ 8]
552c593315Sopenharmony_ci''' ( 39)  |11111111|010                                7fa  [11]
562c593315Sopenharmony_ci'(' ( 40)  |11111110|10                                 3fa  [10]
572c593315Sopenharmony_ci')' ( 41)  |11111110|11                                 3fb  [10]
582c593315Sopenharmony_ci'*' ( 42)  |11111001                                     f9  [ 8]
592c593315Sopenharmony_ci'+' ( 43)  |11111111|011                                7fb  [11]
602c593315Sopenharmony_ci',' ( 44)  |11111010                                     fa  [ 8]
612c593315Sopenharmony_ci'-' ( 45)  |010110                                       16  [ 6]
622c593315Sopenharmony_ci'.' ( 46)  |010111                                       17  [ 6]
632c593315Sopenharmony_ci'/' ( 47)  |011000                                       18  [ 6]
642c593315Sopenharmony_ci'0' ( 48)  |00000                                         0  [ 5]
652c593315Sopenharmony_ci'1' ( 49)  |00001                                         1  [ 5]
662c593315Sopenharmony_ci'2' ( 50)  |00010                                         2  [ 5]
672c593315Sopenharmony_ci'3' ( 51)  |011001                                       19  [ 6]
682c593315Sopenharmony_ci'4' ( 52)  |011010                                       1a  [ 6]
692c593315Sopenharmony_ci'5' ( 53)  |011011                                       1b  [ 6]
702c593315Sopenharmony_ci'6' ( 54)  |011100                                       1c  [ 6]
712c593315Sopenharmony_ci'7' ( 55)  |011101                                       1d  [ 6]
722c593315Sopenharmony_ci'8' ( 56)  |011110                                       1e  [ 6]
732c593315Sopenharmony_ci'9' ( 57)  |011111                                       1f  [ 6]
742c593315Sopenharmony_ci':' ( 58)  |1011100                                      5c  [ 7]
752c593315Sopenharmony_ci';' ( 59)  |11111011                                     fb  [ 8]
762c593315Sopenharmony_ci'<' ( 60)  |11111111|1111100                           7ffc  [15]
772c593315Sopenharmony_ci'=' ( 61)  |100000                                       20  [ 6]
782c593315Sopenharmony_ci'>' ( 62)  |11111111|1011                               ffb  [12]
792c593315Sopenharmony_ci'?' ( 63)  |11111111|00                                 3fc  [10]
802c593315Sopenharmony_ci'@' ( 64)  |11111111|11010                             1ffa  [13]
812c593315Sopenharmony_ci'A' ( 65)  |100001                                       21  [ 6]
822c593315Sopenharmony_ci'B' ( 66)  |1011101                                      5d  [ 7]
832c593315Sopenharmony_ci'C' ( 67)  |1011110                                      5e  [ 7]
842c593315Sopenharmony_ci'D' ( 68)  |1011111                                      5f  [ 7]
852c593315Sopenharmony_ci'E' ( 69)  |1100000                                      60  [ 7]
862c593315Sopenharmony_ci'F' ( 70)  |1100001                                      61  [ 7]
872c593315Sopenharmony_ci'G' ( 71)  |1100010                                      62  [ 7]
882c593315Sopenharmony_ci'H' ( 72)  |1100011                                      63  [ 7]
892c593315Sopenharmony_ci'I' ( 73)  |1100100                                      64  [ 7]
902c593315Sopenharmony_ci'J' ( 74)  |1100101                                      65  [ 7]
912c593315Sopenharmony_ci'K' ( 75)  |1100110                                      66  [ 7]
922c593315Sopenharmony_ci'L' ( 76)  |1100111                                      67  [ 7]
932c593315Sopenharmony_ci'M' ( 77)  |1101000                                      68  [ 7]
942c593315Sopenharmony_ci'N' ( 78)  |1101001                                      69  [ 7]
952c593315Sopenharmony_ci'O' ( 79)  |1101010                                      6a  [ 7]
962c593315Sopenharmony_ci'P' ( 80)  |1101011                                      6b  [ 7]
972c593315Sopenharmony_ci'Q' ( 81)  |1101100                                      6c  [ 7]
982c593315Sopenharmony_ci'R' ( 82)  |1101101                                      6d  [ 7]
992c593315Sopenharmony_ci'S' ( 83)  |1101110                                      6e  [ 7]
1002c593315Sopenharmony_ci'T' ( 84)  |1101111                                      6f  [ 7]
1012c593315Sopenharmony_ci'U' ( 85)  |1110000                                      70  [ 7]
1022c593315Sopenharmony_ci'V' ( 86)  |1110001                                      71  [ 7]
1032c593315Sopenharmony_ci'W' ( 87)  |1110010                                      72  [ 7]
1042c593315Sopenharmony_ci'X' ( 88)  |11111100                                     fc  [ 8]
1052c593315Sopenharmony_ci'Y' ( 89)  |1110011                                      73  [ 7]
1062c593315Sopenharmony_ci'Z' ( 90)  |11111101                                     fd  [ 8]
1072c593315Sopenharmony_ci'[' ( 91)  |11111111|11011                             1ffb  [13]
1082c593315Sopenharmony_ci'\' ( 92)  |11111111|11111110|000                     7fff0  [19]
1092c593315Sopenharmony_ci']' ( 93)  |11111111|11100                             1ffc  [13]
1102c593315Sopenharmony_ci'^' ( 94)  |11111111|111100                            3ffc  [14]
1112c593315Sopenharmony_ci'_' ( 95)  |100010                                       22  [ 6]
1122c593315Sopenharmony_ci'`' ( 96)  |11111111|1111101                           7ffd  [15]
1132c593315Sopenharmony_ci'a' ( 97)  |00011                                         3  [ 5]
1142c593315Sopenharmony_ci'b' ( 98)  |100011                                       23  [ 6]
1152c593315Sopenharmony_ci'c' ( 99)  |00100                                         4  [ 5]
1162c593315Sopenharmony_ci'd' (100)  |100100                                       24  [ 6]
1172c593315Sopenharmony_ci'e' (101)  |00101                                         5  [ 5]
1182c593315Sopenharmony_ci'f' (102)  |100101                                       25  [ 6]
1192c593315Sopenharmony_ci'g' (103)  |100110                                       26  [ 6]
1202c593315Sopenharmony_ci'h' (104)  |100111                                       27  [ 6]
1212c593315Sopenharmony_ci'i' (105)  |00110                                         6  [ 5]
1222c593315Sopenharmony_ci'j' (106)  |1110100                                      74  [ 7]
1232c593315Sopenharmony_ci'k' (107)  |1110101                                      75  [ 7]
1242c593315Sopenharmony_ci'l' (108)  |101000                                       28  [ 6]
1252c593315Sopenharmony_ci'm' (109)  |101001                                       29  [ 6]
1262c593315Sopenharmony_ci'n' (110)  |101010                                       2a  [ 6]
1272c593315Sopenharmony_ci'o' (111)  |00111                                         7  [ 5]
1282c593315Sopenharmony_ci'p' (112)  |101011                                       2b  [ 6]
1292c593315Sopenharmony_ci'q' (113)  |1110110                                      76  [ 7]
1302c593315Sopenharmony_ci'r' (114)  |101100                                       2c  [ 6]
1312c593315Sopenharmony_ci's' (115)  |01000                                         8  [ 5]
1322c593315Sopenharmony_ci't' (116)  |01001                                         9  [ 5]
1332c593315Sopenharmony_ci'u' (117)  |101101                                       2d  [ 6]
1342c593315Sopenharmony_ci'v' (118)  |1110111                                      77  [ 7]
1352c593315Sopenharmony_ci'w' (119)  |1111000                                      78  [ 7]
1362c593315Sopenharmony_ci'x' (120)  |1111001                                      79  [ 7]
1372c593315Sopenharmony_ci'y' (121)  |1111010                                      7a  [ 7]
1382c593315Sopenharmony_ci'z' (122)  |1111011                                      7b  [ 7]
1392c593315Sopenharmony_ci'{' (123)  |11111111|1111110                           7ffe  [15]
1402c593315Sopenharmony_ci'|' (124)  |11111111|100                                7fc  [11]
1412c593315Sopenharmony_ci'}' (125)  |11111111|111101                            3ffd  [14]
1422c593315Sopenharmony_ci'~' (126)  |11111111|11101                             1ffd  [13]
1432c593315Sopenharmony_ci    (127)  |11111111|11111111|11111111|1100         ffffffc  [28]
1442c593315Sopenharmony_ci    (128)  |11111111|11111110|0110                    fffe6  [20]
1452c593315Sopenharmony_ci    (129)  |11111111|11111111|010010                 3fffd2  [22]
1462c593315Sopenharmony_ci    (130)  |11111111|11111110|0111                    fffe7  [20]
1472c593315Sopenharmony_ci    (131)  |11111111|11111110|1000                    fffe8  [20]
1482c593315Sopenharmony_ci    (132)  |11111111|11111111|010011                 3fffd3  [22]
1492c593315Sopenharmony_ci    (133)  |11111111|11111111|010100                 3fffd4  [22]
1502c593315Sopenharmony_ci    (134)  |11111111|11111111|010101                 3fffd5  [22]
1512c593315Sopenharmony_ci    (135)  |11111111|11111111|1011001                7fffd9  [23]
1522c593315Sopenharmony_ci    (136)  |11111111|11111111|010110                 3fffd6  [22]
1532c593315Sopenharmony_ci    (137)  |11111111|11111111|1011010                7fffda  [23]
1542c593315Sopenharmony_ci    (138)  |11111111|11111111|1011011                7fffdb  [23]
1552c593315Sopenharmony_ci    (139)  |11111111|11111111|1011100                7fffdc  [23]
1562c593315Sopenharmony_ci    (140)  |11111111|11111111|1011101                7fffdd  [23]
1572c593315Sopenharmony_ci    (141)  |11111111|11111111|1011110                7fffde  [23]
1582c593315Sopenharmony_ci    (142)  |11111111|11111111|11101011               ffffeb  [24]
1592c593315Sopenharmony_ci    (143)  |11111111|11111111|1011111                7fffdf  [23]
1602c593315Sopenharmony_ci    (144)  |11111111|11111111|11101100               ffffec  [24]
1612c593315Sopenharmony_ci    (145)  |11111111|11111111|11101101               ffffed  [24]
1622c593315Sopenharmony_ci    (146)  |11111111|11111111|010111                 3fffd7  [22]
1632c593315Sopenharmony_ci    (147)  |11111111|11111111|1100000                7fffe0  [23]
1642c593315Sopenharmony_ci    (148)  |11111111|11111111|11101110               ffffee  [24]
1652c593315Sopenharmony_ci    (149)  |11111111|11111111|1100001                7fffe1  [23]
1662c593315Sopenharmony_ci    (150)  |11111111|11111111|1100010                7fffe2  [23]
1672c593315Sopenharmony_ci    (151)  |11111111|11111111|1100011                7fffe3  [23]
1682c593315Sopenharmony_ci    (152)  |11111111|11111111|1100100                7fffe4  [23]
1692c593315Sopenharmony_ci    (153)  |11111111|11111110|11100                  1fffdc  [21]
1702c593315Sopenharmony_ci    (154)  |11111111|11111111|011000                 3fffd8  [22]
1712c593315Sopenharmony_ci    (155)  |11111111|11111111|1100101                7fffe5  [23]
1722c593315Sopenharmony_ci    (156)  |11111111|11111111|011001                 3fffd9  [22]
1732c593315Sopenharmony_ci    (157)  |11111111|11111111|1100110                7fffe6  [23]
1742c593315Sopenharmony_ci    (158)  |11111111|11111111|1100111                7fffe7  [23]
1752c593315Sopenharmony_ci    (159)  |11111111|11111111|11101111               ffffef  [24]
1762c593315Sopenharmony_ci    (160)  |11111111|11111111|011010                 3fffda  [22]
1772c593315Sopenharmony_ci    (161)  |11111111|11111110|11101                  1fffdd  [21]
1782c593315Sopenharmony_ci    (162)  |11111111|11111110|1001                    fffe9  [20]
1792c593315Sopenharmony_ci    (163)  |11111111|11111111|011011                 3fffdb  [22]
1802c593315Sopenharmony_ci    (164)  |11111111|11111111|011100                 3fffdc  [22]
1812c593315Sopenharmony_ci    (165)  |11111111|11111111|1101000                7fffe8  [23]
1822c593315Sopenharmony_ci    (166)  |11111111|11111111|1101001                7fffe9  [23]
1832c593315Sopenharmony_ci    (167)  |11111111|11111110|11110                  1fffde  [21]
1842c593315Sopenharmony_ci    (168)  |11111111|11111111|1101010                7fffea  [23]
1852c593315Sopenharmony_ci    (169)  |11111111|11111111|011101                 3fffdd  [22]
1862c593315Sopenharmony_ci    (170)  |11111111|11111111|011110                 3fffde  [22]
1872c593315Sopenharmony_ci    (171)  |11111111|11111111|11110000               fffff0  [24]
1882c593315Sopenharmony_ci    (172)  |11111111|11111110|11111                  1fffdf  [21]
1892c593315Sopenharmony_ci    (173)  |11111111|11111111|011111                 3fffdf  [22]
1902c593315Sopenharmony_ci    (174)  |11111111|11111111|1101011                7fffeb  [23]
1912c593315Sopenharmony_ci    (175)  |11111111|11111111|1101100                7fffec  [23]
1922c593315Sopenharmony_ci    (176)  |11111111|11111111|00000                  1fffe0  [21]
1932c593315Sopenharmony_ci    (177)  |11111111|11111111|00001                  1fffe1  [21]
1942c593315Sopenharmony_ci    (178)  |11111111|11111111|100000                 3fffe0  [22]
1952c593315Sopenharmony_ci    (179)  |11111111|11111111|00010                  1fffe2  [21]
1962c593315Sopenharmony_ci    (180)  |11111111|11111111|1101101                7fffed  [23]
1972c593315Sopenharmony_ci    (181)  |11111111|11111111|100001                 3fffe1  [22]
1982c593315Sopenharmony_ci    (182)  |11111111|11111111|1101110                7fffee  [23]
1992c593315Sopenharmony_ci    (183)  |11111111|11111111|1101111                7fffef  [23]
2002c593315Sopenharmony_ci    (184)  |11111111|11111110|1010                    fffea  [20]
2012c593315Sopenharmony_ci    (185)  |11111111|11111111|100010                 3fffe2  [22]
2022c593315Sopenharmony_ci    (186)  |11111111|11111111|100011                 3fffe3  [22]
2032c593315Sopenharmony_ci    (187)  |11111111|11111111|100100                 3fffe4  [22]
2042c593315Sopenharmony_ci    (188)  |11111111|11111111|1110000                7ffff0  [23]
2052c593315Sopenharmony_ci    (189)  |11111111|11111111|100101                 3fffe5  [22]
2062c593315Sopenharmony_ci    (190)  |11111111|11111111|100110                 3fffe6  [22]
2072c593315Sopenharmony_ci    (191)  |11111111|11111111|1110001                7ffff1  [23]
2082c593315Sopenharmony_ci    (192)  |11111111|11111111|11111000|00           3ffffe0  [26]
2092c593315Sopenharmony_ci    (193)  |11111111|11111111|11111000|01           3ffffe1  [26]
2102c593315Sopenharmony_ci    (194)  |11111111|11111110|1011                    fffeb  [20]
2112c593315Sopenharmony_ci    (195)  |11111111|11111110|001                     7fff1  [19]
2122c593315Sopenharmony_ci    (196)  |11111111|11111111|100111                 3fffe7  [22]
2132c593315Sopenharmony_ci    (197)  |11111111|11111111|1110010                7ffff2  [23]
2142c593315Sopenharmony_ci    (198)  |11111111|11111111|101000                 3fffe8  [22]
2152c593315Sopenharmony_ci    (199)  |11111111|11111111|11110110|0            1ffffec  [25]
2162c593315Sopenharmony_ci    (200)  |11111111|11111111|11111000|10           3ffffe2  [26]
2172c593315Sopenharmony_ci    (201)  |11111111|11111111|11111000|11           3ffffe3  [26]
2182c593315Sopenharmony_ci    (202)  |11111111|11111111|11111001|00           3ffffe4  [26]
2192c593315Sopenharmony_ci    (203)  |11111111|11111111|11111011|110          7ffffde  [27]
2202c593315Sopenharmony_ci    (204)  |11111111|11111111|11111011|111          7ffffdf  [27]
2212c593315Sopenharmony_ci    (205)  |11111111|11111111|11111001|01           3ffffe5  [26]
2222c593315Sopenharmony_ci    (206)  |11111111|11111111|11110001               fffff1  [24]
2232c593315Sopenharmony_ci    (207)  |11111111|11111111|11110110|1            1ffffed  [25]
2242c593315Sopenharmony_ci    (208)  |11111111|11111110|010                     7fff2  [19]
2252c593315Sopenharmony_ci    (209)  |11111111|11111111|00011                  1fffe3  [21]
2262c593315Sopenharmony_ci    (210)  |11111111|11111111|11111001|10           3ffffe6  [26]
2272c593315Sopenharmony_ci    (211)  |11111111|11111111|11111100|000          7ffffe0  [27]
2282c593315Sopenharmony_ci    (212)  |11111111|11111111|11111100|001          7ffffe1  [27]
2292c593315Sopenharmony_ci    (213)  |11111111|11111111|11111001|11           3ffffe7  [26]
2302c593315Sopenharmony_ci    (214)  |11111111|11111111|11111100|010          7ffffe2  [27]
2312c593315Sopenharmony_ci    (215)  |11111111|11111111|11110010               fffff2  [24]
2322c593315Sopenharmony_ci    (216)  |11111111|11111111|00100                  1fffe4  [21]
2332c593315Sopenharmony_ci    (217)  |11111111|11111111|00101                  1fffe5  [21]
2342c593315Sopenharmony_ci    (218)  |11111111|11111111|11111010|00           3ffffe8  [26]
2352c593315Sopenharmony_ci    (219)  |11111111|11111111|11111010|01           3ffffe9  [26]
2362c593315Sopenharmony_ci    (220)  |11111111|11111111|11111111|1101         ffffffd  [28]
2372c593315Sopenharmony_ci    (221)  |11111111|11111111|11111100|011          7ffffe3  [27]
2382c593315Sopenharmony_ci    (222)  |11111111|11111111|11111100|100          7ffffe4  [27]
2392c593315Sopenharmony_ci    (223)  |11111111|11111111|11111100|101          7ffffe5  [27]
2402c593315Sopenharmony_ci    (224)  |11111111|11111110|1100                    fffec  [20]
2412c593315Sopenharmony_ci    (225)  |11111111|11111111|11110011               fffff3  [24]
2422c593315Sopenharmony_ci    (226)  |11111111|11111110|1101                    fffed  [20]
2432c593315Sopenharmony_ci    (227)  |11111111|11111111|00110                  1fffe6  [21]
2442c593315Sopenharmony_ci    (228)  |11111111|11111111|101001                 3fffe9  [22]
2452c593315Sopenharmony_ci    (229)  |11111111|11111111|00111                  1fffe7  [21]
2462c593315Sopenharmony_ci    (230)  |11111111|11111111|01000                  1fffe8  [21]
2472c593315Sopenharmony_ci    (231)  |11111111|11111111|1110011                7ffff3  [23]
2482c593315Sopenharmony_ci    (232)  |11111111|11111111|101010                 3fffea  [22]
2492c593315Sopenharmony_ci    (233)  |11111111|11111111|101011                 3fffeb  [22]
2502c593315Sopenharmony_ci    (234)  |11111111|11111111|11110111|0            1ffffee  [25]
2512c593315Sopenharmony_ci    (235)  |11111111|11111111|11110111|1            1ffffef  [25]
2522c593315Sopenharmony_ci    (236)  |11111111|11111111|11110100               fffff4  [24]
2532c593315Sopenharmony_ci    (237)  |11111111|11111111|11110101               fffff5  [24]
2542c593315Sopenharmony_ci    (238)  |11111111|11111111|11111010|10           3ffffea  [26]
2552c593315Sopenharmony_ci    (239)  |11111111|11111111|1110100                7ffff4  [23]
2562c593315Sopenharmony_ci    (240)  |11111111|11111111|11111010|11           3ffffeb  [26]
2572c593315Sopenharmony_ci    (241)  |11111111|11111111|11111100|110          7ffffe6  [27]
2582c593315Sopenharmony_ci    (242)  |11111111|11111111|11111011|00           3ffffec  [26]
2592c593315Sopenharmony_ci    (243)  |11111111|11111111|11111011|01           3ffffed  [26]
2602c593315Sopenharmony_ci    (244)  |11111111|11111111|11111100|111          7ffffe7  [27]
2612c593315Sopenharmony_ci    (245)  |11111111|11111111|11111101|000          7ffffe8  [27]
2622c593315Sopenharmony_ci    (246)  |11111111|11111111|11111101|001          7ffffe9  [27]
2632c593315Sopenharmony_ci    (247)  |11111111|11111111|11111101|010          7ffffea  [27]
2642c593315Sopenharmony_ci    (248)  |11111111|11111111|11111101|011          7ffffeb  [27]
2652c593315Sopenharmony_ci    (249)  |11111111|11111111|11111111|1110         ffffffe  [28]
2662c593315Sopenharmony_ci    (250)  |11111111|11111111|11111101|100          7ffffec  [27]
2672c593315Sopenharmony_ci    (251)  |11111111|11111111|11111101|101          7ffffed  [27]
2682c593315Sopenharmony_ci    (252)  |11111111|11111111|11111101|110          7ffffee  [27]
2692c593315Sopenharmony_ci    (253)  |11111111|11111111|11111101|111          7ffffef  [27]
2702c593315Sopenharmony_ci    (254)  |11111111|11111111|11111110|000          7fffff0  [27]
2712c593315Sopenharmony_ci    (255)  |11111111|11111111|11111011|10           3ffffee  [26]
2722c593315Sopenharmony_ciEOS (256)  |11111111|11111111|11111111|111111      3fffffff  [30]
2732c593315Sopenharmony_ci"""
2742c593315Sopenharmony_ci
2752c593315Sopenharmony_ciclass Node:
2762c593315Sopenharmony_ci
2772c593315Sopenharmony_ci    def __init__(self, term = None):
2782c593315Sopenharmony_ci        self.term = term
2792c593315Sopenharmony_ci        self.left = None
2802c593315Sopenharmony_ci        self.right = None
2812c593315Sopenharmony_ci        self.trans = []
2822c593315Sopenharmony_ci        self.id = None
2832c593315Sopenharmony_ci        self.accept = False
2842c593315Sopenharmony_ci
2852c593315Sopenharmony_ciclass Context:
2862c593315Sopenharmony_ci
2872c593315Sopenharmony_ci    def __init__(self):
2882c593315Sopenharmony_ci        self.next_id_ = 0
2892c593315Sopenharmony_ci        self.root = Node()
2902c593315Sopenharmony_ci
2912c593315Sopenharmony_ci    def next_id(self):
2922c593315Sopenharmony_ci        id = self.next_id_
2932c593315Sopenharmony_ci        self.next_id_ += 1
2942c593315Sopenharmony_ci        return id
2952c593315Sopenharmony_ci
2962c593315Sopenharmony_cidef _add(node, sym, bits):
2972c593315Sopenharmony_ci    if len(bits) == 0:
2982c593315Sopenharmony_ci        node.term = sym
2992c593315Sopenharmony_ci        return
3002c593315Sopenharmony_ci    else:
3012c593315Sopenharmony_ci        if bits[0] == '0':
3022c593315Sopenharmony_ci            if node.left is None:
3032c593315Sopenharmony_ci                node.left = Node()
3042c593315Sopenharmony_ci            child = node.left
3052c593315Sopenharmony_ci        else:
3062c593315Sopenharmony_ci            if node.right is None:
3072c593315Sopenharmony_ci                node.right = Node()
3082c593315Sopenharmony_ci            child = node.right
3092c593315Sopenharmony_ci        _add(child, sym, bits[1:])
3102c593315Sopenharmony_ci
3112c593315Sopenharmony_cidef huffman_tree_add(ctx, sym, bits):
3122c593315Sopenharmony_ci    _add(ctx.root, sym, bits)
3132c593315Sopenharmony_ci
3142c593315Sopenharmony_cidef _set_node_id(ctx, node, prefix):
3152c593315Sopenharmony_ci    if node.term is not None:
3162c593315Sopenharmony_ci        return
3172c593315Sopenharmony_ci    if len(prefix) <= 7 and [1] * len(prefix) == prefix:
3182c593315Sopenharmony_ci        node.accept = True
3192c593315Sopenharmony_ci    node.id = ctx.next_id()
3202c593315Sopenharmony_ci    _set_node_id(ctx, node.left, prefix + [0])
3212c593315Sopenharmony_ci    _set_node_id(ctx, node.right, prefix + [1])
3222c593315Sopenharmony_ci
3232c593315Sopenharmony_cidef huffman_tree_set_node_id(ctx):
3242c593315Sopenharmony_ci    _set_node_id(ctx, ctx.root, [])
3252c593315Sopenharmony_ci
3262c593315Sopenharmony_cidef _traverse(node, sym, start_node, root, left):
3272c593315Sopenharmony_ci    if left == 0:
3282c593315Sopenharmony_ci        if sym == 256:
3292c593315Sopenharmony_ci            sym = None
3302c593315Sopenharmony_ci            node = None
3312c593315Sopenharmony_ci        start_node.trans.append((node, sym))
3322c593315Sopenharmony_ci        return
3332c593315Sopenharmony_ci
3342c593315Sopenharmony_ci    if node.term is not None:
3352c593315Sopenharmony_ci        node = root
3362c593315Sopenharmony_ci
3372c593315Sopenharmony_ci    def go(node):
3382c593315Sopenharmony_ci        if node.term is not None:
3392c593315Sopenharmony_ci            assert sym is None
3402c593315Sopenharmony_ci            nsym = node.term
3412c593315Sopenharmony_ci        else:
3422c593315Sopenharmony_ci            nsym = sym
3432c593315Sopenharmony_ci
3442c593315Sopenharmony_ci        _traverse(node, nsym, start_node, root, left - 1)
3452c593315Sopenharmony_ci
3462c593315Sopenharmony_ci    go(node.left)
3472c593315Sopenharmony_ci    go(node.right)
3482c593315Sopenharmony_ci
3492c593315Sopenharmony_cidef _build_transition_table(ctx, node):
3502c593315Sopenharmony_ci    if node is None:
3512c593315Sopenharmony_ci        return
3522c593315Sopenharmony_ci    _traverse(node, None, node, ctx.root, 4)
3532c593315Sopenharmony_ci    _build_transition_table(ctx, node.left)
3542c593315Sopenharmony_ci    _build_transition_table(ctx, node.right)
3552c593315Sopenharmony_ci
3562c593315Sopenharmony_cidef huffman_tree_build_transition_table(ctx):
3572c593315Sopenharmony_ci    _build_transition_table(ctx, ctx.root)
3582c593315Sopenharmony_ci
3592c593315Sopenharmony_ciNGHTTP2_HUFF_ACCEPTED = 1 << 14
3602c593315Sopenharmony_ciNGHTTP2_HUFF_SYM = 1 << 15
3612c593315Sopenharmony_ci
3622c593315Sopenharmony_cidef _print_transition_table(node):
3632c593315Sopenharmony_ci    if node.term is not None:
3642c593315Sopenharmony_ci        return
3652c593315Sopenharmony_ci    print('/* {} */'.format(node.id))
3662c593315Sopenharmony_ci    print('{')
3672c593315Sopenharmony_ci    for nd, sym in node.trans:
3682c593315Sopenharmony_ci        flags = 0
3692c593315Sopenharmony_ci        if sym is None:
3702c593315Sopenharmony_ci            out = 0
3712c593315Sopenharmony_ci        else:
3722c593315Sopenharmony_ci            out = sym
3732c593315Sopenharmony_ci            flags |= NGHTTP2_HUFF_SYM
3742c593315Sopenharmony_ci        if nd is None:
3752c593315Sopenharmony_ci            id = 256
3762c593315Sopenharmony_ci        else:
3772c593315Sopenharmony_ci            id = nd.id
3782c593315Sopenharmony_ci            if id is None:
3792c593315Sopenharmony_ci                # if nd.id is None, it is a leaf node
3802c593315Sopenharmony_ci                id = 0
3812c593315Sopenharmony_ci                flags |= NGHTTP2_HUFF_ACCEPTED
3822c593315Sopenharmony_ci            elif nd.accept:
3832c593315Sopenharmony_ci                flags |= NGHTTP2_HUFF_ACCEPTED
3842c593315Sopenharmony_ci        print('  {{0x{:02x}, {}}},'.format(id | flags, out))
3852c593315Sopenharmony_ci    print('},')
3862c593315Sopenharmony_ci    _print_transition_table(node.left)
3872c593315Sopenharmony_ci    _print_transition_table(node.right)
3882c593315Sopenharmony_ci
3892c593315Sopenharmony_cidef huffman_tree_print_transition_table(ctx):
3902c593315Sopenharmony_ci    _print_transition_table(ctx.root)
3912c593315Sopenharmony_ci    print('/* 256 */')
3922c593315Sopenharmony_ci    print('{')
3932c593315Sopenharmony_ci    print('  {0x100, 0},')
3942c593315Sopenharmony_ci    print('  {0x100, 0},')
3952c593315Sopenharmony_ci    print('  {0x100, 0},')
3962c593315Sopenharmony_ci    print('  {0x100, 0},')
3972c593315Sopenharmony_ci    print('  {0x100, 0},')
3982c593315Sopenharmony_ci    print('  {0x100, 0},')
3992c593315Sopenharmony_ci    print('  {0x100, 0},')
4002c593315Sopenharmony_ci    print('  {0x100, 0},')
4012c593315Sopenharmony_ci    print('  {0x100, 0},')
4022c593315Sopenharmony_ci    print('  {0x100, 0},')
4032c593315Sopenharmony_ci    print('  {0x100, 0},')
4042c593315Sopenharmony_ci    print('  {0x100, 0},')
4052c593315Sopenharmony_ci    print('  {0x100, 0},')
4062c593315Sopenharmony_ci    print('  {0x100, 0},')
4072c593315Sopenharmony_ci    print('  {0x100, 0},')
4082c593315Sopenharmony_ci    print('  {0x100, 0},')
4092c593315Sopenharmony_ci    print('},')
4102c593315Sopenharmony_ci
4112c593315Sopenharmony_ciif __name__ == '__main__':
4122c593315Sopenharmony_ci    ctx = Context()
4132c593315Sopenharmony_ci    symbol_tbl = [(None, 0) for i in range(257)]
4142c593315Sopenharmony_ci
4152c593315Sopenharmony_ci    for line in StringIO(HUFFMAN_CODE_TABLE):
4162c593315Sopenharmony_ci        m = re.match(
4172c593315Sopenharmony_ci            r'.*\(\s*(\d+)\)\s+([|01]+)\s+(\S+)\s+\[\s*(\d+)\].*', line)
4182c593315Sopenharmony_ci        if m:
4192c593315Sopenharmony_ci            sym = int(m.group(1))
4202c593315Sopenharmony_ci            bits = re.sub(r'\|', '', m.group(2))
4212c593315Sopenharmony_ci            code = m.group(3)
4222c593315Sopenharmony_ci            nbits = int(m.group(4))
4232c593315Sopenharmony_ci            if len(code) > 8:
4242c593315Sopenharmony_ci                raise Error('Code is more than 4 bytes long')
4252c593315Sopenharmony_ci            assert(len(bits) == nbits)
4262c593315Sopenharmony_ci            symbol_tbl[sym] = (nbits, code)
4272c593315Sopenharmony_ci            huffman_tree_add(ctx, sym, bits)
4282c593315Sopenharmony_ci
4292c593315Sopenharmony_ci    huffman_tree_set_node_id(ctx)
4302c593315Sopenharmony_ci    huffman_tree_build_transition_table(ctx)
4312c593315Sopenharmony_ci
4322c593315Sopenharmony_ci    print('''\
4332c593315Sopenharmony_citypedef struct {
4342c593315Sopenharmony_ci  uint32_t nbits;
4352c593315Sopenharmony_ci  uint32_t code;
4362c593315Sopenharmony_ci} nghttp2_huff_sym;
4372c593315Sopenharmony_ci''')
4382c593315Sopenharmony_ci
4392c593315Sopenharmony_ci    print('''\
4402c593315Sopenharmony_ciconst nghttp2_huff_sym huff_sym_table[] = {''')
4412c593315Sopenharmony_ci    for i in range(257):
4422c593315Sopenharmony_ci        nbits = symbol_tbl[i][0]
4432c593315Sopenharmony_ci        k = int(symbol_tbl[i][1], 16)
4442c593315Sopenharmony_ci        k = k << (32 - nbits)
4452c593315Sopenharmony_ci        print('''\
4462c593315Sopenharmony_ci  {{ {}, 0x{}u }}{}\
4472c593315Sopenharmony_ci'''.format(symbol_tbl[i][0], hex(k)[2:], ',' if i < 256 else ''))
4482c593315Sopenharmony_ci    print('};')
4492c593315Sopenharmony_ci    print()
4502c593315Sopenharmony_ci
4512c593315Sopenharmony_ci    print('''\
4522c593315Sopenharmony_cienum {{
4532c593315Sopenharmony_ci  NGHTTP2_HUFF_ACCEPTED = {},
4542c593315Sopenharmony_ci  NGHTTP2_HUFF_SYM = {},
4552c593315Sopenharmony_ci}} nghttp2_huff_decode_flag;
4562c593315Sopenharmony_ci'''.format(NGHTTP2_HUFF_ACCEPTED, NGHTTP2_HUFF_SYM))
4572c593315Sopenharmony_ci
4582c593315Sopenharmony_ci    print('''\
4592c593315Sopenharmony_citypedef struct {
4602c593315Sopenharmony_ci  uint16_t fstate;
4612c593315Sopenharmony_ci  uint8_t sym;
4622c593315Sopenharmony_ci} nghttp2_huff_decode;
4632c593315Sopenharmony_ci''')
4642c593315Sopenharmony_ci
4652c593315Sopenharmony_ci    print('''\
4662c593315Sopenharmony_ciconst nghttp2_huff_decode huff_decode_table[][16] = {''')
4672c593315Sopenharmony_ci    huffman_tree_print_transition_table(ctx)
4682c593315Sopenharmony_ci    print('};')
469