summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--mojo/mojo_public.gyp3
-rw-r--r--mojo/public/cpp/bindings/BUILD.gn3
-rw-r--r--mojo/public/cpp/bindings/array.h27
-rw-r--r--mojo/public/cpp/bindings/lib/array_internal.h33
-rw-r--r--mojo/public/cpp/bindings/lib/array_serialization.h445
-rw-r--r--mojo/public/cpp/bindings/lib/array_serialization_traits.h428
-rw-r--r--mojo/public/cpp/bindings/lib/bindings_internal.h16
-rw-r--r--mojo/public/cpp/bindings/lib/map_serialization.h13
-rw-r--r--mojo/public/cpp/bindings/lib/serialization.h13
-rw-r--r--mojo/public/cpp/bindings/lib/serialization_forward.h103
-rw-r--r--mojo/public/cpp/bindings/tests/array_unittest.cc2
-rw-r--r--mojo/public/cpp/bindings/tests/map_unittest.cc2
-rw-r--r--mojo/public/cpp/bindings/tests/serialization_warning_unittest.cc2
-rw-r--r--mojo/public/cpp/bindings/tests/union_unittest.cc2
-rw-r--r--mojo/public/interfaces/bindings/tests/test_sync_methods.mojom2
-rw-r--r--mojo/public/tools/bindings/generators/cpp_templates/interface_macros.tmpl9
-rw-r--r--mojo/public/tools/bindings/generators/cpp_templates/module-internal.h.tmpl2
-rw-r--r--mojo/public/tools/bindings/generators/cpp_templates/module.cc.tmpl4
-rw-r--r--mojo/public/tools/bindings/generators/cpp_templates/module.h.tmpl2
19 files changed, 614 insertions, 497 deletions
diff --git a/mojo/mojo_public.gyp b/mojo/mojo_public.gyp
index 10a0dae..6490657 100644
--- a/mojo/mojo_public.gyp
+++ b/mojo/mojo_public.gyp
@@ -112,6 +112,7 @@
'public/cpp/bindings/lib/array_internal.cc',
'public/cpp/bindings/lib/array_internal.h',
'public/cpp/bindings/lib/array_serialization.h',
+ 'public/cpp/bindings/lib/array_serialization_traits.h',
'public/cpp/bindings/lib/associated_group.cc',
'public/cpp/bindings/lib/associated_interface_ptr_state.h',
'public/cpp/bindings/lib/binding_state.h',
@@ -160,6 +161,8 @@
'public/cpp/bindings/lib/router.h',
'public/cpp/bindings/lib/scoped_interface_endpoint_handle.cc',
'public/cpp/bindings/lib/scoped_interface_endpoint_handle.h',
+ 'public/cpp/bindings/lib/serialization_forward.h',
+ 'public/cpp/bindings/lib/serialization.h',
'public/cpp/bindings/lib/shared_data.h',
'public/cpp/bindings/lib/shared_ptr.h',
'public/cpp/bindings/lib/string_serialization.cc',
diff --git a/mojo/public/cpp/bindings/BUILD.gn b/mojo/public/cpp/bindings/BUILD.gn
index 6b7a015..56b11bf 100644
--- a/mojo/public/cpp/bindings/BUILD.gn
+++ b/mojo/public/cpp/bindings/BUILD.gn
@@ -19,6 +19,7 @@ source_set("bindings") {
"lib/array_internal.cc",
"lib/array_internal.h",
"lib/array_serialization.h",
+ "lib/array_serialization_traits.h",
"lib/associated_group.cc",
"lib/associated_interface_ptr_state.h",
"lib/binding_state.h",
@@ -66,6 +67,8 @@ source_set("bindings") {
"lib/router.h",
"lib/scoped_interface_endpoint_handle.cc",
"lib/scoped_interface_endpoint_handle.h",
+ "lib/serialization.h",
+ "lib/serialization_forward.h",
"lib/string_serialization.cc",
"lib/string_serialization.h",
"lib/sync_handle_watcher.cc",
diff --git a/mojo/public/cpp/bindings/array.h b/mojo/public/cpp/bindings/array.h
index 47973fe..a18d6ca 100644
--- a/mojo/public/cpp/bindings/array.h
+++ b/mojo/public/cpp/bindings/array.h
@@ -27,9 +27,9 @@ template <typename T>
class Array {
MOJO_MOVE_ONLY_TYPE(Array)
public:
- using Traits = internal::ArrayTraits<T, internal::IsMoveOnlyType<T>::value>;
using ConstRefType = typename std::vector<T>::const_reference;
using RefType = typename std::vector<T>::reference;
+ using ElementType = T;
using Data_ =
internal::Array_Data<typename internal::WrapperTraits<T>::DataType>;
@@ -168,7 +168,7 @@ class Array {
Array Clone() const {
Array result;
result.is_null_ = is_null_;
- Traits::Clone(vec_, &result.vec_);
+ CloneTraits<T>::Clone(vec_, &result.vec_);
return std::move(result);
}
@@ -202,6 +202,29 @@ class Array {
template <typename U>
bool operator!=(const Array<U>& other) const = delete;
+ template <typename U,
+ bool is_move_only_type = internal::IsMoveOnlyType<U>::value>
+ struct CloneTraits {};
+
+ template <typename U>
+ struct CloneTraits<U, false> {
+ static inline void Clone(const std::vector<T>& src_vec,
+ std::vector<T>* dest_vec) {
+ dest_vec->assign(src_vec.begin(), src_vec.end());
+ }
+ };
+
+ template <typename U>
+ struct CloneTraits<U, true> {
+ static inline void Clone(const std::vector<T>& src_vec,
+ std::vector<T>* dest_vec) {
+ dest_vec->clear();
+ dest_vec->reserve(src_vec.size());
+ for (const auto& element : src_vec)
+ dest_vec->push_back(element.Clone());
+ }
+ };
+
void Take(Array* other) {
operator=(nullptr);
Swap(other);
diff --git a/mojo/public/cpp/bindings/lib/array_internal.h b/mojo/public/cpp/bindings/lib/array_internal.h
index 7070122..50a4b0d 100644
--- a/mojo/public/cpp/bindings/lib/array_internal.h
+++ b/mojo/public/cpp/bindings/lib/array_internal.h
@@ -23,10 +23,6 @@
#include "mojo/public/cpp/bindings/lib/validation_errors.h"
namespace mojo {
-template <typename T>
-class Array;
-class String;
-
namespace internal {
// std::numeric_limits<uint32_t>::max() is not a compile-time constant (until
@@ -462,34 +458,7 @@ class Array_Data {
static_assert(sizeof(Array_Data<char>) == 8, "Bad sizeof(Array_Data)");
// UTF-8 encoded
-typedef Array_Data<char> String_Data;
-
-template <typename T, bool kIsMoveOnlyType>
-struct ArrayTraits {};
-
-template <typename T>
-struct ArrayTraits<T, false> {
- static inline void Clone(const std::vector<T>& src_vec,
- std::vector<T>* dest_vec) {
- dest_vec->assign(src_vec.begin(), src_vec.end());
- }
-};
-
-template <typename T>
-struct ArrayTraits<T, true> {
- static inline void Clone(const std::vector<T>& src_vec,
- std::vector<T>* dest_vec) {
- dest_vec->clear();
- dest_vec->reserve(src_vec.size());
- for (const auto& element : src_vec)
- dest_vec->push_back(element.Clone());
- }
-};
-
-template <>
-struct WrapperTraits<String, false> {
- typedef String_Data* DataType;
-};
+using String_Data = Array_Data<char>;
} // namespace internal
} // namespace mojo
diff --git a/mojo/public/cpp/bindings/lib/array_serialization.h b/mojo/public/cpp/bindings/lib/array_serialization.h
index a0e0a76..bfcc7df 100644
--- a/mojo/public/cpp/bindings/lib/array_serialization.h
+++ b/mojo/public/cpp/bindings/lib/array_serialization.h
@@ -6,429 +6,15 @@
#define MOJO_PUBLIC_CPP_BINDINGS_LIB_ARRAY_SERIALIZATION_H_
#include <stddef.h>
-#include <string.h> // For |memcpy()|.
-#include <limits>
-#include <type_traits>
-#include <utility>
-#include <vector>
-
-#include "base/logging.h"
-#include "mojo/public/c/system/macros.h"
-#include "mojo/public/cpp/bindings/lib/array_internal.h"
-#include "mojo/public/cpp/bindings/lib/map_serialization.h"
-#include "mojo/public/cpp/bindings/lib/native_serialization.h"
-#include "mojo/public/cpp/bindings/lib/string_serialization.h"
-#include "mojo/public/cpp/bindings/lib/template_util.h"
-#include "mojo/public/cpp/bindings/lib/validation_errors.h"
+#include "mojo/public/cpp/bindings/array.h"
+#include "mojo/public/cpp/bindings/lib/array_serialization_traits.h"
namespace mojo {
template <typename E>
-inline size_t GetSerializedSize_(const Array<E>& input);
-
-template <typename E, typename F>
-inline void SerializeArray_(
- Array<E> input,
- internal::Buffer* buf,
- internal::Array_Data<F>** output,
- const internal::ArrayValidateParams* validate_params);
-
-template <typename E, typename F>
-inline bool Deserialize_(internal::Array_Data<F>* input,
- Array<E>* output,
- internal::SerializationContext* context);
-
-namespace internal {
-
-template <typename E,
- typename F,
- bool is_union =
- IsUnionDataType<typename RemovePointer<F>::type>::value>
-struct ArraySerializer;
-
-// Handles serialization and deserialization of arrays of pod types.
-template <typename E, typename F>
-struct ArraySerializer<E, F, false> {
- static_assert(sizeof(E) == sizeof(F), "Incorrect array serializer");
- static size_t GetSerializedSize(const Array<E>& input) {
- return sizeof(Array_Data<F>) + Align(input.size() * sizeof(E));
- }
-
- static void SerializeElements(Array<E> input,
- Buffer* buf,
- Array_Data<F>* output,
- const ArrayValidateParams* validate_params) {
- DCHECK(!validate_params->element_is_nullable)
- << "Primitive type should be non-nullable";
- DCHECK(!validate_params->element_validate_params)
- << "Primitive type should not have array validate params";
-
- if (input.size())
- memcpy(output->storage(), &input.storage()[0], input.size() * sizeof(E));
- }
- static bool DeserializeElements(Array_Data<F>* input,
- Array<E>* output,
- SerializationContext* context) {
- std::vector<E> result(input->size());
- if (input->size())
- memcpy(&result[0], input->storage(), input->size() * sizeof(E));
- output->Swap(&result);
- return true;
- }
-};
-
-// Serializes and deserializes arrays of bools.
-template <>
-struct ArraySerializer<bool, bool, false> {
- static size_t GetSerializedSize(const Array<bool>& input) {
- return sizeof(Array_Data<bool>) + Align((input.size() + 7) / 8);
- }
-
- static void SerializeElements(Array<bool> input,
- Buffer* buf,
- Array_Data<bool>* output,
- const ArrayValidateParams* validate_params) {
- DCHECK(!validate_params->element_is_nullable)
- << "Primitive type should be non-nullable";
- DCHECK(!validate_params->element_validate_params)
- << "Primitive type should not have array validate params";
-
- // TODO(darin): Can this be a memcpy somehow instead of a bit-by-bit copy?
- for (size_t i = 0; i < input.size(); ++i)
- output->at(i) = input[i];
- }
- static bool DeserializeElements(Array_Data<bool>* input,
- Array<bool>* output,
- SerializationContext* context) {
- Array<bool> result(input->size());
- // TODO(darin): Can this be a memcpy somehow instead of a bit-by-bit copy?
- for (size_t i = 0; i < input->size(); ++i)
- result.at(i) = input->at(i);
- output->Swap(&result);
- return true;
- }
-};
-
-// Serializes and deserializes arrays of handles.
-template <typename H>
-struct ArraySerializer<ScopedHandleBase<H>, H, false> {
- static size_t GetSerializedSize(const Array<ScopedHandleBase<H>>& input) {
- return sizeof(Array_Data<H>) + Align(input.size() * sizeof(H));
- }
-
- static void SerializeElements(Array<ScopedHandleBase<H>> input,
- Buffer* buf,
- Array_Data<H>* output,
- const ArrayValidateParams* validate_params) {
- DCHECK(!validate_params->element_validate_params)
- << "Handle type should not have array validate params";
-
- for (size_t i = 0; i < input.size(); ++i) {
- output->at(i) = input[i].release(); // Transfer ownership of the handle.
- MOJO_INTERNAL_DLOG_SERIALIZATION_WARNING(
- !validate_params->element_is_nullable && !output->at(i).is_valid(),
- VALIDATION_ERROR_UNEXPECTED_INVALID_HANDLE,
- MakeMessageWithArrayIndex(
- "invalid handle in array expecting valid handles", input.size(),
- i));
- }
- }
- static bool DeserializeElements(Array_Data<H>* input,
- Array<ScopedHandleBase<H>>* output,
- SerializationContext* context) {
- Array<ScopedHandleBase<H>> result(input->size());
- for (size_t i = 0; i < input->size(); ++i)
- result.at(i) = MakeScopedHandle(FetchAndReset(&input->at(i)));
- output->Swap(&result);
- return true;
- }
-};
-
-// This template must only apply to pointer mojo entity (structs and arrays).
-// This is done by ensuring that WrapperTraits<S>::DataType is a pointer.
-template <typename S>
-struct ArraySerializer<
- S,
- typename EnableIf<IsPointer<typename WrapperTraits<S>::DataType>::value,
- typename WrapperTraits<S>::DataType>::type,
- false> {
- typedef
- typename RemovePointer<typename WrapperTraits<S>::DataType>::type S_Data;
- static size_t GetSerializedSize(const Array<S>& input) {
- size_t size = sizeof(Array_Data<S_Data*>) +
- input.size() * sizeof(StructPointer<S_Data>);
- for (size_t i = 0; i < input.size(); ++i)
- size += GetSerializedSize_(input[i]);
- return size;
- }
-
- static void SerializeElements(Array<S> input,
- Buffer* buf,
- Array_Data<S_Data*>* output,
- const ArrayValidateParams* validate_params) {
- for (size_t i = 0; i < input.size(); ++i) {
- S_Data* element;
- SerializeCaller<S>::Run(std::move(input[i]), buf, &element,
- validate_params->element_validate_params);
- output->at(i) = element;
- MOJO_INTERNAL_DLOG_SERIALIZATION_WARNING(
- !validate_params->element_is_nullable && !element,
- VALIDATION_ERROR_UNEXPECTED_NULL_POINTER,
- MakeMessageWithArrayIndex("null in array expecting valid pointers",
- input.size(), i));
- }
- }
- static bool DeserializeElements(Array_Data<S_Data*>* input,
- Array<S>* output,
- SerializationContext* context) {
- bool success = true;
- Array<S> result(input->size());
- for (size_t i = 0; i < input->size(); ++i) {
- // Note that we rely on complete deserialization taking place in order to
- // transfer ownership of all encoded handles. Therefore we don't
- // short-circuit on failure here.
- if (!Deserialize_(input->at(i), &result[i], context))
- success = false;
- }
- output->Swap(&result);
- return success;
- }
-
- private:
- template <typename T>
- struct SerializeCaller {
- static void Run(T input,
- Buffer* buf,
- typename WrapperTraits<T>::DataType* output,
- const ArrayValidateParams* validate_params) {
- DCHECK(!validate_params)
- << "Struct type should not have array validate params";
-
- Serialize_(std::move(input), buf, output);
- }
- };
-
- template <typename T>
- struct SerializeCaller<Array<T>> {
- static void Run(Array<T> input,
- Buffer* buf,
- typename Array<T>::Data_** output,
- const ArrayValidateParams* validate_params) {
- SerializeArray_(std::move(input), buf, output, validate_params);
- }
- };
-
- template <typename T, typename U>
- struct SerializeCaller<Map<T, U>> {
- static void Run(Map<T, U> input,
- Buffer* buf,
- typename Map<T, U>::Data_** output,
- const ArrayValidateParams* validate_params) {
- SerializeMap_(std::move(input), buf, output, validate_params);
- }
- };
-};
-
-// Handles serialization and deserialization of arrays of unions.
-template <typename U, typename U_Data>
-struct ArraySerializer<U, U_Data, true> {
- static size_t GetSerializedSize(const Array<U>& input) {
- size_t size = sizeof(Array_Data<U_Data>);
- for (size_t i = 0; i < input.size(); ++i) {
- // GetSerializedSize_ will account for both the data in the union and the
- // space in the array used to hold the union.
- size += GetSerializedSize_(input[i], false);
- }
- return size;
- }
-
- static void SerializeElements(Array<U> input,
- Buffer* buf,
- Array_Data<U_Data>* output,
- const ArrayValidateParams* validate_params) {
- for (size_t i = 0; i < input.size(); ++i) {
- U_Data* result = output->storage() + i;
- SerializeUnion_(std::move(input[i]), buf, &result, true);
- MOJO_INTERNAL_DLOG_SERIALIZATION_WARNING(
- !validate_params->element_is_nullable && output->at(i).is_null(),
- VALIDATION_ERROR_UNEXPECTED_NULL_POINTER,
- MakeMessageWithArrayIndex("null in array expecting valid unions",
- input.size(), i));
- }
- }
-
- static bool DeserializeElements(Array_Data<U_Data>* input,
- Array<U>* output,
- SerializationContext* context) {
- bool success = true;
- Array<U> result(input->size());
- for (size_t i = 0; i < input->size(); ++i) {
- // Note that we rely on complete deserialization taking place in order to
- // transfer ownership of all encoded handles. Therefore we don't
- // short-circuit on failure here.
- if (!Deserialize_(&input->at(i), &result[i], context))
- success = false;
- }
- output->Swap(&result);
- return success;
- }
-};
-
-// Handles serialization and deserialization of arrays of strings.
-template <>
-struct ArraySerializer<String, String_Data*> {
- static size_t GetSerializedSize(const Array<String>& input) {
- size_t size =
- sizeof(Array_Data<String_Data*>) + input.size() * sizeof(StringPointer);
- for (size_t i = 0; i < input.size(); ++i)
- size += GetSerializedSize_(input[i]);
- return size;
- }
-
- static void SerializeElements(Array<String> input,
- Buffer* buf,
- Array_Data<String_Data*>* output,
- const ArrayValidateParams* validate_params) {
- DCHECK(validate_params->element_validate_params &&
- !validate_params->element_validate_params->element_validate_params &&
- !validate_params->element_validate_params->element_is_nullable &&
- validate_params->element_validate_params->expected_num_elements == 0)
- << "String type has unexpected array validate params";
-
- for (size_t i = 0; i < input.size(); ++i) {
- String_Data* element;
- Serialize_(input[i], buf, &element);
- output->at(i) = element;
- MOJO_INTERNAL_DLOG_SERIALIZATION_WARNING(
- !validate_params->element_is_nullable && !element,
- VALIDATION_ERROR_UNEXPECTED_NULL_POINTER,
- MakeMessageWithArrayIndex("null in array expecting valid strings",
- input.size(), i));
- }
- }
- static bool DeserializeElements(Array_Data<String_Data*>* input,
- Array<String>* output,
- SerializationContext* context) {
- Array<String> result(input->size());
- for (size_t i = 0; i < input->size(); ++i) {
- // It's OK to short-circuit here since string data cannot contain handles.
- if (!Deserialize_(input->at(i), &result[i], context))
- return false;
- }
- output->Swap(&result);
- return true;
- }
-};
-
-// Another layer of abstraction to switch between standard mojom type
-// serializers and native-only serializers.
-template <typename E,
- bool use_native = ShouldUseNativeSerializer<E>::value>
-struct ArraySerializationStrategy;
-
-// Serialization strategy for standard mojom types. This branches further
-// by choosing an ArraySerializer specialization from above.
-template <typename E>
-struct ArraySerializationStrategy<E, false> {
- static size_t GetSerializedSize(const Array<E>& input) {
- DCHECK(input);
- return ArraySerializer<E, typename WrapperTraits<E>::DataType>::
- GetSerializedSize(input);
- }
-
- template <typename F>
- static void Serialize(Array<E> input,
- Buffer* buf,
- Array_Data<F>** output,
- const ArrayValidateParams* validate_params) {
- DCHECK(input);
- Array_Data<F>* result = Array_Data<F>::New(input.size(), buf);
- if (result) {
- ArraySerializer<E, F>::SerializeElements(std::move(input), buf, result,
- validate_params);
- }
- *output = result;
- }
-
- template <typename F>
- static bool Deserialize(Array_Data<F>* input,
- Array<E>* output,
- SerializationContext* context) {
- DCHECK(input);
- return ArraySerializer<E, F>::DeserializeElements(input, output, context);
- }
-};
-
-// Serialization for arrays of native-only types, which are opaquely serialized
-// as arrays of uint8_t arrays.
-template <typename E>
-struct ArraySerializationStrategy<E, true> {
- static size_t GetSerializedSize(const Array<E>& input) {
- DCHECK(input);
- DCHECK_LE(input.size(), std::numeric_limits<uint32_t>::max());
- size_t size = ArrayDataTraits<Array_Data<uint8_t>*>::GetStorageSize(
- static_cast<uint32_t>(input.size()));
- for (size_t i = 0; i < input.size(); ++i) {
- size_t element_size = GetSerializedSizeNative_(input[i]);
- DCHECK_LT(element_size, std::numeric_limits<uint32_t>::max());
- size += ArrayDataTraits<uint8_t>::GetStorageSize(
- static_cast<uint32_t>(element_size));
- }
- return size;
- }
-
- template <typename F>
- static void Serialize(Array<E> input,
- Buffer* buf,
- Array_Data<F>** output,
- const ArrayValidateParams* validate_params) {
- static_assert(
- std::is_same<F, Array_Data<uint8_t>*>::value,
- "Native-only type array must serialize to array of byte arrays.");
- DCHECK(input);
- DCHECK(validate_params);
- // TODO(rockot): We may want to support nullable (i.e. scoped_ptr<T>)
- // elements here.
- DCHECK(!validate_params->element_is_nullable);
- Array_Data<Array_Data<uint8_t>*>* result =
- Array_Data<Array_Data<uint8_t>*>::New(input.size(), buf);
- for (size_t i = 0; i < input.size(); ++i)
- SerializeNative_(input[i], buf, &result->at(i));
- *output = result;
- }
-
- template <typename F>
- static bool Deserialize(Array_Data<F>* input,
- Array<E>* output,
- SerializationContext* context) {
- static_assert(
- std::is_same<F, Array_Data<uint8_t>*>::value,
- "Native-only type array must deserialize from array of byte arrays.");
- DCHECK(input);
-
- Array<E> result(input->size());
- bool success = true;
- for (size_t i = 0; i < input->size(); ++i) {
- // We don't short-circuit on failure since we can't know what the native
- // type's ParamTraits' expectations are.
- success = success &&
- DeserializeNative_(input->at(i), &result[i], context);
- }
- output->Swap(&result);
- return success;
- }
-};
-
-} // namespace internal
-
-template <typename E>
inline size_t GetSerializedSize_(const Array<E>& input) {
- if (!input)
- return 0;
- using Strategy = internal::ArraySerializationStrategy<
- E, internal::ShouldUseNativeSerializer<E>::value>;
- return Strategy::GetSerializedSize(input);
+ return internal::ArraySerializationImpl<Array<E>>::GetSerializedSize(input);
}
template <typename E, typename F>
@@ -437,33 +23,16 @@ inline void SerializeArray_(
internal::Buffer* buf,
internal::Array_Data<F>** output,
const internal::ArrayValidateParams* validate_params) {
- using Strategy = internal::ArraySerializationStrategy<
- E, internal::ShouldUseNativeSerializer<E>::value>;
- if (input) {
- MOJO_INTERNAL_DLOG_SERIALIZATION_WARNING(
- validate_params->expected_num_elements != 0 &&
- input.size() != validate_params->expected_num_elements,
- internal::VALIDATION_ERROR_UNEXPECTED_ARRAY_HEADER,
- internal::MakeMessageWithExpectedArraySize(
- "fixed-size array has wrong number of elements", input.size(),
- validate_params->expected_num_elements));
- Strategy::template Serialize<F>(std::move(input), buf, output,
- validate_params);
- } else {
- *output = nullptr;
- }
+ return internal::ArraySerializationImpl<Array<E>>::template Serialize<F>(
+ std::move(input), buf, output, validate_params);
}
template <typename E, typename F>
inline bool Deserialize_(internal::Array_Data<F>* input,
Array<E>* output,
internal::SerializationContext* context) {
- using Strategy = internal::ArraySerializationStrategy<
- E, internal::ShouldUseNativeSerializer<E>::value>;
- if (input)
- return Strategy::template Deserialize<F>(input, output, context);
- *output = nullptr;
- return true;
+ return internal::ArraySerializationImpl<Array<E>>::template Deserialize<F>(
+ input, output, context);
}
} // namespace mojo
diff --git a/mojo/public/cpp/bindings/lib/array_serialization_traits.h b/mojo/public/cpp/bindings/lib/array_serialization_traits.h
new file mode 100644
index 0000000..4d8f42d
--- /dev/null
+++ b/mojo/public/cpp/bindings/lib/array_serialization_traits.h
@@ -0,0 +1,428 @@
+// 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_ARRAY_SERIALIZATION_TRAITS_H_
+#define MOJO_PUBLIC_CPP_BINDINGS_LIB_ARRAY_SERIALIZATION_TRAITS_H_
+
+#include <stddef.h>
+#include <string.h> // For |memcpy()|.
+
+#include <limits>
+#include <type_traits>
+#include <utility>
+#include <vector>
+
+#include "base/logging.h"
+#include "mojo/public/cpp/bindings/lib/array_internal.h"
+#include "mojo/public/cpp/bindings/lib/serialization_forward.h"
+#include "mojo/public/cpp/bindings/lib/template_util.h"
+#include "mojo/public/cpp/bindings/lib/validation_errors.h"
+
+namespace mojo {
+namespace internal {
+
+template <typename ArrayType,
+ typename ElementType,
+ typename ElementDataType,
+ bool is_union = IsUnionDataType<
+ typename RemovePointer<ElementDataType>::type>::value>
+struct ArraySerializer;
+
+// Handles serialization and deserialization of arrays of pod types.
+template <typename ArrayType, typename E, typename F>
+struct ArraySerializer<ArrayType, E, F, false> {
+ static_assert(sizeof(E) == sizeof(F), "Incorrect array serializer");
+ static size_t GetSerializedSize(const ArrayType& input) {
+ return sizeof(Array_Data<F>) + Align(input.size() * sizeof(E));
+ }
+
+ static void SerializeElements(ArrayType input,
+ Buffer* buf,
+ Array_Data<F>* output,
+ const ArrayValidateParams* validate_params) {
+ DCHECK(!validate_params->element_is_nullable)
+ << "Primitive type should be non-nullable";
+ DCHECK(!validate_params->element_validate_params)
+ << "Primitive type should not have array validate params";
+
+ if (input.size())
+ memcpy(output->storage(), &input.storage()[0], input.size() * sizeof(E));
+ }
+ static bool DeserializeElements(Array_Data<F>* input,
+ ArrayType* output,
+ SerializationContext* context) {
+ ArrayType result(input->size());
+ if (input->size())
+ memcpy(&result.front(), input->storage(), input->size() * sizeof(E));
+ output->Swap(&result);
+ return true;
+ }
+};
+
+// Serializes and deserializes arrays of bools.
+template <typename ArrayType>
+struct ArraySerializer<ArrayType, bool, bool, false> {
+ static size_t GetSerializedSize(const ArrayType& input) {
+ return sizeof(Array_Data<bool>) + Align((input.size() + 7) / 8);
+ }
+
+ static void SerializeElements(ArrayType input,
+ Buffer* buf,
+ Array_Data<bool>* output,
+ const ArrayValidateParams* validate_params) {
+ DCHECK(!validate_params->element_is_nullable)
+ << "Primitive type should be non-nullable";
+ DCHECK(!validate_params->element_validate_params)
+ << "Primitive type should not have array validate params";
+
+ // TODO(darin): Can this be a memcpy somehow instead of a bit-by-bit copy?
+ for (size_t i = 0; i < input.size(); ++i)
+ output->at(i) = input[i];
+ }
+ static bool DeserializeElements(Array_Data<bool>* input,
+ ArrayType* output,
+ SerializationContext* context) {
+ ArrayType result(input->size());
+ // TODO(darin): Can this be a memcpy somehow instead of a bit-by-bit copy?
+ for (size_t i = 0; i < input->size(); ++i)
+ result.at(i) = input->at(i);
+ output->Swap(&result);
+ return true;
+ }
+};
+
+// Serializes and deserializes arrays of handles.
+template <typename ArrayType, typename H>
+struct ArraySerializer<ArrayType, ScopedHandleBase<H>, H, false> {
+ static size_t GetSerializedSize(const ArrayType& input) {
+ return sizeof(Array_Data<H>) + Align(input.size() * sizeof(H));
+ }
+
+ static void SerializeElements(ArrayType input,
+ Buffer* buf,
+ Array_Data<H>* output,
+ const ArrayValidateParams* validate_params) {
+ DCHECK(!validate_params->element_validate_params)
+ << "Handle type should not have array validate params";
+
+ for (size_t i = 0; i < input.size(); ++i) {
+ output->at(i) = input[i].release(); // Transfer ownership of the handle.
+ MOJO_INTERNAL_DLOG_SERIALIZATION_WARNING(
+ !validate_params->element_is_nullable && !output->at(i).is_valid(),
+ VALIDATION_ERROR_UNEXPECTED_INVALID_HANDLE,
+ MakeMessageWithArrayIndex(
+ "invalid handle in array expecting valid handles", input.size(),
+ i));
+ }
+ }
+ static bool DeserializeElements(Array_Data<H>* input,
+ ArrayType* output,
+ SerializationContext* context) {
+ ArrayType result(input->size());
+ for (size_t i = 0; i < input->size(); ++i)
+ result.at(i) = MakeScopedHandle(FetchAndReset(&input->at(i)));
+ output->Swap(&result);
+ return true;
+ }
+};
+
+// This template must only apply to pointer mojo entity (strings, structs,
+// arrays and maps). This is done by ensuring that WrapperTraits<S>::DataType is
+// a pointer.
+template <typename ArrayType, typename S>
+struct ArraySerializer<
+ ArrayType,
+ S,
+ typename EnableIf<IsPointer<typename WrapperTraits<S>::DataType>::value,
+ typename WrapperTraits<S>::DataType>::type,
+ false> {
+ typedef
+ typename RemovePointer<typename WrapperTraits<S>::DataType>::type S_Data;
+ static size_t GetSerializedSize(const ArrayType& input) {
+ size_t size = sizeof(Array_Data<S_Data*>) +
+ input.size() * sizeof(StructPointer<S_Data>);
+ for (size_t i = 0; i < input.size(); ++i)
+ size += GetSerializedSize_(input[i]);
+ return size;
+ }
+
+ static void SerializeElements(ArrayType input,
+ Buffer* buf,
+ Array_Data<S_Data*>* output,
+ const ArrayValidateParams* validate_params) {
+ for (size_t i = 0; i < input.size(); ++i) {
+ S_Data* element;
+ SerializeCaller<S>::Run(std::move(input[i]), buf, &element,
+ validate_params->element_validate_params);
+ output->at(i) = element;
+ MOJO_INTERNAL_DLOG_SERIALIZATION_WARNING(
+ !validate_params->element_is_nullable && !element,
+ VALIDATION_ERROR_UNEXPECTED_NULL_POINTER,
+ MakeMessageWithArrayIndex("null in array expecting valid pointers",
+ input.size(), i));
+ }
+ }
+ static bool DeserializeElements(Array_Data<S_Data*>* input,
+ ArrayType* output,
+ SerializationContext* context) {
+ bool success = true;
+ ArrayType result(input->size());
+ for (size_t i = 0; i < input->size(); ++i) {
+ // Note that we rely on complete deserialization taking place in order to
+ // transfer ownership of all encoded handles. Therefore we don't
+ // short-circuit on failure here.
+ if (!Deserialize_(input->at(i), &result[i], context))
+ success = false;
+ }
+ output->Swap(&result);
+ return success;
+ }
+
+ private:
+ template <typename T,
+ bool is_array = IsSpecializationOf<Array, T>::value,
+ bool is_string = std::is_same<T, String>::value>
+ struct SerializeCaller {
+ static void Run(T input,
+ Buffer* buf,
+ typename WrapperTraits<T>::DataType* output,
+ const ArrayValidateParams* validate_params) {
+ DCHECK(!validate_params)
+ << "Struct type should not have array validate params";
+
+ Serialize_(std::move(input), buf, output);
+ }
+ };
+
+ template <typename T>
+ struct SerializeCaller<T, true, false> {
+ static void Run(T input,
+ Buffer* buf,
+ typename T::Data_** output,
+ const ArrayValidateParams* validate_params) {
+ SerializeArray_(std::move(input), buf, output, validate_params);
+ }
+ };
+
+ template <typename T, typename U>
+ struct SerializeCaller<Map<T, U>, false, false> {
+ static void Run(Map<T, U> input,
+ Buffer* buf,
+ typename Map<T, U>::Data_** output,
+ const ArrayValidateParams* validate_params) {
+ SerializeMap_(std::move(input), buf, output, validate_params);
+ }
+ };
+
+ template <typename T>
+ struct SerializeCaller<T, false, true> {
+ static void Run(const T& input,
+ Buffer* buf,
+ String_Data** output,
+ const ArrayValidateParams* validate_params) {
+ DCHECK(validate_params && !validate_params->element_validate_params &&
+ !validate_params->element_is_nullable &&
+ validate_params->expected_num_elements == 0)
+ << "String type has unexpected array validate params";
+
+ Serialize_(input, buf, output);
+ }
+ };
+};
+
+// Handles serialization and deserialization of arrays of unions.
+template <typename ArrayType, typename U, typename U_Data>
+struct ArraySerializer<ArrayType, U, U_Data, true> {
+ static size_t GetSerializedSize(const ArrayType& input) {
+ size_t size = sizeof(Array_Data<U_Data>);
+ for (size_t i = 0; i < input.size(); ++i) {
+ // GetSerializedSize_ will account for both the data in the union and the
+ // space in the array used to hold the union.
+ size += GetSerializedSize_(input[i], false);
+ }
+ return size;
+ }
+
+ static void SerializeElements(ArrayType input,
+ Buffer* buf,
+ Array_Data<U_Data>* output,
+ const ArrayValidateParams* validate_params) {
+ for (size_t i = 0; i < input.size(); ++i) {
+ U_Data* result = output->storage() + i;
+ SerializeUnion_(std::move(input[i]), buf, &result, true);
+ MOJO_INTERNAL_DLOG_SERIALIZATION_WARNING(
+ !validate_params->element_is_nullable && output->at(i).is_null(),
+ VALIDATION_ERROR_UNEXPECTED_NULL_POINTER,
+ MakeMessageWithArrayIndex("null in array expecting valid unions",
+ input.size(), i));
+ }
+ }
+
+ static bool DeserializeElements(Array_Data<U_Data>* input,
+ ArrayType* output,
+ SerializationContext* context) {
+ bool success = true;
+ ArrayType result(input->size());
+ for (size_t i = 0; i < input->size(); ++i) {
+ // Note that we rely on complete deserialization taking place in order to
+ // transfer ownership of all encoded handles. Therefore we don't
+ // short-circuit on failure here.
+ if (!Deserialize_(&input->at(i), &result[i], context))
+ success = false;
+ }
+ output->Swap(&result);
+ return success;
+ }
+};
+
+// Another layer of abstraction to switch between standard mojom type
+// serializers and native-only serializers.
+template <typename ArrayType,
+ bool use_native =
+ ShouldUseNativeSerializer<typename ArrayType::ElementType>::value>
+struct ArraySerializationStrategy;
+
+// Serialization strategy for standard mojom types. This branches further
+// by choosing an ArraySerializer specialization from above.
+template <typename ArrayType>
+struct ArraySerializationStrategy<ArrayType, false> {
+ template <class DataType>
+ using Serializer =
+ ArraySerializer<ArrayType, typename ArrayType::ElementType, DataType>;
+
+ static size_t GetSerializedSize(const ArrayType& input) {
+ DCHECK(input);
+ return Serializer<typename WrapperTraits<
+ typename ArrayType::ElementType>::DataType>::GetSerializedSize(input);
+ }
+
+ template <typename F>
+ static void Serialize(ArrayType input,
+ Buffer* buf,
+ Array_Data<F>** output,
+ const ArrayValidateParams* validate_params) {
+ DCHECK(input);
+ Array_Data<F>* result = Array_Data<F>::New(input.size(), buf);
+ if (result) {
+ Serializer<F>::SerializeElements(std::move(input), buf, result,
+ validate_params);
+ }
+ *output = result;
+ }
+
+ template <typename F>
+ static bool Deserialize(Array_Data<F>* input,
+ ArrayType* output,
+ SerializationContext* context) {
+ DCHECK(input);
+ return Serializer<F>::DeserializeElements(input, output, context);
+ }
+};
+
+// Serialization for arrays of native-only types, which are opaquely serialized
+// as arrays of uint8_t arrays.
+template <typename ArrayType>
+struct ArraySerializationStrategy<ArrayType, true> {
+ static size_t GetSerializedSize(const ArrayType& input) {
+ DCHECK(input);
+ DCHECK_LE(input.size(), std::numeric_limits<uint32_t>::max());
+ size_t size = ArrayDataTraits<Array_Data<uint8_t>*>::GetStorageSize(
+ static_cast<uint32_t>(input.size()));
+ for (size_t i = 0; i < input.size(); ++i) {
+ size_t element_size = GetSerializedSizeNative_(input[i]);
+ DCHECK_LT(element_size, std::numeric_limits<uint32_t>::max());
+ size += ArrayDataTraits<uint8_t>::GetStorageSize(
+ static_cast<uint32_t>(element_size));
+ }
+ return size;
+ }
+
+ template <typename F>
+ static void Serialize(ArrayType input,
+ Buffer* buf,
+ Array_Data<F>** output,
+ const ArrayValidateParams* validate_params) {
+ static_assert(
+ std::is_same<F, Array_Data<uint8_t>*>::value,
+ "Native-only type array must serialize to array of byte arrays.");
+ DCHECK(input);
+ DCHECK(validate_params);
+ // TODO(rockot): We may want to support nullable (i.e. scoped_ptr<T>)
+ // elements here.
+ DCHECK(!validate_params->element_is_nullable);
+ Array_Data<Array_Data<uint8_t>*>* result =
+ Array_Data<Array_Data<uint8_t>*>::New(input.size(), buf);
+ for (size_t i = 0; i < input.size(); ++i)
+ SerializeNative_(input[i], buf, &result->at(i));
+ *output = result;
+ }
+
+ template <typename F>
+ static bool Deserialize(Array_Data<F>* input,
+ ArrayType* output,
+ SerializationContext* context) {
+ static_assert(
+ std::is_same<F, Array_Data<uint8_t>*>::value,
+ "Native-only type array must deserialize from array of byte arrays.");
+ DCHECK(input);
+
+ ArrayType result(input->size());
+ bool success = true;
+ for (size_t i = 0; i < input->size(); ++i) {
+ // We don't short-circuit on failure since we can't know what the native
+ // type's ParamTraits' expectations are.
+ success =
+ success && DeserializeNative_(input->at(i), &result[i], context);
+ }
+ output->Swap(&result);
+ return success;
+ }
+};
+
+template <typename ArrayType>
+struct ArraySerializationImpl {
+ using Strategy = ArraySerializationStrategy<ArrayType>;
+
+ static size_t GetSerializedSize(const ArrayType& input) {
+ if (!input)
+ return 0;
+ return Strategy::GetSerializedSize(input);
+ }
+
+ template <typename F>
+ static void Serialize(ArrayType input,
+ internal::Buffer* buf,
+ internal::Array_Data<F>** output,
+ const internal::ArrayValidateParams* validate_params) {
+ if (input) {
+ MOJO_INTERNAL_DLOG_SERIALIZATION_WARNING(
+ validate_params->expected_num_elements != 0 &&
+ input.size() != validate_params->expected_num_elements,
+ internal::VALIDATION_ERROR_UNEXPECTED_ARRAY_HEADER,
+ internal::MakeMessageWithExpectedArraySize(
+ "fixed-size array has wrong number of elements", input.size(),
+ validate_params->expected_num_elements));
+ Strategy::template Serialize<F>(std::move(input), buf, output,
+ validate_params);
+ } else {
+ *output = nullptr;
+ }
+ }
+
+ template <typename F>
+ static bool Deserialize(internal::Array_Data<F>* input,
+ ArrayType* output,
+ internal::SerializationContext* context) {
+ if (input)
+ return Strategy::template Deserialize<F>(input, output, context);
+ *output = nullptr;
+ return true;
+ }
+};
+
+} // namespace internal
+
+} // namespace mojo
+
+#endif // MOJO_PUBLIC_CPP_BINDINGS_LIB_ARRAY_SERIALIZATION_TRAITS_H_
diff --git a/mojo/public/cpp/bindings/lib/bindings_internal.h b/mojo/public/cpp/bindings/lib/bindings_internal.h
index 9691376..a467acd 100644
--- a/mojo/public/cpp/bindings/lib/bindings_internal.h
+++ b/mojo/public/cpp/bindings/lib/bindings_internal.h
@@ -9,15 +9,24 @@
#include "mojo/public/cpp/bindings/lib/interface_id.h"
#include "mojo/public/cpp/bindings/lib/template_util.h"
-#include "mojo/public/cpp/bindings/struct_ptr.h"
#include "mojo/public/cpp/system/core.h"
namespace mojo {
+class String;
+
+template <typename T>
+class StructPtr;
+
+template <typename T>
+class InlinedStructPtr;
+
namespace internal {
template <typename T>
class Array_Data;
+using String_Data = Array_Data<char>;
+
#pragma pack(push, 1)
struct StructHeader {
@@ -148,6 +157,11 @@ struct WrapperTraits<S, true> {
typedef typename S::Data_* DataType;
};
+template <>
+struct WrapperTraits<String, false> {
+ typedef String_Data* DataType;
+};
+
} // namespace internal
} // namespace mojo
diff --git a/mojo/public/cpp/bindings/lib/map_serialization.h b/mojo/public/cpp/bindings/lib/map_serialization.h
index 048730f..ed2d863 100644
--- a/mojo/public/cpp/bindings/lib/map_serialization.h
+++ b/mojo/public/cpp/bindings/lib/map_serialization.h
@@ -11,21 +11,10 @@
#include "mojo/public/cpp/bindings/lib/array_internal.h"
#include "mojo/public/cpp/bindings/lib/map_data_internal.h"
#include "mojo/public/cpp/bindings/lib/map_internal.h"
-#include "mojo/public/cpp/bindings/lib/string_serialization.h"
+#include "mojo/public/cpp/bindings/lib/serialization_forward.h"
#include "mojo/public/cpp/bindings/map.h"
namespace mojo {
-
-template <typename Key, typename Value>
-inline size_t GetSerializedSize_(const Map<Key, Value>& input);
-
-template <typename ValidateParams, typename E, typename F>
-inline void SerializeArray_(
- Array<E> input,
- internal::Buffer* buf,
- internal::Array_Data<F>** output,
- const internal::ArrayValidateParams* validate_params);
-
namespace internal {
template <typename MapType,
diff --git a/mojo/public/cpp/bindings/lib/serialization.h b/mojo/public/cpp/bindings/lib/serialization.h
new file mode 100644
index 0000000..c3af9ff
--- /dev/null
+++ b/mojo/public/cpp/bindings/lib/serialization.h
@@ -0,0 +1,13 @@
+// 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_H_
+#define MOJO_PUBLIC_CPP_BINDINGS_LIB_SERIALIZATION_H_
+
+#include "mojo/public/cpp/bindings/lib/array_serialization.h"
+#include "mojo/public/cpp/bindings/lib/map_serialization.h"
+#include "mojo/public/cpp/bindings/lib/native_serialization.h"
+#include "mojo/public/cpp/bindings/lib/string_serialization.h"
+
+#endif // MOJO_PUBLIC_CPP_BINDINGS_LIB_SERIALIZATION_H_
diff --git a/mojo/public/cpp/bindings/lib/serialization_forward.h b/mojo/public/cpp/bindings/lib/serialization_forward.h
new file mode 100644
index 0000000..cf1e1e3
--- /dev/null
+++ b/mojo/public/cpp/bindings/lib/serialization_forward.h
@@ -0,0 +1,103 @@
+// 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 <stddef.h>
+
+#include "mojo/public/cpp/bindings/lib/string_serialization.h"
+
+// This file is included by serialization implementation files to avoid circular
+// includes.
+// Users of the serialization funtions should include serialization.h.
+
+namespace mojo {
+
+template <typename T>
+class Array;
+
+template <typename K, typename V>
+class Map;
+
+namespace internal {
+
+template <typename T>
+class Array_Data;
+
+class ArrayValidateParams;
+
+class Buffer;
+
+template <typename K, typename V>
+class Map_Data;
+
+struct SerializationContext;
+
+template <typename T>
+struct ShouldUseNativeSerializer;
+
+// -----------------------------------------------------------------------------
+// Forward declaration for native types.
+
+template <typename T>
+size_t GetSerializedSizeNative_(const T& value);
+
+template <typename T>
+void SerializeNative_(const T& value,
+ Buffer* buffer,
+ Array_Data<uint8_t>** out);
+
+template <typename T>
+bool DeserializeNative_(Array_Data<uint8_t>* data,
+ T* out,
+ SerializationContext* context);
+
+} // namespace internal
+
+// -----------------------------------------------------------------------------
+// Forward declaration for Array.
+
+template <typename E>
+inline size_t GetSerializedSize_(const Array<E>& input);
+
+template <typename E, typename F>
+inline void SerializeArray_(
+ Array<E> input,
+ internal::Buffer* buf,
+ internal::Array_Data<F>** output,
+ const internal::ArrayValidateParams* validate_params);
+
+template <typename E, typename F>
+inline bool Deserialize_(internal::Array_Data<F>* input,
+ Array<E>* output,
+ internal::SerializationContext* context);
+
+// -----------------------------------------------------------------------------
+// Forward declaration for Map.
+
+template <typename MapKey, typename MapValue>
+inline size_t GetSerializedSize_(const Map<MapKey, MapValue>& input);
+
+template <typename MapKey,
+ typename MapValue,
+ typename DataKey,
+ typename DataValue>
+inline void SerializeMap_(
+ Map<MapKey, MapValue> input,
+ internal::Buffer* buf,
+ internal::Map_Data<DataKey, DataValue>** output,
+ const internal::ArrayValidateParams* value_validate_params);
+
+template <typename MapKey,
+ typename MapValue,
+ typename DataKey,
+ typename DataValue>
+inline bool Deserialize_(internal::Map_Data<DataKey, DataValue>* input,
+ Map<MapKey, MapValue>* output,
+ internal::SerializationContext* context);
+
+} // namespace mojo
+
+#endif // MOJO_PUBLIC_CPP_BINDINGS_LIB_SERIALIZATION_FORWARD_H_
diff --git a/mojo/public/cpp/bindings/tests/array_unittest.cc b/mojo/public/cpp/bindings/tests/array_unittest.cc
index edc6fb3..8d07d87 100644
--- a/mojo/public/cpp/bindings/tests/array_unittest.cc
+++ b/mojo/public/cpp/bindings/tests/array_unittest.cc
@@ -9,8 +9,8 @@
#include <utility>
#include "mojo/public/cpp/bindings/lib/array_internal.h"
-#include "mojo/public/cpp/bindings/lib/array_serialization.h"
#include "mojo/public/cpp/bindings/lib/fixed_buffer.h"
+#include "mojo/public/cpp/bindings/lib/serialization.h"
#include "mojo/public/cpp/bindings/tests/container_test_util.h"
#include "mojo/public/interfaces/bindings/tests/test_structs.mojom.h"
#include "testing/gtest/include/gtest/gtest.h"
diff --git a/mojo/public/cpp/bindings/tests/map_unittest.cc b/mojo/public/cpp/bindings/tests/map_unittest.cc
index 69e3dcb..f627cad 100644
--- a/mojo/public/cpp/bindings/tests/map_unittest.cc
+++ b/mojo/public/cpp/bindings/tests/map_unittest.cc
@@ -9,9 +9,9 @@
#include <utility>
#include "mojo/public/cpp/bindings/array.h"
-#include "mojo/public/cpp/bindings/lib/array_serialization.h"
#include "mojo/public/cpp/bindings/lib/bindings_internal.h"
#include "mojo/public/cpp/bindings/lib/fixed_buffer.h"
+#include "mojo/public/cpp/bindings/lib/serialization.h"
#include "mojo/public/cpp/bindings/lib/validate_params.h"
#include "mojo/public/cpp/bindings/string.h"
#include "mojo/public/cpp/bindings/tests/container_test_util.h"
diff --git a/mojo/public/cpp/bindings/tests/serialization_warning_unittest.cc b/mojo/public/cpp/bindings/tests/serialization_warning_unittest.cc
index 74f1f8e..496ea9f 100644
--- a/mojo/public/cpp/bindings/tests/serialization_warning_unittest.cc
+++ b/mojo/public/cpp/bindings/tests/serialization_warning_unittest.cc
@@ -10,8 +10,8 @@
#include "mojo/public/cpp/bindings/array.h"
#include "mojo/public/cpp/bindings/lib/array_internal.h"
-#include "mojo/public/cpp/bindings/lib/array_serialization.h"
#include "mojo/public/cpp/bindings/lib/fixed_buffer.h"
+#include "mojo/public/cpp/bindings/lib/serialization.h"
#include "mojo/public/cpp/bindings/lib/validation_errors.h"
#include "mojo/public/cpp/bindings/string.h"
#include "mojo/public/cpp/system/message_pipe.h"
diff --git a/mojo/public/cpp/bindings/tests/union_unittest.cc b/mojo/public/cpp/bindings/tests/union_unittest.cc
index c90069b..b12983a 100644
--- a/mojo/public/cpp/bindings/tests/union_unittest.cc
+++ b/mojo/public/cpp/bindings/tests/union_unittest.cc
@@ -13,9 +13,9 @@
#include "mojo/public/cpp/bindings/array.h"
#include "mojo/public/cpp/bindings/binding.h"
#include "mojo/public/cpp/bindings/lib/array_internal.h"
-#include "mojo/public/cpp/bindings/lib/array_serialization.h"
#include "mojo/public/cpp/bindings/lib/bounds_checker.h"
#include "mojo/public/cpp/bindings/lib/fixed_buffer.h"
+#include "mojo/public/cpp/bindings/lib/serialization.h"
#include "mojo/public/cpp/bindings/string.h"
#include "mojo/public/cpp/test_support/test_utils.h"
#include "mojo/public/interfaces/bindings/tests/test_structs.mojom.h"
diff --git a/mojo/public/interfaces/bindings/tests/test_sync_methods.mojom b/mojo/public/interfaces/bindings/tests/test_sync_methods.mojom
index 1a55a0f..e2147bc 100644
--- a/mojo/public/interfaces/bindings/tests/test_sync_methods.mojom
+++ b/mojo/public/interfaces/bindings/tests/test_sync_methods.mojom
@@ -4,7 +4,7 @@
module mojo.test;
-interface TestCodeGeneration {
+interface TestSyncCodeGeneration {
[Sync]
NoInput() => (int32 result);
diff --git a/mojo/public/tools/bindings/generators/cpp_templates/interface_macros.tmpl b/mojo/public/tools/bindings/generators/cpp_templates/interface_macros.tmpl
index a6dc1cf..b00b1da 100644
--- a/mojo/public/tools/bindings/generators/cpp_templates/interface_macros.tmpl
+++ b/mojo/public/tools/bindings/generators/cpp_templates/interface_macros.tmpl
@@ -8,7 +8,14 @@
{%- macro declare_callback(method) -%}
mojo::Callback<void(
{%- for param in method.response_parameters -%}
-{{param.kind|cpp_result_type}}
+{#- TODO(yzshen): Previously |cpp_result_type| is used here incorrectly.
+ The outcome is we will use mojo::String instead of const mojo::String&.
+ Preserve the behavior temporarily. #}
+{%- if not param.kind|is_string_kind -%}
+{{param.kind|cpp_const_wrapper_type}}
+{%- else -%}
+mojo::String
+{%- endif %}
{%- if not loop.last %}, {% endif %}
{%- endfor -%}
)>
diff --git a/mojo/public/tools/bindings/generators/cpp_templates/module-internal.h.tmpl b/mojo/public/tools/bindings/generators/cpp_templates/module-internal.h.tmpl
index c761c25..52aab99 100644
--- a/mojo/public/tools/bindings/generators/cpp_templates/module-internal.h.tmpl
+++ b/mojo/public/tools/bindings/generators/cpp_templates/module-internal.h.tmpl
@@ -17,7 +17,7 @@
#include "mojo/public/cpp/bindings/lib/bindings_internal.h"
#include "mojo/public/cpp/bindings/lib/buffer.h"
-#include "mojo/public/cpp/bindings/lib/native_serialization.h"
+#include "mojo/public/cpp/bindings/lib/serialization.h"
#include "mojo/public/cpp/bindings/lib/union_accessor.h"
#include "mojo/public/cpp/bindings/lib/value_traits.h"
#include "mojo/public/cpp/bindings/struct_ptr.h"
diff --git a/mojo/public/tools/bindings/generators/cpp_templates/module.cc.tmpl b/mojo/public/tools/bindings/generators/cpp_templates/module.cc.tmpl
index 447faa9..447b6a4 100644
--- a/mojo/public/tools/bindings/generators/cpp_templates/module.cc.tmpl
+++ b/mojo/public/tools/bindings/generators/cpp_templates/module.cc.tmpl
@@ -26,14 +26,10 @@
#include "base/logging.h"
#include "base/trace_event/trace_event.h"
-#include "mojo/public/cpp/bindings/lib/array_serialization.h"
#include "mojo/public/cpp/bindings/lib/bindings_serialization.h"
#include "mojo/public/cpp/bindings/lib/bounds_checker.h"
#include "mojo/public/cpp/bindings/lib/map_data_internal.h"
-#include "mojo/public/cpp/bindings/lib/map_serialization.h"
#include "mojo/public/cpp/bindings/lib/message_builder.h"
-#include "mojo/public/cpp/bindings/lib/native_serialization.h"
-#include "mojo/public/cpp/bindings/lib/string_serialization.h"
#include "mojo/public/cpp/bindings/lib/validate_params.h"
#include "mojo/public/cpp/bindings/lib/validation_errors.h"
#include "mojo/public/cpp/bindings/lib/validation_util.h"
diff --git a/mojo/public/tools/bindings/generators/cpp_templates/module.h.tmpl b/mojo/public/tools/bindings/generators/cpp_templates/module.h.tmpl
index fa7dd15..91a4473 100644
--- a/mojo/public/tools/bindings/generators/cpp_templates/module.h.tmpl
+++ b/mojo/public/tools/bindings/generators/cpp_templates/module.h.tmpl
@@ -28,7 +28,7 @@
#include "mojo/public/cpp/bindings/interface_request.h"
#include "mojo/public/cpp/bindings/lib/control_message_handler.h"
#include "mojo/public/cpp/bindings/lib/control_message_proxy.h"
-#include "mojo/public/cpp/bindings/lib/native_serialization.h"
+#include "mojo/public/cpp/bindings/lib/serialization.h"
#include "mojo/public/cpp/bindings/map.h"
#include "mojo/public/cpp/bindings/message_filter.h"
#include "mojo/public/cpp/bindings/no_interface.h"