27 #include "absl/utility/utility.h"
47 constexpr
size_t kDataFrameHeaderSize = 9;
73 *p++ =
static_cast<uint8_t>(
id >> 24);
74 *p++ =
static_cast<uint8_t>(
id >> 16);
75 *p++ =
static_cast<uint8_t>(
id >> 8);
80 const size_t frame_size =
97 if (is_first_frame_ && is_end_of_stream_) {
104 if (is_header_boundary) {
108 stream_id_, CurrentFrameSize(),
flags);
109 stats_->framing_bytes += kDataFrameHeaderSize;
110 is_first_frame_ =
false;
137 if (
len == 0)
return;
139 if (
len <= remaining) {
140 stats_->header_bytes +=
len;
144 stats_->header_bytes += remaining;
156 stats_->header_bytes +=
len;
170 huffman_prefix(huffman_prefix),
171 insert_null_before_wire_value(insert_null_before_wire_value),
182 if (true_binary_enabled) {
214 len_val_(wire_value_.
length) {}
217 return len_val_.length() +
218 (wire_value_.insert_null_before_wire_value ? 1 : 0);
222 len_val_.Write(wire_value_.huffman_prefix, prefix_data);
223 if (wire_value_.insert_null_before_wire_value) {
224 prefix_data[len_val_.length()] = 0;
260 len_key_.Write(0x00,
data + 1);
275 key.WritePrefix(0x40, AddTiny(
key.prefix_length()));
278 emit.WritePrefix(AddTiny(
emit.prefix_length()));
287 key.WritePrefix(0x00, AddTiny(
key.prefix_length()));
290 emit.WritePrefix(AddTiny(
emit.prefix_length()));
299 key.WritePrefix(0x40, AddTiny(
key.prefix_length()));
302 emit.WritePrefix(AddTiny(
emit.prefix_length()));
323 key.WritePrefix(0x00, AddTiny(
key.prefix_length()));
326 emit.WritePrefix(AddTiny(
emit.prefix_length()));
339 It prev = values_.end();
348 for (It
it = values_.begin();
it != values_.end(); ++
it) {
351 if (
table.ConvertableToDynamicIndex(
it->index)) {
356 it->index =
table.AllocateIndex(transport_length);
365 while (!values_.empty() &&
366 !
table.ConvertableToDynamicIndex(values_.back().index)) {
383 EmitLitHdrWithBinaryStringKeyNotIdx(
key.Ref(),
value.Ref());
385 EmitLitHdrWithNonBinaryStringKeyNotIdx(
key.Ref(),
value.Ref());
408 if (
value != ContentTypeMetadata::ValueType::kApplicationGrpc) {
412 EncodeAlwaysIndexed(&compressor_->content_type_index_,
"content-type",
421 case HttpSchemeMetadata::ValueType::kHttp:
424 case HttpSchemeMetadata::ValueType::kHttps:
427 case HttpSchemeMetadata::ValueType::kInvalid:
434 EncodeIndexedKeyWithBinaryValue(&compressor_->grpc_trace_bin_index_,
435 "grpc-trace-bin",
slice.Ref());
439 EncodeIndexedKeyWithBinaryValue(&compressor_->grpc_tags_bin_index_,
440 "grpc-tags-bin",
slice.Ref());
480 case HttpMethodMetadata::ValueType::kPost:
483 case HttpMethodMetadata::ValueType::kGet:
486 case HttpMethodMetadata::ValueType::kPut:
492 case HttpMethodMetadata::ValueType::kInvalid:
502 if (compressor_->table_.ConvertableToDynamicIndex(*
index)) {
503 EmitIndexed(compressor_->table_.DynamicIndex(*
index));
505 *
index = compressor_->table_.AllocateIndex(transport_length);
513 if (compressor_->table_.ConvertableToDynamicIndex(*
index)) {
514 EmitLitHdrWithBinaryStringKeyNotIdx(
517 *
index = compressor_->table_.AllocateIndex(
key.length() +
value.length() +
526 for (
auto it = compressor_->previous_timeouts_.begin();
527 it != compressor_->previous_timeouts_.end(); ++
it) {
528 double ratio =
timeout.RatioVersus(
it->timeout);
531 if (ratio > -3 && ratio <= 0 &&
532 compressor_->table_.ConvertableToDynamicIndex(
it->index)) {
533 EmitIndexed(compressor_->table_.DynamicIndex(
it->index));
536 std::swap(*
it, *compressor_->previous_timeouts_.begin());
541 while (!compressor_->previous_timeouts_.empty() &&
542 !compressor_->table_.ConvertableToDynamicIndex(
543 compressor_->previous_timeouts_.back().index)) {
544 compressor_->previous_timeouts_.pop_back();
551 EmitLitHdrWithNonBinaryStringKeyIncIdx(
557 EmitLitHdrWithNonBinaryStringKeyNotIdx(
561 if (!
slice.is_equivalent(compressor_->user_agent_)) {
562 compressor_->user_agent_ =
slice.Ref();
563 compressor_->user_agent_index_ = 0;
566 &compressor_->user_agent_index_,
"user-agent",
slice.Ref(),
575 index = &compressor_->cached_grpc_status_[
code];
576 if (compressor_->table_.ConvertableToDynamicIndex(*
index)) {
577 EmitIndexed(compressor_->table_.DynamicIndex(*
index));
585 if (
index !=
nullptr) {
586 *
index = compressor_->table_.AllocateIndex(transport_length);
598 if (compressor_->table_.ConvertableToDynamicIndex(*
index)) {
599 EmitIndexed(compressor_->table_.DynamicIndex(*
index));
607 if (
index !=
nullptr) {
608 *
index = compressor_->table_.AllocateIndex(transport_length);
619 if (compressor_->grpc_accept_encoding_index_ != 0 &&
620 value == compressor_->grpc_accept_encoding_ &&
621 compressor_->table_.ConvertableToDynamicIndex(
622 compressor_->grpc_accept_encoding_index_)) {
623 EmitIndexed(compressor_->table_.DynamicIndex(
624 compressor_->grpc_accept_encoding_index_));
631 compressor_->grpc_accept_encoding_index_ =
632 compressor_->table_.AllocateIndex(transport_length);
633 compressor_->grpc_accept_encoding_ =
value;
657 use_true_binary_metadata_(
options.use_true_binary_metadata),
658 is_end_of_stream_(
options.is_end_of_stream),
662 compressor_(compressor),