summaryrefslogtreecommitdiffstats
path: root/mojo/public/tools/bindings/generators/cpp_templates/struct_serialization_declaration.tmpl
blob: 2e88cb411e8c4163a912bfda1d12b687f7b3573e (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
size_t GetSerializedSize_(const {{struct.name}}Ptr& input,
                          mojo::internal::SerializationContext* context);
void Serialize_({{struct.name}}Ptr input, mojo::internal::Buffer* buffer,
                internal::{{struct.name}}_Data** output,
                mojo::internal::SerializationContext* context);
bool Deserialize_(internal::{{struct.name}}_Data* input,
                  {{struct.name}}Ptr* output,
                  mojo::internal::SerializationContext* context);

{%- if struct|is_native_only_kind and struct|is_typemapped_kind %}
{# This helps the array serializer understand how to serialize arrays of this
   native-only type. #}

{%-   for namespace in namespaces_as_array|reverse %}
}  // namespace {{namespace}}
{%-   endfor %}
{%-   if variant %}
}  // namespace {{variant}}
{%-   endif %}

namespace mojo {
namespace internal {

template <>
struct ShouldUseNativeSerializer<{{struct|cpp_wrapper_type}}> {
  static const bool value = true;
};

template <>
struct WrapperTraits<{{struct|cpp_wrapper_type}}> {
  using DataType = Array_Data<uint8_t>*;
};

}  // namespace internal
}  // namespace mojo

{%-   for namespace in namespaces_as_array %}
namespace {{namespace}} {
{%-   endfor %}
{%-   if variant %}
namespace {{variant}} {
{%-   endif %}

{%- endif %}

{%- if not variant and not struct|is_native_only_kind %}

{# NOTE: Generated Reader instances are intentionally cheap to copy and devoid
   of heap allocations. They should stay this way. #}
class {{struct.name}}_Reader {
 public:
  {{struct.name}}_Reader(internal::{{struct.name}}_Data* data,
                         mojo::internal::SerializationContext* context);

{%-   for pf in struct.packed.packed_fields_in_ordinal_order %}
{%-     set kind = pf.field.kind -%}
{%-     set name = pf.field.name -%}
{%-     if kind|is_nullable_kind %}
  bool has_{{name}}() const;
{%-     endif %}
{%-     if kind|is_struct_kind and not kind|is_native_only_kind %}
  {{kind|get_name_for_kind}}::Reader {{name}}() const;
{%-     elif kind|is_string_kind %}
  base::StringPiece {{name}}() const;
{%-     elif kind|is_union_kind %}
  // TODO(rockot): Support reading unions. ({{name}}() omitted)
{%-     elif kind|is_object_kind %}
  // TODO(rockot): Support reading other object kinds. ({{name}}() omitted)
{%-     elif kind|is_any_handle_kind %}
  // TODO(rockot): Support reading handles. ({{name}}() omitted)
{%-     elif kind|is_interface_kind %}
  // TODO(rockot): Support reading interfaces. ({{name}}() omitted)
{%-     elif kind|is_interface_request_kind %}
  // TODO(rockot): Support reading interface requests. ({{name}}() omitted)
{%-     elif kind|is_associated_kind %}
  // TODO(rockot): Support reading associated kinds. ({{name}}() omitted)
{%-     elif kind|is_enum_kind %}
  {{kind|cpp_result_type}} {{name}}() const {
    return static_cast<{{kind|cpp_result_type}}>(data_->{{name}}.value);
  }
{%-     else %}
  {{kind|cpp_result_type}} {{name}}() const { return data_->{{name}}; }
{%-     endif %}
{%-   endfor %}

 private:
  internal::{{struct.name}}_Data* data_;
  mojo::internal::SerializationContext* context_;
};

template <typename NativeType>
struct {{struct.name}}_SerializerTraits_ {
  static size_t GetSize(const NativeType& input) {
    size_t size = sizeof(internal::{{struct.name}}_Data);
{%- for pf in struct.packed.packed_fields_in_ordinal_order %}
    do {
{%-   if pf.field.kind|is_nullable_kind %}
      if (!mojo::StructTraits<{{struct.name}}, NativeType>
              ::has_{{pf.field.name}}(input))
        break;
{%-   endif %}
{%-   if pf.field.kind|is_string_kind %}
      size += mojo::internal::String_Data::Traits::GetStorageSize(
          static_cast<uint32_t>(mojo::StructTraits<{{struct.name}}, NativeType>
              ::{{pf.field.name}}(input).size()));
{%-   elif pf.field.kind|is_object_kind %}
      NOTREACHED() << "Unsupported field type for StructTraits: "
                   << "{{pf.field.name}}";
{%-   endif %}
    } while (false);
{%- endfor %}
    return size;
  }

  static void Serialize(const NativeType& input,
                        mojo::internal::Buffer* buffer,
                        internal::{{struct.name}}_Data** output) {
    internal::{{struct.name}}_Data* result =
        internal::{{struct.name}}_Data::New(buffer);
{%- for pf in struct.packed.packed_fields_in_ordinal_order -%}
{%-   set name = pf.field.name -%}
{%-   set kind = pf.field.kind %}
    do {
{%-   if kind|is_nullable_kind %}
      if (!mojo::StructTraits<{{struct.name}}, NativeType>
              ::has_{{name}}(input))
        break;
{%-   endif %}
{%-   if kind|is_string_kind %}
      base::StringPiece input_{{name}} =
          mojo::StructTraits<{{struct.name}}, NativeType>::{{name}}(input);
      result->{{name}}.ptr =
          mojo::internal::String_Data::New(input_{{name}}.size(), buffer);
      memcpy(result->{{name}}.ptr->storage(), input_{{name}}.data(),
             input_{{name}}.size());
{%-   elif kind|is_object_kind %}
      NOTREACHED() << "Unsupported field type for StructTraits: "
                   << "{{pf.field.name}}";
{%-   else %}
      result->{{name}} = mojo::StructTraits<{{struct.name}}, NativeType>
          ::{{name}}(input);
{%-   endif %}
    } while (false);
{%- endfor %}
    *output = result;
  }

  static bool Deserialize(internal::{{struct.name}}_Data* input,
                          NativeType* output,
                          mojo::internal::SerializationContext* context) {
    return mojo::StructTraits<{{struct.name}}, NativeType>::Read(
        {{struct.name}}_Reader(input, context), output);
  }
};

{%- endif %}  {# not variant #}