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
26// SAFETY: `RawVector` is `repr(C)` and contains only `Wire` types (`wire::Uint64` and
27// `wire::Pointer`). It has no padding bytes, and lifetime erasure is safe since `RawVector` is
28// covariant over its lifetime.
29unsafe impl<T: Wire> Wire for RawVector<'static, T> {
30    type Narrowed<'de> = RawVector<'de, T::Narrowed<'de>>;
31
32    #[inline]
33    fn zero_padding(_: &mut MaybeUninit<Self>) {
34        // Wire vectors have no padding bytes
35    }
36}
37
38// SAFETY: `RawWireVector` doesn't add any restrictions on sending across thread boundaries, and so
39// is `Send` if `T` is `Send`.
40unsafe impl<T: Send> Send for RawVector<'_, T> {}
41
42// SAFETY: `RawWireVector` doesn't add any interior mutability, so it is `Sync` if `T` is `Sync`.
43unsafe impl<T: Sync> Sync for RawVector<'_, T> {}
44
45impl<T> RawVector<'_, T> {
46    pub fn encode_present(out: &mut MaybeUninit<Self>, len: u64) {
47        munge!(let Self { len: encoded_len, ptr } = out);
48        encoded_len.write(wire::Uint64(len));
49        wire::Pointer::encode_present(ptr);
50    }
51
52    pub fn encode_absent(out: &mut MaybeUninit<Self>) {
53        munge!(let Self { len, ptr } = out);
54        len.write(wire::Uint64(0));
55        wire::Pointer::encode_absent(ptr);
56    }
57
58    pub fn len(&self) -> u64 {
59        *self.len
60    }
61
62    pub fn as_ptr(&self) -> *mut T {
63        self.ptr.as_ptr()
64    }
65
66    pub fn as_slice_ptr(&self) -> *mut [T] {
67        slice_from_raw_parts_mut(self.as_ptr(), self.len() as usize)
68    }
69}