blob: bf71faf5def706315c0431f86a90c7b9452eba73 [file] [log] [blame]
// Copyright (c) 2018 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 "quic/core/qpack/qpack_encoder_stream_receiver.h"
#include "absl/strings/string_view.h"
#include "http2/decoder/decode_buffer.h"
#include "http2/decoder/decode_status.h"
#include "quic/core/qpack/qpack_instructions.h"
#include "quic/platform/api/quic_logging.h"
namespace quic {
QpackEncoderStreamReceiver::QpackEncoderStreamReceiver(Delegate* delegate)
: instruction_decoder_(QpackEncoderStreamLanguage(), this),
delegate_(delegate),
error_detected_(false) {
QUICHE_DCHECK(delegate_);
}
void QpackEncoderStreamReceiver::Decode(absl::string_view data) {
if (data.empty() || error_detected_) {
return;
}
instruction_decoder_.Decode(data);
}
bool QpackEncoderStreamReceiver::OnInstructionDecoded(
const QpackInstruction* instruction) {
if (instruction == InsertWithNameReferenceInstruction()) {
delegate_->OnInsertWithNameReference(instruction_decoder_.s_bit(),
instruction_decoder_.varint(),
instruction_decoder_.value());
return true;
}
if (instruction == InsertWithoutNameReferenceInstruction()) {
delegate_->OnInsertWithoutNameReference(instruction_decoder_.name(),
instruction_decoder_.value());
return true;
}
if (instruction == DuplicateInstruction()) {
delegate_->OnDuplicate(instruction_decoder_.varint());
return true;
}
QUICHE_DCHECK_EQ(instruction, SetDynamicTableCapacityInstruction());
delegate_->OnSetDynamicTableCapacity(instruction_decoder_.varint());
return true;
}
void QpackEncoderStreamReceiver::OnInstructionDecodingError(
QpackInstructionDecoder::ErrorCode error_code,
absl::string_view error_message) {
QUICHE_DCHECK(!error_detected_);
error_detected_ = true;
QuicErrorCode quic_error_code;
switch (error_code) {
case QpackInstructionDecoder::ErrorCode::INTEGER_TOO_LARGE:
quic_error_code = QUIC_QPACK_ENCODER_STREAM_INTEGER_TOO_LARGE;
break;
case QpackInstructionDecoder::ErrorCode::STRING_LITERAL_TOO_LONG:
quic_error_code = QUIC_QPACK_ENCODER_STREAM_STRING_LITERAL_TOO_LONG;
break;
case QpackInstructionDecoder::ErrorCode::HUFFMAN_ENCODING_ERROR:
quic_error_code = QUIC_QPACK_ENCODER_STREAM_HUFFMAN_ENCODING_ERROR;
break;
default:
quic_error_code = QUIC_INTERNAL_ERROR;
}
delegate_->OnErrorDetected(quic_error_code, error_message);
}
} // namespace quic