genet_abi/
slice.rs

1use std::{
2    io::{Error, ErrorKind, Result},
3    marker::PhantomData,
4    mem,
5    ops::{Deref, Range, RangeFrom, RangeFull, RangeInclusive, RangeTo, RangeToInclusive},
6    slice,
7};
8
9/// TryGet trait.
10pub trait TryGet<T> {
11    type Output;
12
13    /// Returns a byte or subslice depending on the type of index.
14    fn try_get(&self, index: T) -> Result<Self::Output>;
15}
16
17macro_rules! impl_slice_index {
18    ( $( $x:ty ), * ) => {
19        $(
20            impl TryGet<$x> for ByteSlice {
21                type Output = ByteSlice;
22
23                fn try_get(&self, index: $x) -> Result<ByteSlice> {
24                    <[u8]>::get(self, index)
25                        .map(|s| unsafe { ByteSlice::from_raw_parts(s.as_ptr(), s.len()) })
26                        .ok_or_else(|| Error::new(ErrorKind::Other, "out of bounds"))
27                }
28            }
29        )*
30    };
31}
32
33impl_slice_index!(
34    Range<usize>,
35    RangeFrom<usize>,
36    RangeFull,
37    RangeInclusive<usize>,
38    RangeTo<usize>,
39    RangeToInclusive<usize>
40);
41
42impl TryGet<usize> for ByteSlice {
43    type Output = u8;
44
45    fn try_get(&self, index: usize) -> Result<u8> {
46        <[u8]>::get(self, index)
47            .cloned()
48            .ok_or_else(|| Error::new(ErrorKind::Other, "out of bounds"))
49    }
50}
51
52/// A fixed-lifetime slice object.
53#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, Default)]
54pub struct ByteSlice(&'static [u8]);
55
56impl ByteSlice {
57    /// Creates a new empty ByteSlice.
58    pub fn new() -> ByteSlice {
59        ByteSlice(&[])
60    }
61
62    /// Creates a new ByteSlice from a length and pointer.
63    ///
64    /// The pointer must be valid during the program execution.
65    pub unsafe fn from_raw_parts(data: *const u8, len: usize) -> ByteSlice {
66        ByteSlice(slice::from_raw_parts(data, len))
67    }
68
69    /// Returns the length of this ByteSlice.
70    pub fn len(&self) -> usize {
71        self.0.len()
72    }
73
74    /// Returns true if this ByteSlice has a length of zero.
75    ///
76    /// Returns false otherwise.
77    pub fn is_empty(&self) -> bool {
78        self.len() == 0
79    }
80
81    /// Returns a raw pointer to the first byte in this ByteSlice.
82    pub fn as_ptr(&self) -> *const u8 {
83        self.0.as_ptr()
84    }
85}
86
87impl From<&'static [u8]> for ByteSlice {
88    fn from(data: &'static [u8]) -> Self {
89        ByteSlice(data)
90    }
91}
92
93impl From<Box<[u8]>> for ByteSlice {
94    fn from(data: Box<[u8]>) -> Self {
95        let s = unsafe { ByteSlice::from_raw_parts(data.as_ptr(), data.len()) };
96        mem::forget(data);
97        s
98    }
99}
100
101impl From<Vec<u8>> for ByteSlice {
102    fn from(data: Vec<u8>) -> Self {
103        ByteSlice::from(data.into_boxed_slice())
104    }
105}
106
107impl Deref for ByteSlice {
108    type Target = [u8];
109
110    fn deref(&self) -> &'static [u8] {
111        self.0
112    }
113}
114
115impl AsRef<[u8]> for ByteSlice {
116    #[inline]
117    fn as_ref(&self) -> &[u8] {
118        &self.0
119    }
120}
121
122#[repr(C)]
123struct SafeByteSlice<'a, T: 'a> {
124    ptr: *const T,
125    len: u64,
126    phantom: PhantomData<&'a T>,
127}
128
129impl<'a, T: 'a> SafeByteSlice<'a, T> {
130    pub fn as_slice(&self) -> &[T] {
131        unsafe { slice::from_raw_parts(&*self.ptr, self.len as usize) }
132    }
133}
134
135impl<'a, T: 'a> Deref for SafeByteSlice<'a, T> {
136    type Target = [T];
137
138    fn deref(&self) -> &[T] {
139        self.as_slice()
140    }
141}