summaryrefslogtreecommitdiffstats
path: root/mojo/public/tools/bindings/generators/cpp_templates/union_definition.tmpl
blob: 90d6152bd53b3a0a1d1c028bf6b0701042353e1a (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
{%- import "validation_macros.tmpl" as validation_macros %}
{%- set class_name = union.name ~ "_Data" %}
{%- set enum_name = union.name ~ "_Tag" -%}

// static
{{class_name}}* {{class_name}}::New(mojo::internal::Buffer* buf) {
  return new (buf->Allocate(sizeof({{class_name}}))) {{class_name}}();
}

// static
bool {{class_name}}::Validate(const void* data,
                              mojo::internal::BoundsChecker* bounds_checker,
                              bool inlined) {
  if (!data) {
    return true;
  }

  if (!mojo::internal::IsAligned(data)) {
    ReportValidationError(mojo::internal::VALIDATION_ERROR_MISALIGNED_OBJECT);
    return false;
  }

  // If the union is inlined in another structure its memory was already claimed.
  // This ONLY applies to the union itself, NOT anything which the union points
  // to.
  if (!inlined && !bounds_checker->ClaimMemory(data, sizeof({{class_name}}))) {
    ReportValidationError(
        mojo::internal::VALIDATION_ERROR_ILLEGAL_MEMORY_RANGE);
    return false;
  }
  const {{class_name}}* object = static_cast<const {{class_name}}*>(data);
  ALLOW_UNUSED_LOCAL(object);

  switch (object->tag) {
{%  for field in union.fields %}
    case {{enum_name}}::{{field.name|upper}}: {
      {{ validation_macros.validate_union_field(field, union)|indent(6) }}
    }
{%- endfor %}
    default: {
      ReportValidationError(
          mojo::internal::VALIDATION_ERROR_UNKNOWN_UNION_TAG,
          "unknown tag in {{union.name}}");
      return false;
    }
  }
}

void {{class_name}}::set_null() {
  size = 0U;
  tag = static_cast<{{enum_name}}>(0);
  data.unknown = 0U;
}

{{class_name}}::{{class_name}}() {
}

void {{class_name}}::EncodePointersAndHandles(
    std::vector<mojo::Handle>* handles) {
  switch (tag) {
{%- for field in union.fields %}
    case {{enum_name}}::{{field.name|upper}}: {
{%-   if field.kind|is_object_kind %}
      mojo::internal::Encode(&data.f_{{field.name}}, handles);
{%-   elif field.kind|is_any_handle_kind %}
      mojo::internal::EncodeHandle(&data.f_{{field.name}}, handles);
{%-   elif field.kind|is_interface_kind %}
      mojo::internal::EncodeHandle(
          reinterpret_cast<mojo::internal::Interface_Data*>(
              &data.f_{{field.name}}), handles);
{%-   endif %}
      return;
    }
{%- endfor %}
  }
}

void {{class_name}}::DecodePointersAndHandles(
    std::vector<mojo::Handle>* handles) {
  switch (tag) {
{%- for field in union.fields %}
    case {{enum_name}}::{{field.name|upper}}: {
{%-   if field.kind|is_object_kind %}
      mojo::internal::Decode(&data.f_{{field.name}}, handles);
{%-   elif field.kind|is_any_handle_kind %}
      mojo::internal::DecodeHandle(&data.f_{{field.name}}, handles);
{%-   elif field.kind|is_interface_kind %}
      mojo::internal::DecodeHandle(
          reinterpret_cast<mojo::internal::Interface_Data*>(
              &data.f_{{field.name}}), handles);
{%-   endif %}
      return;
    }
{%- endfor %}
  }
}