Home | History | Annotate | Download | only in lib
      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