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