/*
 *  Copyright 2018 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/memory_stream.h"

#include <errno.h>
#include <string.h>

#include <algorithm>
#include <cstdint>

#include "api/array_view.h"
#include "rtc_base/checks.h"
#include "rtc_base/stream.h"

namespace webrtc {

StreamState MemoryStream::GetState() const {
  return webrtc::SS_OPEN;
}

StreamResult MemoryStream::Read(rtc::ArrayView<uint8_t> buffer,
                                size_t& bytes_read,
                                int& error) {
  if (seek_position_ >= data_length_) {
    return webrtc::SR_EOS;
  }
  size_t available = data_length_ - seek_position_;
  size_t bytes;
  if (buffer.size() > available) {
    // Read partial buffer
    bytes = available;
  } else {
    bytes = buffer.size();
  }
  memcpy(buffer.data(), &buffer_[seek_position_], bytes);
  seek_position_ += bytes;
  bytes_read = bytes;
  return webrtc::SR_SUCCESS;
}

StreamResult MemoryStream::Write(rtc::ArrayView<const uint8_t> buffer,
                                 size_t& bytes_written,
                                 int& error) {
  size_t available = buffer_length_ - seek_position_;
  if (0 == available) {
    // Increase buffer size to the larger of:
    // a) new position rounded up to next 256 bytes
    // b) double the previous length
    size_t new_buffer_length = std::max(
        ((seek_position_ + buffer.size()) | 0xFF) + 1, buffer_length_ * 2);
    StreamResult result = DoReserve(new_buffer_length, &error);
    if (webrtc::SR_SUCCESS != result) {
      return result;
    }
    RTC_DCHECK(buffer_length_ >= new_buffer_length);
    available = buffer_length_ - seek_position_;
  }

  size_t bytes = buffer.size();
  if (bytes > available) {
    bytes = available;
  }
  memcpy(&buffer_[seek_position_], buffer.data(), bytes);
  seek_position_ += bytes;
  if (data_length_ < seek_position_) {
    data_length_ = seek_position_;
  }
  bytes_written = bytes;
  return webrtc::SR_SUCCESS;
}

void MemoryStream::Close() {
  // nothing to do
}

bool MemoryStream::SetPosition(size_t position) {
  if (position > data_length_)
    return false;
  seek_position_ = position;
  return true;
}

bool MemoryStream::GetPosition(size_t* position) const {
  if (position)
    *position = seek_position_;
  return true;
}

void MemoryStream::Rewind() {
  seek_position_ = 0;
}

bool MemoryStream::GetSize(size_t* size) const {
  if (size)
    *size = data_length_;
  return true;
}

bool MemoryStream::ReserveSize(size_t size) {
  return (webrtc::SR_SUCCESS == DoReserve(size, nullptr));
}

///////////////////////////////////////////////////////////////////////////////

MemoryStream::MemoryStream() {}

MemoryStream::~MemoryStream() {
  delete[] buffer_;
}

void MemoryStream::SetData(const void* data, size_t length) {
  data_length_ = buffer_length_ = length;
  delete[] buffer_;
  buffer_ = new char[buffer_length_];
  memcpy(buffer_, data, data_length_);
  seek_position_ = 0;
}

StreamResult MemoryStream::DoReserve(size_t size, int* error) {
  if (buffer_length_ >= size)
    return webrtc::SR_SUCCESS;

  if (char* new_buffer = new char[size]) {
    if (buffer_ != nullptr && data_length_ > 0) {
      memcpy(new_buffer, buffer_, data_length_);
    }
    delete[] buffer_;
    buffer_ = new_buffer;
    buffer_length_ = size;
    return webrtc::SR_SUCCESS;
  }

  if (error) {
    *error = ENOMEM;
  }
  return webrtc::SR_ERROR;
}

}  // namespace webrtc
