// 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_FRAME_DECODER_STATE_H_
#define QUICHE_HTTP2_DECODER_FRAME_DECODER_STATE_H_

// FrameDecoderState provides state and behaviors in support of decoding
// the common frame header and the payload of all frame types.
// It is an input to all of the payload decoders.

// TODO(jamessynge): Since FrameDecoderState has far more than state in it,
// rename to FrameDecoderHelper, or similar.

#include <stddef.h>

#include <cstdint>

#include "quiche/http2/core/http2_constants.h"
#include "quiche/http2/core/http2_structures.h"
#include "quiche/http2/decoder/decode_buffer.h"
#include "quiche/http2/decoder/decode_status.h"
#include "quiche/http2/decoder/http2_frame_decoder_listener.h"
#include "quiche/http2/decoder/http2_structure_decoder.h"
#include "quiche/common/platform/api/quiche_export.h"
#include "quiche/common/platform/api/quiche_logging.h"

namespace http2 {
namespace test {
class FrameDecoderStatePeer;
}  // namespace test

class QUICHE_EXPORT FrameDecoderState {
 public:
  FrameDecoderState() {}

  // Sets the listener which the decoders should call as they decode HTTP/2
  // frames. The listener can be changed at any time, which allows for replacing
  // it with a no-op listener when an error is detected, either by the payload
  // decoder (OnPaddingTooLong or OnFrameSizeError) or by the "real" listener.
  // That in turn allows us to define Http2FrameDecoderListener such that all
  // methods have return type void, with no direct way to indicate whether the
  // decoder should stop, and to eliminate from the decoder all checks of the
  // return value. Instead the listener/caller can simply replace the current
  // listener with a no-op listener implementation.
  // TODO(jamessynge): Make set_listener private as only Http2FrameDecoder
  // and tests need to set it, so it doesn't need to be public.
  void set_listener(Http2FrameDecoderListener* listener) {
    listener_ = listener;
  }
  Http2FrameDecoderListener* listener() const { return listener_; }

  // The most recently decoded frame header.
  const Http2FrameHeader& frame_header() const { return frame_header_; }

  // Decode a structure in the payload, adjusting remaining_payload_ to account
  // for the consumed portion of the payload. Returns kDecodeDone when fully
  // decoded, kDecodeError if it ran out of payload before decoding completed,
  // and kDecodeInProgress if the decode buffer didn't have enough of the
  // remaining payload.
  template <class S>
  DecodeStatus StartDecodingStructureInPayload(S* out, DecodeBuffer* db) {
    QUICHE_DVLOG(2) << __func__ << "\n\tdb->Remaining=" << db->Remaining()
                    << "\n\tremaining_payload_=" << remaining_payload_
                    << "\n\tneed=" << S::EncodedSize();
    DecodeStatus status =
        structure_decoder_.Start(out, db, &remaining_payload_);
    if (status != DecodeStatus::kDecodeError) {
      return status;
    }
    QUICHE_DVLOG(2)
        << "StartDecodingStructureInPayload: detected frame size error";
    return ReportFrameSizeError();
  }

  // Resume decoding of a structure that has been split across buffers,
  // adjusting remaining_payload_ to account for the consumed portion of
  // the payload. Returns values are as for StartDecodingStructureInPayload.
  template <class S>
  DecodeStatus ResumeDecodingStructureInPayload(S* out, DecodeBuffer* db) {
    QUICHE_DVLOG(2) << __func__ << "\n\tdb->Remaining=" << db->Remaining()
                    << "\n\tremaining_payload_=" << remaining_payload_;
    if (structure_decoder_.Resume(out, db, &remaining_payload_)) {
      return DecodeStatus::kDecodeDone;
    } else if (remaining_payload_ > 0) {
      return DecodeStatus::kDecodeInProgress;
    } else {
      QUICHE_DVLOG(2)
          << "ResumeDecodingStructureInPayload: detected frame size error";
      return ReportFrameSizeError();
    }
  }

  // Initializes the two remaining* fields, which is needed if the frame's
  // payload is split across buffers, or the decoder calls ReadPadLength or
  // StartDecodingStructureInPayload, and of course the methods below which
  // read those fields, as their names imply.
  void InitializeRemainders() {
    remaining_payload_ = frame_header().payload_length;
    // Note that remaining_total_payload() relies on remaining_padding_ being
    // zero for frames that have no padding.
    remaining_padding_ = 0;
  }

  // Returns the number of bytes of the frame's payload that remain to be
  // decoded, including any trailing padding. This method must only be called
  // after the variables have been initialized, which in practice means once a
  // payload decoder has called InitializeRemainders and/or ReadPadLength.
  size_t remaining_total_payload() const {
    QUICHE_DCHECK(IsPaddable() || remaining_padding_ == 0) << frame_header();
    return remaining_payload_ + remaining_padding_;
  }

  // Returns the number of bytes of the frame's payload that remain to be
  // decoded, excluding any trailing padding. This method must only be called
  // after the variable has been initialized, which in practice means once a
  // payload decoder has called InitializeRemainders; ReadPadLength will deduct
  // the total number of padding bytes from remaining_payload_, including the
  // size of the Pad Length field itself (1 byte).
  size_t remaining_payload() const { return remaining_payload_; }

  // Returns the number of bytes of the frame's payload that remain to be
  // decoded, including any trailing padding. This method must only be called if
  // the frame type allows padding, and after the variable has been initialized,
  // which in practice means once a payload decoder has called
  // InitializeRemainders and/or ReadPadLength.
  size_t remaining_payload_and_padding() const {
    QUICHE_DCHECK(IsPaddable()) << frame_header();
    return remaining_payload_ + remaining_padding_;
  }

