// 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 tracked_objects::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