1{%- import "struct_macros.tmpl" as struct_macros %}
2{%- set mojom_type = struct|get_qualified_name_for_kind %}
3{%- set data_type = struct|get_qualified_name_for_kind(internal=True) %}
4
5template <>
6struct StructTraits<{{mojom_type}}, {{mojom_type}}Ptr> {
7  static bool IsNull(const {{mojom_type}}Ptr& input) { return !input; }
8  static void SetToNull({{mojom_type}}Ptr* output) { output->reset(); }
9
10{%- for field in struct.fields %}
11{%-   set return_ref = field.kind|is_object_kind or
12                       field.kind|is_any_handle_or_interface_kind %}
13{%-   if return_ref %}
14  static decltype({{mojom_type}}::{{field.name}})& {{field.name}}(
15      {{mojom_type}}Ptr& input) {
16    return input->{{field.name}};
17  }
18{%-   else %}
19  static decltype({{mojom_type}}::{{field.name}}) {{field.name}}(
20      const {{mojom_type}}Ptr& input) {
21    return input->{{field.name}};
22  }
23{%-   endif %}
24{%- endfor %}
25
26  static bool Read({{mojom_type}}DataView input, {{mojom_type}}Ptr* output);
27};
28
29namespace internal {
30
31template <typename MaybeConstUserType>
32struct Serializer<{{mojom_type}}Ptr, MaybeConstUserType> {
33  using UserType = typename std::remove_const<MaybeConstUserType>::type;
34  using Traits = StructTraits<{{mojom_type}}, UserType>;
35
36  static size_t PrepareToSerialize(MaybeConstUserType& input,
37                                   SerializationContext* context) {
38    if (CallIsNullIfExists<Traits>(input))
39      return 0;
40
41    void* custom_context = CustomContextHelper<Traits>::SetUp(input, context);
42    ALLOW_UNUSED_LOCAL(custom_context);
43
44    {{struct_macros.get_serialized_size(
45          struct, "CallWithContext(Traits::%s, input, custom_context)",
46          "context", True)|indent(2)}}
47    return size;
48  }
49
50  static void Serialize(MaybeConstUserType& input,
51                        Buffer* buffer,
52                        {{data_type}}** output,
53                        SerializationContext* context) {
54    if (CallIsNullIfExists<Traits>(input)) {
55      *output = nullptr;
56      return;
57    }
58
59    void* custom_context = CustomContextHelper<Traits>::GetNext(context);
60
61    {{struct_macros.serialize(
62          struct, struct.name ~ " struct",
63          "CallWithContext(Traits::%s, input, custom_context)", "result",
64          "buffer", "context", True)|indent(4)}}
65    *output = result;
66
67    CustomContextHelper<Traits>::TearDown(input, custom_context);
68  }
69
70  static bool Deserialize({{data_type}}* input,
71                          UserType* output,
72                          SerializationContext* context) {
73    if (!input)
74      return CallSetToNullIfExists<Traits>(output);
75
76    {{mojom_type}}DataView data_view(input, context);
77    return Traits::Read(data_view, output);
78  }
79};
80
81}  // namespace internal
82