blob: d8cd162bddcbce0b827843cf9dbf34e8e9955237 [file] [log] [blame]
{{/*
// Copyright 2018 The Fuchsia Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
*/}}
{{- define "TableDeclaration" }}
{{- range .DocComments }}
///{{ . }}
{{- end }}
{{ .Derives }}
pub struct {{ .Name }} {
{{- range .Members }}
{{- range .DocComments }}
///{{ . }}
{{- end }}
pub {{ .Name }}: Option<{{ .Type.Owned }}>,
{{- end }}
#[doc(hidden)]
pub __source_breaking: fidl::marker::SourceBreaking,
}
impl fidl::{{ if .IsValueType }}Persistable{{ else }}Standalone{{ end }} for {{ .Name }} {}
{{- end }}
{{- define "TableInternal" }}
impl {{ .Name }} {
#[inline(always)]
fn max_ordinal_present(&self) -> u64 {
{{- range .ReversedMembers }}
if let Some(_) = self.{{ .Name }} {
return {{ .Ordinal }};
}
{{- end }}
0
}
}
unsafe impl fidl::encoding::TypeMarker for {{ .Name }} {
type Owned = Self;
#[inline(always)]
fn inline_align(_context: fidl::encoding::Context) -> usize {
8
}
#[inline(always)]
fn inline_size(_context: fidl::encoding::Context) -> usize {
16
}
}
{{- if .IsResourceType }}
impl fidl::encoding::ResourceTypeMarker for {{ .Name }} {
type Borrowed<'a> = &'a mut Self;
fn take_or_borrow<'a>(value: &'a mut <Self as fidl::encoding::TypeMarker>::Owned) -> Self::Borrowed<'a> {
value
}
}
{{- else }}
impl fidl::encoding::ValueTypeMarker for {{ .Name }} {
type Borrowed<'a> = &'a Self;
fn borrow<'a>(value: &'a <Self as fidl::encoding::TypeMarker>::Owned) -> Self::Borrowed<'a> {
value
}
}
{{- end }}
unsafe impl fidl::encoding::Encode<{{ .Name }}> for &{{ if .IsResourceType }}mut {{ end }}{{ .Name }} {
unsafe fn encode(self, encoder: &mut fidl::encoding::Encoder<'_>, offset: usize, mut depth: fidl::encoding::Depth) -> fidl::Result<()> {
encoder.debug_check_bounds::<{{ .Name }}>(offset);
// Vector header
let max_ordinal: u64 = self.max_ordinal_present();
encoder.write_num(max_ordinal, offset);
encoder.write_num(fidl::encoding::ALLOC_PRESENT_U64, offset + 8);
// Calling encoder.out_of_line_offset(0) is not allowed.
if max_ordinal == 0 {
return Ok(());
}
depth.increment()?;
let envelope_size = 8;
let bytes_len = max_ordinal as usize * envelope_size;
#[allow(unused_variables)]
let offset = encoder.out_of_line_offset(bytes_len);
let mut _prev_end_offset: usize = 0;
{{- range .Members }}
if {{ .Ordinal }} > max_ordinal {
return Ok(());
}
// Write at offset+(ordinal-1)*envelope_size, since ordinals are one-based and envelopes
// are envelope_size bytes.
let cur_offset: usize = ({{ .Ordinal }} - 1) * envelope_size;
// Zero reserved fields.
encoder.padding(offset + _prev_end_offset, cur_offset - _prev_end_offset);
// Safety:
// - bytes_len is calculated to fit envelope_size*max(member.ordinal).
// - Since cur_offset is envelope_size*(member.ordinal - 1) and the envelope takes
// envelope_size bytes, there is always sufficient room.
fidl::encoding::encode_in_envelope_optional::<{{ .Type.Fidl }}>(
{{- if .Type.IsResourceType }}
self.{{ .Name }}.as_mut().map(<{{ .Type.Fidl }} as fidl::encoding::ResourceTypeMarker>::take_or_borrow),
{{- else }}
self.{{ .Name }}.as_ref().map(<{{ .Type.Fidl }} as fidl::encoding::ValueTypeMarker>::borrow),
{{- end }}
encoder, offset + cur_offset, depth
)?;
_prev_end_offset = cur_offset + envelope_size;
{{- end }}
Ok(())
}
}
impl fidl::encoding::Decode<Self> for {{ .Name }} {
#[inline(always)]
fn new_empty() -> Self {
Self::default()
}
unsafe fn decode(&mut self, decoder: &mut fidl::encoding::Decoder<'_>, offset: usize, mut depth: fidl::encoding::Depth) -> fidl::Result<()> {
decoder.debug_check_bounds::<Self>(offset);
let len = match fidl::encoding::decode_vector_header(decoder, offset)? {
None => return Err(fidl::Error::NotNullable),
Some(len) => len,
};
// Calling decoder.out_of_line_offset(0) is not allowed.
if len == 0 {
return Ok(());
};
depth.increment()?;
let envelope_size = 8;
let bytes_len = len * envelope_size;
let offset = decoder.out_of_line_offset(bytes_len)?;
// Decode the envelope for each type.
let mut _next_ordinal_to_read = 0;
let mut next_offset = offset;
let end_offset = offset + bytes_len;
{{- range .Members }}
_next_ordinal_to_read += 1;
if next_offset >= end_offset {
return Ok(());
}
// Decode unknown envelopes for gaps in ordinals.
while _next_ordinal_to_read < {{ .Ordinal }} {
fidl::encoding::decode_unknown_envelope(decoder, next_offset, depth)?;
_next_ordinal_to_read += 1;
next_offset += envelope_size;
}
let next_out_of_line = decoder.next_out_of_line();
let handles_before = decoder.remaining_handles();
if let Some((inlined, num_bytes, num_handles)) =
fidl::encoding::decode_envelope_header(decoder, next_offset)?
{
let member_inline_size = <{{ .Type.Fidl }} as fidl::encoding::TypeMarker>::inline_size(decoder.context);
if inlined != (member_inline_size <= 4) {
return Err(fidl::Error::InvalidInlineBitInEnvelope);
}
let inner_offset;
let mut inner_depth = depth.clone();
if inlined {
decoder.check_inline_envelope_padding(next_offset, member_inline_size)?;
inner_offset = next_offset;
} else {
inner_offset = decoder.out_of_line_offset(member_inline_size)?;
inner_depth.increment()?;
}
let val_ref =
self.{{ .Name }}.get_or_insert_with(|| fidl::new_empty!({{ .Type.Fidl }}));
fidl::decode!({{ .Type.Fidl }}, val_ref, decoder, inner_offset, inner_depth)?;
if !inlined && decoder.next_out_of_line() != next_out_of_line + (num_bytes as usize) {
return Err(fidl::Error::InvalidNumBytesInEnvelope);
}
if handles_before != decoder.remaining_handles() + (num_handles as usize) {
return Err(fidl::Error::InvalidNumHandlesInEnvelope);
}
}
next_offset += envelope_size;
{{- end }}
// Decode the remaining unknown envelopes.
while next_offset < end_offset {
_next_ordinal_to_read += 1;
fidl::encoding::decode_unknown_envelope(decoder, next_offset, depth)?;
next_offset += envelope_size;
}
Ok(())
}
}
{{ end }}