You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
180 lines
5.8 KiB
180 lines
5.8 KiB
// 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.
|
|
|
|
#ifndef MOJO_PUBLIC_CPP_BASE_BIG_BUFFER_H_
|
|
#define MOJO_PUBLIC_CPP_BASE_BIG_BUFFER_H_
|
|
|
|
#include <cstdint>
|
|
#include <vector>
|
|
|
|
#include "base/component_export.h"
|
|
#include "base/containers/span.h"
|
|
#include "base/macros.h"
|
|
#include "base/optional.h"
|
|
#include "mojo/public/cpp/bindings/struct_traits.h"
|
|
#include "mojo/public/cpp/system/buffer.h"
|
|
|
|
namespace mojo_base {
|
|
|
|
class BigBuffer;
|
|
class BigBufferView;
|
|
|
|
namespace internal {
|
|
|
|
// Internal helper used by BigBuffer when backed by shared memory.
|
|
class COMPONENT_EXPORT(MOJO_BASE) BigBufferSharedMemoryRegion {
|
|
public:
|
|
BigBufferSharedMemoryRegion();
|
|
BigBufferSharedMemoryRegion(mojo::ScopedSharedBufferHandle buffer_handle,
|
|
size_t size);
|
|
BigBufferSharedMemoryRegion(BigBufferSharedMemoryRegion&& other);
|
|
~BigBufferSharedMemoryRegion();
|
|
|
|
BigBufferSharedMemoryRegion& operator=(BigBufferSharedMemoryRegion&& other);
|
|
|
|
void* memory() const { return buffer_mapping_.get(); }
|
|
|
|
size_t size() const { return size_; }
|
|
mojo::ScopedSharedBufferHandle TakeBufferHandle();
|
|
|
|
private:
|
|
friend class mojo_base::BigBuffer;
|
|
friend class mojo_base::BigBufferView;
|
|
|
|
size_t size_;
|
|
mojo::ScopedSharedBufferHandle buffer_handle_;
|
|
mojo::ScopedSharedBufferMapping buffer_mapping_;
|
|
|
|
DISALLOW_COPY_AND_ASSIGN(BigBufferSharedMemoryRegion);
|
|
};
|
|
|
|
} // namespace internal
|
|
|
|
// BigBuffer represents a potentially large sequence of bytes. When passed over
|
|
// mojom (as a mojo_base::mojom::BigBuffer union), it may serialize as either an
|
|
// inlined array of bytes or as a shared buffer handle with the payload copied
|
|
// into the corresponding shared memory region. This makes it easier to send
|
|
// payloads of varying and unbounded size over IPC without fear of hitting
|
|
// message size limits.
|
|
//
|
|
// A BigBuffer may be (implicitly) constructed over any span of bytes, and it
|
|
// exposes simple |data()| and |size()| accessors akin to what common container
|
|
// types provide. Users do not need to be concerned with the actual backing
|
|
// storage used to implement this interface.
|
|
class COMPONENT_EXPORT(MOJO_BASE) BigBuffer {
|
|
public:
|
|
static constexpr size_t kMaxInlineBytes = 64 * 1024;
|
|
|
|
enum class StorageType {
|
|
kBytes,
|
|
kSharedMemory,
|
|
};
|
|
|
|
// Defaults to empty vector storage.
|
|
BigBuffer();
|
|
BigBuffer(BigBuffer&& other);
|
|
|
|
// Constructs a BigBuffer over an existing span of bytes. Intentionally
|
|
// implicit for convenience. Always copies the contents of |data| into some
|
|
// internal storage.
|
|
BigBuffer(base::span<const uint8_t> data);
|
|
|
|
// Helper for implicit conversion from byte vectors.
|
|
BigBuffer(const std::vector<uint8_t>& data);
|
|
|
|
// Constructs a BigBuffer from an existing shared memory region. Not intended
|
|
// for general-purpose use.
|
|
explicit BigBuffer(internal::BigBufferSharedMemoryRegion shared_memory);
|
|
|
|
~BigBuffer();
|
|
|
|
BigBuffer& operator=(BigBuffer&& other);
|
|
|
|
// Returns a pointer to the data stored by this BigBuffer, regardless of
|
|
// backing storage type.
|
|
uint8_t* data();
|
|
const uint8_t* data() const;
|
|
|
|
// Returns the size of the data stored by this BigBuffer, regardless of
|
|
// backing storage type.
|
|
size_t size() const;
|
|
|
|
StorageType storage_type() const { return storage_type_; }
|
|
|
|
const std::vector<uint8_t>& bytes() const {
|
|
DCHECK_EQ(storage_type_, StorageType::kBytes);
|
|
return bytes_;
|
|
}
|
|
|
|
internal::BigBufferSharedMemoryRegion& shared_memory() {
|
|
DCHECK_EQ(storage_type_, StorageType::kSharedMemory);
|
|
return shared_memory_.value();
|
|
}
|
|
|
|
private:
|
|
friend class BigBufferView;
|
|
|
|
StorageType storage_type_;
|
|
std::vector<uint8_t> bytes_;
|
|
base::Optional<internal::BigBufferSharedMemoryRegion> shared_memory_;
|
|
|
|
DISALLOW_COPY_AND_ASSIGN(BigBuffer);
|
|
};
|
|
|
|
// Similar to BigBuffer, but doesn't *necessarily* own the buffer storage.
|
|
// Namely, if constructed over a small enough span of memory, it will simply
|
|
// retain a reference to that memory. This is generally only safe to use for
|
|
// serialization and deserialization.
|
|
class COMPONENT_EXPORT(MOJO_BASE) BigBufferView {
|
|
public:
|
|
BigBufferView();
|
|
BigBufferView(BigBufferView&& other);
|
|
|
|
// Constructs a BigBufferView over |bytes|. If |bytes| is large enough, this
|
|
// will allocate shared memory and copy the contents there. Otherwise this
|
|
// will retain an unsafe reference to |bytes| and must therefore not outlive
|
|
// |bytes|.
|
|
explicit BigBufferView(base::span<const uint8_t> bytes);
|
|
~BigBufferView();
|
|
|
|
BigBufferView& operator=(BigBufferView&& other);
|
|
|
|
base::span<const uint8_t> data() const;
|
|
|
|
// Explicitly retains a reference to |bytes| as the backing storage for this
|
|
// view. Does not copy and therefore |bytes| must remain valid throughout the
|
|
// view's lifetime. Used for deserialization.
|
|
void SetBytes(base::span<const uint8_t> bytes);
|
|
|
|
// Explictly adopts |shared_memory| as the backing storage for this view. Used
|
|
// for deserialization.
|
|
void SetSharedMemory(internal::BigBufferSharedMemoryRegion shared_memory);
|
|
|
|
// Converts to a BigBuffer which owns the viewed data. May have to copy data.
|
|
static BigBuffer ToBigBuffer(BigBufferView view) WARN_UNUSED_RESULT;
|
|
|
|
BigBuffer::StorageType storage_type() const { return storage_type_; }
|
|
|
|
base::span<const uint8_t> bytes() const {
|
|
DCHECK_EQ(storage_type_, BigBuffer::StorageType::kBytes);
|
|
return bytes_;
|
|
}
|
|
|
|
internal::BigBufferSharedMemoryRegion& shared_memory() {
|
|
DCHECK_EQ(storage_type_, BigBuffer::StorageType::kSharedMemory);
|
|
return shared_memory_.value();
|
|
}
|
|
|
|
private:
|
|
BigBuffer::StorageType storage_type_;
|
|
base::span<const uint8_t> bytes_;
|
|
base::Optional<internal::BigBufferSharedMemoryRegion> shared_memory_;
|
|
|
|
DISALLOW_COPY_AND_ASSIGN(BigBufferView);
|
|
};
|
|
|
|
} // namespace mojo_base
|
|
|
|
#endif // MOJO_PUBLIC_CPP_BASE_BIG_BUFFER_H_
|