// 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_DECODER_DECODE_BUFFER_H_
#define QUICHE_HTTP2_DECODER_DECODE_BUFFER_H_

// DecodeBuffer provides primitives for decoding various integer types found in
// HTTP/2 frames. It wraps a byte array from which we can read and decode
// serialized HTTP/2 frames, or parts thereof. DecodeBuffer is intended only for
// stack allocation, where the caller is typically going to use the DecodeBuffer
// instance as part of decoding the entire buffer before returning to its own
// caller.

#include <stddef.h>

#include <algorithm>
#include <cstdint>

#include "absl/strings/string_view.h"
#include "quiche/common/platform/api/quiche_export.h"
#include "quiche/common/platform/api/quiche_logging.h"

namespace http2 {
class DecodeBufferSubset;

class QUICHE_EXPORT_PRIVATE DecodeBuffer {
 public:
  // We assume the decode buffers will typically be modest in size (i.e. often a
  // few KB, perhaps as high as 100KB). Let's make sure during testing that we
  // don't go very high, with 32MB selected rather arbitrarily. This is exposed
  // to support testing.
  static constexpr size_t kMaxDecodeBufferLength = 1 << 25;

  DecodeBuffer(const char* buffer, size_t len)
      : buffer_(buffer), cursor_(buffer), beyond_(buffer + len) {
    QUICHE_DCHECK(buffer != nullptr);
    QUICHE_DCHECK_LE(len, kMaxDecodeBufferLength);
  }
  explicit DecodeBuffer(absl::string_view s)
      : DecodeBuffer(s.data(), s.size()) {}
  // Constructor for character arrays, typically in tests. For example:
  //    const char input[] = { 0x11 };
  //    DecodeBuffer b(input);
  template <size_t N>
  explicit DecodeBuffer(const char (&buf)[N]) : DecodeBuffer(buf, N) {}

  DecodeBuffer(const DecodeBuffer&) = delete;
  DecodeBuffer operator=(const DecodeBuffer&) = delete;

  bool Empty() const { return cursor_ >= beyond_; }
  bool HasData() const { return cursor_ < beyond_; }
  size_t Remaining() const {
    QUICHE_DCHECK_LE(cursor_, beyond_);
    return beyond_ - cursor_;
  }
  size_t Offset() const { return cursor_ - buffer_; }
  size_t FullSize() const { return beyond_ - buffer_; }

  // Returns the minimum of the number of bytes remaining in this DecodeBuffer
  // and |length|, in support of determining how much of some structure/payload
  // is in this DecodeBuffer.
  size_t MinLengthRemaining(size_t length) const {
    return std::min(length, Remaining());
  }

  // For string decoding, returns a pointer to the next byte/char to be decoded.
  const char* cursor() const { return cursor_; }
  // Advances the cursor (pointer to the next byte/char to be decoded).
  void AdvanceCursor(size_t amount) {
    QUICHE_DCHECK_LE(amount,
                     Remaining());  // Need at least that much remaining.
    QUICHE_DCHECK_EQ(subset_, nullptr)
        << "Access via subset only when present.";
    cursor_ += amount;
  }

  // Only call methods starting "Decode" when there is enough input remaining.
  char DecodeChar() {
    QUICHE_DCHECK_LE(1u, Remaining());  // Need at least one byte remaining.
    QUICHE_DCHECK_EQ(subset_, nullptr)
        << "Access via subset only when present.";
    return *cursor_++;
  }

  uint8_t DecodeUInt8();
  uint16_t DecodeUInt16();
  uint32_t DecodeUInt24();

  // For 31-bit unsigned integers, where the 32nd bit is reserved for future
  // use (i.e. the high-bit of the first byte of the encoding); examples:
  // the Stream Id in a frame header or the Window Size Increment in a
  // WINDOW_UPDATE frame.
  uint32_t DecodeUInt31();

  uint32_t DecodeUInt32();

 protected:
#ifndef NDEBUG
  // These are part of validating during tests that there is at most one
  // DecodeBufferSubset instance at a time for any DecodeBuffer instance.
  void set_subset_of_base(DecodeBuffer* base, const DecodeBufferSubset* subset);
  void clear_subset_of_base(DecodeBuffer* base,
                            const DecodeBufferSubset* subset);
#endif

 private:
#ifndef NDEBUG
  void set_subset(const DecodeBufferSubset* subset);
  void clear_subset(const DecodeBufferSubset* subset);
#endif

  // Prevent heap allocation of DecodeBuffer.
  static void* operator new(size_t s);
  static void* operator new[](size_t s);
  static void operator delete(void* p);
  static void operator delete[](void* p);

  const char* const buffer_;
  const char* cursor_;
  const char* const beyond_;
  const DecodeBufferSubset* subset_ = nullptr;  // Used for QUICHE_DCHECKs.
};

// DecodeBufferSubset is used when decoding a known sized chunk of data, which
// starts at base->cursor(), and continues for subset_len, which may be
// entirely in |base|, or may extend beyond it (hence the MinLengthRemaining
// in the constructor).
// There are two benefits to using DecodeBufferSubset: it ensures that the
// cursor of |base| is advanced when the subset's destructor runs, and it
// ensures that the consumer of the subset can't go beyond the subset which
// it is intended to decode.
// There must be only a single DecodeBufferSubset at a time for a base
// DecodeBuffer, though they can be nested (i.e. a DecodeBufferSubset's
// base may itself be a DecodeBufferSubset). This avoids the AdvanceCursor
// being called erroneously.
class QUICHE_EXPORT_PRIVATE DecodeBufferSubset : public DecodeBuffer {
 public:
  DecodeBufferSubset(DecodeBuffer* base, size_t subset_len)
      : DecodeBuffer(base->cursor(), base->MinLengthRemaining(subset_len)),
        base_buffer_(base) {
#ifndef NDEBUG
    DebugSetup();
#endif
  }

  DecodeBufferSubset(const DecodeBufferSubset&) = delete;
  DecodeBufferSubset operator=(const DecodeBufferSubset&) = delete;

  ~DecodeBufferSubset() {
    size_t offset = Offset();
#ifndef NDEBUG
    DebugTearDown();
#endif
    base_buffer_->AdvanceCursor(offset);
  }

 private:
  DecodeBuffer* const base_buffer_;
#ifndef NDEBUG
  size_t start_base_offset_;  // Used for QUICHE_DCHECKs.
  size_t max_base_offset_;    // Used for QUICHE_DCHECKs.

  void DebugSetup();
  void DebugTearDown();
#endif
};

}  // namespace http2

#endif  // QUICHE_HTTP2_DECODER_DECODE_BUFFER_H_
