| // Copyright 2016 The Chromium 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 "mojo/public/cpp/bindings/lib/native_struct_serialization.h" |
| |
| #include "ipc/ipc_message_attachment.h" |
| #include "ipc/ipc_message_attachment_set.h" |
| #include "ipc/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, |
| Buffer* buffer, |
| native::internal::NativeStruct_Data::BufferWriter* writer, |
| SerializationContext* context) { |
| if (!input) |
| return; |
| |
| writer->Allocate(buffer); |
| |
| Array_Data<uint8_t>::BufferWriter data_writer; |
| const mojo::internal::ContainerValidateParams data_validate_params(0, false, |
| nullptr); |
| mojo::internal::Serialize<ArrayDataView<uint8_t>>( |
| input->data, buffer, &data_writer, &data_validate_params, context); |
| writer->data()->data.Set(data_writer.data()); |
| |
| mojo::internal::Array_Data<mojo::internal::Pointer< |
| native::internal::SerializedHandle_Data>>::BufferWriter handles_writer; |
| const mojo::internal::ContainerValidateParams handles_validate_params( |
| 0, false, nullptr); |
| mojo::internal::Serialize< |
| mojo::ArrayDataView<::mojo::native::SerializedHandleDataView>>( |
| input->handles, buffer, &handles_writer, &handles_validate_params, |
| context); |
| writer->data()->handles.Set(handles_writer.is_null() ? nullptr |
| : handles_writer.data()); |
| } |
| |
| // static |
| bool UnmappedNativeStructSerializerImpl::Deserialize( |
| native::internal::NativeStruct_Data* input, |
| native::NativeStructPtr* output, |
| SerializationContext* context) { |
| if (!input) { |
| output->reset(); |
| return true; |
| } |
| |
| native::NativeStructDataView data_view(input, context); |
| return StructTraits<::mojo::native::NativeStructDataView, |
| native::NativeStructPtr>::Read(data_view, output); |
| } |
| |
| // static |
| void UnmappedNativeStructSerializerImpl::SerializeMessageContents( |
| IPC::Message* message, |
| Buffer* buffer, |
| native::internal::NativeStruct_Data::BufferWriter* writer, |
| SerializationContext* context) { |
| writer->Allocate(buffer); |
| |
| // Allocate a uint8 array, initialize its header, and copy the Pickle in. |
| Array_Data<uint8_t>::BufferWriter data_writer; |
| data_writer.Allocate(message->payload_size(), buffer); |
| memcpy(data_writer->storage(), message->payload(), message->payload_size()); |
| writer->data()->data.Set(data_writer.data()); |
| |
| if (message->attachment_set()->empty()) { |
| writer->data()->handles.Set(nullptr); |
| return; |
| } |
| |
| mojo::internal::Array_Data<mojo::internal::Pointer< |
| native::internal::SerializedHandle_Data>>::BufferWriter handles_writer; |
| auto* attachments = message->attachment_set(); |
| handles_writer.Allocate(attachments->size(), buffer); |
| for (unsigned i = 0; i < attachments->size(); ++i) { |
| native::internal::SerializedHandle_Data::BufferWriter handle_writer; |
| handle_writer.Allocate(buffer); |
| |
| auto attachment = attachments->GetAttachmentAt(i); |
| ScopedHandle handle = attachment->TakeMojoHandle(); |
| internal::Serializer<ScopedHandle, ScopedHandle>::Serialize( |
| handle, &handle_writer->the_handle, context); |
| handle_writer->type = static_cast<int32_t>( |
| mojo::ConvertTo<native::SerializedHandle::Type>(attachment->GetType())); |
| handles_writer.data()->at(i).Set(handle_writer.data()); |
| } |
| writer->data()->handles.Set(handles_writer.data()); |
| } |
| |
| // static |
| bool UnmappedNativeStructSerializerImpl::DeserializeMessageAttachments( |
| native::internal::NativeStruct_Data* data, |
| SerializationContext* context, |
| IPC::Message* 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, context); |
| auto attachment = IPC::MessageAttachment::CreateFromMojoHandle( |
| std::move(handle), |
| mojo::ConvertTo<IPC::MessageAttachment::Type>( |
| static_cast<native::SerializedHandle::Type>(handle_data->type))); |
| message->attachment_set()->AddAttachment(std::move(attachment)); |
| } |
| return true; |
| } |
| |
| } // namespace internal |
| } // namespace mojo |