fidl_next_codec/wire/vec/
required.rs

1// Copyright 2024 The Fuchsia Authors. All rights reserved.
2// Use of this source code is governed by a BSD-style license that can be
3// found in the LICENSE file.
4
5use core::marker::PhantomData;
6use core::mem::{MaybeUninit, forget, needs_drop};
7use core::ops::Deref;
8use core::ptr::{NonNull, copy_nonoverlapping};
9use core::{fmt, slice};
10
11use munge::munge;
12
13use super::raw::RawWireVector;
14use crate::{
15    Chunk, Decode, DecodeError, Decoder, DecoderExt as _, Encodable, Encode, EncodeError,
16    EncodeRef, Encoder, EncoderExt as _, FromWire, FromWireRef, IntoNatural, Slot, Wire,
17    WirePointer,
18};
19
20/// A FIDL vector
21#[repr(transparent)]
22pub struct WireVector<'de, T> {
23    pub(crate) raw: RawWireVector<'de, T>,
24}
25
26unsafe impl<T: Wire> Wire for WireVector<'static, T> {
27    type Decoded<'de> = WireVector<'de, T::Decoded<'de>>;
28
29    #[inline]
30    fn zero_padding(out: &mut MaybeUninit<Self>) {
31        munge!(let Self { raw } = out);
32        RawWireVector::<T>::zero_padding(raw);
33    }
34}
35
36impl<T> Drop for WireVector<'_, T> {
37    fn drop(&mut self) {
38        if needs_drop::<T>() {
39            unsafe {
40                self.raw.as_slice_ptr().drop_in_place();
41            }
42        }
43    }
44}
45
46impl<T> WireVector<'_, T> {
47    /// Encodes that a vector is present in a slot.
48    pub fn encode_present(out: &mut MaybeUninit<Self>, len: u64) {
49        munge!(let Self { raw } = out);
50        RawWireVector::encode_present(raw, len);
51    }
52
53    /// Returns the length of the vector in elements.
54    pub fn len(&self) -> usize {
55        self.raw.len() as usize
56    }
57
58    /// Returns whether the vector is empty.
59    pub fn is_empty(&self) -> bool {
60        self.len() == 0
61    }
62
63    /// Returns a pointer to the elements of the vector.
64    fn as_slice_ptr(&self) -> NonNull<[T]> {
65        unsafe { NonNull::new_unchecked(self.raw.as_slice_ptr()) }
66    }
67
68    /// Returns a slice of the elements of the vector.
69    pub fn as_slice(&self) -> &[T] {
70        unsafe { self.as_slice_ptr().as_ref() }
71    }
72
73    /// Decodes a wire vector which contains raw data.
74    ///
75    /// # Safety
76    ///
77    /// The elements of the wire vector must not need to be individually decoded, and must always be
78    /// valid.
79    pub unsafe fn decode_raw<D>(
80        mut slot: Slot<'_, Self>,
81        mut decoder: &mut D,
82    ) -> Result<(), DecodeError>
83    where
84        D: Decoder + ?Sized,
85        T: Decode<D>,
86    {
87        munge!(let Self { raw: RawWireVector { len, mut ptr } } = slot.as_mut());
88
89        if !WirePointer::is_encoded_present(ptr.as_mut())? {
90            return Err(DecodeError::RequiredValueAbsent);
91        }
92
93        let mut slice = decoder.take_slice_slot::<T>(**len as usize)?;
94        WirePointer::set_decoded(ptr, slice.as_mut_ptr().cast());
95
96        Ok(())
97    }
98}
99
100/// An iterator over the items of a `WireVector`.
101pub struct IntoIter<'de, T> {
102    current: *mut T,
103    remaining: usize,
104    _phantom: PhantomData<&'de mut [Chunk]>,
105}
106
107impl<T> Drop for IntoIter<'_, T> {
108    fn drop(&mut self) {
109        for i in 0..self.remaining {
110            unsafe {
111                self.current.add(i).drop_in_place();
112            }
113        }
114    }
115}
116
117impl<T> Iterator for IntoIter<'_, T> {
118    type Item = T;
119
120    fn next(&mut self) -> Option<Self::Item> {
121        if self.remaining == 0 {
122            None
123        } else {
124            let result = unsafe { self.current.read() };
125            self.current = unsafe { self.current.add(1) };
126            self.remaining -= 1;
127            Some(result)
128        }
129    }
130}
131
132impl<'de, T> IntoIterator for WireVector<'de, T> {
133    type IntoIter = IntoIter<'de, T>;
134    type Item = T;
135
136    fn into_iter(self) -> Self::IntoIter {
137        let current = self.raw.as_ptr();
138        let remaining = self.len();
139        forget(self);
140
141        IntoIter { current, remaining, _phantom: PhantomData }
142    }
143}
144
145impl<T> Deref for WireVector<'_, T> {
146    type Target = [T];
147
148    fn deref(&self) -> &Self::Target {
149        self.as_slice()
150    }
151}
152
153impl<T: fmt::Debug> fmt::Debug for WireVector<'_, T> {
154    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
155        self.as_slice().fmt(f)
156    }
157}
158
159unsafe impl<D: Decoder + ?Sized, T: Decode<D>> Decode<D> for WireVector<'static, T> {
160    fn decode(mut slot: Slot<'_, Self>, mut decoder: &mut D) -> Result<(), DecodeError> {
161        munge!(let Self { raw: RawWireVector { len, mut ptr } } = slot.as_mut());
162
163        if !WirePointer::is_encoded_present(ptr.as_mut())? {
164            return Err(DecodeError::RequiredValueAbsent);
165        }
166
167        let mut slice = decoder.take_slice_slot::<T>(**len as usize)?;
168        for i in 0..**len as usize {
169            T::decode(slice.index(i), decoder)?;
170        }
171        WirePointer::set_decoded(ptr, slice.as_mut_ptr().cast());
172
173        Ok(())
174    }
175}
176
177#[inline]
178fn encode_to_vector<V, E, T>(
179    value: V,
180    encoder: &mut E,
181    out: &mut MaybeUninit<WireVector<'_, T::Encoded>>,
182) -> Result<(), EncodeError>
183where
184    V: AsRef<[T]> + IntoIterator,
185    V::IntoIter: ExactSizeIterator,
186    V::Item: Encode<E, Encoded = T::Encoded>,
187    E: Encoder + ?Sized,
188    T: Encode<E>,
189{
190    let len = value.as_ref().len();
191    if T::COPY_OPTIMIZATION.is_enabled() {
192        let slice = value.as_ref();
193        // SAFETY: `T` has copy optimization enabled, which guarantees that it has no uninit bytes
194        // and can be copied directly to the output instead of calling `encode`. This means that we
195        // may cast `&[T]` to `&[u8]` and write those bytes.
196        let bytes = unsafe { slice::from_raw_parts(slice.as_ptr().cast(), size_of_val(slice)) };
197        encoder.write(bytes);
198    } else {
199        encoder.encode_next_iter(value.into_iter())?;
200    }
201    WireVector::encode_present(out, len as u64);
202    Ok(())
203}
204
205impl<T: Encodable> Encodable for Vec<T> {
206    type Encoded = WireVector<'static, T::Encoded>;
207}
208
209unsafe impl<E, T> Encode<E> for Vec<T>
210where
211    E: Encoder + ?Sized,
212    T: Encode<E>,
213{
214    fn encode(
215        self,
216        encoder: &mut E,
217        out: &mut MaybeUninit<Self::Encoded>,
218    ) -> Result<(), EncodeError> {
219        encode_to_vector(self, encoder, out)
220    }
221}
222
223unsafe impl<E, T> EncodeRef<E> for Vec<T>
224where
225    E: Encoder + ?Sized,
226    T: EncodeRef<E>,
227{
228    fn encode_ref(
229        &self,
230        encoder: &mut E,
231        out: &mut MaybeUninit<Self::Encoded>,
232    ) -> Result<(), EncodeError> {
233        encode_to_vector(self, encoder, out)
234    }
235}
236
237impl<T: Encodable> Encodable for &[T] {
238    type Encoded = WireVector<'static, T::Encoded>;
239}
240
241unsafe impl<E, T> Encode<E> for &[T]
242where
243    E: Encoder + ?Sized,
244    T: EncodeRef<E>,
245{
246    fn encode(
247        self,
248        encoder: &mut E,
249        out: &mut MaybeUninit<Self::Encoded>,
250    ) -> Result<(), EncodeError> {
251        encode_to_vector(self, encoder, out)
252    }
253}
254
255impl<T: FromWire<W>, W> FromWire<WireVector<'_, W>> for Vec<T> {
256    fn from_wire(wire: WireVector<'_, W>) -> Self {
257        let mut result = Vec::<T>::with_capacity(wire.len());
258        if T::COPY_OPTIMIZATION.is_enabled() {
259            unsafe {
260                copy_nonoverlapping(wire.as_ptr().cast(), result.as_mut_ptr(), wire.len());
261            }
262            unsafe {
263                result.set_len(wire.len());
264            }
265            forget(wire);
266        } else {
267            for item in wire.into_iter() {
268                result.push(T::from_wire(item));
269            }
270        }
271        result
272    }
273}
274
275impl<T: IntoNatural> IntoNatural for WireVector<'_, T> {
276    type Natural = Vec<T::Natural>;
277}
278
279impl<T: FromWireRef<W>, W> FromWireRef<WireVector<'_, W>> for Vec<T> {
280    fn from_wire_ref(wire: &WireVector<'_, W>) -> Self {
281        let mut result = Vec::<T>::with_capacity(wire.len());
282        if T::COPY_OPTIMIZATION.is_enabled() {
283            unsafe {
284                copy_nonoverlapping(wire.as_ptr().cast(), result.as_mut_ptr(), wire.len());
285            }
286            unsafe {
287                result.set_len(wire.len());
288            }
289        } else {
290            for item in wire.iter() {
291                result.push(T::from_wire_ref(item));
292            }
293        }
294        result
295    }
296}