blob: 9ea45dd960107256a3a02314ad925596f6eb9de1 [file]
{%- 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::ValidationError::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::ValidationError::ILLEGAL_MEMORY_RANGE);
return false;
}
const {{class_name}}* object = static_cast<const {{class_name}}*>(data);
MOJO_ALLOW_UNUSED_LOCAL(object);
if (object->is_null()) {
return true;
}
switch (object->tag) {
{% for field in union.fields %}
case {{enum_name}}::{{field.name|upper}}: {
{{ validation_macros.validate_union_field(field, union)|indent(8) }}
}
{%- endfor %}
default:
// Unknown tags should not cause validation to fail.
break;
}
return true;
}
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 %}
case {{enum_name}}::__UNKNOWN__: {
MOJO_DCHECK(false) << "No sane way to serialize a union with an unknown tag.";
break;
}
}
}
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 %}
default:
return;
}
}