• 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 #ifndef MOJO_PUBLIC_CPP_BINDINGS_LIB_HANDLE_INTERFACE_SERIALIZATION_H_
6 #define MOJO_PUBLIC_CPP_BINDINGS_LIB_HANDLE_INTERFACE_SERIALIZATION_H_
7 
8 #include <type_traits>
9 
10 #include "mojo/public/cpp/bindings/associated_group_controller.h"
11 #include "mojo/public/cpp/bindings/associated_interface_ptr_info.h"
12 #include "mojo/public/cpp/bindings/associated_interface_request.h"
13 #include "mojo/public/cpp/bindings/interface_data_view.h"
14 #include "mojo/public/cpp/bindings/interface_ptr.h"
15 #include "mojo/public/cpp/bindings/interface_request.h"
16 #include "mojo/public/cpp/bindings/lib/bindings_internal.h"
17 #include "mojo/public/cpp/bindings/lib/serialization_context.h"
18 #include "mojo/public/cpp/bindings/lib/serialization_forward.h"
19 #include "mojo/public/cpp/system/handle.h"
20 
21 namespace mojo {
22 namespace internal {
23 
24 template <typename Base, typename T>
25 struct Serializer<AssociatedInterfacePtrInfoDataView<Base>,
26                   AssociatedInterfacePtrInfo<T>> {
27   static_assert(std::is_base_of<Base, T>::value, "Interface type mismatch.");
28 
29   static size_t PrepareToSerialize(const AssociatedInterfacePtrInfo<T>& input,
30                                    SerializationContext* context) {
31     if (input.handle().is_valid())
32       context->associated_endpoint_count++;
33     return 0;
34   }
35 
36   static void Serialize(AssociatedInterfacePtrInfo<T>& input,
37                         AssociatedInterface_Data* output,
38                         SerializationContext* context) {
39     DCHECK(!input.handle().is_valid() || input.handle().pending_association());
40     if (input.handle().is_valid()) {
41       // Set to the index of the element pushed to the back of the vector.
42       output->handle.value =
43           static_cast<uint32_t>(context->associated_endpoint_handles.size());
44       context->associated_endpoint_handles.push_back(input.PassHandle());
45     } else {
46       output->handle.value = kEncodedInvalidHandleValue;
47     }
48     output->version = input.version();
49   }
50 
51   static bool Deserialize(AssociatedInterface_Data* input,
52                           AssociatedInterfacePtrInfo<T>* output,
53                           SerializationContext* context) {
54     if (input->handle.is_valid()) {
55       DCHECK_LT(input->handle.value,
56                 context->associated_endpoint_handles.size());
57       output->set_handle(
58           std::move(context->associated_endpoint_handles[input->handle.value]));
59     } else {
60       output->set_handle(ScopedInterfaceEndpointHandle());
61     }
62     output->set_version(input->version);
63     return true;
64   }
65 };
66 
67 template <typename Base, typename T>
68 struct Serializer<AssociatedInterfaceRequestDataView<Base>,
69                   AssociatedInterfaceRequest<T>> {
70   static_assert(std::is_base_of<Base, T>::value, "Interface type mismatch.");
71 
72   static size_t PrepareToSerialize(const AssociatedInterfaceRequest<T>& input,
73                                    SerializationContext* context) {
74     if (input.handle().is_valid())
75       context->associated_endpoint_count++;
76     return 0;
77   }
78 
79   static void Serialize(AssociatedInterfaceRequest<T>& input,
80                         AssociatedEndpointHandle_Data* output,
81                         SerializationContext* context) {
82     DCHECK(!input.handle().is_valid() || input.handle().pending_association());
83     if (input.handle().is_valid()) {
84       // Set to the index of the element pushed to the back of the vector.
85       output->value =
86           static_cast<uint32_t>(context->associated_endpoint_handles.size());
87       context->associated_endpoint_handles.push_back(input.PassHandle());
88     } else {
89       output->value = kEncodedInvalidHandleValue;
90     }
91   }
92 
93   static bool Deserialize(AssociatedEndpointHandle_Data* input,
94                           AssociatedInterfaceRequest<T>* output,
95                           SerializationContext* context) {
96     if (input->is_valid()) {
97       DCHECK_LT(input->value, context->associated_endpoint_handles.size());
98       output->Bind(
99           std::move(context->associated_endpoint_handles[input->value]));
100     } else {
101       output->Bind(ScopedInterfaceEndpointHandle());
102     }
103     return true;
104   }
105 };
106 
107 template <typename Base, typename T>
108 struct Serializer<InterfacePtrDataView<Base>, InterfacePtr<T>> {
109   static_assert(std::is_base_of<Base, T>::value, "Interface type mismatch.");
110 
111   static size_t PrepareToSerialize(const InterfacePtr<T>& input,
112                                    SerializationContext* context) {
113     return 0;
114   }
115 
116   static void Serialize(InterfacePtr<T>& input,
117                         Interface_Data* output,
118                         SerializationContext* context) {
119     InterfacePtrInfo<T> info = input.PassInterface();
120     output->handle = context->handles.AddHandle(info.PassHandle().release());
121     output->version = info.version();
122   }
123 
124   static bool Deserialize(Interface_Data* input,
125                           InterfacePtr<T>* output,
126                           SerializationContext* context) {
127     output->Bind(InterfacePtrInfo<T>(
128         context->handles.TakeHandleAs<mojo::MessagePipeHandle>(input->handle),
129         input->version));
130     return true;
131   }
132 };
133 
134 template <typename Base, typename T>
135 struct Serializer<InterfaceRequestDataView<Base>, InterfaceRequest<T>> {
136   static_assert(std::is_base_of<Base, T>::value, "Interface type mismatch.");
137 
138   static size_t PrepareToSerialize(const InterfaceRequest<T>& input,
139                                    SerializationContext* context) {
140     return 0;
141   }
142 
143   static void Serialize(InterfaceRequest<T>& input,
144                         Handle_Data* output,
145                         SerializationContext* context) {
146     *output = context->handles.AddHandle(input.PassMessagePipe().release());
147   }
148 
149   static bool Deserialize(Handle_Data* input,
150                           InterfaceRequest<T>* output,
151                           SerializationContext* context) {
152     output->Bind(context->handles.TakeHandleAs<MessagePipeHandle>(*input));
153     return true;
154   }
155 };
156 
157 template <typename T>
158 struct Serializer<ScopedHandleBase<T>, ScopedHandleBase<T>> {
159   static size_t PrepareToSerialize(const ScopedHandleBase<T>& input,
160                                    SerializationContext* context) {
161     return 0;
162   }
163 
164   static void Serialize(ScopedHandleBase<T>& input,
165                         Handle_Data* output,
166                         SerializationContext* context) {
167     *output = context->handles.AddHandle(input.release());
168   }
169 
170   static bool Deserialize(Handle_Data* input,
171                           ScopedHandleBase<T>* output,
172                           SerializationContext* context) {
173     *output = context->handles.TakeHandleAs<T>(*input);
174     return true;
175   }
176 };
177 
178 }  // namespace internal
179 }  // namespace mojo
180 
181 #endif  // MOJO_PUBLIC_CPP_BINDINGS_LIB_HANDLE_INTERFACE_SERIALIZATION_H_
182