// Copyright 2020 The Fuchsia Authors
//
// Use of this source code is governed by a MIT-style
// license that can be found in the LICENSE file or at
// https://opensource.org/licenses/MIT

#ifndef ZIRCON_KERNEL_LIB_ACPI_LITE_BINARY_READER_H_
#define ZIRCON_KERNEL_LIB_ACPI_LITE_BINARY_READER_H_

#include <lib/acpi_lite/structures.h>
#include <lib/stdcompat/span.h>
#include <lib/zx/status.h>

namespace acpi_lite {

// Light-weight class for decoding structs in a safe manner.
//
// Each operation returns a pointer to a valid struct or nullptr indicating
// that the read would return an invalid structure, such as a structure out of
// bounds of the original input buffer.
//
// BinaryReader supports a common requirement in ACPI of variable-length
// structures, where a struct consists of a header followed by a payload.
// To support such structures, we require a |size| method returning the
// size of the header + payload.
//
// Successful reads consume bytes from the buffer, while failed reads don't
// modify internal state.
class BinaryReader {
 public:
  BinaryReader() = default;

  // Construct a BinaryReader from the given span.
  explicit BinaryReader(cpp20::span<const uint8_t> data) : buffer_(data) {}

  // Construct a BinaryReader from the given pointer / size pair.
  explicit BinaryReader(const void* data, size_t size)
      : buffer_(reinterpret_cast<const uint8_t*>(data), size) {}

  // Construct a BinaryReader from a valid structure with a size() method.
  template <typename T>
  static BinaryReader FromVariableSizedStruct(const T* header) {
    return BinaryReader(reinterpret_cast<const uint8_t*>(header), header->size());
  }

  // Construct a BinaryReader from a class with a size() method, skipping the header T.
  template <typename T>
  static BinaryReader FromPayloadOfStruct(const T* header) {
    BinaryReader result(reinterpret_cast<const uint8_t*>(header), header->size());
    result.buffer_ = result.buffer_.subspan(sizeof(T));
    return result;
  }

  // Read a fixed-length structure.
  template <typename T>
  const T* ReadFixedLength() {
    static_assert(alignof(T) == 1, "Can only safely read types with alignof(T) == 1.");

    // Ensure we have space.
    if (buffer_.size_bytes() < sizeof(T)) {
      return nullptr;
    }

    // Consume the bytes, and return the struct.
    auto* result = reinterpret_cast<const T*>(buffer_.data());
    buffer_ = buffer_.subspan(sizeof(T));
    return result;
  }

  // Read a variable length structure, where the size is determined by T::size().
  template <typename T>
  const T* Read() {
    static_assert(alignof(T) == 1, "Can only safely read types with alignof(T) == 1.");

    // Read the header.
    if (buffer_.size_bytes() < sizeof(T)) {
      return nullptr;
    }
    auto* ptr = reinterpret_cast<const T*>(buffer_.data());

    // Read the desired size.
    //
    // The reported size must be at least sizeof(T), and must not be larger than
    // the number of bytes we have left in our buffer.
    size_t desired_size = ptr->size();
    if (desired_size < sizeof(T) || desired_size > buffer_.size_bytes()) {
      return nullptr;
    }

    // Consume the bytes, and return the header.
    buffer_ = buffer_.subspan(desired_size);
    return ptr;
  }

  // Discard the given number of bytes.
  //
  // Return true if the bytes could be discarded, or false if there are insufficient bytes.
  bool SkipBytes(size_t bytes) {
    if (buffer_.size() < bytes) {
      return false;
    }
    buffer_ = buffer_.subspan(bytes);
    return true;
  }

  // Return true if all the bytes of the reader have been consumed.
  inline bool empty() const { return buffer_.empty(); }

 private:
  cpp20::span<const uint8_t> buffer_;
};

// Convert a pointer to type |Src| to a pointer of type |Dest|, ensuring that the size of |Src|
// is valid.
//
// We require that the type |Dest| has a field |header| at offset 0 of type |Src|.
template <typename Dest, typename Src>
const Dest* Downcast(const Src* src) {
  static_assert(offsetof(Dest, header) == 0,
                "Expected field |header| to be first field in struct.");
  static_assert(std::is_same_v<decltype(Dest::header), Src>,
                "Expected |Dest::header| type to match |Src|.");
  if (src->size() < sizeof(Dest)) {
    return nullptr;
  }
  return reinterpret_cast<const Dest*>(src);
}

// A "packed" type wraps a plain type, but instructs the compiler to treat it as unaligned data.
template <typename T>
struct Packed {
  T value;
} __PACKED;

}  // namespace acpi_lite

#endif  // ZIRCON_KERNEL_LIB_ACPI_LITE_BINARY_READER_H_
