• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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