blob: dc8c7be29bd03c2a910078405223a886a5b10bf6 [file] [log] [blame]
// Copyright 2016 The Fuchsia Authors
//
// Use of this source code is governed by a MIT-style
// license that can be found in the LICENSE file or at
// https://opensource.org/licenses/MIT
#pragma once
#include <stdint.h>
#include <lib/user_copy/user_ptr.h>
#include <zircon/types.h>
#include <fbl/intrusive_double_list.h>
#include <fbl/intrusive_single_list.h>
#include <fbl/unique_ptr.h>
constexpr uint32_t kMaxMessageSize = 65536u;
constexpr uint32_t kMaxMessageHandles = 64u;
// ensure public constants are aligned
static_assert(ZX_CHANNEL_MAX_MSG_BYTES == kMaxMessageSize, "");
static_assert(ZX_CHANNEL_MAX_MSG_HANDLES == kMaxMessageHandles, "");
class Handle;
class MessagePacket : public fbl::DoublyLinkedListable<fbl::unique_ptr<MessagePacket>> {
public:
// Creates a message packet containing the provided data and space for
// |num_handles| handles. The handles array is uninitialized and must
// be completely overwritten by clients.
static zx_status_t Create(user_in_ptr<const void> data, uint32_t data_size,
uint32_t num_handles,
fbl::unique_ptr<MessagePacket>* msg);
static zx_status_t Create(const void* data, uint32_t data_size,
uint32_t num_handles,
fbl::unique_ptr<MessagePacket>* msg);
uint32_t data_size() const { return data_size_; }
// Copies the packet's |data_size()| bytes to |buf|.
// Returns an error if |buf| points to a bad user address.
zx_status_t CopyDataTo(user_out_ptr<void> buf) const;
uint32_t num_handles() const { return num_handles_; }
Handle* const* handles() const { return handles_; }
Handle** mutable_handles() { return handles_; }
void set_owns_handles(bool own_handles) { owns_handles_ = own_handles; }
// zx_channel_call treats the leading bytes of the payload as
// a transaction id of type zx_txid_t.
zx_txid_t get_txid() const;
struct Buffer;
private:
typedef fbl::SinglyLinkedList<Buffer*> BufferList;
MessagePacket(BufferList* buffers, uint32_t data_size, uint32_t num_handles, Handle** handles);
~MessagePacket();
template <typename PTR>
static zx_status_t CreateCommon(PTR data, uint32_t data_size, uint32_t num_handles,
fbl::unique_ptr<MessagePacket>* msg);
static void Free(void* p);
friend class fbl::unique_ptr<MessagePacket>;
static void operator delete(void* ptr);
BufferList* buffers_;
Handle** const handles_;
const uint32_t data_size_;
const uint16_t num_handles_;
bool owns_handles_;
};