Move Http2HeaderBlock to http2_header_block*.
This allows users of SpdyHeaderBlock to update includes and build dependencies
at the same time when they are migrated to Http2HeaderBlock.
PiperOrigin-RevId: 461041592
diff --git a/build/source_list.bzl b/build/source_list.bzl
index e5c653b..9fb34e8 100644
--- a/build/source_list.bzl
+++ b/build/source_list.bzl
@@ -371,6 +371,7 @@
"spdy/core/hpack/hpack_output_stream.h",
"spdy/core/hpack/hpack_static_table.h",
"spdy/core/http2_frame_decoder_adapter.h",
+ "spdy/core/http2_header_block.h",
"spdy/core/http2_header_block_hpack_listener.h",
"spdy/core/metadata_extension.h",
"spdy/core/no_op_headers_handler.h",
@@ -670,12 +671,12 @@
"spdy/core/hpack/hpack_output_stream.cc",
"spdy/core/hpack/hpack_static_table.cc",
"spdy/core/http2_frame_decoder_adapter.cc",
+ "spdy/core/http2_header_block.cc",
"spdy/core/metadata_extension.cc",
"spdy/core/recording_headers_handler.cc",
"spdy/core/spdy_alt_svc_wire_format.cc",
"spdy/core/spdy_frame_builder.cc",
"spdy/core/spdy_framer.cc",
- "spdy/core/spdy_header_block.cc",
"spdy/core/spdy_header_storage.cc",
"spdy/core/spdy_no_op_visitor.cc",
"spdy/core/spdy_pinnable_buffer_piece.cc",
@@ -1266,11 +1267,11 @@
"spdy/core/hpack/hpack_output_stream_test.cc",
"spdy/core/hpack/hpack_round_trip_test.cc",
"spdy/core/hpack/hpack_static_table_test.cc",
+ "spdy/core/http2_header_block_test.cc",
"spdy/core/metadata_extension_test.cc",
"spdy/core/spdy_alt_svc_wire_format_test.cc",
"spdy/core/spdy_frame_builder_test.cc",
"spdy/core/spdy_framer_test.cc",
- "spdy/core/spdy_header_block_test.cc",
"spdy/core/spdy_header_storage_test.cc",
"spdy/core/spdy_intrusive_list_test.cc",
"spdy/core/spdy_pinnable_buffer_piece_test.cc",
diff --git a/build/source_list.gni b/build/source_list.gni
index 3deabbd..a89cff2 100644
--- a/build/source_list.gni
+++ b/build/source_list.gni
@@ -371,6 +371,7 @@
"src/quiche/spdy/core/hpack/hpack_output_stream.h",
"src/quiche/spdy/core/hpack/hpack_static_table.h",
"src/quiche/spdy/core/http2_frame_decoder_adapter.h",
+ "src/quiche/spdy/core/http2_header_block.h",
"src/quiche/spdy/core/http2_header_block_hpack_listener.h",
"src/quiche/spdy/core/metadata_extension.h",
"src/quiche/spdy/core/no_op_headers_handler.h",
@@ -670,12 +671,12 @@
"src/quiche/spdy/core/hpack/hpack_output_stream.cc",
"src/quiche/spdy/core/hpack/hpack_static_table.cc",
"src/quiche/spdy/core/http2_frame_decoder_adapter.cc",
+ "src/quiche/spdy/core/http2_header_block.cc",
"src/quiche/spdy/core/metadata_extension.cc",
"src/quiche/spdy/core/recording_headers_handler.cc",
"src/quiche/spdy/core/spdy_alt_svc_wire_format.cc",
"src/quiche/spdy/core/spdy_frame_builder.cc",
"src/quiche/spdy/core/spdy_framer.cc",
- "src/quiche/spdy/core/spdy_header_block.cc",
"src/quiche/spdy/core/spdy_header_storage.cc",
"src/quiche/spdy/core/spdy_no_op_visitor.cc",
"src/quiche/spdy/core/spdy_pinnable_buffer_piece.cc",
@@ -1266,11 +1267,11 @@
"src/quiche/spdy/core/hpack/hpack_output_stream_test.cc",
"src/quiche/spdy/core/hpack/hpack_round_trip_test.cc",
"src/quiche/spdy/core/hpack/hpack_static_table_test.cc",
+ "src/quiche/spdy/core/http2_header_block_test.cc",
"src/quiche/spdy/core/metadata_extension_test.cc",
"src/quiche/spdy/core/spdy_alt_svc_wire_format_test.cc",
"src/quiche/spdy/core/spdy_frame_builder_test.cc",
"src/quiche/spdy/core/spdy_framer_test.cc",
- "src/quiche/spdy/core/spdy_header_block_test.cc",
"src/quiche/spdy/core/spdy_header_storage_test.cc",
"src/quiche/spdy/core/spdy_intrusive_list_test.cc",
"src/quiche/spdy/core/spdy_pinnable_buffer_piece_test.cc",
diff --git a/build/source_list.json b/build/source_list.json
index f3ebe33..4d7c2f9 100644
--- a/build/source_list.json
+++ b/build/source_list.json
@@ -370,6 +370,7 @@
"quiche/spdy/core/hpack/hpack_output_stream.h",
"quiche/spdy/core/hpack/hpack_static_table.h",
"quiche/spdy/core/http2_frame_decoder_adapter.h",
+ "quiche/spdy/core/http2_header_block.h",
"quiche/spdy/core/http2_header_block_hpack_listener.h",
"quiche/spdy/core/metadata_extension.h",
"quiche/spdy/core/no_op_headers_handler.h",
@@ -669,12 +670,12 @@
"quiche/spdy/core/hpack/hpack_output_stream.cc",
"quiche/spdy/core/hpack/hpack_static_table.cc",
"quiche/spdy/core/http2_frame_decoder_adapter.cc",
+ "quiche/spdy/core/http2_header_block.cc",
"quiche/spdy/core/metadata_extension.cc",
"quiche/spdy/core/recording_headers_handler.cc",
"quiche/spdy/core/spdy_alt_svc_wire_format.cc",
"quiche/spdy/core/spdy_frame_builder.cc",
"quiche/spdy/core/spdy_framer.cc",
- "quiche/spdy/core/spdy_header_block.cc",
"quiche/spdy/core/spdy_header_storage.cc",
"quiche/spdy/core/spdy_no_op_visitor.cc",
"quiche/spdy/core/spdy_pinnable_buffer_piece.cc",
@@ -1265,11 +1266,11 @@
"quiche/spdy/core/hpack/hpack_output_stream_test.cc",
"quiche/spdy/core/hpack/hpack_round_trip_test.cc",
"quiche/spdy/core/hpack/hpack_static_table_test.cc",
+ "quiche/spdy/core/http2_header_block_test.cc",
"quiche/spdy/core/metadata_extension_test.cc",
"quiche/spdy/core/spdy_alt_svc_wire_format_test.cc",
"quiche/spdy/core/spdy_frame_builder_test.cc",
"quiche/spdy/core/spdy_framer_test.cc",
- "quiche/spdy/core/spdy_header_block_test.cc",
"quiche/spdy/core/spdy_header_storage_test.cc",
"quiche/spdy/core/spdy_intrusive_list_test.cc",
"quiche/spdy/core/spdy_pinnable_buffer_piece_test.cc",
diff --git a/quiche/spdy/core/spdy_header_block.cc b/quiche/spdy/core/http2_header_block.cc
similarity index 99%
rename from quiche/spdy/core/spdy_header_block.cc
rename to quiche/spdy/core/http2_header_block.cc
index fe11260..5004ba9 100644
--- a/quiche/spdy/core/spdy_header_block.cc
+++ b/quiche/spdy/core/http2_header_block.cc
@@ -2,7 +2,7 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
-#include "quiche/spdy/core/spdy_header_block.h"
+#include "quiche/spdy/core/http2_header_block.h"
#include <string.h>
diff --git a/quiche/spdy/core/http2_header_block.h b/quiche/spdy/core/http2_header_block.h
new file mode 100644
index 0000000..62e4d1d
--- /dev/null
+++ b/quiche/spdy/core/http2_header_block.h
@@ -0,0 +1,291 @@
+// Copyright (c) 2012 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_HTTP2_HEADER_BLOCK_H_
+#define QUICHE_SPDY_CORE_HTTP2_HEADER_BLOCK_H_
+
+#include <stddef.h>
+
+#include <functional>
+#include <list>
+#include <string>
+#include <utility>
+#include <vector>
+
+#include "absl/base/attributes.h"
+#include "quiche/common/platform/api/quiche_export.h"
+#include "quiche/common/platform/api/quiche_logging.h"
+#include "quiche/common/quiche_linked_hash_map.h"
+#include "quiche/common/quiche_text_utils.h"
+#include "quiche/spdy/core/spdy_header_storage.h"
+
+namespace spdy {
+
+namespace test {
+class Http2HeaderBlockPeer;
+class ValueProxyPeer;
+} // namespace test
+
+#ifndef SPDY_HEADER_DEBUG
+#if !defined(NDEBUG) || defined(ADDRESS_SANITIZER)
+#define SPDY_HEADER_DEBUG 1
+#else // !defined(NDEBUG) || defined(ADDRESS_SANITIZER)
+#define SPDY_HEADER_DEBUG 0
+#endif // !defined(NDEBUG) || defined(ADDRESS_SANITIZER)
+#endif // SPDY_HEADER_DEBUG
+
+// This class provides a key-value map that can be used to store SPDY header
+// names and values. This data structure preserves insertion order.
+//
+// Under the hood, this data structure uses large, contiguous blocks of memory
+// to store names and values. Lookups may be performed with absl::string_view
+// keys, and values are returned as absl::string_views (via ValueProxy, below).
+// Value absl::string_views are valid as long as the Http2HeaderBlock exists;
+// allocated memory is never freed until Http2HeaderBlock's destruction.
+//
+// This implementation does not make much of an effort to minimize wasted space.
+// It's expected that keys are rarely deleted from a Http2HeaderBlock.
+class QUICHE_EXPORT_PRIVATE Http2HeaderBlock {
+ private:
+ // Stores a list of value fragments that can be joined later with a
+ // key-dependent separator.
+ class QUICHE_EXPORT_PRIVATE HeaderValue {
+ public:
+ HeaderValue(SpdyHeaderStorage* storage, absl::string_view key,
+ absl::string_view initial_value);
+
+ // Moves are allowed.
+ HeaderValue(HeaderValue&& other);
+ HeaderValue& operator=(HeaderValue&& other);
+
+ void set_storage(SpdyHeaderStorage* storage);
+
+ // Copies are not.
+ HeaderValue(const HeaderValue& other) = delete;
+ HeaderValue& operator=(const HeaderValue& other) = delete;
+
+ ~HeaderValue();
+
+ // Consumes at most |fragment.size()| bytes of memory.
+ void Append(absl::string_view fragment);
+
+ absl::string_view value() const { return as_pair().second; }
+ const std::pair<absl::string_view, absl::string_view>& as_pair() const;
+
+ // Size estimate including separators. Used when keys are erased from
+ // Http2HeaderBlock.
+ size_t SizeEstimate() const { return size_; }
+
+ private:
+ // May allocate a large contiguous region of memory to hold the concatenated
+ // fragments and separators.
+ absl::string_view ConsolidatedValue() const;
+
+ mutable SpdyHeaderStorage* storage_;
+ mutable std::vector<absl::string_view> fragments_;
+ // The first element is the key; the second is the consolidated value.
+ mutable std::pair<absl::string_view, absl::string_view> pair_;
+ size_t size_ = 0;
+ size_t separator_size_ = 0;
+ };
+
+ typedef quiche::QuicheLinkedHashMap<absl::string_view, HeaderValue,
+ quiche::StringPieceCaseHash,
+ quiche::StringPieceCaseEqual>
+ MapType;
+
+ public:
+ typedef std::pair<absl::string_view, absl::string_view> value_type;
+
+ // Provides iteration over a sequence of std::pair<absl::string_view,
+ // absl::string_view>, even though the underlying MapType::value_type is
+ // different. Dereferencing the iterator will result in memory allocation for
+ // multi-value headers.
+ class QUICHE_EXPORT_PRIVATE iterator {
+ public:
+ // The following type definitions fulfill the requirements for iterator
+ // implementations.
+ typedef std::pair<absl::string_view, absl::string_view> value_type;
+ typedef value_type& reference;
+ typedef value_type* pointer;
+ typedef std::forward_iterator_tag iterator_category;
+ typedef MapType::iterator::difference_type difference_type;
+
+ // In practice, this iterator only offers access to const value_type.
+ typedef const value_type& const_reference;
+ typedef const value_type* const_pointer;
+
+ explicit iterator(MapType::const_iterator it);
+ iterator(const iterator& other);
+ ~iterator();
+
+ // This will result in memory allocation if the value consists of multiple
+ // fragments.
+ const_reference operator*() const {
+#if SPDY_HEADER_DEBUG
+ QUICHE_CHECK(!dereference_forbidden_);
+#endif // SPDY_HEADER_DEBUG
+ return it_->second.as_pair();
+ }
+
+ const_pointer operator->() const { return &(this->operator*()); }
+ bool operator==(const iterator& it) const { return it_ == it.it_; }
+ bool operator!=(const iterator& it) const { return !(*this == it); }
+
+ iterator& operator++() {
+ it_++;
+ return *this;
+ }
+
+ iterator operator++(int) {
+ auto ret = *this;
+ this->operator++();
+ return ret;
+ }
+
+#if SPDY_HEADER_DEBUG
+ void forbid_dereference() { dereference_forbidden_ = true; }
+#endif // SPDY_HEADER_DEBUG
+
+ private:
+ MapType::const_iterator it_;
+#if SPDY_HEADER_DEBUG
+ bool dereference_forbidden_ = false;
+#endif // SPDY_HEADER_DEBUG
+ };
+ typedef iterator const_iterator;
+
+ Http2HeaderBlock();
+ Http2HeaderBlock(const Http2HeaderBlock& other) = delete;
+ Http2HeaderBlock(Http2HeaderBlock&& other);
+ ~Http2HeaderBlock();
+
+ Http2HeaderBlock& operator=(const Http2HeaderBlock& other) = delete;
+ Http2HeaderBlock& operator=(Http2HeaderBlock&& other);
+ Http2HeaderBlock Clone() const;
+
+ bool operator==(const Http2HeaderBlock& other) const;
+ bool operator!=(const Http2HeaderBlock& other) const;
+
+ // Provides a human readable multi-line representation of the stored header
+ // keys and values.
+ std::string DebugString() const;
+
+ iterator begin() { return wrap_iterator(map_.begin()); }
+ iterator end() { return wrap_iterator(map_.end()); }
+ const_iterator begin() const { return wrap_const_iterator(map_.begin()); }
+ const_iterator end() const { return wrap_const_iterator(map_.end()); }
+ bool empty() const { return map_.empty(); }
+ size_t size() const { return map_.size(); }
+ iterator find(absl::string_view key) { return wrap_iterator(map_.find(key)); }
+ const_iterator find(absl::string_view key) const {
+ return wrap_const_iterator(map_.find(key));
+ }
+ bool contains(absl::string_view key) const { return find(key) != end(); }
+ void erase(absl::string_view key);
+
+ // Clears both our MapType member and the memory used to hold headers.
+ void clear();
+
+ // The next few methods copy data into our backing storage.
+
+ // If key already exists in the block, replaces the value of that key. Else
+ // adds a new header to the end of the block.
+ void insert(const value_type& value);
+
+ // If a header with the key is already present, then append the value to the
+ // existing header value, NUL ("\0") separated unless the key is cookie, in
+ // which case the separator is "; ".
+ // If there is no such key, a new header with the key and value is added.
+ void AppendValueOrAddHeader(const absl::string_view key,
+ const absl::string_view value);
+
+ // This object provides automatic conversions that allow Http2HeaderBlock to
+ // be nearly a drop-in replacement for
+ // SpdyLinkedHashMap<std::string, std::string>.
+ // It reads data from or writes data to a SpdyHeaderStorage.
+ class QUICHE_EXPORT_PRIVATE ValueProxy {
+ public:
+ ~ValueProxy();
+
+ // Moves are allowed.
+ ValueProxy(ValueProxy&& other);
+ ValueProxy& operator=(ValueProxy&& other);
+
+ // Copies are not.
+ ValueProxy(const ValueProxy& other) = delete;
+ ValueProxy& operator=(const ValueProxy& other) = delete;
+
+ // Assignment modifies the underlying Http2HeaderBlock.
+ ValueProxy& operator=(absl::string_view value);
+
+ // Provides easy comparison against absl::string_view.
+ bool operator==(absl::string_view value) const;
+
+ std::string as_string() const;
+
+ private:
+ friend class Http2HeaderBlock;
+ friend class test::ValueProxyPeer;
+
+ ValueProxy(Http2HeaderBlock* block,
+ Http2HeaderBlock::MapType::iterator lookup_result,
+ const absl::string_view key,
+ size_t* spdy_header_block_value_size);
+
+ Http2HeaderBlock* block_;
+ Http2HeaderBlock::MapType::iterator lookup_result_;
+ absl::string_view key_;
+ size_t* spdy_header_block_value_size_;
+ bool valid_;
+ };
+
+ // Allows either lookup or mutation of the value associated with a key.
+ ABSL_MUST_USE_RESULT ValueProxy operator[](const absl::string_view key);
+
+ size_t TotalBytesUsed() const { return key_size_ + value_size_; }
+
+ private:
+ friend class test::Http2HeaderBlockPeer;
+
+ inline iterator wrap_iterator(MapType::const_iterator inner_iterator) const {
+#if SPDY_HEADER_DEBUG
+ iterator outer_iterator(inner_iterator);
+ if (inner_iterator == map_.end()) {
+ outer_iterator.forbid_dereference();
+ }
+ return outer_iterator;
+#else // SPDY_HEADER_DEBUG
+ return iterator(inner_iterator);
+#endif // SPDY_HEADER_DEBUG
+ }
+
+ inline const_iterator wrap_const_iterator(
+ MapType::const_iterator inner_iterator) const {
+#if SPDY_HEADER_DEBUG
+ const_iterator outer_iterator(inner_iterator);
+ if (inner_iterator == map_.end()) {
+ outer_iterator.forbid_dereference();
+ }
+ return outer_iterator;
+#else // SPDY_HEADER_DEBUG
+ return iterator(inner_iterator);
+#endif // SPDY_HEADER_DEBUG
+ }
+
+ void AppendHeader(const absl::string_view key, const absl::string_view value);
+ absl::string_view WriteKey(const absl::string_view key);
+ size_t bytes_allocated() const;
+
+ // absl::string_views held by |map_| point to memory owned by |storage_|.
+ MapType map_;
+ SpdyHeaderStorage storage_;
+
+ size_t key_size_ = 0;
+ size_t value_size_ = 0;
+};
+
+} // namespace spdy
+
+#endif // QUICHE_SPDY_CORE_HTTP2_HEADER_BLOCK_H_
diff --git a/quiche/spdy/core/spdy_header_block_test.cc b/quiche/spdy/core/http2_header_block_test.cc
similarity index 99%
rename from quiche/spdy/core/spdy_header_block_test.cc
rename to quiche/spdy/core/http2_header_block_test.cc
index 6fc604d..4624d7b 100644
--- a/quiche/spdy/core/spdy_header_block_test.cc
+++ b/quiche/spdy/core/http2_header_block_test.cc
@@ -2,7 +2,7 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
-#include "quiche/spdy/core/spdy_header_block.h"
+#include "quiche/spdy/core/http2_header_block.h"
#include <memory>
#include <utility>
diff --git a/quiche/spdy/core/spdy_header_block.h b/quiche/spdy/core/spdy_header_block.h
index 21bde19..62c4109 100644
--- a/quiche/spdy/core/spdy_header_block.h
+++ b/quiche/spdy/core/spdy_header_block.h
@@ -5,287 +5,10 @@
#ifndef QUICHE_SPDY_CORE_SPDY_HEADER_BLOCK_H_
#define QUICHE_SPDY_CORE_SPDY_HEADER_BLOCK_H_
-#include <stddef.h>
-
-#include <functional>
-#include <list>
-#include <string>
-#include <utility>
-#include <vector>
-
-#include "absl/base/attributes.h"
-#include "quiche/common/platform/api/quiche_export.h"
-#include "quiche/common/platform/api/quiche_logging.h"
-#include "quiche/common/quiche_linked_hash_map.h"
-#include "quiche/common/quiche_text_utils.h"
-#include "quiche/spdy/core/spdy_header_storage.h"
+#include "quiche/spdy/core/http2_header_block.h"
namespace spdy {
-namespace test {
-class Http2HeaderBlockPeer;
-class ValueProxyPeer;
-} // namespace test
-
-#ifndef SPDY_HEADER_DEBUG
-#if !defined(NDEBUG) || defined(ADDRESS_SANITIZER)
-#define SPDY_HEADER_DEBUG 1
-#else // !defined(NDEBUG) || defined(ADDRESS_SANITIZER)
-#define SPDY_HEADER_DEBUG 0
-#endif // !defined(NDEBUG) || defined(ADDRESS_SANITIZER)
-#endif // SPDY_HEADER_DEBUG
-
-// This class provides a key-value map that can be used to store SPDY header
-// names and values. This data structure preserves insertion order.
-//
-// Under the hood, this data structure uses large, contiguous blocks of memory
-// to store names and values. Lookups may be performed with absl::string_view
-// keys, and values are returned as absl::string_views (via ValueProxy, below).
-// Value absl::string_views are valid as long as the Http2HeaderBlock exists;
-// allocated memory is never freed until Http2HeaderBlock's destruction.
-//
-// This implementation does not make much of an effort to minimize wasted space.
-// It's expected that keys are rarely deleted from a Http2HeaderBlock.
-class QUICHE_EXPORT_PRIVATE Http2HeaderBlock {
- private:
- // Stores a list of value fragments that can be joined later with a
- // key-dependent separator.
- class QUICHE_EXPORT_PRIVATE HeaderValue {
- public:
- HeaderValue(SpdyHeaderStorage* storage, absl::string_view key,
- absl::string_view initial_value);
-
- // Moves are allowed.
- HeaderValue(HeaderValue&& other);
- HeaderValue& operator=(HeaderValue&& other);
-
- void set_storage(SpdyHeaderStorage* storage);
-
- // Copies are not.
- HeaderValue(const HeaderValue& other) = delete;
- HeaderValue& operator=(const HeaderValue& other) = delete;
-
- ~HeaderValue();
-
- // Consumes at most |fragment.size()| bytes of memory.
- void Append(absl::string_view fragment);
-
- absl::string_view value() const { return as_pair().second; }
- const std::pair<absl::string_view, absl::string_view>& as_pair() const;
-
- // Size estimate including separators. Used when keys are erased from
- // Http2HeaderBlock.
- size_t SizeEstimate() const { return size_; }
-
- private:
- // May allocate a large contiguous region of memory to hold the concatenated
- // fragments and separators.
- absl::string_view ConsolidatedValue() const;
-
- mutable SpdyHeaderStorage* storage_;
- mutable std::vector<absl::string_view> fragments_;
- // The first element is the key; the second is the consolidated value.
- mutable std::pair<absl::string_view, absl::string_view> pair_;
- size_t size_ = 0;
- size_t separator_size_ = 0;
- };
-
- typedef quiche::QuicheLinkedHashMap<absl::string_view, HeaderValue,
- quiche::StringPieceCaseHash,
- quiche::StringPieceCaseEqual>
- MapType;
-
- public:
- typedef std::pair<absl::string_view, absl::string_view> value_type;
-
- // Provides iteration over a sequence of std::pair<absl::string_view,
- // absl::string_view>, even though the underlying MapType::value_type is
- // different. Dereferencing the iterator will result in memory allocation for
- // multi-value headers.
- class QUICHE_EXPORT_PRIVATE iterator {
- public:
- // The following type definitions fulfill the requirements for iterator
- // implementations.
- typedef std::pair<absl::string_view, absl::string_view> value_type;
- typedef value_type& reference;
- typedef value_type* pointer;
- typedef std::forward_iterator_tag iterator_category;
- typedef MapType::iterator::difference_type difference_type;
-
- // In practice, this iterator only offers access to const value_type.
- typedef const value_type& const_reference;
- typedef const value_type* const_pointer;
-
- explicit iterator(MapType::const_iterator it);
- iterator(const iterator& other);
- ~iterator();
-
- // This will result in memory allocation if the value consists of multiple
- // fragments.
- const_reference operator*() const {
-#if SPDY_HEADER_DEBUG
- QUICHE_CHECK(!dereference_forbidden_);
-#endif // SPDY_HEADER_DEBUG
- return it_->second.as_pair();
- }
-
- const_pointer operator->() const { return &(this->operator*()); }
- bool operator==(const iterator& it) const { return it_ == it.it_; }
- bool operator!=(const iterator& it) const { return !(*this == it); }
-
- iterator& operator++() {
- it_++;
- return *this;
- }
-
- iterator operator++(int) {
- auto ret = *this;
- this->operator++();
- return ret;
- }
-
-#if SPDY_HEADER_DEBUG
- void forbid_dereference() { dereference_forbidden_ = true; }
-#endif // SPDY_HEADER_DEBUG
-
- private:
- MapType::const_iterator it_;
-#if SPDY_HEADER_DEBUG
- bool dereference_forbidden_ = false;
-#endif // SPDY_HEADER_DEBUG
- };
- typedef iterator const_iterator;
-
- Http2HeaderBlock();
- Http2HeaderBlock(const Http2HeaderBlock& other) = delete;
- Http2HeaderBlock(Http2HeaderBlock&& other);
- ~Http2HeaderBlock();
-
- Http2HeaderBlock& operator=(const Http2HeaderBlock& other) = delete;
- Http2HeaderBlock& operator=(Http2HeaderBlock&& other);
- Http2HeaderBlock Clone() const;
-
- bool operator==(const Http2HeaderBlock& other) const;
- bool operator!=(const Http2HeaderBlock& other) const;
-
- // Provides a human readable multi-line representation of the stored header
- // keys and values.
- std::string DebugString() const;
-
- iterator begin() { return wrap_iterator(map_.begin()); }
- iterator end() { return wrap_iterator(map_.end()); }
- const_iterator begin() const { return wrap_const_iterator(map_.begin()); }
- const_iterator end() const { return wrap_const_iterator(map_.end()); }
- bool empty() const { return map_.empty(); }
- size_t size() const { return map_.size(); }
- iterator find(absl::string_view key) { return wrap_iterator(map_.find(key)); }
- const_iterator find(absl::string_view key) const {
- return wrap_const_iterator(map_.find(key));
- }
- bool contains(absl::string_view key) const { return find(key) != end(); }
- void erase(absl::string_view key);
-
- // Clears both our MapType member and the memory used to hold headers.
- void clear();
-
- // The next few methods copy data into our backing storage.
-
- // If key already exists in the block, replaces the value of that key. Else
- // adds a new header to the end of the block.
- void insert(const value_type& value);
-
- // If a header with the key is already present, then append the value to the
- // existing header value, NUL ("\0") separated unless the key is cookie, in
- // which case the separator is "; ".
- // If there is no such key, a new header with the key and value is added.
- void AppendValueOrAddHeader(const absl::string_view key,
- const absl::string_view value);
-
- // This object provides automatic conversions that allow Http2HeaderBlock to
- // be nearly a drop-in replacement for
- // SpdyLinkedHashMap<std::string, std::string>.
- // It reads data from or writes data to a SpdyHeaderStorage.
- class QUICHE_EXPORT_PRIVATE ValueProxy {
- public:
- ~ValueProxy();
-
- // Moves are allowed.
- ValueProxy(ValueProxy&& other);
- ValueProxy& operator=(ValueProxy&& other);
-
- // Copies are not.
- ValueProxy(const ValueProxy& other) = delete;
- ValueProxy& operator=(const ValueProxy& other) = delete;
-
- // Assignment modifies the underlying Http2HeaderBlock.
- ValueProxy& operator=(absl::string_view value);
-
- // Provides easy comparison against absl::string_view.
- bool operator==(absl::string_view value) const;
-
- std::string as_string() const;
-
- private:
- friend class Http2HeaderBlock;
- friend class test::ValueProxyPeer;
-
- ValueProxy(Http2HeaderBlock* block,
- Http2HeaderBlock::MapType::iterator lookup_result,
- const absl::string_view key,
- size_t* spdy_header_block_value_size);
-
- Http2HeaderBlock* block_;
- Http2HeaderBlock::MapType::iterator lookup_result_;
- absl::string_view key_;
- size_t* spdy_header_block_value_size_;
- bool valid_;
- };
-
- // Allows either lookup or mutation of the value associated with a key.
- ABSL_MUST_USE_RESULT ValueProxy operator[](const absl::string_view key);
-
- size_t TotalBytesUsed() const { return key_size_ + value_size_; }
-
- private:
- friend class test::Http2HeaderBlockPeer;
-
- inline iterator wrap_iterator(MapType::const_iterator inner_iterator) const {
-#if SPDY_HEADER_DEBUG
- iterator outer_iterator(inner_iterator);
- if (inner_iterator == map_.end()) {
- outer_iterator.forbid_dereference();
- }
- return outer_iterator;
-#else // SPDY_HEADER_DEBUG
- return iterator(inner_iterator);
-#endif // SPDY_HEADER_DEBUG
- }
-
- inline const_iterator wrap_const_iterator(
- MapType::const_iterator inner_iterator) const {
-#if SPDY_HEADER_DEBUG
- const_iterator outer_iterator(inner_iterator);
- if (inner_iterator == map_.end()) {
- outer_iterator.forbid_dereference();
- }
- return outer_iterator;
-#else // SPDY_HEADER_DEBUG
- return iterator(inner_iterator);
-#endif // SPDY_HEADER_DEBUG
- }
-
- void AppendHeader(const absl::string_view key, const absl::string_view value);
- absl::string_view WriteKey(const absl::string_view key);
- size_t bytes_allocated() const;
-
- // absl::string_views held by |map_| point to memory owned by |storage_|.
- MapType map_;
- SpdyHeaderStorage storage_;
-
- size_t key_size_ = 0;
- size_t value_size_ = 0;
-};
-
// TODO(b/156770486): Remove this alias when the rename is complete.
using SpdyHeaderBlock = Http2HeaderBlock;