blob: 55c9982cccc803a7119a0f95e17c59a70b305595 [file] [log] [blame]
// Copyright 2016 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_SERIALIZATION_FORWARD_H_
#define MOJO_PUBLIC_CPP_BINDINGS_LIB_SERIALIZATION_FORWARD_H_
#include "base/optional.h"
#include "mojo/public/cpp/bindings/array_traits.h"
#include "mojo/public/cpp/bindings/enum_traits.h"
#include "mojo/public/cpp/bindings/lib/template_util.h"
#include "mojo/public/cpp/bindings/map_traits.h"
#include "mojo/public/cpp/bindings/string_traits.h"
#include "mojo/public/cpp/bindings/struct_traits.h"
#include "mojo/public/cpp/bindings/union_traits.h"
// This file is included by serialization implementation files to avoid circular
// includes.
// Users of the serialization funtions should include serialization.h (and also
// wtf_serialization.h if necessary).
namespace mojo {
namespace internal {
template <typename MojomType, typename MaybeConstUserType>
struct Serializer;
template <typename T>
struct IsOptionalWrapper {
static const bool value = IsSpecializationOf<
base::Optional,
typename std::remove_const<
typename std::remove_reference<T>::type>::type>::value;
};
// PrepareToSerialize() must be matched by a Serialize() for the same input
// later. Moreover, within the same SerializationContext if PrepareToSerialize()
// is called for |input_1|, ..., |input_n|, Serialize() must be called for
// those objects in the exact same order.
template <typename MojomType,
typename InputUserType,
typename... Args,
typename std::enable_if<
!IsOptionalWrapper<InputUserType>::value>::type* = nullptr>
size_t PrepareToSerialize(InputUserType&& input, Args&&... args) {
return Serializer<MojomType,
typename std::remove_reference<InputUserType>::type>::
PrepareToSerialize(std::forward<InputUserType>(input),
std::forward<Args>(args)...);
}
template <typename MojomType,
typename InputUserType,
typename... Args,
typename std::enable_if<
!IsOptionalWrapper<InputUserType>::value>::type* = nullptr>
void Serialize(InputUserType&& input, Args&&... args) {
Serializer<MojomType, typename std::remove_reference<InputUserType>::type>::
Serialize(std::forward<InputUserType>(input),
std::forward<Args>(args)...);
}
template <typename MojomType,
typename DataType,
typename InputUserType,
typename... Args,
typename std::enable_if<
!IsOptionalWrapper<InputUserType>::value>::type* = nullptr>
bool Deserialize(DataType&& input, InputUserType* output, Args&&... args) {
return Serializer<MojomType, InputUserType>::Deserialize(
std::forward<DataType>(input), output, std::forward<Args>(args)...);
}
// Specialization that unwraps base::Optional<>.
template <typename MojomType,
typename InputUserType,
typename... Args,
typename std::enable_if<
IsOptionalWrapper<InputUserType>::value>::type* = nullptr>
size_t PrepareToSerialize(InputUserType&& input, Args&&... args) {
if (!input)
return 0;
return PrepareToSerialize<MojomType>(*input, std::forward<Args>(args)...);
}
template <typename MojomType,
typename InputUserType,
typename DataType,
typename... Args,
typename std::enable_if<
IsOptionalWrapper<InputUserType>::value>::type* = nullptr>
void Serialize(InputUserType&& input,
Buffer* buffer,
DataType** output,
Args&&... args) {
if (!input) {
*output = nullptr;
return;
}
Serialize<MojomType>(*input, buffer, output, std::forward<Args>(args)...);
}
template <typename MojomType,
typename DataType,
typename InputUserType,
typename... Args,
typename std::enable_if<
IsOptionalWrapper<InputUserType>::value>::type* = nullptr>
bool Deserialize(DataType&& input, InputUserType* output, Args&&... args) {
if (!input) {
*output = base::nullopt;
return true;
}
if (!*output)
output->emplace();
return Deserialize<MojomType>(std::forward<DataType>(input), &output->value(),
std::forward<Args>(args)...);
}
} // namespace internal
} // namespace mojo
#endif // MOJO_PUBLIC_CPP_BINDINGS_LIB_SERIALIZATION_FORWARD_H_