| // Copyright 2014 The Chromium Authors. All rights reserved. |
| // Use of this source code is governed by a BSD-style license that can be |
| // found in the LICENSE file. |
| |
| #ifndef NET_SPDY_HPACK_HPACK_INPUT_STREAM_H_ |
| #define NET_SPDY_HPACK_HPACK_INPUT_STREAM_H_ |
| |
| #include <stddef.h> |
| #include <stdint.h> |
| |
| #include <string> |
| #include <utility> |
| |
| #include "base/macros.h" |
| #include "net/base/net_export.h" |
| #include "net/spdy/hpack/hpack_constants.h" |
| #include "net/spdy/hpack/hpack_huffman_table.h" |
| #include "net/spdy/platform/api/spdy_string_piece.h" |
| |
| // All section references below are to |
| // http://tools.ietf.org/html/draft-ietf-httpbis-header-compression-08 |
| |
| namespace net { |
| |
| namespace test { |
| class HpackInputStreamPeer; |
| } // namespace test |
| |
| typedef std::pair<size_t, uint32_t> InitialPeekResult; |
| |
| // An HpackInputStream handles all the low-level details of decoding |
| // header fields. |
| class NET_EXPORT_PRIVATE HpackInputStream { |
| public: |
| friend class test::HpackInputStreamPeer; |
| |
| explicit HpackInputStream(SpdyStringPiece buffer); |
| ~HpackInputStream(); |
| |
| // Returns whether or not there is more data to process. |
| bool HasMoreData() const; |
| |
| // If the next bits of input match |prefix|, consumes them and returns true. |
| // Otherwise, consumes nothing and returns false. |
| bool MatchPrefixAndConsume(HpackPrefix prefix); |
| |
| // The Decode* functions return true and fill in their arguments if |
| // decoding was successful, or false if an error was encountered. |
| |
| bool DecodeNextUint32(uint32_t* I); |
| bool DecodeNextIdentityString(SpdyStringPiece* str); |
| bool DecodeNextHuffmanString(std::string* str); |
| |
| // Stores input bits into the most-significant, unfilled bits of |out|. |
| // |peeked_count| is the number of filled bits in |out| which have been |
| // previously peeked. PeekBits() will fill some number of remaining bits, |
| // returning the new total number via |peeked_count|. Returns true if one |
| // or more additional bits were added to |out|, and false otherwise. |
| bool PeekBits(size_t* peeked_count, uint32_t* out) const; |
| |
| // Similar to PeekBits, but intended to be used when starting to decode a |
| // Huffman encoded string. Returns a pair containing the peeked_count and |
| // out values as described for PeekBits, with the bits from the first N bytes |
| // of buffer_, where N == min(4, buffer_.size()), starting with the high |
| // order bits. |
| // Should only be called when first peeking at bits from the input stream as |
| // it does not take peeked_count as an input, so doesn't know how many bits |
| // have already been returned by previous calls to InitializePeekBits and |
| // PeekBits. |
| InitialPeekResult InitializePeekBits(); |
| |
| // Consumes |count| bits of input. Generally paired with PeekBits(). |
| void ConsumeBits(size_t count); |
| |
| // If not currently on a byte boundary, consumes and discards |
| // remaining bits in the current byte. |
| void ConsumeByteRemainder(); |
| |
| // Return the total bytes that have been parsed SUCCESSFULLY. |
| uint32_t ParsedBytes() const; |
| |
| // When incrementally decode the header, need to remember the current |
| // position in the buffer after we successfully decode one opcode. |
| void MarkCurrentPosition(); |
| |
| // Returning true indicates this instance of HpackInputStream |
| // doesn't have enough data to parse the current opcode, and we |
| // are done with this instance. When more data arrive, a new |
| // HpackInputStream should be created to restart the parsing. |
| bool NeedMoreData() const; |
| |
| private: |
| SpdyStringPiece buffer_; |
| size_t bit_offset_; |
| // Total number of bytes parsed successfully. Only get updated when an |
| // opcode is parsed successfully. |
| uint32_t parsed_bytes_; |
| // Total number of bytes parsed currently. Get updated when an octet, |
| // a number or a string has been parsed successfully. Can point to the |
| // middle of an opcode. |
| uint32_t parsed_bytes_current_; |
| bool need_more_data_; |
| |
| bool PeekNextOctet(uint8_t* next_octet); |
| |
| bool DecodeNextOctet(uint8_t* next_octet); |
| |
| DISALLOW_COPY_AND_ASSIGN(HpackInputStream); |
| }; |
| |
| } // namespace net |
| |
| #endif // NET_SPDY_HPACK_HPACK_INPUT_STREAM_H_ |