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 #include <lib/fidl/cpp/message_buffer.h>
6 #include <zircon/assert.h>
7 
8 #include <stdlib.h>
9 
10 namespace fidl {
11 namespace {
12 
AddPadding(uint32_t offset)13 uint64_t AddPadding(uint32_t offset) {
14     constexpr uint32_t kMask = alignof(zx_handle_t) - 1;
15     // Cast before addition to avoid overflow.
16     return static_cast<uint64_t>(offset) + static_cast<uint64_t>(offset & kMask);
17 }
18 
GetAllocSize(uint32_t bytes_capacity,uint32_t handles_capacity)19 size_t GetAllocSize(uint32_t bytes_capacity, uint32_t handles_capacity) {
20     return AddPadding(bytes_capacity) + sizeof(zx_handle_t) * handles_capacity;
21 }
22 
23 } // namespace
24 
MessageBuffer(uint32_t bytes_capacity,uint32_t handles_capacity)25 MessageBuffer::MessageBuffer(uint32_t bytes_capacity,
26                              uint32_t handles_capacity)
27     : buffer_(static_cast<uint8_t*>(malloc(GetAllocSize(bytes_capacity, handles_capacity)))),
28       bytes_capacity_(bytes_capacity),
29       handles_capacity_(handles_capacity) {
30     ZX_ASSERT_MSG(buffer_, "malloc returned NULL in MessageBuffer::MessageBuffer()");
31 }
32 
~MessageBuffer()33 MessageBuffer::~MessageBuffer() {
34     free(buffer_);
35 }
36 
handles() const37 zx_handle_t* MessageBuffer::handles() const {
38     return reinterpret_cast<zx_handle_t*>(buffer_ + AddPadding(bytes_capacity_));
39 }
40 
CreateEmptyMessage()41 Message MessageBuffer::CreateEmptyMessage() {
42     return Message(BytePart(bytes(), bytes_capacity()),
43                    HandlePart(handles(), handles_capacity()));
44 }
45 
CreateBuilder()46 Builder MessageBuffer::CreateBuilder() {
47     return Builder(bytes(), bytes_capacity());
48 }
49 
50 } // namespace fidl
51