bufpool_fixed/
buf.rs

1use crate::FixedBufPool;
2use off64::usz;
3use std::borrow::Borrow;
4use std::borrow::BorrowMut;
5use std::cmp::Ordering;
6use std::fmt;
7use std::fmt::Debug;
8use std::hash::Hash;
9use std::hash::Hasher;
10use std::ops::Deref;
11use std::ops::DerefMut;
12use std::ops::Index;
13use std::ops::IndexMut;
14use std::slice;
15use std::slice::SliceIndex;
16
17pub struct FixedBuf {
18  pub(crate) ptr_and_cap: usize,
19  pub(crate) pool: FixedBufPool,
20}
21
22unsafe impl Send for FixedBuf {}
23unsafe impl Sync for FixedBuf {}
24
25impl FixedBuf {
26  fn ptr(&self) -> *mut u8 {
27    let raw = self.ptr_and_cap & !(self.pool.inner.align - 1);
28    raw as *mut u8
29  }
30
31  pub fn allocator(&self) -> &FixedBufPool {
32    &self.pool
33  }
34
35  pub fn as_slice(&self) -> &[u8] {
36    unsafe { slice::from_raw_parts(self.ptr(), self.capacity()) }
37  }
38
39  pub fn as_mut_slice(&mut self) -> &mut [u8] {
40    unsafe { slice::from_raw_parts_mut(self.ptr(), self.capacity()) }
41  }
42
43  pub fn capacity(&self) -> usize {
44    let l2 = self.ptr_and_cap & (self.pool.inner.align - 1);
45    1 << l2
46  }
47}
48
49impl AsRef<[u8]> for FixedBuf {
50  fn as_ref(&self) -> &[u8] {
51    self.as_slice()
52  }
53}
54
55impl AsMut<[u8]> for FixedBuf {
56  fn as_mut(&mut self) -> &mut [u8] {
57    self.as_mut_slice()
58  }
59}
60
61impl Borrow<[u8]> for FixedBuf {
62  fn borrow(&self) -> &[u8] {
63    self.as_slice()
64  }
65}
66
67impl BorrowMut<[u8]> for FixedBuf {
68  fn borrow_mut(&mut self) -> &mut [u8] {
69    self.as_mut_slice()
70  }
71}
72
73impl Clone for FixedBuf {
74  /// Uses the same pool that the current `FixedBuf` was allocated from.
75  fn clone(&self) -> Self {
76    self.pool.allocate_from_data(self)
77  }
78}
79
80impl Debug for FixedBuf {
81  fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
82    f.debug_struct("FixedBuf")
83      .field("data", &self.as_slice())
84      .finish()
85  }
86}
87
88impl Deref for FixedBuf {
89  type Target = [u8];
90
91  fn deref(&self) -> &Self::Target {
92    self.as_slice()
93  }
94}
95
96impl DerefMut for FixedBuf {
97  fn deref_mut(&mut self) -> &mut Self::Target {
98    self.as_mut_slice()
99  }
100}
101
102impl Drop for FixedBuf {
103  fn drop(&mut self) {
104    self.pool.inner.sizes[usz!(self.capacity().ilog2())]
105      .0
106      .lock()
107      .push_back(self.ptr_and_cap);
108  }
109}
110
111impl Eq for FixedBuf {}
112
113impl Hash for FixedBuf {
114  fn hash<H: Hasher>(&self, state: &mut H) {
115    self.as_slice().hash(state);
116  }
117}
118
119// Copied from Vec implementation.
120impl<I: SliceIndex<[u8]>> Index<I> for FixedBuf {
121  type Output = I::Output;
122
123  fn index(&self, index: I) -> &Self::Output {
124    Index::index(self.as_slice(), index)
125  }
126}
127
128// Copied from Vec implementation.
129impl<I: SliceIndex<[u8]>> IndexMut<I> for FixedBuf {
130  fn index_mut(&mut self, index: I) -> &mut Self::Output {
131    IndexMut::index_mut(self.as_mut_slice(), index)
132  }
133}
134
135impl Ord for FixedBuf {
136  fn cmp(&self, other: &Self) -> Ordering {
137    self.as_slice().cmp(other.as_slice())
138  }
139}
140
141impl PartialEq for FixedBuf {
142  fn eq(&self, other: &Self) -> bool {
143    self.ptr_and_cap == other.ptr_and_cap || self.as_slice() == other.as_slice()
144  }
145}
146
147impl PartialOrd for FixedBuf {
148  fn partial_cmp(&self, other: &Self) -> Option<Ordering> {
149    self.as_slice().partial_cmp(other.as_slice())
150  }
151}