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