fidl_next_codec/
decoder.rs1use core::mem::take;
8use core::ptr::NonNull;
9use core::slice;
10
11use crate::{Chunk, Decode, DecodeError, Decoded, Owned, Slot, CHUNK_SIZE};
12
13pub trait InternalHandleDecoder {
15 #[doc(hidden)]
20 fn __internal_take_handles(&mut self, count: usize) -> Result<(), DecodeError>;
21
22 #[doc(hidden)]
27 fn __internal_handles_remaining(&self) -> usize;
28}
29
30pub unsafe trait Decoder: InternalHandleDecoder {
42 fn take_chunks_raw(&mut self, count: usize) -> Result<NonNull<Chunk>, DecodeError>;
46
47 fn commit(&mut self);
54
55 fn finish(&self) -> Result<(), DecodeError>;
57}
58
59impl InternalHandleDecoder for &mut [Chunk] {
60 #[inline]
61 fn __internal_take_handles(&mut self, _: usize) -> Result<(), DecodeError> {
62 Err(DecodeError::InsufficientHandles)
63 }
64
65 #[inline]
66 fn __internal_handles_remaining(&self) -> usize {
67 0
68 }
69}
70
71unsafe impl Decoder for &mut [Chunk] {
72 #[inline]
73 fn take_chunks_raw(&mut self, count: usize) -> Result<NonNull<Chunk>, DecodeError> {
74 if count > self.len() {
75 return Err(DecodeError::InsufficientData);
76 }
77
78 let chunks = take(self);
79 let (prefix, suffix) = unsafe { chunks.split_at_mut_unchecked(count) };
80 *self = suffix;
81 unsafe { Ok(NonNull::new_unchecked(prefix.as_mut_ptr())) }
82 }
83
84 #[inline]
85 fn commit(&mut self) {
86 }
88
89 #[inline]
90 fn finish(&self) -> Result<(), DecodeError> {
91 if !self.is_empty() {
92 return Err(DecodeError::ExtraBytes { num_extra: self.len() * CHUNK_SIZE });
93 }
94
95 Ok(())
96 }
97}
98
99pub trait DecoderExt {
101 fn take_chunks<'buf>(
103 self: &mut &'buf mut Self,
104 count: usize,
105 ) -> Result<&'buf mut [Chunk], DecodeError>;
106
107 fn take_slot<'buf, T>(self: &mut &'buf mut Self) -> Result<Slot<'buf, T>, DecodeError>;
109
110 fn take_slice_slot<'buf, T>(
112 self: &mut &'buf mut Self,
113 len: usize,
114 ) -> Result<Slot<'buf, [T]>, DecodeError>;
115
116 fn decode_prefix<'buf, T: Decode<Self>>(
120 self: &mut &'buf mut Self,
121 ) -> Result<Owned<'buf, T>, DecodeError>;
122
123 fn decode_slice_prefix<'buf, T: Decode<Self>>(
127 self: &mut &'buf mut Self,
128 len: usize,
129 ) -> Result<Owned<'buf, [T]>, DecodeError>;
130
131 fn decode<T>(self) -> Result<Decoded<T, Self>, DecodeError>
136 where
137 T: Decode<Self>,
138 Self: Sized;
139
140 fn decode_slice<T>(self, len: usize) -> Result<Decoded<[T], Self>, DecodeError>
145 where
146 T: Decode<Self>,
147 Self: Sized;
148}
149
150impl<D: Decoder + ?Sized> DecoderExt for D {
151 fn take_chunks<'buf>(
152 self: &mut &'buf mut Self,
153 count: usize,
154 ) -> Result<&'buf mut [Chunk], DecodeError> {
155 self.take_chunks_raw(count).map(|p| unsafe { slice::from_raw_parts_mut(p.as_ptr(), count) })
156 }
157
158 fn take_slot<'buf, T>(self: &mut &'buf mut Self) -> Result<Slot<'buf, T>, DecodeError> {
159 assert!(
162 align_of::<T>() <= CHUNK_SIZE,
163 "attempted to take a slot for a type with an alignment higher \
164 than {CHUNK_SIZE}",
165 );
166
167 let count = size_of::<T>().div_ceil(CHUNK_SIZE);
168 let chunks = self.take_chunks(count)?;
169 unsafe { Ok(Slot::new_unchecked(chunks.as_mut_ptr().cast())) }
172 }
173
174 fn take_slice_slot<'buf, T>(
175 self: &mut &'buf mut Self,
176 len: usize,
177 ) -> Result<Slot<'buf, [T]>, DecodeError> {
178 assert!(
179 align_of::<T>() <= CHUNK_SIZE,
180 "attempted to take a slice slot for a type with an alignment \
181 higher than {CHUNK_SIZE}",
182 );
183
184 let count = (size_of::<T>() * len).div_ceil(CHUNK_SIZE);
185 let chunks = self.take_chunks(count)?;
186 unsafe { Ok(Slot::new_slice_unchecked(chunks.as_mut_ptr().cast(), len)) }
189 }
190
191 fn decode_prefix<'buf, T: Decode<Self>>(
192 self: &mut &'buf mut Self,
193 ) -> Result<Owned<'buf, T>, DecodeError> {
194 let mut slot = self.take_slot::<T>()?;
195 T::decode(slot.as_mut(), self)?;
196 self.commit();
197 unsafe { Ok(Owned::new_unchecked(slot.as_mut_ptr())) }
200 }
201
202 fn decode_slice_prefix<'buf, T: Decode<Self>>(
203 self: &mut &'buf mut Self,
204 len: usize,
205 ) -> Result<Owned<'buf, [T]>, DecodeError> {
206 let mut slot = self.take_slice_slot::<T>(len)?;
207 for i in 0..len {
208 T::decode(slot.index(i), self)?;
209 }
210 self.commit();
211 unsafe { Ok(Owned::new_unchecked(slot.as_mut_ptr())) }
214 }
215
216 fn decode<T>(mut self) -> Result<Decoded<T, Self>, DecodeError>
217 where
218 T: Decode<Self>,
219 Self: Sized,
220 {
221 let mut decoder = &mut self;
222 let result = decoder.decode_prefix::<T>()?;
223 decoder.finish()?;
224 unsafe { Ok(Decoded::new_unchecked(result.into_raw(), self)) }
226 }
227
228 fn decode_slice<T: Decode<Self>>(
229 mut self,
230 len: usize,
231 ) -> Result<Decoded<[T], Self>, DecodeError>
232 where
233 Self: Sized,
234 {
235 let mut decoder = &mut self;
236 let result = decoder.decode_slice_prefix::<T>(len)?;
237 decoder.finish()?;
238 unsafe { Ok(Decoded::new_unchecked(result.into_raw(), self)) }
240 }
241}