tor-browser

The Tor Browser
git clone https://git.dasho.dev/tor-browser.git
Log | Files | Refs | README | LICENSE

owned_slice.rs (5340B)


      1 /* This Source Code Form is subject to the terms of the Mozilla Public
      2 * License, v. 2.0. If a copy of the MPL was not distributed with this
      3 * file, You can obtain one at https://mozilla.org/MPL/2.0/. */
      4 
      5 #![allow(unsafe_code)]
      6 
      7 //! A replacement for `Box<[T]>` that cbindgen can understand.
      8 
      9 use malloc_size_of::{MallocShallowSizeOf, MallocSizeOf, MallocSizeOfOps};
     10 use serde::de::{Deserialize, Deserializer};
     11 use serde::ser::{Serialize, Serializer};
     12 use std::marker::PhantomData;
     13 use std::ops::{Deref, DerefMut};
     14 use std::ptr::NonNull;
     15 use std::{
     16    fmt,
     17    hash::{Hash, Hasher},
     18    iter, mem, slice,
     19 };
     20 use to_shmem::{SharedMemoryBuilder, ToShmem};
     21 
     22 /// A struct that basically replaces a `Box<[T]>`, but which cbindgen can
     23 /// understand.
     24 ///
     25 /// We could rely on the struct layout of `Box<[T]>` per:
     26 ///
     27 ///   https://github.com/rust-lang/unsafe-code-guidelines/blob/master/reference/src/layout/pointers.md
     28 ///
     29 /// But handling fat pointers with cbindgen both in structs and argument
     30 /// positions more generally is a bit tricky.
     31 ///
     32 /// cbindgen:derive-eq=false
     33 /// cbindgen:derive-neq=false
     34 #[repr(C)]
     35 pub struct OwnedSlice<T: Sized> {
     36    ptr: NonNull<T>,
     37    len: usize,
     38    _phantom: PhantomData<T>,
     39 }
     40 
     41 impl<T: Sized> Default for OwnedSlice<T> {
     42    #[inline]
     43    fn default() -> Self {
     44        Self {
     45            len: 0,
     46            ptr: NonNull::dangling(),
     47            _phantom: PhantomData,
     48        }
     49    }
     50 }
     51 
     52 impl<T: Sized> Drop for OwnedSlice<T> {
     53    #[inline]
     54    fn drop(&mut self) {
     55        if self.len != 0 {
     56            let _ = mem::replace(self, Self::default()).into_vec();
     57        }
     58    }
     59 }
     60 
     61 unsafe impl<T: Sized + Send> Send for OwnedSlice<T> {}
     62 unsafe impl<T: Sized + Sync> Sync for OwnedSlice<T> {}
     63 
     64 impl<T: Clone> Clone for OwnedSlice<T> {
     65    #[inline]
     66    fn clone(&self) -> Self {
     67        Self::from_slice(&**self)
     68    }
     69 }
     70 
     71 impl<T: fmt::Debug> fmt::Debug for OwnedSlice<T> {
     72    fn fmt(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
     73        self.deref().fmt(formatter)
     74    }
     75 }
     76 
     77 impl<T: PartialEq> PartialEq for OwnedSlice<T> {
     78    fn eq(&self, other: &Self) -> bool {
     79        self.deref().eq(other.deref())
     80    }
     81 }
     82 
     83 impl<T: Eq> Eq for OwnedSlice<T> {}
     84 
     85 impl<T: Sized> OwnedSlice<T> {
     86    /// Convert the OwnedSlice into a boxed slice.
     87    #[inline]
     88    pub fn into_box(self) -> Box<[T]> {
     89        self.into_vec().into_boxed_slice()
     90    }
     91 
     92    /// Convert the OwnedSlice into a Vec.
     93    #[inline]
     94    pub fn into_vec(self) -> Vec<T> {
     95        let ret = unsafe { Vec::from_raw_parts(self.ptr.as_ptr(), self.len, self.len) };
     96        mem::forget(self);
     97        ret
     98    }
     99 
    100    /// Convert the regular slice into an owned slice.
    101    #[inline]
    102    pub fn from_slice(s: &[T]) -> Self
    103    where
    104        T: Clone,
    105    {
    106        Self::from(s.to_vec())
    107    }
    108 }
    109 
    110 impl<T> IntoIterator for OwnedSlice<T> {
    111    type Item = T;
    112    type IntoIter = <Vec<T> as IntoIterator>::IntoIter;
    113 
    114    #[inline]
    115    fn into_iter(self) -> Self::IntoIter {
    116        self.into_vec().into_iter()
    117    }
    118 }
    119 
    120 impl<T> Deref for OwnedSlice<T> {
    121    type Target = [T];
    122 
    123    #[inline(always)]
    124    fn deref(&self) -> &Self::Target {
    125        unsafe { slice::from_raw_parts(self.ptr.as_ptr(), self.len) }
    126    }
    127 }
    128 
    129 impl<T> DerefMut for OwnedSlice<T> {
    130    #[inline(always)]
    131    fn deref_mut(&mut self) -> &mut Self::Target {
    132        unsafe { slice::from_raw_parts_mut(self.ptr.as_ptr(), self.len) }
    133    }
    134 }
    135 
    136 impl<T> From<Box<[T]>> for OwnedSlice<T> {
    137    #[inline]
    138    fn from(mut b: Box<[T]>) -> Self {
    139        let len = b.len();
    140        let ptr = unsafe { NonNull::new_unchecked(b.as_mut_ptr()) };
    141        mem::forget(b);
    142        Self {
    143            len,
    144            ptr,
    145            _phantom: PhantomData,
    146        }
    147    }
    148 }
    149 
    150 impl<T> From<Vec<T>> for OwnedSlice<T> {
    151    #[inline]
    152    fn from(b: Vec<T>) -> Self {
    153        Self::from(b.into_boxed_slice())
    154    }
    155 }
    156 
    157 impl<T: Sized> MallocShallowSizeOf for OwnedSlice<T> {
    158    fn shallow_size_of(&self, ops: &mut MallocSizeOfOps) -> usize {
    159        unsafe { ops.malloc_size_of(self.ptr.as_ptr()) }
    160    }
    161 }
    162 
    163 impl<T: MallocSizeOf + Sized> MallocSizeOf for OwnedSlice<T> {
    164    fn size_of(&self, ops: &mut MallocSizeOfOps) -> usize {
    165        self.shallow_size_of(ops) + (**self).size_of(ops)
    166    }
    167 }
    168 
    169 impl<T: ToShmem + Sized> ToShmem for OwnedSlice<T> {
    170    fn to_shmem(&self, builder: &mut SharedMemoryBuilder) -> to_shmem::Result<Self> {
    171        unsafe {
    172            let dest = to_shmem::to_shmem_slice(self.iter(), builder)?;
    173            Ok(mem::ManuallyDrop::new(Self::from(Box::from_raw(dest))))
    174        }
    175    }
    176 }
    177 
    178 impl<T> iter::FromIterator<T> for OwnedSlice<T> {
    179    #[inline]
    180    fn from_iter<I: IntoIterator<Item = T>>(iter: I) -> Self {
    181        Vec::from_iter(iter).into()
    182    }
    183 }
    184 
    185 impl<T: Serialize> Serialize for OwnedSlice<T> {
    186    fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
    187    where
    188        S: Serializer,
    189    {
    190        self.deref().serialize(serializer)
    191    }
    192 }
    193 
    194 impl<'de, T: Deserialize<'de>> Deserialize<'de> for OwnedSlice<T> {
    195    fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
    196    where
    197        D: Deserializer<'de>,
    198    {
    199        let r = Box::<[T]>::deserialize(deserializer)?;
    200        Ok(r.into())
    201    }
    202 }
    203 
    204 impl<T: Hash> Hash for OwnedSlice<T> {
    205    fn hash<H: Hasher>(&self, state: &mut H) {
    206        T::hash_slice(&**self, state)
    207    }
    208 }