// Copyright 2015 The Chromium OS Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#include <brillo/streams/memory_containers.h>

#include <base/callback.h>
#include <brillo/streams/stream_errors.h>

namespace brillo {
namespace data_container {

namespace {

bool ErrorStreamReadOnly(const base::Location& location,
                         ErrorPtr* error) {
  Error::AddTo(error,
               location,
               errors::stream::kDomain,
               errors::stream::kOperationNotSupported,
               "Stream is read-only");
  return false;
}

}  // anonymous namespace

void ContiguousBufferBase::CopyMemoryBlock(void* dest,
                                           const void* src,
                                           size_t size) const {
  memcpy(dest, src, size);
}

bool ContiguousBufferBase::Read(void* buffer,
                                size_t size_to_read,
                                size_t offset,
                                size_t* size_read,
                                ErrorPtr* error) {
  size_t buf_size = GetSize();
  if (offset < buf_size) {
    size_t remaining = buf_size - offset;
    if (size_to_read >= remaining) {
      size_to_read = remaining;
    }
    const void* src_buffer = GetReadOnlyBuffer(offset, error);
    if (!src_buffer)
      return false;

    CopyMemoryBlock(buffer, src_buffer, size_to_read);
  } else {
    size_to_read = 0;
  }
  if (size_read)
    *size_read = size_to_read;
  return true;
}

bool ContiguousBufferBase::Write(const void* buffer,
                                 size_t size_to_write,
                                 size_t offset,
                                 size_t* size_written,
                                 ErrorPtr* error) {
  if (size_to_write) {
    size_t new_size = offset + size_to_write;
    if (GetSize() < new_size && !Resize(new_size, error))
      return false;
    void* ptr = GetBuffer(offset, error);
    if (!ptr)
      return false;
    CopyMemoryBlock(ptr, buffer, size_to_write);
    if (size_written)
      *size_written = size_to_write;
  }
  return true;
}

bool ContiguousReadOnlyBufferBase::Write(const void* /* buffer */,
                                         size_t /* size_to_write */,
                                         size_t /* offset */,
                                         size_t* /* size_written */,
                                         ErrorPtr* error) {
  return ErrorStreamReadOnly(FROM_HERE, error);
}

bool ContiguousReadOnlyBufferBase::Resize(size_t /* new_size */,
                                          ErrorPtr* error) {
  return ErrorStreamReadOnly(FROM_HERE, error);
}

void* ContiguousReadOnlyBufferBase::GetBuffer(size_t /* offset */,
                                              ErrorPtr* error) {
  ErrorStreamReadOnly(FROM_HERE, error);
  return nullptr;
}

ByteBuffer::ByteBuffer(size_t reserve_size)
    : VectorPtr(new std::vector<uint8_t>()) {
  vector_ptr_->reserve(reserve_size);
}

ByteBuffer::~ByteBuffer() {
  delete vector_ptr_;
}

StringPtr::StringPtr(std::string* string) : string_ptr_(string) {}

bool StringPtr::Resize(size_t new_size, ErrorPtr* /* error */) {
  string_ptr_->resize(new_size);
  return true;
}

const void* StringPtr::GetReadOnlyBuffer(size_t offset,
                                         ErrorPtr* /* error */) const {
  return string_ptr_->data() + offset;
}

void* StringPtr::GetBuffer(size_t offset, ErrorPtr* /* error */) {
  return &(*string_ptr_)[offset];
}

ReadOnlyStringRef::ReadOnlyStringRef(const std::string& string)
    : string_ref_(string) {}

const void* ReadOnlyStringRef::GetReadOnlyBuffer(size_t offset,
                                                 ErrorPtr* /* error */) const {
  return string_ref_.data() + offset;
}

ReadOnlyStringCopy::ReadOnlyStringCopy(std::string string)
    : ReadOnlyStringRef(string_copy_), string_copy_(std::move(string)) {}

}  // namespace data_container
}  // namespace brillo
