1// Copyright 2018 The Fuchsia Authors. All rights reserved.
2// Use of this source code is governed by a BSD-style license that can be
3// found in the LICENSE file.
4
5#pragma once
6
7#include <stdint.h>
8
9#include <lib/fidl/cpp/builder.h>
10#include <lib/fidl/cpp/message_buffer.h>
11#include <lib/fidl/cpp/message.h>
12#include <zircon/fidl.h>
13#include <zircon/types.h>
14
15namespace fidl {
16
17// A builder for FIDL messages that owns the memory for the message.
18//
19// A |MessageBuilder| is a |Builder| that uses the heap to back the memory for
20// the message. If you wish to manage the memory yourself, you can use |Builder|
21// and |Message| directly.
22//
23// Upon creation, the |MessageBuilder| creates a FIDL message header, which you
24// can modify using |header()|.
25class MessageBuilder : public Builder {
26public:
27    // Creates a |MessageBuilder| for the given |type| that allocates buffers
28    // for message of the given capacities.
29    //
30    // The bytes buffer is initialied by adding a |fidl_message_header_t|
31    // header.
32    //
33    // The buffers are freed when the |MessageBuilder| is destructed.
34    explicit MessageBuilder(
35        const fidl_type_t* type,
36        uint32_t bytes_capacity = ZX_CHANNEL_MAX_MSG_BYTES,
37        uint32_t handles_capacity = ZX_CHANNEL_MAX_MSG_HANDLES);
38
39    // The memory that backs the message is freed by this destructor.
40    ~MessageBuilder();
41
42    // The type of the message payload this object is building.
43    const fidl_type_t* type() const { return type_; }
44
45    // The header for the message.
46    //
47    // The message header is allocated by the |MessageBuilder| itself.
48    fidl_message_header_t* header() const {
49        return reinterpret_cast<fidl_message_header_t*>(buffer());
50    }
51
52    // Encodes a message of the given |type|.
53    //
54    // The memory that backs the message returned by this function is owned by
55    // the |MessageBuilder|, which means the |MessageBuilder| must remain alive
56    // as long as the |Message| object is in use.
57    //
58    // The |message| parameter might be modified even if this method returns an
59    // error.
60    zx_status_t Encode(Message* message_out, const char** error_msg_out);
61
62    // Resets all the data in the |MessageBuffer|.
63    //
64    // The underlying buffer is retained and reused. The next object will be
65    // allocated at the start of the buffer.
66    void Reset();
67
68private:
69    const fidl_type_t* type_;
70    MessageBuffer buffer_;
71};
72
73} // namespace fidl
74