fidl_next_codec/wire/
ptr.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;
7
8use munge::munge;
9
10use crate::{Chunk, DecodeError, Slot, WireU64};
11use fidl_constants::{ALLOC_ABSENT_U64, ALLOC_PRESENT_U64};
12
13/// A raw FIDL pointer
14#[repr(C, align(8))]
15pub union WirePointer<'de, T> {
16    encoded: WireU64,
17    decoded: *mut T,
18    _phantom: PhantomData<&'de mut [Chunk]>,
19}
20
21unsafe impl<T: Send> Send for WirePointer<'_, T> {}
22unsafe impl<T: Sync> Sync for WirePointer<'_, T> {}
23
24impl<T> WirePointer<'_, T> {
25    /// Returns whether the wire pointer was encoded present.
26    pub fn is_encoded_present(slot: Slot<'_, Self>) -> Result<bool, DecodeError> {
27        munge!(let Self { encoded } = slot);
28        match **encoded {
29            ALLOC_ABSENT_U64 => Ok(false),
30            ALLOC_PRESENT_U64 => Ok(true),
31            x => Err(DecodeError::InvalidPointerPresence(x)),
32        }
33    }
34
35    /// Encodes that a pointer is present in an output.
36    pub fn encode_present(out: &mut MaybeUninit<Self>) {
37        munge!(let Self { encoded } = out);
38        encoded.write(WireU64(ALLOC_PRESENT_U64));
39    }
40
41    /// Encodes that a pointer is absent in a slot.
42    pub fn encode_absent(out: &mut MaybeUninit<Self>) {
43        munge!(let Self { encoded } = out);
44        encoded.write(WireU64(ALLOC_ABSENT_U64));
45    }
46
47    /// Sets the decoded value of the pointer.
48    pub fn set_decoded(slot: Slot<'_, Self>, ptr: *mut T) {
49        munge!(let Self { mut decoded } = slot);
50        // SAFETY: Identical to `decoded.write(ptr.into_raw())`, but raw
51        // pointers don't currently implement `IntoBytes`.
52        unsafe {
53            *decoded.as_mut_ptr() = ptr;
54        }
55    }
56
57    /// Returns the underlying pointer.
58    pub fn as_ptr(&self) -> *mut T {
59        unsafe { self.decoded }
60    }
61}