Skip to main content

fidl_next_codec/wire/vec/
raw.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::mem::MaybeUninit;
6use core::ptr::slice_from_raw_parts_mut;
7
8use munge::munge;
9
10use crate::{Constrained, Slot, ValidationError, Wire, wire};
11
12#[repr(C)]
13pub struct RawVector<'de, T> {
14    pub len: wire::Uint64,
15    pub ptr: wire::Pointer<'de, T>,
16}
17
18impl<T> Constrained for RawVector<'_, T> {
19    type Constraint = ();
20
21    fn validate(_: Slot<'_, Self>, _: Self::Constraint) -> Result<(), ValidationError> {
22        Ok(())
23    }
24}
25
26unsafe impl<T: Wire> Wire for RawVector<'static, T> {
27    type Narrowed<'de> = RawVector<'de, T::Narrowed<'de>>;
28
29    #[inline]
30    fn zero_padding(_: &mut MaybeUninit<Self>) {
31        // Wire vectors have no padding bytes
32    }
33}
34
35// SAFETY: `RawWireVector` doesn't add any restrictions on sending across thread boundaries, and so
36// is `Send` if `T` is `Send`.
37unsafe impl<T: Send> Send for RawVector<'_, T> {}
38
39// SAFETY: `RawWireVector` doesn't add any interior mutability, so it is `Sync` if `T` is `Sync`.
40unsafe impl<T: Sync> Sync for RawVector<'_, T> {}
41
42impl<T> RawVector<'_, T> {
43    pub fn encode_present(out: &mut MaybeUninit<Self>, len: u64) {
44        munge!(let Self { len: encoded_len, ptr } = out);
45        encoded_len.write(wire::Uint64(len));
46        wire::Pointer::encode_present(ptr);
47    }
48
49    pub fn encode_absent(out: &mut MaybeUninit<Self>) {
50        munge!(let Self { len, ptr } = out);
51        len.write(wire::Uint64(0));
52        wire::Pointer::encode_absent(ptr);
53    }
54
55    pub fn len(&self) -> u64 {
56        *self.len
57    }
58
59    pub fn as_ptr(&self) -> *mut T {
60        self.ptr.as_ptr()
61    }
62
63    pub fn as_slice_ptr(&self) -> *mut [T] {
64        slice_from_raw_parts_mut(self.as_ptr(), self.len() as usize)
65    }
66}