fidl_next_codec/
decoder.rs1use core::mem::take;
8
9use crate::{CHUNK_SIZE, Chunk, Decode, DecodeError, Slot};
10
11pub trait InternalHandleDecoder {
13 #[doc(hidden)]
18 fn __internal_take_handles(&mut self, count: usize) -> Result<(), DecodeError>;
19
20 #[doc(hidden)]
25 fn __internal_handles_remaining(&self) -> usize;
26}
27
28pub trait Decoder<'de>: InternalHandleDecoder {
30 fn take_chunks(&mut self, count: usize) -> Result<&'de mut [Chunk], DecodeError>;
32
33 fn commit(&mut self);
40
41 fn finish(&self) -> Result<(), DecodeError>;
43}
44
45impl InternalHandleDecoder for &mut [Chunk] {
46 #[inline]
47 fn __internal_take_handles(&mut self, _: usize) -> Result<(), DecodeError> {
48 Err(DecodeError::InsufficientHandles)
49 }
50
51 #[inline]
52 fn __internal_handles_remaining(&self) -> usize {
53 0
54 }
55}
56
57impl<'de> Decoder<'de> for &'de mut [Chunk] {
58 #[inline]
59 fn take_chunks(&mut self, count: usize) -> Result<&'de mut [Chunk], DecodeError> {
60 if count > self.len() {
61 return Err(DecodeError::InsufficientData);
62 }
63
64 let chunks = take(self);
65 let (prefix, suffix) = unsafe { chunks.split_at_mut_unchecked(count) };
67 *self = suffix;
68 Ok(prefix)
69 }
70
71 #[inline]
72 fn commit(&mut self) {
73 }
75
76 #[inline]
77 fn finish(&self) -> Result<(), DecodeError> {
78 if !self.is_empty() {
79 return Err(DecodeError::ExtraBytes { num_extra: self.len() * CHUNK_SIZE });
80 }
81
82 Ok(())
83 }
84}
85
86pub trait DecoderExt<'de> {
88 fn take_slot<T>(&mut self) -> Result<Slot<'de, T>, DecodeError>;
90
91 fn take_slice_slot<T>(&mut self, len: usize) -> Result<Slot<'de, [T]>, DecodeError>;
94
95 fn decode_prefix<T>(&mut self) -> Result<T, DecodeError>
100 where
101 T: Decode<Self, Constraint = ()>;
102
103 fn decode_prefix_with_constraint<T>(
109 &mut self,
110 constraint: T::Constraint,
111 ) -> Result<T, DecodeError>
112 where
113 T: Decode<Self>;
114
115 fn decode<T>(&mut self) -> Result<T, DecodeError>
120 where
121 T: Decode<Self, Constraint = ()>;
122
123 fn decode_with_constraint<T>(&mut self, constraint: T::Constraint) -> Result<T, DecodeError>
129 where
130 T: Decode<Self>;
131}
132
133impl<'de, D: Decoder<'de> + ?Sized> DecoderExt<'de> for D {
134 fn take_slot<T>(&mut self) -> Result<Slot<'de, T>, DecodeError> {
135 assert!(
138 align_of::<T>() <= CHUNK_SIZE,
139 "attempted to take a slot for a type with an alignment higher \
140 than {CHUNK_SIZE}",
141 );
142
143 let count = size_of::<T>().div_ceil(CHUNK_SIZE);
144 let chunks = self.take_chunks(count)?;
145 unsafe { Ok(Slot::new_unchecked(chunks.as_mut_ptr().cast())) }
148 }
149
150 fn take_slice_slot<T>(&mut self, len: usize) -> Result<Slot<'de, [T]>, DecodeError> {
151 assert!(
152 align_of::<T>() <= CHUNK_SIZE,
153 "attempted to take a slice slot for a type with an alignment \
154 higher than {CHUNK_SIZE}",
155 );
156
157 let slice_byte_length = size_of::<T>() * len;
158 let chunk_count = slice_byte_length.div_ceil(CHUNK_SIZE);
159 let chunk_length = CHUNK_SIZE * chunk_count;
160 let padding_length = chunk_length - slice_byte_length;
161 let chunks_ptr = self.take_chunks(chunk_count)?.as_mut_ptr();
162 let padding: &[u8] = unsafe {
163 core::slice::from_raw_parts(
164 chunks_ptr.cast::<u8>().add(slice_byte_length),
165 padding_length,
166 )
167 };
168 if padding.iter().any(|byte| *byte != 0) {
169 return Err(DecodeError::InvalidPadding);
170 }
171
172 unsafe { Ok(Slot::new_slice_unchecked(chunks_ptr.cast(), len)) }
175 }
176
177 fn decode_prefix<T>(&mut self) -> Result<T, DecodeError>
178 where
179 T: Decode<Self, Constraint = ()>,
180 {
181 self.decode_prefix_with_constraint(())
182 }
183
184 fn decode_prefix_with_constraint<T>(
185 &mut self,
186 constraint: T::Constraint,
187 ) -> Result<T, DecodeError>
188 where
189 T: Decode<Self>,
190 {
191 let mut slot = self.take_slot::<T>()?;
192 T::decode(slot.as_mut(), self, constraint)?;
193 self.commit();
194 unsafe { Ok(slot.as_mut_ptr().read()) }
197 }
198
199 fn decode<T>(&mut self) -> Result<T, DecodeError>
200 where
201 T: Decode<Self, Constraint = ()>,
202 {
203 self.decode_with_constraint(())
204 }
205
206 fn decode_with_constraint<T>(&mut self, constraint: T::Constraint) -> Result<T, DecodeError>
207 where
208 T: Decode<Self>,
209 {
210 let result = self.decode_prefix_with_constraint(constraint)?;
211 self.finish()?;
212 Ok(result)
213 }
214}