/*
 *  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.
 */

#include "rtc_base/byte_buffer.h"

#include <string.h>

#include <cstdint>
#include <string>

#include "absl/strings/string_view.h"
#include "api/array_view.h"
#include "rtc_base/byte_order.h"

namespace webrtc {

ByteBufferWriter::ByteBufferWriter() : ByteBufferWriterT() {}

ByteBufferWriter::ByteBufferWriter(const uint8_t* bytes, size_t len)
    : ByteBufferWriterT(bytes, len) {}

ByteBufferReader::ByteBufferReader(ArrayView<const uint8_t> bytes) {
  Construct(bytes.data(), bytes.size());
}

ByteBufferReader::ByteBufferReader(const ByteBufferWriter& buf) {
  Construct(reinterpret_cast<const uint8_t*>(buf.Data()), buf.Length());
}

void ByteBufferReader::Construct(const uint8_t* bytes, size_t len) {
  bytes_ = bytes;
  size_ = len;
  start_ = 0;
  end_ = len;
}

bool ByteBufferReader::ReadUInt8(uint8_t* val) {
  if (!val)
    return false;

  return ReadBytes(val, 1);
}

bool ByteBufferReader::ReadUInt16(uint16_t* val) {
  if (!val)
    return false;

  uint16_t v;
  if (!ReadBytes(reinterpret_cast<uint8_t*>(&v), 2)) {
    return false;
  } else {
    *val = webrtc::NetworkToHost16(v);
    return true;
  }
}

bool ByteBufferReader::ReadUInt24(uint32_t* val) {
  if (!val)
    return false;

  uint32_t v = 0;
  uint8_t* read_into = reinterpret_cast<uint8_t*>(&v);
  ++read_into;

  if (!ReadBytes(read_into, 3)) {
    return false;
  } else {
    *val = webrtc::NetworkToHost32(v);
    return true;
  }
}

bool ByteBufferReader::ReadUInt32(uint32_t* val) {
  if (!val)
    return false;

  uint32_t v;
  if (!ReadBytes(reinterpret_cast<uint8_t*>(&v), 4)) {
    return false;
  } else {
    *val = webrtc::NetworkToHost32(v);
    return true;
  }
}

bool ByteBufferReader::ReadUInt64(uint64_t* val) {
  if (!val)
    return false;

  uint64_t v;
  if (!ReadBytes(reinterpret_cast<uint8_t*>(&v), 8)) {
    return false;
  } else {
    *val = webrtc::NetworkToHost64(v);
    return true;
  }
}

bool ByteBufferReader::ReadUVarint(uint64_t* val) {
  if (!val) {
    return false;
  }
  // Integers are deserialized 7 bits at a time, with each byte having a
  // continuation byte (msb=1) if there are more bytes to be read.
  uint64_t v = 0;
  for (int i = 0; i < 64; i += 7) {
    uint8_t byte;
    if (!ReadBytes(&byte, 1)) {
      return false;
    }
    // Read the first 7 bits of the byte, then offset by bits read so far.
    v |= (static_cast<uint64_t>(byte) & 0x7F) << i;
    // Return if the msb is not a continuation byte.
    if (byte < 0x80) {
      *val = v;
      return true;
    }
  }
  return false;
}

bool ByteBufferReader::ReadString(std::string* val, size_t len) {
  if (!val)
    return false;

  if (len > Length()) {
    return false;
  } else {
    val->append(reinterpret_cast<const char*>(bytes_ + start_), len);
    start_ += len;
    return true;
  }
}

bool ByteBufferReader::ReadStringView(absl::string_view* val, size_t len) {
  if (!val || len > Length())
    return false;
  *val = absl::string_view(reinterpret_cast<const char*>(bytes_ + start_), len);
  start_ += len;
  return true;
}

bool ByteBufferReader::ReadBytes(ArrayView<uint8_t> val) {
  if (val.size() == 0) {
    return true;
  }
  return ReadBytes(val.data(), val.size());
}

// Private function supporting the other Read* functions.
bool ByteBufferReader::ReadBytes(uint8_t* val, size_t len) {
  if (len > Length()) {
    return false;
  }
  if (len == 0) {
    return true;
  }
  memcpy(val, bytes_ + start_, len);
  start_ += len;
  return true;
}

bool ByteBufferReader::Consume(size_t size) {
  if (size > Length())
    return false;
  start_ += size;
  return true;
}

}  // namespace webrtc
