| // Copyright 2016 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_HTTP2_HPACK_TOOLS_HPACK_BLOCK_BUILDER_H_ | 
 | #define QUICHE_HTTP2_HPACK_TOOLS_HPACK_BLOCK_BUILDER_H_ | 
 |  | 
 | // HpackBlockBuilder builds wire-format HPACK blocks (or fragments thereof) | 
 | // from components. | 
 |  | 
 | // Supports very large varints to enable tests to create HPACK blocks with | 
 | // values that the decoder should reject. For now, this is only intended for | 
 | // use in tests, and thus has EXPECT* in the code. If desired to use it in an | 
 | // encoder, it will need optimization work, especially w.r.t memory mgmt, and | 
 | // the EXPECT* will need to be removed or replaced with QUICHE_DCHECKs. And of | 
 | // course the support for very large varints will not be needed in production | 
 | // code. | 
 |  | 
 | #include <stddef.h> | 
 |  | 
 | #include <cstdint> | 
 | #include <string> | 
 |  | 
 | #include "absl/strings/string_view.h" | 
 | #include "http2/hpack/http2_hpack_constants.h" | 
 | #include "common/platform/api/quiche_test.h" | 
 |  | 
 | namespace http2 { | 
 | namespace test { | 
 |  | 
 | class HpackBlockBuilder { | 
 |  public: | 
 |   explicit HpackBlockBuilder(absl::string_view initial_contents) | 
 |       : buffer_(initial_contents.data(), initial_contents.size()) {} | 
 |   HpackBlockBuilder() {} | 
 |   ~HpackBlockBuilder() {} | 
 |  | 
 |   size_t size() const { return buffer_.size(); } | 
 |   const std::string& buffer() const { return buffer_; } | 
 |  | 
 |   //---------------------------------------------------------------------------- | 
 |   // Methods for appending a valid HPACK entry. | 
 |  | 
 |   void AppendIndexedHeader(uint64_t index) { | 
 |     AppendEntryTypeAndVarint(HpackEntryType::kIndexedHeader, index); | 
 |   } | 
 |  | 
 |   void AppendDynamicTableSizeUpdate(uint64_t size) { | 
 |     AppendEntryTypeAndVarint(HpackEntryType::kDynamicTableSizeUpdate, size); | 
 |   } | 
 |  | 
 |   void AppendNameIndexAndLiteralValue(HpackEntryType entry_type, | 
 |                                       uint64_t name_index, | 
 |                                       bool value_is_huffman_encoded, | 
 |                                       absl::string_view value) { | 
 |     // name_index==0 would indicate that the entry includes a literal name. | 
 |     // Call AppendLiteralNameAndValue in that case. | 
 |     EXPECT_NE(0u, name_index); | 
 |     AppendEntryTypeAndVarint(entry_type, name_index); | 
 |     AppendString(value_is_huffman_encoded, value); | 
 |   } | 
 |  | 
 |   void AppendLiteralNameAndValue(HpackEntryType entry_type, | 
 |                                  bool name_is_huffman_encoded, | 
 |                                  absl::string_view name, | 
 |                                  bool value_is_huffman_encoded, | 
 |                                  absl::string_view value) { | 
 |     AppendEntryTypeAndVarint(entry_type, 0); | 
 |     AppendString(name_is_huffman_encoded, name); | 
 |     AppendString(value_is_huffman_encoded, value); | 
 |   } | 
 |  | 
 |   //---------------------------------------------------------------------------- | 
 |   // Primitive methods that are not guaranteed to write a valid HPACK entry. | 
 |  | 
 |   // Appends a varint, with the specified high_bits above the prefix of the | 
 |   // varint. | 
 |   void AppendHighBitsAndVarint(uint8_t high_bits, | 
 |                                uint8_t prefix_length, | 
 |                                uint64_t varint); | 
 |  | 
 |   // Append the start of an HPACK entry for the specified type, with the | 
 |   // specified varint. | 
 |   void AppendEntryTypeAndVarint(HpackEntryType entry_type, uint64_t varint); | 
 |  | 
 |   // Append a header string (i.e. a header name or value) in HPACK format. | 
 |   // Does NOT perform Huffman encoding. | 
 |   void AppendString(bool is_huffman_encoded, absl::string_view str); | 
 |  | 
 |  private: | 
 |   std::string buffer_; | 
 | }; | 
 |  | 
 | }  // namespace test | 
 | }  // namespace http2 | 
 |  | 
 | #endif  // QUICHE_HTTP2_HPACK_TOOLS_HPACK_BLOCK_BUILDER_H_ |