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