/*
 *  Copyright 2004 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 RTC_BASE_BYTEBUFFER_H_
#define RTC_BASE_BYTEBUFFER_H_

#include <stddef.h>
#include <stdint.h>
#include <string>

#include "rtc_base/buffer.h"
#include "rtc_base/byteorder.h"
#include "rtc_base/constructormagic.h"

namespace rtc {

class ByteBuffer {
 public:
  enum ByteOrder {
    ORDER_NETWORK = 0,  // Default, use network byte order (big endian).
    ORDER_HOST,         // Use the native order of the host.
  };

  explicit ByteBuffer(ByteOrder byte_order) : byte_order_(byte_order) {}

  ByteOrder Order() const { return byte_order_; }

 private:
  ByteOrder byte_order_;

  RTC_DISALLOW_COPY_AND_ASSIGN(ByteBuffer);
};

template <class BufferClassT>
class ByteBufferWriterT : public ByteBuffer {
 public:
  // |byte_order| defines order of bytes in the buffer.
  ByteBufferWriterT() : ByteBuffer(ORDER_NETWORK) {
    Construct(nullptr, kDefaultCapacity);
  }
  explicit ByteBufferWriterT(ByteOrder byte_order) : ByteBuffer(byte_order) {
    Construct(nullptr, kDefaultCapacity);
  }
  ByteBufferWriterT(const char* bytes, size_t len) : ByteBuffer(ORDER_NETWORK) {
    Construct(bytes, len);
  }
  ByteBufferWriterT(const char* bytes, size_t len, ByteOrder byte_order)
      : ByteBuffer(byte_order) {
    Construct(bytes, len);
  }

  const char* Data() const { return buffer_.data(); }
  size_t Length() const { return buffer_.size(); }
  size_t Capacity() const { return buffer_.capacity(); }

  // Write value to the buffer. Resizes the buffer when it is
  // neccessary.
  void WriteUInt8(uint8_t val) {
    WriteBytes(reinterpret_cast<const char*>(&val), 1);
  }
  void WriteUInt16(uint16_t val) {
    uint16_t v = (Order() == ORDER_NETWORK) ? HostToNetwork16(val) : val;
    WriteBytes(reinterpret_cast<const char*>(&v), 2);
  }
  void WriteUInt24(uint32_t val) {
    uint32_t v = (Order() == ORDER_NETWORK) ? HostToNetwork32(val) : val;
    char* start = reinterpret_cast<char*>(&v);
    if (Order() == ORDER_NETWORK || IsHostBigEndian()) {
      ++start;
    }
    WriteBytes(start, 3);
  }
  void WriteUInt32(uint32_t val) {
    uint32_t v = (Order() == ORDER_NETWORK) ? HostToNetwork32(val) : val;
    WriteBytes(reinterpret_cast<const char*>(&v), 4);
  }
  void WriteUInt64(uint64_t val) {
    uint64_t v = (Order() == ORDER_NETWORK) ? HostToNetwork64(val) : val;
    WriteBytes(reinterpret_cast<const char*>(&v), 8);
  }
  // Serializes an unsigned varint in the format described by
  // https://developers.google.com/protocol-buffers/docs/encoding#varints
  // with the caveat that integers are 64-bit, not 128-bit.
  void WriteUVarint(uint64_t val) {
    while (val >= 0x80) {
      // Write 7 bits at a time, then set the msb to a continuation byte
      // (msb=1).
      char byte = static_cast<char>(val) | 0x80;
      WriteBytes(&byte, 1);
      val >>= 7;
    }
    char last_byte = static_cast<char>(val);
    WriteBytes(&last_byte, 1);
  }
  void WriteString(const std::string& val) {
    WriteBytes(val.c_str(), val.size());
  }
  void WriteBytes(const char* val, size_t len) { buffer_.AppendData(val, len); }

  // Reserves the given number of bytes and returns a char* that can be written
  // into. Useful for functions that require a char* buffer and not a
  // ByteBufferWriter.
  char* ReserveWriteBuffer(size_t len) {
    buffer_.SetSize(buffer_.size() + len);
    return buffer_.data();
  }

  // Resize the buffer to the specified |size|.
  void Resize(size_t size) { buffer_.SetSize(size); }

  // Clears the contents of the buffer. After this, Length() will be 0.
  void Clear() { buffer_.Clear(); }

 private:
  static constexpr size_t kDefaultCapacity = 4096;

  void Construct(const char* bytes, size_t size) {
    if (bytes) {
      buffer_.AppendData(bytes, size);
    } else {
      buffer_.EnsureCapacity(size);
    }
  }

  BufferClassT buffer_;

  // There are sensible ways to define these, but they aren't needed in our code
  // base.
  RTC_DISALLOW_COPY_AND_ASSIGN(ByteBufferWriterT);
};

class ByteBufferWriter : public ByteBufferWriterT<BufferT<char>> {
 public:
  // |byte_order| defines order of bytes in the buffer.
  ByteBufferWriter();
  explicit ByteBufferWriter(ByteOrder byte_order);
  ByteBufferWriter(const char* bytes, size_t len);
  ByteBufferWriter(const char* bytes, size_t len, ByteOrder byte_order);

 private:
  RTC_DISALLOW_COPY_AND_ASSIGN(ByteBufferWriter);
};

// The ByteBufferReader references the passed data, i.e. the pointer must be
// valid during the lifetime of the reader.
class ByteBufferReader : public ByteBuffer {
 public:
  ByteBufferReader(const char* bytes, size_t len);
  ByteBufferReader(const char* bytes, size_t len, ByteOrder byte_order);

  // Initializes buffer from a zero-terminated string.
  explicit ByteBufferReader(const char* bytes);

  explicit ByteBufferReader(const Buffer& buf);

  explicit ByteBufferReader(const ByteBufferWriter& buf);

  // Returns start of unprocessed data.
  const char* Data() const { return bytes_ + start_; }
  // Returns number of unprocessed bytes.
  size_t Length() const { return end_ - start_; }

  // Read a next value from the buffer. Return false if there isn't
  // enough data left for the specified type.
  bool ReadUInt8(uint8_t* val);
  bool ReadUInt16(uint16_t* val);
  bool ReadUInt24(uint32_t* val);
  bool ReadUInt32(uint32_t* val);
  bool ReadUInt64(uint64_t* val);
  bool ReadUVarint(uint64_t* val);
  bool ReadBytes(char* val, size_t len);

  // Appends next |len| bytes from the buffer to |val|. Returns false
  // if there is less than |len| bytes left.
  bool ReadString(std::string* val, size_t len);

  // Moves current position |size| bytes forward. Returns false if
  // there is less than |size| bytes left in the buffer. Consume doesn't
  // permanently remove data, so remembered read positions are still valid
  // after this call.
  bool Consume(size_t size);

 protected:
  void Construct(const char* bytes, size_t size);

  const char* bytes_;
  size_t size_;
  size_t start_;
  size_t end_;

 private:
  RTC_DISALLOW_COPY_AND_ASSIGN(ByteBufferReader);
};

}  // namespace rtc

#endif  // RTC_BASE_BYTEBUFFER_H_
