Skip to main content

iceoryx2_cal/shm_allocator/
pointer_offset.rs

1// Copyright (c) 2023 Contributors to the Eclipse Foundation
2//
3// See the NOTICE file(s) distributed with this work for additional
4// information regarding copyright ownership.
5//
6// This program and the accompanying materials are made available under the
7// terms of the Apache Software License 2.0 which is available at
8// https://www.apache.org/licenses/LICENSE-2.0, or the MIT license
9// which is available at https://opensource.org/licenses/MIT.
10//
11// SPDX-License-Identifier: Apache-2.0 OR MIT
12
13use core::fmt::Debug;
14
15pub type SegmentIdUnderlyingType = u8;
16
17/// Defines the [`SegmentId`] of a [`SharedMemory`](crate::shared_memory::SharedMemory)
18#[derive(Debug, Clone, Copy, PartialEq, Eq)]
19pub struct SegmentId(SegmentIdUnderlyingType);
20
21impl SegmentId {
22    /// Creates a new [`SegmentId`] from a given value.
23    pub const fn new(value: SegmentIdUnderlyingType) -> Self {
24        Self(value)
25    }
26
27    /// Returns the underlying value of the [`SegmentId`]
28    pub const fn value(&self) -> SegmentIdUnderlyingType {
29        self.0
30    }
31
32    /// Returns the maximum value the [`SegmentId`] supports.
33    pub const fn max_segment_id() -> SegmentIdUnderlyingType {
34        SegmentIdUnderlyingType::MAX
35    }
36}
37
38/// An offset to a [`SharedMemory`](crate::shared_memory::SharedMemory) address. It requires the
39///
40/// [`SharedMemory::payload_start_address()`](crate::shared_memory::SharedMemory::payload_start_address())
41/// of the corresponding [`SharedMemory`](crate::shared_memory::SharedMemory) to be converted into
42/// an actual pointer.
43///
44/// Contains the offset and the corresponding [`SegmentId`].
45#[derive(Clone, Copy, Eq, PartialEq)]
46pub struct PointerOffset(u64);
47
48impl PointerOffset {
49    /// Creates a new [`PointerOffset`] from the given offset value with the [`SegmentId`] == 0.
50    pub const fn new(offset: usize) -> PointerOffset {
51        const SEGMENT_ID: u8 = 0;
52        Self::from_offset_and_segment_id(offset, SegmentId::new(SEGMENT_ID))
53    }
54
55    /// Creates a new [`PointerOffset`] from an offset and a [`SegmentId`]
56    pub const fn from_offset_and_segment_id(offset: usize, segment_id: SegmentId) -> PointerOffset {
57        Self(((offset as u64) << (SegmentIdUnderlyingType::BITS)) | segment_id.value() as u64)
58    }
59
60    /// Creates a new [`PointerOffset`] from a provided raw value.
61    pub const fn from_value(value: u64) -> PointerOffset {
62        Self(value)
63    }
64
65    /// Returns the underlying raw value of the [`PointerOffset`]
66    pub const fn as_value(&self) -> u64 {
67        self.0
68    }
69
70    /// Sets the [`SegmentId`] of the [`PointerOffset`].
71    pub fn set_segment_id(&mut self, value: SegmentId) {
72        self.0 &= !((1u64 << SegmentIdUnderlyingType::BITS) - 1);
73        self.0 |= value.0 as u64;
74    }
75
76    /// Returns the offset.
77    pub const fn offset(&self) -> usize {
78        (self.0 >> (SegmentIdUnderlyingType::BITS)) as usize
79    }
80
81    /// Returns the [`SegmentId`].
82    pub const fn segment_id(&self) -> SegmentId {
83        SegmentId((self.0 & ((1u64 << SegmentIdUnderlyingType::BITS) - 1)) as u8)
84    }
85}
86
87impl Debug for PointerOffset {
88    fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
89        write!(
90            f,
91            "PointerOffset {{ offset: {}, segment_id: {:?} }}",
92            self.offset(),
93            self.segment_id()
94        )
95    }
96}