1#[cfg(feature = "allocator_api")]
2use std::alloc::Allocator;
3use std::{mem::MaybeUninit, rc::Rc, sync::Arc};
4
5use crate::*;
6
7pub unsafe trait IoBuf: 'static {
17 fn as_buf_ptr(&self) -> *const u8;
22
23 fn buf_len(&self) -> usize;
30
31 fn buf_capacity(&self) -> usize;
38
39 fn as_slice(&self) -> &[u8] {
41 unsafe { std::slice::from_raw_parts(self.as_buf_ptr(), self.buf_len()) }
42 }
43
44 unsafe fn as_io_slice(&self) -> IoSlice {
52 unsafe { IoSlice::from_slice(self.as_slice()) }
53 }
54
55 unsafe fn as_io_buffer(&self) -> IoBuffer {
63 unsafe {
64 IoBuffer::new(
65 self.as_buf_ptr().cast_mut().cast(),
66 self.buf_len(),
67 self.buf_capacity(),
68 )
69 }
70 }
71
72 fn slice(self, range: impl std::ops::RangeBounds<usize>) -> Slice<Self>
86 where
87 Self: Sized,
88 {
89 use std::ops::Bound;
90
91 let begin = match range.start_bound() {
92 Bound::Included(&n) => n,
93 Bound::Excluded(&n) => n + 1,
94 Bound::Unbounded => 0,
95 };
96
97 assert!(begin <= self.buf_capacity());
98
99 let end = match range.end_bound() {
100 Bound::Included(&n) => n.checked_add(1).expect("out of range"),
101 Bound::Excluded(&n) => n,
102 Bound::Unbounded => self.buf_capacity(),
103 };
104
105 assert!(end <= self.buf_capacity());
106 assert!(begin <= self.buf_len());
107
108 Slice::new(self, begin, end)
109 }
110
111 fn uninit(self) -> Uninit<Self>
133 where
134 Self: Sized,
135 {
136 Uninit::new(self)
137 }
138
139 fn filled(&self) -> bool {
141 self.buf_len() == self.buf_capacity()
142 }
143}
144
145unsafe impl<B: IoBuf + ?Sized> IoBuf for &'static B {
146 fn as_buf_ptr(&self) -> *const u8 {
147 (**self).as_buf_ptr()
148 }
149
150 fn buf_len(&self) -> usize {
151 (**self).buf_len()
152 }
153
154 fn buf_capacity(&self) -> usize {
155 (**self).buf_capacity()
156 }
157}
158
159unsafe impl<B: IoBuf + ?Sized> IoBuf for &'static mut B {
160 fn as_buf_ptr(&self) -> *const u8 {
161 (**self).as_buf_ptr()
162 }
163
164 fn buf_len(&self) -> usize {
165 (**self).buf_len()
166 }
167
168 fn buf_capacity(&self) -> usize {
169 (**self).buf_capacity()
170 }
171}
172
173unsafe impl<B: IoBuf + ?Sized, #[cfg(feature = "allocator_api")] A: Allocator + 'static> IoBuf
174 for t_alloc!(Box, B, A)
175{
176 fn as_buf_ptr(&self) -> *const u8 {
177 (**self).as_buf_ptr()
178 }
179
180 fn buf_len(&self) -> usize {
181 (**self).buf_len()
182 }
183
184 fn buf_capacity(&self) -> usize {
185 (**self).buf_capacity()
186 }
187}
188
189unsafe impl<B: IoBuf + ?Sized, #[cfg(feature = "allocator_api")] A: Allocator + 'static> IoBuf
190 for t_alloc!(Rc, B, A)
191{
192 fn as_buf_ptr(&self) -> *const u8 {
193 (**self).as_buf_ptr()
194 }
195
196 fn buf_len(&self) -> usize {
197 (**self).buf_len()
198 }
199
200 fn buf_capacity(&self) -> usize {
201 (**self).buf_capacity()
202 }
203}
204
205unsafe impl<B: IoBuf + ?Sized, #[cfg(feature = "allocator_api")] A: Allocator + 'static> IoBuf
206 for t_alloc!(Arc, B, A)
207{
208 fn as_buf_ptr(&self) -> *const u8 {
209 (**self).as_buf_ptr()
210 }
211
212 fn buf_len(&self) -> usize {
213 (**self).buf_len()
214 }
215
216 fn buf_capacity(&self) -> usize {
217 (**self).buf_capacity()
218 }
219}
220
221unsafe impl<#[cfg(feature = "allocator_api")] A: Allocator + 'static> IoBuf
222 for t_alloc!(Vec, u8, A)
223{
224 fn as_buf_ptr(&self) -> *const u8 {
225 self.as_ptr()
226 }
227
228 fn buf_len(&self) -> usize {
229 self.len()
230 }
231
232 fn buf_capacity(&self) -> usize {
233 self.capacity()
234 }
235}
236
237unsafe impl IoBuf for String {
238 fn as_buf_ptr(&self) -> *const u8 {
239 self.as_ptr()
240 }
241
242 fn buf_len(&self) -> usize {
243 self.len()
244 }
245
246 fn buf_capacity(&self) -> usize {
247 self.capacity()
248 }
249}
250
251unsafe impl IoBuf for str {
252 fn as_buf_ptr(&self) -> *const u8 {
253 self.as_ptr()
254 }
255
256 fn buf_len(&self) -> usize {
257 self.len()
258 }
259
260 fn buf_capacity(&self) -> usize {
261 self.len()
262 }
263}
264
265unsafe impl IoBuf for [u8] {
266 fn as_buf_ptr(&self) -> *const u8 {
267 self.as_ptr()
268 }
269
270 fn buf_len(&self) -> usize {
271 self.len()
272 }
273
274 fn buf_capacity(&self) -> usize {
275 self.len()
276 }
277}
278
279unsafe impl<const N: usize> IoBuf for [u8; N] {
280 fn as_buf_ptr(&self) -> *const u8 {
281 self.as_ptr()
282 }
283
284 fn buf_len(&self) -> usize {
285 N
286 }
287
288 fn buf_capacity(&self) -> usize {
289 N
290 }
291}
292
293#[cfg(feature = "bytes")]
294unsafe impl IoBuf for bytes::Bytes {
295 fn as_buf_ptr(&self) -> *const u8 {
296 self.as_ptr()
297 }
298
299 fn buf_len(&self) -> usize {
300 self.len()
301 }
302
303 fn buf_capacity(&self) -> usize {
304 self.len()
305 }
306}
307
308#[cfg(feature = "bytes")]
309unsafe impl IoBuf for bytes::BytesMut {
310 fn as_buf_ptr(&self) -> *const u8 {
311 self.as_ptr()
312 }
313
314 fn buf_len(&self) -> usize {
315 self.len()
316 }
317
318 fn buf_capacity(&self) -> usize {
319 self.capacity()
320 }
321}
322
323#[cfg(feature = "read_buf")]
324unsafe impl IoBuf for std::io::BorrowedBuf<'static> {
325 fn as_buf_ptr(&self) -> *const u8 {
326 self.filled().as_ptr()
327 }
328
329 fn buf_len(&self) -> usize {
330 self.len()
331 }
332
333 fn buf_capacity(&self) -> usize {
334 self.capacity()
335 }
336}
337
338#[cfg(feature = "arrayvec")]
339unsafe impl<const N: usize> IoBuf for arrayvec::ArrayVec<u8, N> {
340 fn as_buf_ptr(&self) -> *const u8 {
341 self.as_ptr()
342 }
343
344 fn buf_len(&self) -> usize {
345 self.len()
346 }
347
348 fn buf_capacity(&self) -> usize {
349 self.capacity()
350 }
351}
352
353#[cfg(feature = "smallvec")]
354unsafe impl<const N: usize> IoBuf for smallvec::SmallVec<[u8; N]>
355where
356 [u8; N]: smallvec::Array<Item = u8>,
357{
358 fn as_buf_ptr(&self) -> *const u8 {
359 self.as_ptr()
360 }
361
362 fn buf_len(&self) -> usize {
363 self.len()
364 }
365
366 fn buf_capacity(&self) -> usize {
367 self.capacity()
368 }
369}
370
371pub unsafe trait IoBufMut: IoBuf + SetBufInit {
382 fn as_buf_mut_ptr(&mut self) -> *mut u8;
387
388 fn as_mut_slice(&mut self) -> &mut [MaybeUninit<u8>] {
390 unsafe {
391 std::slice::from_raw_parts_mut(self.as_buf_mut_ptr().cast(), (*self).buf_capacity())
392 }
393 }
394
395 unsafe fn as_io_slice_mut(&mut self) -> IoSliceMut {
403 unsafe { IoSliceMut::from_uninit(self.as_mut_slice()) }
404 }
405}
406
407unsafe impl<B: IoBufMut + ?Sized> IoBufMut for &'static mut B {
408 fn as_buf_mut_ptr(&mut self) -> *mut u8 {
409 (**self).as_buf_mut_ptr()
410 }
411}
412
413unsafe impl<B: IoBufMut + ?Sized, #[cfg(feature = "allocator_api")] A: Allocator + 'static> IoBufMut
414 for t_alloc!(Box, B, A)
415{
416 fn as_buf_mut_ptr(&mut self) -> *mut u8 {
417 (**self).as_buf_mut_ptr()
418 }
419}
420
421unsafe impl<#[cfg(feature = "allocator_api")] A: Allocator + 'static> IoBufMut
422 for t_alloc!(Vec, u8, A)
423{
424 fn as_buf_mut_ptr(&mut self) -> *mut u8 {
425 self.as_mut_ptr()
426 }
427}
428
429unsafe impl IoBufMut for [u8] {
430 fn as_buf_mut_ptr(&mut self) -> *mut u8 {
431 self.as_mut_ptr()
432 }
433}
434
435unsafe impl<const N: usize> IoBufMut for [u8; N] {
436 fn as_buf_mut_ptr(&mut self) -> *mut u8 {
437 self.as_mut_ptr()
438 }
439}
440
441#[cfg(feature = "bytes")]
442unsafe impl IoBufMut for bytes::BytesMut {
443 fn as_buf_mut_ptr(&mut self) -> *mut u8 {
444 self.as_mut_ptr()
445 }
446}
447
448#[cfg(feature = "read_buf")]
449unsafe impl IoBufMut for std::io::BorrowedBuf<'static> {
450 fn as_buf_mut_ptr(&mut self) -> *mut u8 {
451 (*self).filled().as_ptr() as _
452 }
453}
454
455#[cfg(feature = "arrayvec")]
456unsafe impl<const N: usize> IoBufMut for arrayvec::ArrayVec<u8, N> {
457 fn as_buf_mut_ptr(&mut self) -> *mut u8 {
458 self.as_mut_ptr()
459 }
460}
461
462#[cfg(feature = "smallvec")]
463unsafe impl<const N: usize> IoBufMut for smallvec::SmallVec<[u8; N]>
464where
465 [u8; N]: smallvec::Array<Item = u8>,
466{
467 fn as_buf_mut_ptr(&mut self) -> *mut u8 {
468 self.as_mut_ptr()
469 }
470}
471
472pub trait SetBufInit {
474 unsafe fn set_buf_init(&mut self, len: usize);
482}
483
484impl<B: SetBufInit + ?Sized> SetBufInit for &'static mut B {
485 unsafe fn set_buf_init(&mut self, len: usize) {
486 unsafe { (**self).set_buf_init(len) }
487 }
488}
489
490impl<B: SetBufInit + ?Sized, #[cfg(feature = "allocator_api")] A: Allocator + 'static> SetBufInit
491 for t_alloc!(Box, B, A)
492{
493 unsafe fn set_buf_init(&mut self, len: usize) {
494 unsafe { (**self).set_buf_init(len) }
495 }
496}
497
498impl<#[cfg(feature = "allocator_api")] A: Allocator + 'static> SetBufInit for t_alloc!(Vec, u8, A) {
499 unsafe fn set_buf_init(&mut self, len: usize) {
500 if (**self).buf_len() < len {
501 unsafe { self.set_len(len) };
502 }
503 }
504}
505
506impl SetBufInit for [u8] {
507 unsafe fn set_buf_init(&mut self, len: usize) {
508 debug_assert!(len <= self.len());
509 }
510}
511
512impl<const N: usize> SetBufInit for [u8; N] {
513 unsafe fn set_buf_init(&mut self, len: usize) {
514 debug_assert!(len <= N);
515 }
516}
517
518#[cfg(feature = "bytes")]
519impl SetBufInit for bytes::BytesMut {
520 unsafe fn set_buf_init(&mut self, len: usize) {
521 if (**self).buf_len() < len {
522 unsafe { self.set_len(len) };
523 }
524 }
525}
526
527#[cfg(feature = "read_buf")]
528impl SetBufInit for std::io::BorrowedBuf<'static> {
529 unsafe fn set_buf_init(&mut self, len: usize) {
530 let current_len = (*self).buf_len();
531 if current_len < len {
532 self.unfilled().advance(len - current_len);
533 }
534 }
535}
536
537#[cfg(feature = "arrayvec")]
538impl<const N: usize> SetBufInit for arrayvec::ArrayVec<u8, N> {
539 unsafe fn set_buf_init(&mut self, len: usize) {
540 if (**self).buf_len() < len {
541 unsafe { self.set_len(len) };
542 }
543 }
544}
545
546#[cfg(feature = "smallvec")]
547impl<const N: usize> SetBufInit for smallvec::SmallVec<[u8; N]>
548where
549 [u8; N]: smallvec::Array<Item = u8>,
550{
551 unsafe fn set_buf_init(&mut self, len: usize) {
552 if (**self).buf_len() < len {
553 unsafe { self.set_len(len) };
554 }
555 }
556}
557
558impl<T: IoBufMut> SetBufInit for [T] {
559 unsafe fn set_buf_init(&mut self, len: usize) {
560 unsafe { default_set_buf_init(self.iter_mut(), len) }
561 }
562}
563
564impl<T: IoBufMut, const N: usize> SetBufInit for [T; N] {
565 unsafe fn set_buf_init(&mut self, len: usize) {
566 unsafe { default_set_buf_init(self.iter_mut(), len) }
567 }
568}
569
570impl<T: IoBufMut, #[cfg(feature = "allocator_api")] A: Allocator + 'static> SetBufInit
571 for t_alloc!(Vec, T, A)
572{
573 unsafe fn set_buf_init(&mut self, len: usize) {
574 unsafe { default_set_buf_init(self.iter_mut(), len) }
575 }
576}
577
578#[cfg(feature = "arrayvec")]
579impl<T: IoBufMut, const N: usize> SetBufInit for arrayvec::ArrayVec<T, N> {
580 unsafe fn set_buf_init(&mut self, len: usize) {
581 unsafe { default_set_buf_init(self.iter_mut(), len) }
582 }
583}
584
585#[cfg(feature = "smallvec")]
586impl<T: IoBufMut, const N: usize> SetBufInit for smallvec::SmallVec<[T; N]>
587where
588 [T; N]: smallvec::Array<Item = T>,
589{
590 unsafe fn set_buf_init(&mut self, len: usize) {
591 unsafe { default_set_buf_init(self.iter_mut(), len) }
592 }
593}
594
595unsafe fn default_set_buf_init<'a, B: IoBufMut>(
601 iter: impl IntoIterator<Item = &'a mut B>,
602 mut len: usize,
603) {
604 for buf in iter {
605 let capacity = (*buf).buf_capacity();
606 if len >= capacity {
607 unsafe { buf.set_buf_init(capacity) };
608 len -= capacity;
609 } else {
610 unsafe { buf.set_buf_init(len) };
611 len = 0;
612 }
613 }
614}