  // Returns the number of bytes of trailing padding after the payload that
  // remain to be decoded. This method must only be called if the frame type
  // allows padding, and after the variable has been initialized, which in
  // practice means once a payload decoder has called InitializeRemainders,
  // and isn't set to a non-zero value until ReadPadLength has been called.
  uint32_t remaining_padding() const {
    QUICHE_DCHECK(IsPaddable()) << frame_header();
    return remaining_padding_;
  }

  // How many bytes of the remaining payload are in db?
  size_t AvailablePayload(DecodeBuffer* db) const {
    return db->MinLengthRemaining(remaining_payload_);
  }

  // How many bytes of the remaining payload and padding are in db?
  // Call only for frames whose type is paddable.
  size_t AvailablePayloadAndPadding(DecodeBuffer* db) const {
    QUICHE_DCHECK(IsPaddable()) << frame_header();
    return db->MinLengthRemaining(remaining_payload_ + remaining_padding_);
  }

  // How many bytes of the padding that have not yet been skipped are in db?
  // Call only after remaining_padding_ has been set (for padded frames), or
  // been cleared (for unpadded frames); and after all of the non-padding
  // payload has been decoded.
  size_t AvailablePadding(DecodeBuffer* db) const {
    QUICHE_DCHECK(IsPaddable()) << frame_header();
    QUICHE_DCHECK_EQ(remaining_payload_, 0u);
    return db->MinLengthRemaining(remaining_padding_);
  }

  // Reduces remaining_payload_ by amount. To be called by a payload decoder
  // after it has passed a variable length portion of the payload to the
  // listener; remaining_payload_ will be automatically reduced when fixed
  // size structures and padding, including the Pad Length field, are decoded.
  void ConsumePayload(size_t amount) {
    QUICHE_DCHECK_LE(amount, remaining_payload_);
    remaining_payload_ -= amount;
  }

  // Reads the Pad Length field into remaining_padding_, and appropriately sets
  // remaining_payload_. When present, the Pad Length field is always the first
  // field in the payload, which this method relies on so that the caller need
  // not set remaining_payload_ before calling this method.
  // If report_pad_length is true, calls the listener's OnPadLength method when
  // it decodes the Pad Length field.
  // Returns kDecodeDone if the decode buffer was not empty (i.e. because the
  // field is only a single byte long, it can always be decoded if the buffer is
  // not empty).
  // Returns kDecodeError if the buffer is empty because the frame has no
  // payload (i.e. payload_length() == 0).
  // Returns kDecodeInProgress if the buffer is empty but the frame has a
  // payload.
  DecodeStatus ReadPadLength(DecodeBuffer* db, bool report_pad_length);

  // Skip the trailing padding bytes; only call once remaining_payload_==0.
  // Returns true when the padding has been skipped.
  // Does NOT check that the padding is all zeroes.
  bool SkipPadding(DecodeBuffer* db);

  // Calls the listener's OnFrameSizeError method and returns kDecodeError.
  DecodeStatus ReportFrameSizeError();

 private:
  friend class Http2FrameDecoder;
  friend class test::FrameDecoderStatePeer;

  // Starts the decoding of a common frame header. Returns true if completed the
  // decoding, false if the decode buffer didn't have enough data in it, in
  // which case the decode buffer will have been drained and the caller should
  // call ResumeDecodingFrameHeader when more data is available. This is called
  // from Http2FrameDecoder, a friend class.
  bool StartDecodingFrameHeader(DecodeBuffer* db) {
    return structure_decoder_.Start(&frame_header_, db);
  }

  // Resumes decoding the common frame header after the preceding call to
  // StartDecodingFrameHeader returned false, as did any subsequent calls to
  // ResumeDecodingFrameHeader. This is called from Http2FrameDecoder,
  // a friend class.
  bool ResumeDecodingFrameHeader(DecodeBuffer* db) {
    return structure_decoder_.Resume(&frame_header_, db);
  }

  // Clear any of the flags in the frame header that aren't set in valid_flags.
  void RetainFlags(uint8_t valid_flags) {
    frame_header_.RetainFlags(valid_flags);
  }

  // Clear all of the flags in the frame header; for use with frame types that
  // don't define any flags, such as WINDOW_UPDATE.
  void ClearFlags() { frame_header_.flags = Http2FrameFlag(); }

  // Returns true if the type of frame being decoded can have padding.
  bool IsPaddable() const {
    return frame_header().type == Http2FrameType::DATA ||
           frame_header().type == Http2FrameType::HEADERS ||
           frame_header().type == Http2FrameType::PUSH_PROMISE;
  }

  Http2FrameDecoderListener* listener_ = nullptr;
  Http2FrameHeader frame_header_;

  // Number of bytes remaining to be decoded, if set; does not include the
  // trailing padding once the length of padding has been determined.
  // See ReadPadLength.
  uint32_t remaining_payload_;

  // The amount of trailing padding after the payload that remains to be
  // decoded. See ReadPadLength.
  uint32_t remaining_padding_;

  // Generic decoder of structures, which takes care of buffering the needed
  // bytes if the encoded structure is split across decode buffers.
  Http2StructureDecoder structure_decoder_;
};

}  // namespace http2

#endif  // QUICHE_HTTP2_DECODER_FRAME_DECODER_STATE_H_
