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}