below_btrfs/btrfs_api/
utils.rs

1// Copyright (c) Facebook, Inc. and its affiliates.
2//
3// Licensed under the Apache License, Version 2.0 (the "License");
4// you may not use this file except in compliance with the License.
5// You may obtain a copy of the License at
6//
7//     http://www.apache.org/licenses/LICENSE-2.0
8//
9// Unless required by applicable law or agreed to in writing, software
10// distributed under the License is distributed on an "AS IS" BASIS,
11// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12// See the License for the specific language governing permissions and
13// limitations under the License.
14
15use std::ops::Deref;
16use std::ops::DerefMut;
17
18#[repr(C)]
19pub struct WithMemAfter<T, const N: usize> {
20    value: T,
21    extra: [u8; N],
22}
23
24impl<T: Sized, const N: usize> Default for WithMemAfter<T, N> {
25    fn default() -> Self {
26        Self::new()
27    }
28}
29
30impl<T: Sized, const N: usize> WithMemAfter<T, N> {
31    pub fn new() -> Self {
32        unsafe {
33            WithMemAfter {
34                value: std::mem::zeroed(),
35                extra: [0; N],
36            }
37        }
38    }
39
40    pub fn as_mut_ptr(&mut self) -> *mut T {
41        &mut self.value
42    }
43
44    pub fn total_size(&self) -> usize {
45        std::mem::size_of::<Self>()
46    }
47
48    pub fn extra_ptr(&self) -> *const u8 {
49        self.extra.as_ptr()
50    }
51
52    pub fn extra_size(&self) -> usize {
53        N
54    }
55}
56
57impl<T: Sized, const N: usize> Deref for WithMemAfter<T, N> {
58    type Target = T;
59
60    fn deref(&self) -> &Self::Target {
61        &self.value
62    }
63}
64
65impl<T: Sized, const N: usize> DerefMut for WithMemAfter<T, N> {
66    fn deref_mut(&mut self) -> &mut Self::Target {
67        &mut self.value
68    }
69}
70
71/// # Safety
72///
73/// Refer to the documentation of `core::ptr::const_ptr::add()`.
74pub unsafe fn get_and_move(ptr: &mut *const u8, n: usize) -> *const u8 {
75    let res = *ptr;
76    *ptr = (*ptr).add(n);
77    res
78}
79
80/// # Safety
81///
82/// Refer to the documentation of `get_and_move()`.
83pub unsafe fn get_and_move_typed<T: Sized>(ptr: &mut *const u8) -> *const T {
84    get_and_move(ptr, std::mem::size_of::<T>()) as *const T
85}