blob: 8bf1e84b0020fe1c99feee388da2eb11471f978f [file] [log] [blame]
// Copyright 2018 The Chromium 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 "mojo/public/cpp/base/big_buffer.h"
#include "base/logging.h"
namespace mojo_base {
namespace internal {
BigBufferSharedMemoryRegion::BigBufferSharedMemoryRegion() = default;
BigBufferSharedMemoryRegion::BigBufferSharedMemoryRegion(
mojo::ScopedSharedBufferHandle buffer_handle,
size_t size)
: size_(size),
buffer_handle_(std::move(buffer_handle)),
buffer_mapping_(buffer_handle_->Map(size)) {}
BigBufferSharedMemoryRegion::BigBufferSharedMemoryRegion(
BigBufferSharedMemoryRegion&& other) = default;
BigBufferSharedMemoryRegion::~BigBufferSharedMemoryRegion() = default;
BigBufferSharedMemoryRegion& BigBufferSharedMemoryRegion::operator=(
BigBufferSharedMemoryRegion&& other) = default;
mojo::ScopedSharedBufferHandle BigBufferSharedMemoryRegion::TakeBufferHandle() {
DCHECK(buffer_handle_.is_valid());
buffer_mapping_.reset();
return std::move(buffer_handle_);
}
} // namespace internal
// static
constexpr size_t BigBuffer::kMaxInlineBytes;
BigBuffer::BigBuffer() : storage_type_(StorageType::kBytes) {}
BigBuffer::BigBuffer(BigBuffer&& other) = default;
BigBuffer::BigBuffer(base::span<const uint8_t> data) {
if (data.size() > kMaxInlineBytes) {
auto buffer = mojo::SharedBufferHandle::Create(data.size());
if (buffer.is_valid()) {
storage_type_ = StorageType::kSharedMemory;
shared_memory_.emplace(std::move(buffer), data.size());
std::copy(data.begin(), data.end(),
static_cast<uint8_t*>(shared_memory_->buffer_mapping_.get()));
return;
}
}
// Either the data is small enough that we're happy to carry it in an array,
// or shared buffer allocation failed and we fall back on this as a best-
// effort alternative.
storage_type_ = StorageType::kBytes;
bytes_.resize(data.size());
std::copy(data.begin(), data.end(), bytes_.begin());
}
BigBuffer::BigBuffer(const std::vector<uint8_t>& data)
: BigBuffer(base::make_span(data)) {}
BigBuffer::BigBuffer(internal::BigBufferSharedMemoryRegion shared_memory)
: storage_type_(StorageType::kSharedMemory),
shared_memory_(std::move(shared_memory)) {}
BigBuffer::~BigBuffer() = default;
BigBuffer& BigBuffer::operator=(BigBuffer&& other) = default;
uint8_t* BigBuffer::data() {
return const_cast<uint8_t*>(const_cast<const BigBuffer*>(this)->data());
}
const uint8_t* BigBuffer::data() const {
switch (storage_type_) {
case StorageType::kBytes:
return bytes_.data();
case StorageType::kSharedMemory:
DCHECK(shared_memory_->buffer_mapping_);
return static_cast<const uint8_t*>(
const_cast<const void*>(shared_memory_->buffer_mapping_.get()));
default:
NOTREACHED();
return nullptr;
}
}
size_t BigBuffer::size() const {
switch (storage_type_) {
case StorageType::kBytes:
return bytes_.size();
case StorageType::kSharedMemory:
return shared_memory_->size();
default:
NOTREACHED();
return 0;
}
}
} // namespace mojo_base