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_SERIALIZATION_H_ 6 #define MOJO_PUBLIC_CPP_BINDINGS_LIB_SERIALIZATION_H_ 7 8 #include <string.h> 9 10 #include "mojo/public/cpp/bindings/array_traits_carray.h" 11 #include "mojo/public/cpp/bindings/array_traits_standard.h" 12 #include "mojo/public/cpp/bindings/array_traits_stl.h" 13 #include "mojo/public/cpp/bindings/lib/array_serialization.h" 14 #include "mojo/public/cpp/bindings/lib/fixed_buffer.h" 15 #include "mojo/public/cpp/bindings/lib/handle_interface_serialization.h" 16 #include "mojo/public/cpp/bindings/lib/map_serialization.h" 17 #include "mojo/public/cpp/bindings/lib/native_enum_serialization.h" 18 #include "mojo/public/cpp/bindings/lib/native_struct_serialization.h" 19 #include "mojo/public/cpp/bindings/lib/string_serialization.h" 20 #include "mojo/public/cpp/bindings/lib/template_util.h" 21 #include "mojo/public/cpp/bindings/map_traits_standard.h" 22 #include "mojo/public/cpp/bindings/map_traits_stl.h" 23 #include "mojo/public/cpp/bindings/string_traits_standard.h" 24 #include "mojo/public/cpp/bindings/string_traits_stl.h" 25 #include "mojo/public/cpp/bindings/string_traits_string16.h" 26 #include "mojo/public/cpp/bindings/string_traits_string_piece.h" 27 28 namespace mojo { 29 namespace internal { 30 31 template <typename MojomType, typename DataArrayType, typename UserType> 32 DataArrayType StructSerializeImpl(UserType* input) { 33 static_assert(BelongsTo<MojomType, MojomTypeCategory::STRUCT>::value, 34 "Unexpected type."); 35 36 SerializationContext context; 37 size_t size = PrepareToSerialize<MojomType>(*input, &context); 38 DCHECK_EQ(size, Align(size)); 39 40 DataArrayType result(size); 41 if (size == 0) 42 return result; 43 44 void* result_buffer = &result.front(); 45 // The serialization logic requires that the buffer is 8-byte aligned. If the 46 // result buffer is not properly aligned, we have to do an extra copy. In 47 // practice, this should never happen for mojo::Array (backed by std::vector). 48 bool need_copy = !IsAligned(result_buffer); 49 50 if (need_copy) { 51 // calloc sets the memory to all zero. 52 result_buffer = calloc(size, 1); 53 DCHECK(IsAligned(result_buffer)); 54 } 55 56 FixedBuffer buffer; 57 buffer.Initialize(result_buffer, size); 58 typename MojomType::Struct::Data_* data = nullptr; 59 Serialize<MojomType>(*input, &buffer, &data, &context); 60 61 if (need_copy) { 62 memcpy(&result.front(), result_buffer, size); 63 free(result_buffer); 64 } 65 66 return result; 67 } 68 69 template <typename MojomType, typename DataArrayType, typename UserType> 70 bool StructDeserializeImpl(const DataArrayType& input, UserType* output) { 71 static_assert(BelongsTo<MojomType, MojomTypeCategory::STRUCT>::value, 72 "Unexpected type."); 73 using DataType = typename MojomType::Struct::Data_; 74 75 if (input.is_null()) 76 return false; 77 78 void* input_buffer = 79 input.empty() 80 ? nullptr 81 : const_cast<void*>(reinterpret_cast<const void*>(&input.front())); 82 83 // Please see comments in StructSerializeImpl. 84 bool need_copy = !IsAligned(input_buffer); 85 86 if (need_copy) { 87 input_buffer = malloc(input.size()); 88 DCHECK(IsAligned(input_buffer)); 89 memcpy(input_buffer, &input.front(), input.size()); 90 } 91 92 ValidationContext validation_context(input_buffer, input.size(), 0); 93 bool result = false; 94 if (DataType::Validate(input_buffer, &validation_context)) { 95 auto data = reinterpret_cast<DataType*>(input_buffer); 96 SerializationContext context; 97 result = Deserialize<MojomType>(data, output, &context); 98 } 99 100 if (need_copy) 101 free(input_buffer); 102 103 return result; 104 } 105 106 } // namespace internal 107 } // namespace mojo 108 109 #endif // MOJO_PUBLIC_CPP_BINDINGS_LIB_SERIALIZATION_H_ 110