diff options
author | Hidehiko Abe <hidehiko@google.com> | 2018-04-23 20:01:13 -0700 |
---|---|---|
committer | android-build-merger <android-build-merger@google.com> | 2018-04-23 20:01:13 -0700 |
commit | ed7128dca79cff94e99465e3c1bc31d91d83c76d (patch) | |
tree | bd2d04362f66c36d4279f7a9735ba21ea3a2a021 /mojo/public/cpp/bindings/lib/native_struct_serialization.h | |
parent | d6187ab7d79d95d101c2ecb83aa98c05bcdcccd1 (diff) | |
parent | 0ab20ac2283987e63b0e7c1318db2a5cf7c668d2 (diff) | |
download | libchrome-ed7128dca79cff94e99465e3c1bc31d91d83c76d.tar.gz |
Migrate libmojo repository into libchrome, part 2. am: b268b43ac6
am: 0ab20ac228
Change-Id: I1b1afe0c902f1d122b100f5bf56d1df4a94eb090
Diffstat (limited to 'mojo/public/cpp/bindings/lib/native_struct_serialization.h')
-rw-r--r-- | mojo/public/cpp/bindings/lib/native_struct_serialization.h | 134 |
1 files changed, 134 insertions, 0 deletions
diff --git a/mojo/public/cpp/bindings/lib/native_struct_serialization.h b/mojo/public/cpp/bindings/lib/native_struct_serialization.h new file mode 100644 index 0000000000..457435b955 --- /dev/null +++ b/mojo/public/cpp/bindings/lib/native_struct_serialization.h @@ -0,0 +1,134 @@ +// Copyright 2015 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifndef MOJO_PUBLIC_CPP_BINDINGS_LIB_NATIVE_STRUCT_SERIALIZATION_H_ +#define MOJO_PUBLIC_CPP_BINDINGS_LIB_NATIVE_STRUCT_SERIALIZATION_H_ + +#include <stddef.h> +#include <stdint.h> + +#include <limits> + +#include "base/logging.h" +#include "base/pickle.h" +#include "ipc/ipc_param_traits.h" +#include "mojo/public/cpp/bindings/bindings_export.h" +#include "mojo/public/cpp/bindings/lib/array_internal.h" +#include "mojo/public/cpp/bindings/lib/bindings_internal.h" +#include "mojo/public/cpp/bindings/lib/native_struct_data.h" +#include "mojo/public/cpp/bindings/lib/serialization_forward.h" +#include "mojo/public/cpp/bindings/lib/serialization_util.h" +#include "mojo/public/cpp/bindings/native_struct.h" +#include "mojo/public/cpp/bindings/native_struct_data_view.h" + +namespace mojo { +namespace internal { + +template <typename MaybeConstUserType> +struct NativeStructSerializerImpl { + using UserType = typename std::remove_const<MaybeConstUserType>::type; + using Traits = IPC::ParamTraits<UserType>; + + static size_t PrepareToSerialize(MaybeConstUserType& value, + SerializationContext* context) { + base::PickleSizer sizer; + Traits::GetSize(&sizer, value); + return Align(sizer.payload_size() + sizeof(ArrayHeader)); + } + + static void Serialize(MaybeConstUserType& value, + Buffer* buffer, + NativeStruct_Data** out, + SerializationContext* context) { + base::Pickle pickle; + Traits::Write(&pickle, value); + +#if DCHECK_IS_ON() + base::PickleSizer sizer; + Traits::GetSize(&sizer, value); + DCHECK_EQ(sizer.payload_size(), pickle.payload_size()); +#endif + + size_t total_size = pickle.payload_size() + sizeof(ArrayHeader); + DCHECK_LT(total_size, std::numeric_limits<uint32_t>::max()); + + // Allocate a uint8 array, initialize its header, and copy the Pickle in. + ArrayHeader* header = + reinterpret_cast<ArrayHeader*>(buffer->Allocate(total_size)); + header->num_bytes = static_cast<uint32_t>(total_size); + header->num_elements = static_cast<uint32_t>(pickle.payload_size()); + memcpy(reinterpret_cast<char*>(header) + sizeof(ArrayHeader), + pickle.payload(), pickle.payload_size()); + + *out = reinterpret_cast<NativeStruct_Data*>(header); + } + + static bool Deserialize(NativeStruct_Data* data, + UserType* out, + SerializationContext* context) { + if (!data) + return false; + + // Construct a temporary base::Pickle view over the array data. Note that + // the Array_Data is laid out like this: + // + // [num_bytes (4 bytes)] [num_elements (4 bytes)] [elements...] + // + // and base::Pickle expects to view data like this: + // + // [payload_size (4 bytes)] [header bytes ...] [payload...] + // + // Because ArrayHeader's num_bytes includes the length of the header and + // Pickle's payload_size does not, we need to adjust the stored value + // momentarily so Pickle can view the data. + ArrayHeader* header = reinterpret_cast<ArrayHeader*>(data); + DCHECK_GE(header->num_bytes, sizeof(ArrayHeader)); + header->num_bytes -= sizeof(ArrayHeader); + + { + // Construct a view over the full Array_Data, including our hacked up + // header. Pickle will infer from this that the header is 8 bytes long, + // and the payload will contain all of the pickled bytes. + base::Pickle pickle_view(reinterpret_cast<const char*>(header), + header->num_bytes + sizeof(ArrayHeader)); + base::PickleIterator iter(pickle_view); + if (!Traits::Read(&pickle_view, &iter, out)) + return false; + } + + // Return the header to its original state. + header->num_bytes += sizeof(ArrayHeader); + + return true; + } +}; + +struct MOJO_CPP_BINDINGS_EXPORT UnmappedNativeStructSerializerImpl { + static size_t PrepareToSerialize(const NativeStructPtr& input, + SerializationContext* context); + static void Serialize(const NativeStructPtr& input, + Buffer* buffer, + NativeStruct_Data** output, + SerializationContext* context); + static bool Deserialize(NativeStruct_Data* input, + NativeStructPtr* output, + SerializationContext* context); +}; + +template <> +struct NativeStructSerializerImpl<NativeStructPtr> + : public UnmappedNativeStructSerializerImpl {}; + +template <> +struct NativeStructSerializerImpl<const NativeStructPtr> + : public UnmappedNativeStructSerializerImpl {}; + +template <typename MaybeConstUserType> +struct Serializer<NativeStructDataView, MaybeConstUserType> + : public NativeStructSerializerImpl<MaybeConstUserType> {}; + +} // namespace internal +} // namespace mojo + +#endif // MOJO_PUBLIC_CPP_BINDINGS_LIB_NATIVE_STRUCT_SERIALIZATION_H_ |