blob: e06db6c374b13576d80b017c2b5bea962228569e [file] [log] [blame]
// Copyright 2016 The Chromium Authors
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#include "mojo/public/cpp/bindings/lib/native_struct_serialization.h"
#include "base/compiler_specific.h"
#include "ipc/ipc_message_attachment.h"
#include "ipc/ipc_message_attachment_set.h"
#include "mojo/public/cpp/bindings/lib/message_fragment.h"
#include "mojo/public/cpp/bindings/lib/native_handle_type_converters.h"
#include "mojo/public/cpp/bindings/lib/serialization.h"
#include "mojo/public/cpp/bindings/lib/serialization_forward.h"
namespace mojo {
namespace internal {
// static
void UnmappedNativeStructSerializerImpl::Serialize(
const native::NativeStructPtr& input,
MessageFragment<native::internal::NativeStruct_Data>& fragment) {
if (!input)
return;
fragment.Allocate();
MessageFragment<Array_Data<uint8_t>> data_fragment(fragment.message());
constexpr const ContainerValidateParams& data_validate_params =
GetArrayValidator<0, false, nullptr>();
mojo::internal::Serialize<ArrayDataView<uint8_t>>(input->data, data_fragment,
&data_validate_params);
fragment->data.Set(data_fragment.data());
MessageFragment<Array_Data<Pointer<native::internal::SerializedHandle_Data>>>
handles_fragment(fragment.message());
constexpr const ContainerValidateParams& handles_validate_params =
GetArrayValidator<0, false, nullptr>();
mojo::internal::Serialize<
mojo::ArrayDataView<::mojo::native::SerializedHandleDataView>>(
input->handles, handles_fragment, &handles_validate_params);
fragment->handles.Set(handles_fragment.is_null() ? nullptr
: handles_fragment.data());
}
// static
bool UnmappedNativeStructSerializerImpl::Deserialize(
native::internal::NativeStruct_Data* input,
native::NativeStructPtr* output,
Message* message) {
if (!input) {
output->reset();
return true;
}
native::NativeStructDataView data_view(input, message);
return StructTraits<::mojo::native::NativeStructDataView,
native::NativeStructPtr>::Read(data_view, output);
}
// static
void UnmappedNativeStructSerializerImpl::SerializeMessageContents(
IPC::Message* ipc_message,
MessageFragment<native::internal::NativeStruct_Data>& fragment) {
fragment.Allocate();
// Allocate a uint8 array, initialize its header, and copy the Pickle in.
MessageFragment<Array_Data<uint8_t>> data_fragment(fragment.message());
data_fragment.AllocateArrayData(ipc_message->payload_size());
UNSAFE_TODO(memcpy(data_fragment->storage(), ipc_message->payload(),
ipc_message->payload_size()));
fragment->data.Set(data_fragment.data());
if (ipc_message->attachment_set()->empty()) {
fragment->handles.Set(nullptr);
return;
}
MessageFragment<Array_Data<Pointer<native::internal::SerializedHandle_Data>>>
handles_fragment(fragment.message());
auto* attachments = ipc_message->attachment_set();
handles_fragment.AllocateArrayData(attachments->size());
for (unsigned i = 0; i < attachments->size(); ++i) {
MessageFragment<native::internal::SerializedHandle_Data> handle_fragment(
fragment.message());
handle_fragment.Allocate();
auto attachment = attachments->GetAttachmentAt(i);
ScopedHandle handle = attachment->TakeMojoHandle();
internal::Serializer<ScopedHandle, ScopedHandle>::Serialize(
handle, &handle_fragment->the_handle, &fragment.message());
handle_fragment->type = static_cast<int32_t>(
mojo::ConvertTo<native::SerializedHandleType>(attachment->GetType()));
handles_fragment->at(i).Set(handle_fragment.data());
}
fragment->handles.Set(handles_fragment.data());
}
// static
bool UnmappedNativeStructSerializerImpl::DeserializeMessageAttachments(
native::internal::NativeStruct_Data* data,
Message* message,
IPC::Message* ipc_message) {
if (data->handles.is_null())
return true;
auto* handles_data = data->handles.Get();
for (size_t i = 0; i < handles_data->size(); ++i) {
auto* handle_data = handles_data->at(i).Get();
if (!handle_data)
return false;
ScopedHandle handle;
internal::Serializer<ScopedHandle, ScopedHandle>::Deserialize(
&handle_data->the_handle, &handle, message);
auto attachment = IPC::MessageAttachment::CreateFromMojoHandle(
std::move(handle),
mojo::ConvertTo<IPC::MessageAttachment::Type>(
static_cast<native::SerializedHandleType>(handle_data->type)));
ipc_message->attachment_set()->AddAttachment(std::move(attachment));
}
return true;
}
} // namespace internal
} // namespace mojo