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