OLD | NEW |
| (Empty) |
1 // Copyright 2014 The Chromium Authors. All rights reserved. | |
2 // Use of this source code is governed by a BSD-style license that can be | |
3 // found in the LICENSE file. | |
4 | |
5 #ifndef NET_SPDY_HPACK_HUFFMAN_TABLE_H_ | |
6 #define NET_SPDY_HPACK_HUFFMAN_TABLE_H_ | |
7 | |
8 #include <cstddef> | |
9 #include <string> | |
10 #include <vector> | |
11 | |
12 #include "base/basictypes.h" | |
13 #include "base/strings/string_piece.h" | |
14 #include "net/base/net_export.h" | |
15 #include "net/spdy/hpack_constants.h" | |
16 | |
17 namespace net { | |
18 | |
19 namespace test { | |
20 class HpackHuffmanTablePeer; | |
21 } // namespace test | |
22 | |
23 class HpackInputStream; | |
24 class HpackOutputStream; | |
25 | |
26 // HpackHuffmanTable encodes and decodes string literals using a constructed | |
27 // canonical Huffman code. Once initialized, an instance is read only and | |
28 // may be accessed only through its const interface. | |
29 class NET_EXPORT_PRIVATE HpackHuffmanTable { | |
30 public: | |
31 friend class test::HpackHuffmanTablePeer; | |
32 | |
33 typedef HpackHuffmanSymbol Symbol; | |
34 | |
35 // DecodeTables are multilevel indexes on code prefixes. Each table indexes | |
36 // a portion of the prefix mapped to DecodeEntry, which in turn either | |
37 // captures a terminal symbol, or points to the next DecodeTable to consult | |
38 // with successive portions of the prefix. | |
39 struct NET_EXPORT_PRIVATE DecodeEntry { | |
40 DecodeEntry(); | |
41 DecodeEntry(uint8 next_table_index, uint8 length, uint16 symbol_id); | |
42 | |
43 // The next table to consult. If this is a terminal, | |
44 // |next_table_index| will be self-referential. | |
45 uint8 next_table_index; | |
46 // Bit-length of terminal code, if this is a terminal. Length of the | |
47 // longest code having this prefix, if non-terminal. | |
48 uint8 length; | |
49 // Set only for terminal entries. | |
50 uint16 symbol_id; | |
51 }; | |
52 struct NET_EXPORT_PRIVATE DecodeTable { | |
53 // Number of bits indexed by the chain leading to this table. | |
54 uint8 prefix_length; | |
55 // Number of additional prefix bits this table indexes. | |
56 uint8 indexed_length; | |
57 // Entries are represented as a length |size()| slice into | |
58 // |decode_entries_| beginning at |entries_offset|. | |
59 size_t entries_offset; | |
60 // Returns |1 << indexed_length|. | |
61 size_t size() const; | |
62 }; | |
63 | |
64 HpackHuffmanTable(); | |
65 ~HpackHuffmanTable(); | |
66 | |
67 // Prepares HpackHuffmanTable to encode & decode the canonical Huffman | |
68 // code as determined by the given symbols. Must be called exactly once. | |
69 // Returns false if the input symbols define an invalid coding, and true | |
70 // otherwise. Symbols must be presented in ascending ID order with no gaps, | |
71 // and |symbol_count| must fit in a uint16. | |
72 bool Initialize(const Symbol* input_symbols, size_t symbol_count); | |
73 | |
74 // Returns whether Initialize() has been successfully called. | |
75 bool IsInitialized() const; | |
76 | |
77 // Encodes the input string to the output stream using the table's Huffman | |
78 // context. | |
79 void EncodeString(base::StringPiece in, HpackOutputStream* out) const; | |
80 | |
81 // Returns the encoded size of the input string. | |
82 size_t EncodedSize(base::StringPiece in) const; | |
83 | |
84 // Decodes symbols from |in| into |out|. It is the caller's responsibility | |
85 // to ensure |out| has a reserved a sufficient buffer to hold decoded output. | |
86 // DecodeString() halts when |in| runs out of input, in which case true is | |
87 // returned. It also halts (returning false) if an invalid Huffman code | |
88 // prefix is read, or if |out_capacity| would otherwise be overflowed. | |
89 bool DecodeString(HpackInputStream* in, | |
90 size_t out_capacity, | |
91 std::string* out) const; | |
92 | |
93 private: | |
94 // Expects symbols ordered on length & ID ascending. | |
95 void BuildDecodeTables(const std::vector<Symbol>& symbols); | |
96 | |
97 // Expects symbols ordered on ID ascending. | |
98 void BuildEncodeTable(const std::vector<Symbol>& symbols); | |
99 | |
100 // Adds a new DecodeTable with the argument prefix & indexed length. | |
101 // Returns the new table index. | |
102 uint8 AddDecodeTable(uint8 prefix, uint8 indexed); | |
103 | |
104 const DecodeEntry& Entry(const DecodeTable& table, uint32 index) const; | |
105 | |
106 void SetEntry(const DecodeTable& table, uint32 index, | |
107 const DecodeEntry& entry); | |
108 | |
109 std::vector<DecodeTable> decode_tables_; | |
110 std::vector<DecodeEntry> decode_entries_; | |
111 | |
112 // Symbol code and code length, in ascending symbol ID order. | |
113 // Codes are stored in the most-significant bits of the word. | |
114 std::vector<uint32> code_by_id_; | |
115 std::vector<uint8> length_by_id_; | |
116 | |
117 // The first 8 bits of the longest code. Applied when generating padding bits. | |
118 uint8 pad_bits_; | |
119 | |
120 // If initialization fails, preserve the symbol ID which failed validation | |
121 // for examination in tests. | |
122 uint16 failed_symbol_id_; | |
123 }; | |
124 | |
125 } // namespace net | |
126 | |
127 #endif // NET_SPDY_HPACK_HUFFMAN_TABLE_H_ | |
OLD | NEW |