/*
 *  Copyright (c) 2021 The WebRTC project authors. All Rights Reserved.
 *
 *  Use of this source code is governed by a BSD-style license
 *  that can be found in the LICENSE file in the root of the source
 *  tree. An additional intellectual property rights grant can be found
 *  in the file PATENTS.  All contributing project authors may
 *  be found in the AUTHORS file in the root of the source tree.
 */

#ifndef NET_DCSCTP_PACKET_BOUNDED_BYTE_READER_H_
#define NET_DCSCTP_PACKET_BOUNDED_BYTE_READER_H_

#include <cstdint>

#include "api/array_view.h"

namespace dcsctp {

// TODO(boivie): These generic functions - and possibly this entire class -
// could be a candidate to have added to rtc_base/. They should use compiler
// intrinsics as well.
namespace internal {
// Loads a 8-bit unsigned word at `data`.
inline uint8_t LoadBigEndian8(const uint8_t* data) {
  return data[0];
}

// Loads a 16-bit unsigned word at `data`.
inline uint16_t LoadBigEndian16(const uint8_t* data) {
  return (data[0] << 8) | data[1];
}

// Loads a 32-bit unsigned word at `data`.
inline uint32_t LoadBigEndian32(const uint8_t* data) {
  return (data[0] << 24) | (data[1] << 16) | (data[2] << 8) | data[3];
}
}  // namespace internal

// BoundedByteReader wraps an ArrayView and divides it into two parts; A fixed
// size - which is the template parameter - and a variable size, which is what
// remains in `data` after the `FixedSize`.
//
// The BoundedByteReader provides methods to load/read big endian numbers from
// the FixedSize portion of the buffer, and these are read with static bounds
// checking, to avoid out-of-bounds accesses without a run-time penalty.
//
// The variable sized portion can either be used to create sub-readers, which
// themselves would provide compile-time bounds-checking, or the entire variable
// sized portion can be retrieved as an ArrayView.
template <int FixedSize>
class BoundedByteReader {
 public:
  explicit BoundedByteReader(rtc::ArrayView<const uint8_t> data) : data_(data) {
    RTC_DCHECK(data.size() >= FixedSize);
  }

  template <size_t offset>
  uint8_t Load8() const {
    static_assert(offset + sizeof(uint8_t) <= FixedSize, "Out-of-bounds");
    return internal::LoadBigEndian8(&data_[offset]);
  }

  template <size_t offset>
  uint16_t Load16() const {
    static_assert(offset + sizeof(uint16_t) <= FixedSize, "Out-of-bounds");
    static_assert((offset % sizeof(uint16_t)) == 0, "Unaligned access");
    return internal::LoadBigEndian16(&data_[offset]);
  }

  template <size_t offset>
  uint32_t Load32() const {
    static_assert(offset + sizeof(uint32_t) <= FixedSize, "Out-of-bounds");
    static_assert((offset % sizeof(uint32_t)) == 0, "Unaligned access");
    return internal::LoadBigEndian32(&data_[offset]);
  }

  template <size_t SubSize>
  BoundedByteReader<SubSize> sub_reader(size_t variable_offset) const {
    RTC_DCHECK(FixedSize + variable_offset + SubSize <= data_.size());

    rtc::ArrayView<const uint8_t> sub_span =
        data_.subview(FixedSize + variable_offset, SubSize);
    return BoundedByteReader<SubSize>(sub_span);
  }

  size_t variable_data_size() const { return data_.size() - FixedSize; }

  rtc::ArrayView<const uint8_t> variable_data() const {
    return data_.subview(FixedSize, data_.size() - FixedSize);
  }

 private:
  const rtc::ArrayView<const uint8_t> data_;
};

}  // namespace dcsctp

#endif  // NET_DCSCTP_PACKET_BOUNDED_BYTE_READER_H_
