// 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 "http2/platform/api/http2_logging.h"
#include "common/platform/api/quiche_export.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_
