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