fidl_next_codec/wire/
table.rs
1use munge::munge;
6
7use crate::{
8 DecodeError, Decoder, DecoderExt as _, Owned, Slot, WireEnvelope, WirePointer, WireU64,
9 ZeroPadding,
10};
11
12#[repr(C)]
14pub struct WireTable {
15 len: WireU64,
16 ptr: WirePointer<WireEnvelope>,
17}
18
19unsafe impl ZeroPadding for WireTable {
20 #[inline]
21 unsafe fn zero_padding(_: *mut Self) {
22 }
24}
25
26impl WireTable {
27 #[inline]
29 pub fn encode_len(slot: Slot<'_, Self>, len: usize) {
30 munge!(let Self { len: mut table_len, ptr } = slot);
31 **table_len = len.try_into().unwrap();
32 WirePointer::encode_present(ptr);
33 }
34
35 #[inline]
39 pub fn decode_with<D: Decoder + ?Sized>(
40 slot: Slot<'_, Self>,
41 mut decoder: &mut D,
42 f: impl Fn(i64, Slot<'_, WireEnvelope>, &mut D) -> Result<(), DecodeError>,
43 ) -> Result<(), DecodeError> {
44 munge!(let Self { len, mut ptr } = slot);
45
46 if WirePointer::is_encoded_present(ptr.as_mut())? {
47 let mut envelopes = decoder.take_slice_slot::<WireEnvelope>(**len as usize)?;
48 let envelopes_ptr = envelopes.as_mut_ptr().cast::<WireEnvelope>();
49
50 for i in 0..**len as usize {
51 let mut envelope = envelopes.index(i);
52 if !WireEnvelope::is_encoded_zero(envelope.as_mut()) {
53 f((i + 1) as i64, envelope, decoder)?;
54 }
55 }
56
57 let envelopes = unsafe { Owned::new_unchecked(envelopes_ptr) };
58 WirePointer::set_decoded(ptr, envelopes.into_raw());
59 } else if **len != 0 {
60 return Err(DecodeError::InvalidOptionalSize(**len));
61 }
62
63 Ok(())
64 }
65
66 #[inline]
68 pub fn get(&self, ordinal: usize) -> Option<&WireEnvelope> {
69 if ordinal == 0 || ordinal > *self.len as usize {
70 return None;
71 }
72
73 let envelope = unsafe { &*self.ptr.as_ptr().add(ordinal - 1) };
74 (!envelope.is_zero()).then_some(envelope)
75 }
76}