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