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.
132 lines
4.4 KiB
132 lines
4.4 KiB
// Copyright 2013 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_BINDINGS_LIB_BUFFER_H_
|
|
#define MOJO_PUBLIC_CPP_BINDINGS_LIB_BUFFER_H_
|
|
|
|
#include <stddef.h>
|
|
#include <stdint.h>
|
|
|
|
#include <vector>
|
|
|
|
#include "base/component_export.h"
|
|
#include "base/macros.h"
|
|
#include "mojo/public/cpp/system/handle.h"
|
|
#include "mojo/public/cpp/system/message.h"
|
|
|
|
namespace mojo {
|
|
namespace internal {
|
|
|
|
// Buffer provides an interface to allocate memory blocks which are 8-byte
|
|
// aligned. It doesn't own the underlying memory. Users must ensure that the
|
|
// memory stays valid while using the allocated blocks from Buffer.
|
|
//
|
|
// A Buffer may be moved around. A moved-from Buffer is reset and may no longer
|
|
// be used to Allocate memory unless re-Initialized.
|
|
class COMPONENT_EXPORT(MOJO_CPP_BINDINGS_BASE) Buffer {
|
|
public:
|
|
// Constructs an invalid Buffer. May not call Allocate().
|
|
Buffer();
|
|
|
|
// Constructs a Buffer which can Allocate() blocks from a buffer of fixed size
|
|
// |size| at |data|. Allocations start at |cursor|, so if |cursor| == |size|
|
|
// then no allocations are allowed.
|
|
//
|
|
// |data| is not owned.
|
|
Buffer(void* data, size_t size, size_t cursor);
|
|
|
|
// Like above, but gives the Buffer an underlying message object which can
|
|
// have its payload extended to acquire more storage capacity on Allocate().
|
|
//
|
|
// |data| and |size| must correspond to |message|'s data buffer at the time of
|
|
// construction.
|
|
//
|
|
// |payload_size| is the length of the payload as known by |message|, and it
|
|
// must be less than or equal to |size|.
|
|
//
|
|
// |message| is NOT owned and must outlive this Buffer.
|
|
Buffer(MessageHandle message,
|
|
size_t message_payload_size,
|
|
void* data,
|
|
size_t size);
|
|
|
|
Buffer(Buffer&& other);
|
|
~Buffer();
|
|
|
|
Buffer& operator=(Buffer&& other);
|
|
|
|
void* data() const { return data_; }
|
|
size_t size() const { return size_; }
|
|
size_t cursor() const { return cursor_; }
|
|
|
|
bool is_valid() const {
|
|
return data_ != nullptr || (size_ == 0 && !message_.is_valid());
|
|
}
|
|
|
|
// Allocates |num_bytes| from the buffer and returns an index to the start of
|
|
// the allocated block. The resulting index is 8-byte aligned and can be
|
|
// resolved to an address using Get<T>() below.
|
|
size_t Allocate(size_t num_bytes);
|
|
|
|
// Returns a typed address within the Buffer corresponding to |index|. Note
|
|
// that this address is NOT stable across calls to |Allocate()| and thus must
|
|
// not be cached accordingly.
|
|
template <typename T>
|
|
T* Get(size_t index) {
|
|
DCHECK_LT(index, cursor_);
|
|
return reinterpret_cast<T*>(static_cast<uint8_t*>(data_) + index);
|
|
}
|
|
|
|
// A template helper combining Allocate() and Get<T>() above to allocate and
|
|
// return a block of size |sizeof(T)|.
|
|
template <typename T>
|
|
T* AllocateAndGet() {
|
|
return Get<T>(Allocate(sizeof(T)));
|
|
}
|
|
|
|
// A helper which combines Allocate() and Get<void>() for a specified number
|
|
// of bytes.
|
|
void* AllocateAndGet(size_t num_bytes) {
|
|
return Get<void>(Allocate(num_bytes));
|
|
}
|
|
|
|
// Serializes |handles| into the buffer object. Only valid to call when this
|
|
// Buffer is backed by a message object.
|
|
void AttachHandles(std::vector<ScopedHandle>* handles);
|
|
|
|
// Seals this Buffer so it can no longer be used for allocation, and ensures
|
|
// the backing message object has a complete accounting of the size of the
|
|
// meaningful payload bytes.
|
|
void Seal();
|
|
|
|
// Resets the buffer to an invalid state. Can no longer be used to Allocate().
|
|
void Reset();
|
|
|
|
private:
|
|
MessageHandle message_;
|
|
|
|
// The payload size from the message's internal perspective. This differs from
|
|
// |size_| as Mojo may intentionally over-allocate space to account for future
|
|
// growth. It differs from |cursor_| because we don't push payload size
|
|
// updates to the message object as frequently as we update |cursor_|, for
|
|
// performance.
|
|
size_t message_payload_size_ = 0;
|
|
|
|
// The storage location and capacity currently backing |message_|. Owned by
|
|
// the message object internally, not by this Buffer.
|
|
void* data_ = nullptr;
|
|
size_t size_ = 0;
|
|
|
|
// The current write offset into |data_| if this Buffer is being used for
|
|
// message creation.
|
|
size_t cursor_ = 0;
|
|
|
|
DISALLOW_COPY_AND_ASSIGN(Buffer);
|
|
};
|
|
|
|
} // namespace internal
|
|
} // namespace mojo
|
|
|
|
#endif // MOJO_PUBLIC_CPP_BINDINGS_LIB_BUFFER_H_
|