blob: c9bdaedd19f9eccc7271d0026a0dd442cac1994f [file] [log] [blame]
{%- 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}}();
}
{# TODO(vardhan): Set error messages here for the remaining validation
errors. #}
// static
mojo::internal::ValidationError {{class_name}}::Validate(
const void* data,
mojo::internal::BoundsChecker* bounds_checker,
bool inlined,
std::string* err) {
if (!data)
return mojo::internal::ValidationError::NONE;
if (!mojo::internal::IsAligned(data)) {
MOJO_INTERNAL_DEBUG_SET_ERROR_MSG(err) << "";
return mojo::internal::ValidationError::MISALIGNED_OBJECT;
}
// 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}}))) {
MOJO_INTERNAL_DEBUG_SET_ERROR_MSG(err) << "";
return mojo::internal::ValidationError::ILLEGAL_MEMORY_RANGE;
}
const {{class_name}}* object = static_cast<const {{class_name}}*>(data);
MOJO_ALLOW_UNUSED_LOCAL(object);
if (object->is_null())
return mojo::internal::ValidationError::NONE;
switch (object->tag) {
{% for field in union.fields %}
case {{enum_name}}::{{field.name|upper}}: {
{{ validation_macros.validate_union_field(field, union, "err")|indent(8) }}
}
{%- endfor %}
default:
// Unknown tags should not cause validation to fail.
break;
}
return mojo::internal::ValidationError::NONE;
}
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;
}
}