1 // Copyright 2016 The Chromium 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 "mojo/public/cpp/bindings/lib/native_struct_serialization.h"
6
7 #include "ipc/ipc_message_attachment.h"
8 #include "ipc/ipc_message_attachment_set.h"
9 #include "ipc/native_handle_type_converters.h"
10 #include "mojo/public/cpp/bindings/lib/serialization.h"
11 #include "mojo/public/cpp/bindings/lib/serialization_forward.h"
12
13 namespace mojo {
14 namespace internal {
15
16 // static
Serialize(const native::NativeStructPtr & input,Buffer * buffer,native::internal::NativeStruct_Data::BufferWriter * writer,SerializationContext * context)17 void UnmappedNativeStructSerializerImpl::Serialize(
18 const native::NativeStructPtr& input,
19 Buffer* buffer,
20 native::internal::NativeStruct_Data::BufferWriter* writer,
21 SerializationContext* context) {
22 if (!input)
23 return;
24
25 writer->Allocate(buffer);
26
27 Array_Data<uint8_t>::BufferWriter data_writer;
28 const mojo::internal::ContainerValidateParams data_validate_params(0, false,
29 nullptr);
30 mojo::internal::Serialize<ArrayDataView<uint8_t>>(
31 input->data, buffer, &data_writer, &data_validate_params, context);
32 writer->data()->data.Set(data_writer.data());
33
34 mojo::internal::Array_Data<mojo::internal::Pointer<
35 native::internal::SerializedHandle_Data>>::BufferWriter handles_writer;
36 const mojo::internal::ContainerValidateParams handles_validate_params(
37 0, false, nullptr);
38 mojo::internal::Serialize<
39 mojo::ArrayDataView<::mojo::native::SerializedHandleDataView>>(
40 input->handles, buffer, &handles_writer, &handles_validate_params,
41 context);
42 writer->data()->handles.Set(handles_writer.is_null() ? nullptr
43 : handles_writer.data());
44 }
45
46 // static
Deserialize(native::internal::NativeStruct_Data * input,native::NativeStructPtr * output,SerializationContext * context)47 bool UnmappedNativeStructSerializerImpl::Deserialize(
48 native::internal::NativeStruct_Data* input,
49 native::NativeStructPtr* output,
50 SerializationContext* context) {
51 if (!input) {
52 output->reset();
53 return true;
54 }
55
56 native::NativeStructDataView data_view(input, context);
57 return StructTraits<::mojo::native::NativeStructDataView,
58 native::NativeStructPtr>::Read(data_view, output);
59 }
60
61 // static
SerializeMessageContents(IPC::Message * message,Buffer * buffer,native::internal::NativeStruct_Data::BufferWriter * writer,SerializationContext * context)62 void UnmappedNativeStructSerializerImpl::SerializeMessageContents(
63 IPC::Message* message,
64 Buffer* buffer,
65 native::internal::NativeStruct_Data::BufferWriter* writer,
66 SerializationContext* context) {
67 writer->Allocate(buffer);
68
69 // Allocate a uint8 array, initialize its header, and copy the Pickle in.
70 Array_Data<uint8_t>::BufferWriter data_writer;
71 data_writer.Allocate(message->payload_size(), buffer);
72 memcpy(data_writer->storage(), message->payload(), message->payload_size());
73 writer->data()->data.Set(data_writer.data());
74
75 if (message->attachment_set()->empty()) {
76 writer->data()->handles.Set(nullptr);
77 return;
78 }
79
80 mojo::internal::Array_Data<mojo::internal::Pointer<
81 native::internal::SerializedHandle_Data>>::BufferWriter handles_writer;
82 auto* attachments = message->attachment_set();
83 handles_writer.Allocate(attachments->size(), buffer);
84 for (unsigned i = 0; i < attachments->size(); ++i) {
85 native::internal::SerializedHandle_Data::BufferWriter handle_writer;
86 handle_writer.Allocate(buffer);
87
88 auto attachment = attachments->GetAttachmentAt(i);
89 ScopedHandle handle = attachment->TakeMojoHandle();
90 internal::Serializer<ScopedHandle, ScopedHandle>::Serialize(
91 handle, &handle_writer->the_handle, context);
92 handle_writer->type = static_cast<int32_t>(
93 mojo::ConvertTo<native::SerializedHandle::Type>(attachment->GetType()));
94 handles_writer.data()->at(i).Set(handle_writer.data());
95 }
96 writer->data()->handles.Set(handles_writer.data());
97 }
98
99 // static
DeserializeMessageAttachments(native::internal::NativeStruct_Data * data,SerializationContext * context,IPC::Message * message)100 bool UnmappedNativeStructSerializerImpl::DeserializeMessageAttachments(
101 native::internal::NativeStruct_Data* data,
102 SerializationContext* context,
103 IPC::Message* message) {
104 if (data->handles.is_null())
105 return true;
106
107 auto* handles_data = data->handles.Get();
108 for (size_t i = 0; i < handles_data->size(); ++i) {
109 auto* handle_data = handles_data->at(i).Get();
110 if (!handle_data)
111 return false;
112 ScopedHandle handle;
113 internal::Serializer<ScopedHandle, ScopedHandle>::Deserialize(
114 &handle_data->the_handle, &handle, context);
115 auto attachment = IPC::MessageAttachment::CreateFromMojoHandle(
116 std::move(handle),
117 mojo::ConvertTo<IPC::MessageAttachment::Type>(
118 static_cast<native::SerializedHandle::Type>(handle_data->type)));
119 message->attachment_set()->AddAttachment(std::move(attachment));
120 }
121 return true;
122 }
123
124 } // namespace internal
125 } // namespace mojo
126