1
  2
  3
  4
  5
  6
  7
  8
  9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 31
 32
 33
 34
 35
 36
 37
 38
 39
 40
 41
 42
 43
 44
 45
 46
 47
 48
 49
 50
 51
 52
 53
 54
 55
 56
 57
 58
 59
 60
 61
 62
 63
 64
 65
 66
 67
 68
 69
 70
 71
 72
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
use core::fmt;
use core::hash;
use core::marker::PhantomData;
use core::ptr::NonNull;
use core::slice;
use crate::block::ZSP;

/// Address, size, and lifetime of a raw memory area.
#[derive(Clone, Copy)]
pub struct Block<'a> {
    /// Non-null pointer to the base address of the memory area.
    data: NonNull<u8>,
    /// Number of bytes in the memory area.
    size: usize,
    /// Covariant lifetime of the memory area.
    marker: PhantomData<&'a ()>,
}

unsafe impl<'a> Send for Block<'a> {
}

unsafe impl<'a> Sync for Block<'a> {
}

impl<'a> Block<'a> {
    /// Returns a zero-length `Block` with an undereferenceable sentinel pointer.
    #[inline]
    pub const fn empty() -> Block<'a> {
        Block {
            data: unsafe { NonNull::new_unchecked(ZSP) },
            size: 0,
            marker: PhantomData,
        }
    }

    /// Constructs a `Block` from a non-zero `data` pointer to `size` bytes.
    ///
    /// # Safety
    ///
    /// The returned `Block` logically takes ownership of the pointed-to `data`.
    #[inline]
    pub const unsafe fn from_raw_parts(data: *mut u8, size: usize) -> Block<'a> {
        Block {
            data: NonNull::new_unchecked(data),
            size: size,
            marker: PhantomData,
        }
    }

    /// Constructs a `Block` from a slice of bytes.
    ///
    /// # Safety
    ///
    /// The returned `Block` logically takes ownership of the bytes in `slice`.
    #[inline]
    pub fn from_slice(slice: &'a mut [u8]) -> Block<'a> {
        Block {
            data: unsafe { NonNull::new_unchecked(slice.as_mut_ptr()) },
            size: slice.len(),
            marker: PhantomData,
        }
    }

    /// Returns the number of bytes of memory owned by this `Block`.
    #[inline]
    pub fn size(&self) -> usize {
        self.size
    }

    /// Returns a slice of the memory owned by this `Block`.
    #[inline]
    pub fn as_slice(&self) -> &[u8] {
        unsafe { slice::from_raw_parts(self.data.as_ptr(), self.size) }
    }

    /// Returns a mutable slice of the memory owned by this `Block`.
    #[inline]
    pub fn as_mut_slice(&mut self) -> &mut [u8] {
        unsafe { slice::from_raw_parts_mut(self.data.as_ptr(), self.size) }
    }

    /// Returns a pointer to the memory owned by this `Block.`
    #[inline]
    pub fn as_ptr(&self) -> *mut u8 {
        self.data.as_ptr()
    }

    /// Consumes this `Block` and returns a mutable pointer to its memory.
    #[inline]
    pub fn into_raw(self) -> *mut u8 {
        self.data.as_ptr()
    }
}

impl<'a> PartialEq for Block<'a> {
    #[inline]
    fn eq(&self, other: &Self) -> bool {
        self.data.as_ptr() == other.data.as_ptr() && self.size == other.size
    }
}

impl<'a> Eq for Block<'a> {
}

impl<'a> hash::Hash for Block<'a> {
    #[inline]
    fn hash<H: hash::Hasher>(&self, state: &mut H) {
        self.data.as_ptr().hash(state)
    }
}

impl<'a> fmt::Debug for Block<'a> {
    #[inline]
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        fmt::Pointer::fmt(&self.data.as_ptr(), f)
    }
}

impl<'a> fmt::Pointer for Block<'a> {
    #[inline]
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        fmt::Pointer::fmt(&self.data.as_ptr(), f)
    }
}