// 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.

#include "quiche/http2/decoder/decode_buffer.h"

namespace http2 {

uint8_t DecodeBuffer::DecodeUInt8() {
  return static_cast<uint8_t>(DecodeChar());
}

uint16_t DecodeBuffer::DecodeUInt16() {
  QUICHE_DCHECK_LE(2u, Remaining());
  const uint8_t b1 = DecodeUInt8();
  const uint8_t b2 = DecodeUInt8();
  // Note that chars are automatically promoted to ints during arithmetic,
  // so the b1 << 8 doesn't end up as zero before being or-ed with b2.
  // And the left-shift operator has higher precedence than the or operator.
  return b1 << 8 | b2;
}

uint32_t DecodeBuffer::DecodeUInt24() {
  QUICHE_DCHECK_LE(3u, Remaining());
  const uint8_t b1 = DecodeUInt8();
  const uint8_t b2 = DecodeUInt8();
  const uint8_t b3 = DecodeUInt8();
  return b1 << 16 | b2 << 8 | b3;
}

uint32_t DecodeBuffer::DecodeUInt31() {
  QUICHE_DCHECK_LE(4u, Remaining());
  const uint8_t b1 = DecodeUInt8() & 0x7f;  // Mask out the high order bit.
  const uint8_t b2 = DecodeUInt8();
  const uint8_t b3 = DecodeUInt8();
  const uint8_t b4 = DecodeUInt8();
  return b1 << 24 | b2 << 16 | b3 << 8 | b4;
}

uint32_t DecodeBuffer::DecodeUInt32() {
  QUICHE_DCHECK_LE(4u, Remaining());
  const uint8_t b1 = DecodeUInt8();
  const uint8_t b2 = DecodeUInt8();
  const uint8_t b3 = DecodeUInt8();
  const uint8_t b4 = DecodeUInt8();
  return b1 << 24 | b2 << 16 | b3 << 8 | b4;
}

#ifndef NDEBUG
void DecodeBuffer::set_subset_of_base(DecodeBuffer* base,
                                      const DecodeBufferSubset* subset) {
  QUICHE_DCHECK_EQ(this, subset);
  base->set_subset(subset);
}
void DecodeBuffer::clear_subset_of_base(DecodeBuffer* base,
                                        const DecodeBufferSubset* subset) {
  QUICHE_DCHECK_EQ(this, subset);
  base->clear_subset(subset);
}
void DecodeBuffer::set_subset(const DecodeBufferSubset* subset) {
  QUICHE_DCHECK(subset != nullptr);
  QUICHE_DCHECK_EQ(subset_, nullptr) << "There is already a subset";
  subset_ = subset;
}
void DecodeBuffer::clear_subset(const DecodeBufferSubset* subset) {
  QUICHE_DCHECK(subset != nullptr);
  QUICHE_DCHECK_EQ(subset_, subset);
  subset_ = nullptr;
}
void DecodeBufferSubset::DebugSetup() {
  start_base_offset_ = base_buffer_->Offset();
  max_base_offset_ = start_base_offset_ + FullSize();
  QUICHE_DCHECK_LE(max_base_offset_, base_buffer_->FullSize());

  // Ensure that there is only one DecodeBufferSubset at a time for a base.
  set_subset_of_base(base_buffer_, this);
}
void DecodeBufferSubset::DebugTearDown() {
  // Ensure that the base hasn't been modified.
  QUICHE_DCHECK_EQ(start_base_offset_, base_buffer_->Offset())
      << "The base buffer was modified";

  // Ensure that we haven't gone beyond the maximum allowed offset.
  size_t offset = Offset();
  QUICHE_DCHECK_LE(offset, FullSize());
  QUICHE_DCHECK_LE(start_base_offset_ + offset, max_base_offset_);
  QUICHE_DCHECK_LE(max_base_offset_, base_buffer_->FullSize());

  clear_subset_of_base(base_buffer_, this);
}
#endif

}  // namespace http2
