fidl_next_codec/wire/
table.rs1use core::mem::MaybeUninit;
6
7use munge::munge;
8
9use crate::{
10 Constrained, DecodeError, Decoder, DecoderExt as _, Slot, ValidationError, Wire, wire,
11};
12
13#[repr(C)]
15pub struct Table<'de> {
16 len: wire::Uint64,
17 ptr: wire::Pointer<'de, wire::Envelope>,
18}
19
20impl Constrained for Table<'_> {
21 type Constraint = ();
22
23 fn validate(_: Slot<'_, Self>, _: Self::Constraint) -> Result<(), ValidationError> {
24 Ok(())
25 }
26}
27
28unsafe impl Wire for Table<'static> {
30 type Narrowed<'de> = Table<'de>;
31
32 #[inline]
33 fn zero_padding(_: &mut MaybeUninit<Self>) {
34 }
36}
37
38impl<'de> Table<'de> {
39 #[inline]
41 pub fn encode_len(out: &mut MaybeUninit<Self>, len: usize) {
42 munge!(let Self { len: table_len, ptr } = out);
43 table_len.write(wire::Uint64(len.try_into().unwrap()));
44 wire::Pointer::encode_present(ptr);
45 }
46
47 #[inline]
51 pub fn decode_with<D: Decoder<'de> + ?Sized>(
52 slot: Slot<'_, Self>,
53 decoder: &mut D,
54 f: impl Fn(i64, Slot<'_, wire::Envelope>, &mut D) -> Result<(), DecodeError>,
55 ) -> Result<(), DecodeError> {
56 munge!(let Self { len, mut ptr } = slot);
57
58 if wire::Pointer::is_encoded_present(ptr.as_mut())? {
59 let mut envelopes = decoder.take_slice_slot::<wire::Envelope>(**len as usize)?;
60
61 for i in 0..**len as usize {
62 let mut envelope = envelopes.index(i);
63 if !wire::Envelope::is_encoded_zero(envelope.as_mut()) {
64 f((i + 1) as i64, envelope, decoder)?;
65 }
66 }
67
68 wire::Pointer::set_decoded_slice(ptr, envelopes);
69 } else if **len != 0 {
70 return Err(DecodeError::InvalidOptionalSize(**len));
71 }
72
73 Ok(())
74 }
75}
76
77impl Table<'_> {
78 #[inline]
79 fn get_raw(&self, ordinal: usize) -> Option<*mut wire::Envelope> {
80 if ordinal == 0 || ordinal > *self.len as usize {
81 return None;
82 }
83
84 unsafe {
87 let ptr = self.ptr.as_ptr().add(ordinal - 1);
88 (!(*ptr).is_zero()).then_some(ptr)
89 }
90 }
91
92 #[inline]
94 pub fn get(&self, ordinal: usize) -> Option<&wire::Envelope> {
95 unsafe { Some(&*self.get_raw(ordinal)?) }
99 }
100
101 #[inline]
103 pub fn get_mut(&mut self, ordinal: usize) -> Option<&mut wire::Envelope> {
104 unsafe { Some(&mut *self.get_raw(ordinal)?) }
108 }
109}