1use bytes::{Bytes, BytesMut};
2
3pub unsafe trait IoBuf {
9 fn stable_ptr(&self) -> *const u8;
11
12 fn bytes_init(&self) -> usize;
14
15 fn bytes_total(&self) -> usize;
18
19 fn slice(self, range: impl std::ops::RangeBounds<usize>) -> Slice<Self>
21 where
22 Self: Sized,
23 {
24 let begin = match range.start_bound() {
25 std::ops::Bound::Included(&n) => n,
26 std::ops::Bound::Unbounded => 0,
27 _ => unreachable!(),
28 };
29 let end = match range.end_bound() {
30 std::ops::Bound::Excluded(&n) => n,
31 std::ops::Bound::Included(&n) => n + 1,
32 std::ops::Bound::Unbounded => self.bytes_total(),
33 };
34 assert!(begin <= end && end <= self.bytes_total());
35 Slice::new(self, begin, end)
36 }
37}
38
39pub unsafe trait IoBufMut: IoBuf {
45 fn stable_mut_ptr(&mut self) -> *mut u8;
47
48 unsafe fn set_init(&mut self, pos: usize);
55
56 fn clear(&mut self) {
58 unsafe { self.set_init(0) };
60 }
61}
62
63#[derive(Debug)]
70pub struct Slice<B> {
71 buf: B,
72 begin: usize,
73 end: usize,
74}
75
76impl<B: IoBuf> Slice<B> {
77 pub fn new(buf: B, begin: usize, end: usize) -> Self {
83 assert!(begin <= end && end <= buf.bytes_total());
84 Self { buf, begin, end }
85 }
86
87 pub fn into_inner(self) -> B {
89 self.buf
90 }
91
92 pub fn len(&self) -> usize {
94 self.bytes_init()
95 }
96
97 pub fn is_empty(&self) -> bool {
99 self.bytes_init() == 0
100 }
101}
102
103unsafe impl<B: IoBuf> IoBuf for Slice<B> {
104 fn stable_ptr(&self) -> *const u8 {
105 unsafe { self.buf.stable_ptr().add(self.begin) }
106 }
107
108 fn bytes_init(&self) -> usize {
109 self.buf
111 .bytes_init()
112 .saturating_sub(self.begin)
113 .min(self.end - self.begin)
114 }
115
116 fn bytes_total(&self) -> usize {
117 self.end - self.begin
118 }
119}
120
121unsafe impl<B: IoBufMut> IoBufMut for Slice<B> {
122 fn stable_mut_ptr(&mut self) -> *mut u8 {
123 unsafe { self.buf.stable_mut_ptr().add(self.begin) }
124 }
125
126 unsafe fn set_init(&mut self, pos: usize) {
127 unsafe { self.buf.set_init(self.begin + pos) };
129 }
130}
131
132impl<B: IoBuf> AsRef<[u8]> for Slice<B> {
133 fn as_ref(&self) -> &[u8] {
134 let ptr = self.stable_ptr();
135 let len = self.bytes_init();
136 unsafe { std::slice::from_raw_parts(ptr, len) }
138 }
139}
140
141pub enum MaybeRegistered<R, F> {
142 Registered(R),
143 Fallback(F),
144}
145
146unsafe impl<R: IoBuf, F: IoBuf> IoBuf for MaybeRegistered<R, F> {
147 fn stable_ptr(&self) -> *const u8 {
148 match self {
149 Self::Registered(r) => r.stable_ptr(),
150 Self::Fallback(f) => f.stable_ptr(),
151 }
152 }
153
154 fn bytes_init(&self) -> usize {
155 match self {
156 Self::Registered(r) => r.bytes_init(),
157 Self::Fallback(f) => f.bytes_init(),
158 }
159 }
160
161 fn bytes_total(&self) -> usize {
162 match self {
163 Self::Registered(r) => r.bytes_total(),
164 Self::Fallback(f) => f.bytes_total(),
165 }
166 }
167}
168
169unsafe impl<R: IoBufMut, F: IoBufMut> IoBufMut for MaybeRegistered<R, F> {
170 fn stable_mut_ptr(&mut self) -> *mut u8 {
171 match self {
172 Self::Registered(r) => r.stable_mut_ptr(),
173 Self::Fallback(f) => f.stable_mut_ptr(),
174 }
175 }
176
177 unsafe fn set_init(&mut self, pos: usize) {
178 unsafe {
180 match self {
181 Self::Registered(r) => r.set_init(pos),
182 Self::Fallback(f) => f.set_init(pos),
183 }
184 }
185 }
186}
187
188unsafe impl<const N: usize> IoBuf for [u8; N] {
189 fn stable_ptr(&self) -> *const u8 {
190 self.as_ptr()
191 }
192
193 fn bytes_init(&self) -> usize {
194 N
195 }
196
197 fn bytes_total(&self) -> usize {
198 N
199 }
200}
201
202unsafe impl<const N: usize> IoBufMut for [u8; N] {
203 fn stable_mut_ptr(&mut self) -> *mut u8 {
204 self.as_mut_ptr()
205 }
206
207 unsafe fn set_init(&mut self, _pos: usize) {} }
209
210unsafe impl IoBuf for &'static [u8] {
211 fn stable_ptr(&self) -> *const u8 {
212 self.as_ptr()
213 }
214
215 fn bytes_init(&self) -> usize {
216 self.len()
217 }
218
219 fn bytes_total(&self) -> usize {
220 self.len()
221 }
222}
223
224unsafe impl IoBuf for Bytes {
225 fn stable_ptr(&self) -> *const u8 {
226 self.as_ptr()
227 }
228
229 fn bytes_init(&self) -> usize {
230 self.len()
231 }
232
233 fn bytes_total(&self) -> usize {
234 self.len()
236 }
237}
238
239unsafe impl IoBuf for BytesMut {
240 fn stable_ptr(&self) -> *const u8 {
241 self.as_ptr()
242 }
243
244 fn bytes_init(&self) -> usize {
245 self.len()
246 }
247
248 fn bytes_total(&self) -> usize {
249 self.capacity()
250 }
251}
252
253unsafe impl IoBufMut for BytesMut {
254 fn stable_mut_ptr(&mut self) -> *mut u8 {
255 self.as_mut_ptr()
256 }
257
258 unsafe fn set_init(&mut self, pos: usize) {
259 unsafe { self.set_len(pos) };
261 }
262}
263
264unsafe impl IoBuf for Vec<u8> {
265 fn stable_ptr(&self) -> *const u8 {
266 self.as_ptr()
267 }
268 fn bytes_init(&self) -> usize {
269 self.len()
270 }
271 fn bytes_total(&self) -> usize {
272 self.capacity()
273 }
274}
275
276unsafe impl IoBufMut for Vec<u8> {
277 fn stable_mut_ptr(&mut self) -> *mut u8 {
278 self.as_mut_ptr()
279 }
280
281 unsafe fn set_init(&mut self, pos: usize) {
282 unsafe { self.set_len(pos) };
284 }
285}