Remove unused HpackHuffmanTable. PiperOrigin-RevId: 354323882 Change-Id: I7ff667ae18ae7e15e710ebc41c97569c2dbb0d48
diff --git a/spdy/core/hpack/hpack_constants.cc b/spdy/core/hpack/hpack_constants.cc index 6f928c5..d65680f 100644 --- a/spdy/core/hpack/hpack_constants.cc +++ b/spdy/core/hpack/hpack_constants.cc
@@ -9,7 +9,6 @@ #include <vector> #include "absl/base/macros.h" -#include "spdy/core/hpack/hpack_huffman_table.h" #include "spdy/core/hpack/hpack_static_table.h" #include "spdy/platform/api/spdy_logging.h" @@ -361,17 +360,6 @@ #undef STATIC_ENTRY -const HpackHuffmanTable& ObtainHpackHuffmanTable() { - static const HpackHuffmanTable* const shared_huffman_table = []() { - auto* table = new HpackHuffmanTable(); - CHECK(table->Initialize(HpackHuffmanCodeVector().data(), - HpackHuffmanCodeVector().size())); - CHECK(table->IsInitialized()); - return table; - }(); - return *shared_huffman_table; -} - const HpackStaticTable& ObtainHpackStaticTable() { static const HpackStaticTable* const shared_static_table = []() { auto* table = new HpackStaticTable();
diff --git a/spdy/core/hpack/hpack_constants.h b/spdy/core/hpack/hpack_constants.h index e7c816b..b0ffef1 100644 --- a/spdy/core/hpack/hpack_constants.h +++ b/spdy/core/hpack/hpack_constants.h
@@ -40,7 +40,6 @@ const size_t value_len; }; -class HpackHuffmanTable; class HpackStaticTable; // RFC 7540, 6.5.2: Initial value for SETTINGS_HEADER_TABLE_SIZE. @@ -78,11 +77,6 @@ QUICHE_EXPORT_PRIVATE const std::vector<HpackStaticEntry>& HpackStaticTableVector(); -// Returns a HpackHuffmanTable instance initialized with |kHpackHuffmanCode|. -// The instance is read-only, has static lifetime, and is safe to share amoung -// threads. This function is thread-safe. -QUICHE_EXPORT_PRIVATE const HpackHuffmanTable& ObtainHpackHuffmanTable(); - // Returns a HpackStaticTable instance initialized with |kHpackStaticTable|. // The instance is read-only, has static lifetime, and is safe to share amoung // threads. This function is thread-safe.
diff --git a/spdy/core/hpack/hpack_encoder.cc b/spdy/core/hpack/hpack_encoder.cc index b6715c3..7e924af 100644 --- a/spdy/core/hpack/hpack_encoder.cc +++ b/spdy/core/hpack/hpack_encoder.cc
@@ -11,7 +11,6 @@ #include "http2/hpack/huffman/hpack_huffman_encoder.h" #include "spdy/core/hpack/hpack_constants.h" #include "spdy/core/hpack/hpack_header_table.h" -#include "spdy/core/hpack/hpack_huffman_table.h" #include "spdy/core/hpack/hpack_output_stream.h" #include "spdy/platform/api/spdy_estimate_memory_usage.h" #include "spdy/platform/api/spdy_flag_utils.h"
diff --git a/spdy/core/hpack/hpack_encoder_test.cc b/spdy/core/hpack/hpack_encoder_test.cc index d7c4eba..0257aa6 100644 --- a/spdy/core/hpack/hpack_encoder_test.cc +++ b/spdy/core/hpack/hpack_encoder_test.cc
@@ -10,7 +10,6 @@ #include "http2/hpack/huffman/hpack_huffman_encoder.h" #include "http2/test_tools/http2_random.h" #include "common/platform/api/quiche_test.h" -#include "spdy/core/hpack/hpack_huffman_table.h" #include "spdy/core/spdy_simple_arena.h" #include "spdy/platform/api/spdy_flags.h" @@ -125,8 +124,7 @@ kRepresentations, }; -class HpackEncoderTest - : public QuicheTestWithParam<std::tuple<EncodeStrategy, bool>> { +class HpackEncoderTest : public QuicheTestWithParam<EncodeStrategy> { protected: typedef test::HpackEncoderPeer::Representations Representations; @@ -134,8 +132,7 @@ : peer_(&encoder_), static_(peer_.table()->GetByIndex(1)), headers_storage_(1024 /* block size */), - strategy_(std::get<0>(GetParam())), - use_fast_huffman_encoder_(std::get<1>(GetParam())) {} + strategy_(GetParam()) {} void SetUp() override { // Populate dynamic entries into the table fixture. For simplicity each @@ -187,20 +184,12 @@ ExpectString(&expected_, value); } void ExpectString(HpackOutputStream* stream, absl::string_view str) { - const HpackHuffmanTable& huffman_table = ObtainHpackHuffmanTable(); size_t encoded_size = - peer_.compression_enabled() - ? (use_fast_huffman_encoder_ ? http2::HuffmanSize(str) - : huffman_table.EncodedSize(str)) - : str.size(); + peer_.compression_enabled() ? http2::HuffmanSize(str) : str.size(); if (encoded_size < str.size()) { expected_.AppendPrefix(kStringLiteralHuffmanEncoded); expected_.AppendUint32(encoded_size); - if (use_fast_huffman_encoder_) { - http2::HuffmanEncodeFast(str, encoded_size, stream->MutableString()); - } else { - huffman_table.EncodeString(str, stream); - } + http2::HuffmanEncodeFast(str, encoded_size, stream->MutableString()); } else { expected_.AppendPrefix(kStringLiteralIdentityEncoded); expected_.AppendUint32(str.size()); @@ -263,15 +252,13 @@ HpackOutputStream expected_; const EncodeStrategy strategy_; - const bool use_fast_huffman_encoder_; }; using HpackEncoderTestWithDefaultStrategy = HpackEncoderTest; INSTANTIATE_TEST_SUITE_P(HpackEncoderTests, HpackEncoderTestWithDefaultStrategy, - ::testing::Combine(::testing::Values(kDefault), - ::testing::Bool())); + ::testing::Values(kDefault)); TEST_P(HpackEncoderTestWithDefaultStrategy, EncodeRepresentations) { encoder_.SetHeaderListener( @@ -306,10 +293,9 @@ INSTANTIATE_TEST_SUITE_P(HpackEncoderTests, HpackEncoderTest, - ::testing::Combine(::testing::Values(kDefault, - kIncremental, - kRepresentations), - ::testing::Bool())); + ::testing::Values(kDefault, + kIncremental, + kRepresentations)); TEST_P(HpackEncoderTest, SingleDynamicIndex) { encoder_.SetHeaderListener(
diff --git a/spdy/core/hpack/hpack_huffman_table.cc b/spdy/core/hpack/hpack_huffman_table.cc deleted file mode 100644 index 50faefd..0000000 --- a/spdy/core/hpack/hpack_huffman_table.cc +++ /dev/null
@@ -1,151 +0,0 @@ -// 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. - -#include "spdy/core/hpack/hpack_huffman_table.h" - -#include <algorithm> -#include <cmath> -#include <limits> -#include <memory> - -#include "spdy/core/hpack/hpack_output_stream.h" -#include "spdy/platform/api/spdy_estimate_memory_usage.h" -#include "spdy/platform/api/spdy_logging.h" - -namespace spdy { - -namespace { - -bool SymbolLengthAndIdCompare(const HpackHuffmanSymbol& a, - const HpackHuffmanSymbol& b) { - if (a.length == b.length) { - return a.id < b.id; - } - return a.length < b.length; -} -bool SymbolIdCompare(const HpackHuffmanSymbol& a, const HpackHuffmanSymbol& b) { - return a.id < b.id; -} - -} // namespace - -HpackHuffmanTable::HpackHuffmanTable() : pad_bits_(0), failed_symbol_id_(0) {} - -HpackHuffmanTable::~HpackHuffmanTable() = default; - -bool HpackHuffmanTable::Initialize(const HpackHuffmanSymbol* input_symbols, - size_t symbol_count) { - CHECK(!IsInitialized()); - DCHECK_LE(symbol_count, std::numeric_limits<uint16_t>::max()); - - std::vector<Symbol> symbols(symbol_count); - // Validate symbol id sequence, and copy into |symbols|. - for (uint16_t i = 0; i < symbol_count; i++) { - if (i != input_symbols[i].id) { - failed_symbol_id_ = i; - return false; - } - symbols[i] = input_symbols[i]; - } - // Order on length and ID ascending, to verify symbol codes are canonical. - std::sort(symbols.begin(), symbols.end(), SymbolLengthAndIdCompare); - if (symbols[0].code != 0) { - failed_symbol_id_ = 0; - return false; - } - for (size_t i = 1; i != symbols.size(); i++) { - unsigned code_shift = 32 - symbols[i - 1].length; - uint32_t code = symbols[i - 1].code + (1 << code_shift); - - if (code != symbols[i].code) { - failed_symbol_id_ = symbols[i].id; - return false; - } - if (code < symbols[i - 1].code) { - // An integer overflow occurred. This implies the input - // lengths do not represent a valid Huffman code. - failed_symbol_id_ = symbols[i].id; - return false; - } - } - if (symbols.back().length < 8) { - // At least one code (such as an EOS symbol) must be 8 bits or longer. - // Without this, some inputs will not be encodable in a whole number - // of bytes. - return false; - } - pad_bits_ = static_cast<uint8_t>(symbols.back().code >> 24); - - // Order on symbol ID ascending. - std::sort(symbols.begin(), symbols.end(), SymbolIdCompare); - BuildEncodeTable(symbols); - return true; -} - -void HpackHuffmanTable::BuildEncodeTable(const std::vector<Symbol>& symbols) { - for (size_t i = 0; i != symbols.size(); i++) { - const Symbol& symbol = symbols[i]; - CHECK_EQ(i, symbol.id); - code_by_id_.push_back(symbol.code); - length_by_id_.push_back(symbol.length); - } -} - -bool HpackHuffmanTable::IsInitialized() const { - return !code_by_id_.empty(); -} - -void HpackHuffmanTable::EncodeString(absl::string_view in, - HpackOutputStream* out) const { - size_t bit_remnant = 0; - for (size_t i = 0; i != in.size(); i++) { - uint16_t symbol_id = static_cast<uint8_t>(in[i]); - CHECK_GT(code_by_id_.size(), symbol_id); - - // Load, and shift code to low bits. - unsigned length = length_by_id_[symbol_id]; - uint32_t code = code_by_id_[symbol_id] >> (32 - length); - - bit_remnant = (bit_remnant + length) % 8; - - if (length > 24) { - out->AppendBits(static_cast<uint8_t>(code >> 24), length - 24); - length = 24; - } - if (length > 16) { - out->AppendBits(static_cast<uint8_t>(code >> 16), length - 16); - length = 16; - } - if (length > 8) { - out->AppendBits(static_cast<uint8_t>(code >> 8), length - 8); - length = 8; - } - out->AppendBits(static_cast<uint8_t>(code), length); - } - if (bit_remnant != 0) { - // Pad current byte as required. - out->AppendBits(pad_bits_ >> bit_remnant, 8 - bit_remnant); - } -} - -size_t HpackHuffmanTable::EncodedSize(absl::string_view in) const { - size_t bit_count = 0; - for (size_t i = 0; i != in.size(); i++) { - uint16_t symbol_id = static_cast<uint8_t>(in[i]); - CHECK_GT(code_by_id_.size(), symbol_id); - - bit_count += length_by_id_[symbol_id]; - } - if (bit_count % 8 != 0) { - bit_count += 8 - bit_count % 8; - } - return bit_count / 8; -} - -size_t HpackHuffmanTable::EstimateMemoryUsage() const { - return SpdyEstimateMemoryUsage(code_by_id_) + - SpdyEstimateMemoryUsage(length_by_id_); -} - -} // namespace spdy
diff --git a/spdy/core/hpack/hpack_huffman_table.h b/spdy/core/hpack/hpack_huffman_table.h deleted file mode 100644 index a465866..0000000 --- a/spdy/core/hpack/hpack_huffman_table.h +++ /dev/null
@@ -1,75 +0,0 @@ -// 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 QUICHE_SPDY_CORE_HPACK_HPACK_HUFFMAN_TABLE_H_ -#define QUICHE_SPDY_CORE_HPACK_HPACK_HUFFMAN_TABLE_H_ - -#include <cstddef> -#include <cstdint> -#include <vector> - -#include "absl/strings/string_view.h" -#include "common/platform/api/quiche_export.h" -#include "spdy/core/hpack/hpack_constants.h" - -namespace spdy { - -namespace test { -class HpackHuffmanTablePeer; -} // namespace test - -class HpackOutputStream; - -// HpackHuffmanTable encodes string literals using a constructed canonical -// Huffman code. Once initialized, an instance is read only and may be accessed -// only through its const interface. -class QUICHE_EXPORT_PRIVATE HpackHuffmanTable { - public: - friend class test::HpackHuffmanTablePeer; - - typedef HpackHuffmanSymbol Symbol; - - HpackHuffmanTable(); - ~HpackHuffmanTable(); - - // Prepares HpackHuffmanTable to encode the canonical Huffman code as - // determined by the given symbols. Must be called exactly once. - // Returns false if the input symbols define an invalid coding, and true - // otherwise. Symbols must be presented in ascending ID order with no gaps, - // and |symbol_count| must fit in a uint16_t. - bool Initialize(const Symbol* input_symbols, size_t symbol_count); - - // Returns whether Initialize() has been successfully called. - bool IsInitialized() const; - - // Encodes the input string to the output stream using the table's Huffman - // context. - void EncodeString(absl::string_view in, HpackOutputStream* out) const; - - // Returns the encoded size of the input string. - size_t EncodedSize(absl::string_view in) const; - - // Returns the estimate of dynamically allocated memory in bytes. - size_t EstimateMemoryUsage() const; - - private: - // Expects symbols ordered on ID ascending. - void BuildEncodeTable(const std::vector<Symbol>& symbols); - - // Symbol code and code length, in ascending symbol ID order. - // Codes are stored in the most-significant bits of the word. - std::vector<uint32_t> code_by_id_; - std::vector<uint8_t> length_by_id_; - - // The first 8 bits of the longest code. Applied when generating padding bits. - uint8_t pad_bits_; - - // If initialization fails, preserve the symbol ID which failed validation - // for examination in tests. - uint16_t failed_symbol_id_; -}; - -} // namespace spdy - -#endif // QUICHE_SPDY_CORE_HPACK_HPACK_HUFFMAN_TABLE_H_
diff --git a/spdy/core/hpack/hpack_huffman_table_test.cc b/spdy/core/hpack/hpack_huffman_table_test.cc deleted file mode 100644 index 858afea..0000000 --- a/spdy/core/hpack/hpack_huffman_table_test.cc +++ /dev/null
@@ -1,308 +0,0 @@ -// 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. - -#include "spdy/core/hpack/hpack_huffman_table.h" - -#include <string> -#include <utility> - -#include "absl/base/macros.h" -#include "http2/hpack/huffman/hpack_huffman_decoder.h" -#include "common/platform/api/quiche_test.h" -#include "spdy/core/hpack/hpack_constants.h" -#include "spdy/core/hpack/hpack_output_stream.h" -#include "spdy/platform/api/spdy_string_utils.h" - -namespace spdy { - -namespace test { - -class HpackHuffmanTablePeer { - public: - explicit HpackHuffmanTablePeer(const HpackHuffmanTable& table) - : table_(table) {} - - const std::vector<uint32_t>& code_by_id() const { return table_.code_by_id_; } - const std::vector<uint8_t>& length_by_id() const { - return table_.length_by_id_; - } - uint8_t pad_bits() const { return table_.pad_bits_; } - uint16_t failed_symbol_id() const { return table_.failed_symbol_id_; } - - private: - const HpackHuffmanTable& table_; -}; - -namespace { - -// Tests of the ability to encode some canonical Huffman code, -// not just the one defined in the RFC 7541. -class GenericHuffmanTableTest : public QuicheTest { - protected: - GenericHuffmanTableTest() : table_(), peer_(table_) {} - - std::string EncodeString(absl::string_view input) { - std::string result; - HpackOutputStream output_stream; - table_.EncodeString(input, &output_stream); - - output_stream.TakeString(&result); - // Verify EncodedSize() agrees with EncodeString(). - EXPECT_EQ(result.size(), table_.EncodedSize(input)); - return result; - } - - HpackHuffmanTable table_; - HpackHuffmanTablePeer peer_; -}; - -TEST_F(GenericHuffmanTableTest, InitializeEdgeCases) { - { - // Verify eight symbols can be encoded with 3 bits per symbol. - HpackHuffmanSymbol code[] = {{0b00000000000000000000000000000000, 3, 0}, - {0b00100000000000000000000000000000, 3, 1}, - {0b01000000000000000000000000000000, 3, 2}, - {0b01100000000000000000000000000000, 3, 3}, - {0b10000000000000000000000000000000, 3, 4}, - {0b10100000000000000000000000000000, 3, 5}, - {0b11000000000000000000000000000000, 3, 6}, - {0b11100000000000000000000000000000, 8, 7}}; - HpackHuffmanTable table; - EXPECT_TRUE(table.Initialize(code, ABSL_ARRAYSIZE(code))); - } - { - // But using 2 bits with one symbol overflows the code. - HpackHuffmanSymbol code[] = { - {0b01000000000000000000000000000000, 3, 0}, - {0b01100000000000000000000000000000, 3, 1}, - {0b00000000000000000000000000000000, 2, 2}, - {0b10000000000000000000000000000000, 3, 3}, - {0b10100000000000000000000000000000, 3, 4}, - {0b11000000000000000000000000000000, 3, 5}, - {0b11100000000000000000000000000000, 3, 6}, - {0b00000000000000000000000000000000, 8, 7}}; // Overflow. - HpackHuffmanTable table; - EXPECT_FALSE(table.Initialize(code, ABSL_ARRAYSIZE(code))); - EXPECT_EQ(7, HpackHuffmanTablePeer(table).failed_symbol_id()); - } - { - // Verify four symbols can be encoded with incremental bits per symbol. - HpackHuffmanSymbol code[] = {{0b00000000000000000000000000000000, 1, 0}, - {0b10000000000000000000000000000000, 2, 1}, - {0b11000000000000000000000000000000, 3, 2}, - {0b11100000000000000000000000000000, 8, 3}}; - HpackHuffmanTable table; - EXPECT_TRUE(table.Initialize(code, ABSL_ARRAYSIZE(code))); - } - { - // But repeating a length overflows the code. - HpackHuffmanSymbol code[] = { - {0b00000000000000000000000000000000, 1, 0}, - {0b10000000000000000000000000000000, 2, 1}, - {0b11000000000000000000000000000000, 2, 2}, - {0b00000000000000000000000000000000, 8, 3}}; // Overflow. - HpackHuffmanTable table; - EXPECT_FALSE(table.Initialize(code, ABSL_ARRAYSIZE(code))); - EXPECT_EQ(3, HpackHuffmanTablePeer(table).failed_symbol_id()); - } - { - // Symbol IDs must be assigned sequentially with no gaps. - HpackHuffmanSymbol code[] = { - {0b00000000000000000000000000000000, 1, 0}, - {0b10000000000000000000000000000000, 2, 1}, - {0b11000000000000000000000000000000, 3, 1}, // Repeat. - {0b11100000000000000000000000000000, 8, 3}}; - HpackHuffmanTable table; - EXPECT_FALSE(table.Initialize(code, ABSL_ARRAYSIZE(code))); - EXPECT_EQ(2, HpackHuffmanTablePeer(table).failed_symbol_id()); - } - { - // Canonical codes must begin with zero. - HpackHuffmanSymbol code[] = {{0b10000000000000000000000000000000, 4, 0}, - {0b10010000000000000000000000000000, 4, 1}, - {0b10100000000000000000000000000000, 4, 2}, - {0b10110000000000000000000000000000, 8, 3}}; - HpackHuffmanTable table; - EXPECT_FALSE(table.Initialize(code, ABSL_ARRAYSIZE(code))); - EXPECT_EQ(0, HpackHuffmanTablePeer(table).failed_symbol_id()); - } - { - // Codes must match the expected canonical sequence. - HpackHuffmanSymbol code[] = { - {0b00000000000000000000000000000000, 2, 0}, - {0b01000000000000000000000000000000, 2, 1}, - {0b11000000000000000000000000000000, 2, 2}, // Code not canonical. - {0b10000000000000000000000000000000, 8, 3}}; - HpackHuffmanTable table; - EXPECT_FALSE(table.Initialize(code, ABSL_ARRAYSIZE(code))); - EXPECT_EQ(2, HpackHuffmanTablePeer(table).failed_symbol_id()); - } - { - // At least one code must have a length of 8 bits (to ensure pad-ability). - HpackHuffmanSymbol code[] = {{0b00000000000000000000000000000000, 1, 0}, - {0b10000000000000000000000000000000, 2, 1}, - {0b11000000000000000000000000000000, 3, 2}, - {0b11100000000000000000000000000000, 7, 3}}; - HpackHuffmanTable table; - EXPECT_FALSE(table.Initialize(code, ABSL_ARRAYSIZE(code))); - } -} - -TEST_F(GenericHuffmanTableTest, ValidateInternalsWithSmallCode) { - HpackHuffmanSymbol code[] = { - {0b01100000000000000000000000000000, 4, 0}, // 3rd. - {0b01110000000000000000000000000000, 4, 1}, // 4th. - {0b00000000000000000000000000000000, 2, 2}, // 1st assigned code. - {0b01000000000000000000000000000000, 3, 3}, // 2nd. - {0b10000000000000000000000000000000, 5, 4}, // 5th. - {0b10001000000000000000000000000000, 5, 5}, // 6th. - {0b10011000000000000000000000000000, 8, 6}, // 8th. - {0b10010000000000000000000000000000, 5, 7}}; // 7th. - EXPECT_TRUE(table_.Initialize(code, ABSL_ARRAYSIZE(code))); - - ASSERT_EQ(ABSL_ARRAYSIZE(code), peer_.code_by_id().size()); - ASSERT_EQ(ABSL_ARRAYSIZE(code), peer_.length_by_id().size()); - for (size_t i = 0; i < ABSL_ARRAYSIZE(code); ++i) { - EXPECT_EQ(code[i].code, peer_.code_by_id()[i]); - EXPECT_EQ(code[i].length, peer_.length_by_id()[i]); - } - - EXPECT_EQ(0b10011000, peer_.pad_bits()); - - char input_storage[] = {2, 3, 2, 7, 4}; - absl::string_view input(input_storage, ABSL_ARRAYSIZE(input_storage)); - // By symbol: (2) 00 (3) 010 (2) 00 (7) 10010 (4) 10000 (6 as pad) 1001100. - char expect_storage[] = {0b00010001, 0b00101000, 0b01001100}; - absl::string_view expect(expect_storage, ABSL_ARRAYSIZE(expect_storage)); - EXPECT_EQ(expect, EncodeString(input)); -} - -// Tests of the ability to encode the HPACK Huffman Code, defined in: -// https://httpwg.github.io/specs/rfc7541.html#huffman.code -class HpackHuffmanTableTest : public GenericHuffmanTableTest { - protected: - void SetUp() override { - EXPECT_TRUE(table_.Initialize(HpackHuffmanCodeVector().data(), - HpackHuffmanCodeVector().size())); - EXPECT_TRUE(table_.IsInitialized()); - } - - // Use http2::HpackHuffmanDecoder for roundtrip tests. - void DecodeString(const std::string& encoded, std::string* out) { - http2::HpackHuffmanDecoder decoder; - out->clear(); - EXPECT_TRUE(decoder.Decode(encoded, out)); - } -}; - -TEST_F(HpackHuffmanTableTest, InitializeHpackCode) { - EXPECT_EQ(peer_.pad_bits(), 0b11111111); // First 8 bits of EOS. -} - -TEST_F(HpackHuffmanTableTest, SpecRequestExamples) { - std::string buffer; - std::string test_table[] = { - SpdyHexDecode("f1e3c2e5f23a6ba0ab90f4ff"), - "www.example.com", - SpdyHexDecode("a8eb10649cbf"), - "no-cache", - SpdyHexDecode("25a849e95ba97d7f"), - "custom-key", - SpdyHexDecode("25a849e95bb8e8b4bf"), - "custom-value", - }; - // Round-trip each test example. - for (size_t i = 0; i != ABSL_ARRAYSIZE(test_table); i += 2) { - const std::string& encodedFixture(test_table[i]); - const std::string& decodedFixture(test_table[i + 1]); - DecodeString(encodedFixture, &buffer); - EXPECT_EQ(decodedFixture, buffer); - buffer = EncodeString(decodedFixture); - EXPECT_EQ(encodedFixture, buffer); - } -} - -TEST_F(HpackHuffmanTableTest, SpecResponseExamples) { - std::string buffer; - std::string test_table[] = { - SpdyHexDecode("6402"), - "302", - SpdyHexDecode("aec3771a4b"), - "private", - SpdyHexDecode("d07abe941054d444a8200595040b8166" - "e082a62d1bff"), - "Mon, 21 Oct 2013 20:13:21 GMT", - SpdyHexDecode("9d29ad171863c78f0b97c8e9ae82ae43" - "d3"), - "https://www.example.com", - SpdyHexDecode("94e7821dd7f2e6c7b335dfdfcd5b3960" - "d5af27087f3672c1ab270fb5291f9587" - "316065c003ed4ee5b1063d5007"), - "foo=ASDJKHQKBZXOQWEOPIUAXQWEOIU; max-age=3600; version=1", - }; - // Round-trip each test example. - for (size_t i = 0; i != ABSL_ARRAYSIZE(test_table); i += 2) { - const std::string& encodedFixture(test_table[i]); - const std::string& decodedFixture(test_table[i + 1]); - DecodeString(encodedFixture, &buffer); - EXPECT_EQ(decodedFixture, buffer); - buffer = EncodeString(decodedFixture); - EXPECT_EQ(encodedFixture, buffer); - } -} - -TEST_F(HpackHuffmanTableTest, RoundTripIndividualSymbols) { - for (size_t i = 0; i != 256; i++) { - char c = static_cast<char>(i); - char storage[3] = {c, c, c}; - absl::string_view input(storage, ABSL_ARRAYSIZE(storage)); - std::string buffer_in = EncodeString(input); - std::string buffer_out; - DecodeString(buffer_in, &buffer_out); - EXPECT_EQ(input, buffer_out); - } -} - -TEST_F(HpackHuffmanTableTest, RoundTripSymbolSequence) { - char storage[512]; - for (size_t i = 0; i != 256; i++) { - storage[i] = static_cast<char>(i); - storage[511 - i] = static_cast<char>(i); - } - absl::string_view input(storage, ABSL_ARRAYSIZE(storage)); - std::string buffer_in = EncodeString(input); - std::string buffer_out; - DecodeString(buffer_in, &buffer_out); - EXPECT_EQ(input, buffer_out); -} - -TEST_F(HpackHuffmanTableTest, EncodedSizeAgreesWithEncodeString) { - std::string test_table[] = { - "", - "Mon, 21 Oct 2013 20:13:21 GMT", - "https://www.example.com", - "foo=ASDJKHQKBZXOQWEOPIUAXQWEOIU; max-age=3600; version=1", - std::string(1, '\0'), - std::string("foo\0bar", 7), - std::string(256, '\0'), - }; - for (size_t i = 0; i != 256; ++i) { - // Expand last |test_table| entry to cover all codes. - test_table[ABSL_ARRAYSIZE(test_table) - 1][i] = static_cast<char>(i); - } - - HpackOutputStream output_stream; - std::string encoding; - for (size_t i = 0; i != ABSL_ARRAYSIZE(test_table); ++i) { - table_.EncodeString(test_table[i], &output_stream); - output_stream.TakeString(&encoding); - EXPECT_EQ(encoding.size(), table_.EncodedSize(test_table[i])); - } -} - -} // namespace - -} // namespace test - -} // namespace spdy