blob: 3ef6a2ca83f43fcf0536a0884f6ef287c6c21fbc [file] [log] [blame]
// Copyright 2018 The Fuchsia Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#include <lib/fidl/cpp/wire/message.h>
#include <lib/fidl/internal.h>
#include <zircon/assert.h>
#include <zircon/errors.h>
#include <cstring>
#include <string>
#ifdef __Fuchsia__
#include <lib/fidl/cpp/wire/client_base.h>
#include <lib/fidl/cpp/wire/internal/transport_channel.h>
#include <lib/fidl/cpp/wire/server.h>
#include <zircon/syscalls.h>
#else
#include <lib/fidl/cpp/wire/internal/transport_channel_host.h>
#endif // __Fuchsia__
namespace fidl {
OutgoingToEncodedMessage::OutgoingToEncodedMessage(OutgoingMessage& input)
: encoded_message_(
ConversionImpl(input, buf_bytes_, buf_handles_, buf_handle_metadata_, status_)) {}
[[nodiscard]] std::string OutgoingToEncodedMessage::FormatDescription() const {
return status_.FormatDescription();
}
EncodedMessage OutgoingToEncodedMessage::ConversionImpl(
OutgoingMessage& input, OutgoingMessage::CopiedBytes& buf_bytes,
std::unique_ptr<zx_handle_t[]>& buf_handles,
// TODO(https://fxbug.dev/42166666) Remove channel-specific logic.
std::unique_ptr<fidl_channel_handle_metadata_t[]>& buf_handle_metadata,
fidl::Status& out_status) {
ZX_ASSERT(!input.is_transactional());
zx_handle_t* handles = input.handles();
fidl_channel_handle_metadata_t* handle_metadata =
input.handle_metadata<fidl::internal::ChannelTransport>();
uint32_t num_handles = input.handle_actual();
input.ReleaseHandles();
// Note: it may be possible to remove these allocations.
buf_handles = std::make_unique<zx_handle_t[]>(num_handles);
buf_handle_metadata = std::make_unique<fidl_channel_handle_metadata_t[]>(num_handles);
for (uint32_t i = 0; i < num_handles; i++) {
const char* error;
zx_status_t status = FidlEnsureActualHandleRights(&handles[i], handle_metadata[i].obj_type,
handle_metadata[i].rights, &error);
if (status != ZX_OK) {
FidlHandleCloseMany(handles, num_handles);
FidlHandleCloseMany(buf_handles.get(), num_handles);
out_status = fidl::Status::EncodeError(status);
return fidl::EncodedMessage::Create({});
}
buf_handles[i] = handles[i];
buf_handle_metadata[i] = handle_metadata[i];
}
buf_bytes = input.CopyBytes();
out_status = fidl::Status::Ok();
return fidl::EncodedMessage::Create(cpp20::span<uint8_t>{buf_bytes}, buf_handles.get(),
buf_handle_metadata.get(), num_handles);
}
} // namespace fidl