Skip to main content

leveldb/database/
bytes.rs

1//! Bytes allocated by LevelDB.
2use ::std::slice;
3
4/// Bytes allocated by LevelDB
5///
6/// It's basically the same thing as `Box<[u8]>` except that it uses
7/// leveldb_free() as a destructor.
8pub struct Bytes {
9    // We use static reference instead of pointer to inform the compiler that
10    // it can't be null. (Because `NonZero` is unstable now.)
11    bytes: &'static mut u8,
12    size: usize,
13    // Tells the compiler that we own u8
14    _marker: ::std::marker::PhantomData<u8>,
15}
16
17impl Bytes {
18    /// Creates instance of `Bytes` from LevelDB-allocated data.
19    ///
20    /// Returns `None` if `ptr` is `null`.
21    ///
22    /// # Safety
23    ///
24    /// The caller must ensure that:
25    /// - `ptr` points to a valid memory block of at least `size` bytes
26    /// - The memory block was allocated by LevelDB
27    /// - The memory block remains valid for the lifetime of the returned `Bytes`
28    /// - If `ptr` is not null, it must be properly aligned for u8
29    pub unsafe fn from_raw(ptr: *mut u8, size: usize) -> Option<Self> {
30        if ptr.is_null() {
31            None
32        } else {
33            Some(Bytes {
34                bytes: unsafe { &mut *ptr },
35                size,
36                _marker: Default::default(),
37            })
38        }
39    }
40
41    /// Creates instance of `Bytes` from LevelDB-allocated data without null checking.
42    ///
43    /// # Safety
44    ///
45    /// The caller must ensure that:
46    /// - `ptr` is not null and points to a valid memory block of at least `size` bytes
47    /// - The memory block was allocated by LevelDB
48    /// - The memory block remains valid for the lifetime of the returned `Bytes`
49    /// - `ptr` is properly aligned for u8
50    pub unsafe fn from_raw_unchecked(ptr: *mut u8, size: usize) -> Self {
51        Bytes {
52            bytes: unsafe { &mut *ptr },
53            size,
54            _marker: Default::default(),
55        }
56    }
57}
58
59impl Drop for Bytes {
60    fn drop(&mut self) {
61        unsafe {
62            use libc::c_void;
63
64            crate::binding::leveldb_free(self.bytes as *mut u8 as *mut c_void);
65        }
66    }
67}
68
69impl ::std::ops::Deref for Bytes {
70    type Target = [u8];
71
72    fn deref(&self) -> &Self::Target {
73        unsafe { slice::from_raw_parts(self.bytes, self.size) }
74    }
75}
76
77impl AsRef<[u8]> for Bytes {
78    fn as_ref(&self) -> &[u8] {
79        self
80    }
81}