#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 "base/check_op.h"
#include "base/component_export.h"
#include "base/pickle.h"
#include "ipc/ipc_message.h"
#include "ipc/param_traits.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/message_fragment.h"
#include "mojo/public/cpp/bindings/lib/serialization_forward.h"
#include "mojo/public/cpp/bindings/lib/serialization_util.h"
#include "mojo/public/interfaces/bindings/native_struct.mojom.h"
namespace mojo {
namespace internal {
struct COMPONENT_EXPORT(MOJO_CPP_BINDINGS) UnmappedNativeStructSerializerImpl {
static void Serialize(
const native::NativeStructPtr& input,
MessageFragment<native::internal::NativeStruct_Data>& fragment);
static bool Deserialize(native::internal::NativeStruct_Data* input,
native::NativeStructPtr* output,
Message* message);
static void SerializeMessageContents(
IPC::Message* ipc_message,
MessageFragment<native::internal::NativeStruct_Data>& fragment);
static bool DeserializeMessageAttachments(
native::internal::NativeStruct_Data* data,
Message* message,
IPC::Message* ipc_message);
};
template <typename MaybeConstUserType>
struct NativeStructSerializerImpl {
using UserType = typename std::remove_const<MaybeConstUserType>::type;
using Traits = IPC::ParamTraits<UserType>;
static void Serialize(
MaybeConstUserType& value,
MessageFragment<native::internal::NativeStruct_Data>& fragment) {
IPC::Message ipc_message;
Traits::Write(&ipc_message, value);
UnmappedNativeStructSerializerImpl::SerializeMessageContents(&ipc_message,
fragment);
}
static bool Deserialize(native::internal::NativeStruct_Data* data,
UserType* out,
Message* message) {
if (!data)
return false;
ArrayHeader* header = reinterpret_cast<ArrayHeader*>(data->data.Get());
DCHECK_GE(header->num_bytes, sizeof(ArrayHeader));
header->num_bytes -= sizeof(ArrayHeader);
{
IPC::Message message_view(reinterpret_cast<const char*>(header),
header->num_bytes + sizeof(ArrayHeader));
base::PickleIterator iter(message_view);
if (!UnmappedNativeStructSerializerImpl::DeserializeMessageAttachments(
data, message, &message_view)) {
return false;
}
if (!Traits::Read(&message_view, &iter, out))
return false;
}
header->num_bytes += sizeof(ArrayHeader);
return true;
}
};
template <>
struct NativeStructSerializerImpl<native::NativeStructPtr>
: public UnmappedNativeStructSerializerImpl {};
template <>
struct NativeStructSerializerImpl<const native::NativeStructPtr>
: public UnmappedNativeStructSerializerImpl {};
template <typename MaybeConstUserType>
struct Serializer<native::NativeStructDataView, MaybeConstUserType>
: public NativeStructSerializerImpl<MaybeConstUserType> {};
}
}
#endif