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 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
119impl<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
128impl<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}