// 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 NET_THIRD_PARTY_HTTP2_DECODER_FRAME_DECODER_STATE_H_
#define NET_THIRD_PARTY_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 "base/logging.h"
#include "net/third_party/http2/decoder/decode_buffer.h"
#include "net/third_party/http2/decoder/decode_status.h"
#include "net/third_party/http2/decoder/http2_frame_decoder_listener.h"
#include "net/third_party/http2/decoder/http2_structure_decoder.h"
#include "net/third_party/http2/http2_constants.h"
#include "net/third_party/http2/http2_structures.h"
#include "net/third_party/http2/platform/api/http2_export.h"
#include "starboard/types.h"

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

class HTTP2_EXPORT_PRIVATE 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) {
    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;
    }
    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) {
    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 {
      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 {
    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 {
    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 {
    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 {
    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 {
    DCHECK(IsPaddable()) << frame_header();
    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) {
    DCHECK_LE(amount, remaining_payload_);
#if defined(STARBOARD)
    remaining_payload_ -= static_cast<uint32_t>(amount);
#else
    remaining_payload_ -= amount;
#endif
  }

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