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 IoSlice::from_slice(self.as_slice())
53 }
54
55 fn slice(self, range: impl std::ops::RangeBounds<usize>) -> Slice<Self>
69 where
70 Self: Sized,
71 {
72 use std::ops::Bound;
73
74 let begin = match range.start_bound() {
75 Bound::Included(&n) => n,
76 Bound::Excluded(&n) => n + 1,
77 Bound::Unbounded => 0,
78 };
79
80 assert!(begin <= self.buf_capacity());
81
82 let end = match range.end_bound() {
83 Bound::Included(&n) => n.checked_add(1).expect("out of range"),
84 Bound::Excluded(&n) => n,
85 Bound::Unbounded => self.buf_capacity(),
86 };
87
88 assert!(end <= self.buf_capacity());
89 assert!(begin <= self.buf_len());
90
91 Slice::new(self, begin, end)
92 }
93
94 fn filled(&self) -> bool {
96 self.buf_len() == self.buf_capacity()
97 }
98}
99
100unsafe impl<B: IoBuf + ?Sized> IoBuf for &'static B {
101 fn as_buf_ptr(&self) -> *const u8 {
102 (**self).as_buf_ptr()
103 }
104
105 fn buf_len(&self) -> usize {
106 (**self).buf_len()
107 }
108
109 fn buf_capacity(&self) -> usize {
110 (**self).buf_capacity()
111 }
112}
113
114unsafe impl<B: IoBuf + ?Sized> IoBuf for &'static mut B {
115 fn as_buf_ptr(&self) -> *const u8 {
116 (**self).as_buf_ptr()
117 }
118
119 fn buf_len(&self) -> usize {
120 (**self).buf_len()
121 }
122
123 fn buf_capacity(&self) -> usize {
124 (**self).buf_capacity()
125 }
126}
127
128unsafe impl<B: IoBuf + ?Sized, #[cfg(feature = "allocator_api")] A: Allocator + 'static> IoBuf
129 for t_alloc!(Box, B, A)
130{
131 fn as_buf_ptr(&self) -> *const u8 {
132 (**self).as_buf_ptr()
133 }
134
135 fn buf_len(&self) -> usize {
136 (**self).buf_len()
137 }
138
139 fn buf_capacity(&self) -> usize {
140 (**self).buf_capacity()
141 }
142}
143
144unsafe impl<B: IoBuf + ?Sized, #[cfg(feature = "allocator_api")] A: Allocator + 'static> IoBuf
145 for t_alloc!(Rc, B, A)
146{
147 fn as_buf_ptr(&self) -> *const u8 {
148 (**self).as_buf_ptr()
149 }
150
151 fn buf_len(&self) -> usize {
152 (**self).buf_len()
153 }
154
155 fn buf_capacity(&self) -> usize {
156 (**self).buf_capacity()
157 }
158}
159
160unsafe impl<B: IoBuf + ?Sized, #[cfg(feature = "allocator_api")] A: Allocator + 'static> IoBuf
161 for t_alloc!(Arc, B, A)
162{
163 fn as_buf_ptr(&self) -> *const u8 {
164 (**self).as_buf_ptr()
165 }
166
167 fn buf_len(&self) -> usize {
168 (**self).buf_len()
169 }
170
171 fn buf_capacity(&self) -> usize {
172 (**self).buf_capacity()
173 }
174}
175
176unsafe impl<#[cfg(feature = "allocator_api")] A: Allocator + 'static> IoBuf
177 for t_alloc!(Vec, u8, A)
178{
179 fn as_buf_ptr(&self) -> *const u8 {
180 self.as_ptr()
181 }
182
183 fn buf_len(&self) -> usize {
184 self.len()
185 }
186
187 fn buf_capacity(&self) -> usize {
188 self.capacity()
189 }
190}
191
192unsafe impl IoBuf for String {
193 fn as_buf_ptr(&self) -> *const u8 {
194 self.as_ptr()
195 }
196
197 fn buf_len(&self) -> usize {
198 self.len()
199 }
200
201 fn buf_capacity(&self) -> usize {
202 self.capacity()
203 }
204}
205
206unsafe impl IoBuf for str {
207 fn as_buf_ptr(&self) -> *const u8 {
208 self.as_ptr()
209 }
210
211 fn buf_len(&self) -> usize {
212 self.len()
213 }
214
215 fn buf_capacity(&self) -> usize {
216 self.len()
217 }
218}
219
220unsafe impl IoBuf for [u8] {
221 fn as_buf_ptr(&self) -> *const u8 {
222 self.as_ptr()
223 }
224
225 fn buf_len(&self) -> usize {
226 self.len()
227 }
228
229 fn buf_capacity(&self) -> usize {
230 self.len()
231 }
232}
233
234unsafe impl<const N: usize> IoBuf for [u8; N] {
235 fn as_buf_ptr(&self) -> *const u8 {
236 self.as_ptr()
237 }
238
239 fn buf_len(&self) -> usize {
240 N
241 }
242
243 fn buf_capacity(&self) -> usize {
244 N
245 }
246}
247
248#[cfg(feature = "bytes")]
249unsafe impl IoBuf for bytes::Bytes {
250 fn as_buf_ptr(&self) -> *const u8 {
251 self.as_ptr()
252 }
253
254 fn buf_len(&self) -> usize {
255 self.len()
256 }
257
258 fn buf_capacity(&self) -> usize {
259 self.len()
260 }
261}
262
263#[cfg(feature = "bytes")]
264unsafe impl IoBuf for bytes::BytesMut {
265 fn as_buf_ptr(&self) -> *const u8 {
266 self.as_ptr()
267 }
268
269 fn buf_len(&self) -> usize {
270 self.len()
271 }
272
273 fn buf_capacity(&self) -> usize {
274 self.capacity()
275 }
276}
277
278#[cfg(feature = "read_buf")]
279unsafe impl IoBuf for std::io::BorrowedBuf<'static> {
280 fn as_buf_ptr(&self) -> *const u8 {
281 self.filled().as_ptr()
282 }
283
284 fn buf_len(&self) -> usize {
285 self.len()
286 }
287
288 fn buf_capacity(&self) -> usize {
289 self.capacity()
290 }
291}
292
293#[cfg(feature = "arrayvec")]
294unsafe impl<const N: usize> IoBuf for arrayvec::ArrayVec<u8, N> {
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.capacity()
305 }
306}
307
308#[cfg(feature = "smallvec")]
309unsafe impl<const N: usize> IoBuf for smallvec::SmallVec<[u8; N]>
310where
311 [u8; N]: smallvec::Array<Item = u8>,
312{
313 fn as_buf_ptr(&self) -> *const u8 {
314 self.as_ptr()
315 }
316
317 fn buf_len(&self) -> usize {
318 self.len()
319 }
320
321 fn buf_capacity(&self) -> usize {
322 self.capacity()
323 }
324}
325
326pub unsafe trait IoBufMut: IoBuf + SetBufInit {
337 fn as_buf_mut_ptr(&mut self) -> *mut u8;
342
343 fn as_mut_slice(&mut self) -> &mut [MaybeUninit<u8>] {
345 unsafe {
346 std::slice::from_raw_parts_mut(self.as_buf_mut_ptr().cast(), (*self).buf_capacity())
347 }
348 }
349
350 unsafe fn as_io_slice_mut(&mut self) -> IoSliceMut {
358 IoSliceMut::from_uninit(self.as_mut_slice())
359 }
360}
361
362unsafe impl<B: IoBufMut + ?Sized> IoBufMut for &'static mut B {
363 fn as_buf_mut_ptr(&mut self) -> *mut u8 {
364 (**self).as_buf_mut_ptr()
365 }
366}
367
368unsafe impl<B: IoBufMut + ?Sized, #[cfg(feature = "allocator_api")] A: Allocator + 'static> IoBufMut
369 for t_alloc!(Box, B, A)
370{
371 fn as_buf_mut_ptr(&mut self) -> *mut u8 {
372 (**self).as_buf_mut_ptr()
373 }
374}
375
376unsafe impl<#[cfg(feature = "allocator_api")] A: Allocator + 'static> IoBufMut
377 for t_alloc!(Vec, u8, A)
378{
379 fn as_buf_mut_ptr(&mut self) -> *mut u8 {
380 self.as_mut_ptr()
381 }
382}
383
384unsafe impl IoBufMut for [u8] {
385 fn as_buf_mut_ptr(&mut self) -> *mut u8 {
386 self.as_mut_ptr()
387 }
388}
389
390unsafe impl<const N: usize> IoBufMut for [u8; N] {
391 fn as_buf_mut_ptr(&mut self) -> *mut u8 {
392 self.as_mut_ptr()
393 }
394}
395
396#[cfg(feature = "bytes")]
397unsafe impl IoBufMut for bytes::BytesMut {
398 fn as_buf_mut_ptr(&mut self) -> *mut u8 {
399 self.as_mut_ptr()
400 }
401}
402
403#[cfg(feature = "read_buf")]
404unsafe impl IoBufMut for std::io::BorrowedBuf<'static> {
405 fn as_buf_mut_ptr(&mut self) -> *mut u8 {
406 (*self).filled().as_ptr() as _
407 }
408}
409
410#[cfg(feature = "arrayvec")]
411unsafe impl<const N: usize> IoBufMut for arrayvec::ArrayVec<u8, N> {
412 fn as_buf_mut_ptr(&mut self) -> *mut u8 {
413 self.as_mut_ptr()
414 }
415}
416
417#[cfg(feature = "smallvec")]
418unsafe impl<const N: usize> IoBufMut for smallvec::SmallVec<[u8; N]>
419where
420 [u8; N]: smallvec::Array<Item = u8>,
421{
422 fn as_buf_mut_ptr(&mut self) -> *mut u8 {
423 self.as_mut_ptr()
424 }
425}
426
427pub trait SetBufInit {
429 unsafe fn set_buf_init(&mut self, len: usize);
436}
437
438impl<B: SetBufInit + ?Sized> SetBufInit for &'static mut B {
439 unsafe fn set_buf_init(&mut self, len: usize) {
440 (**self).set_buf_init(len)
441 }
442}
443
444impl<B: SetBufInit + ?Sized, #[cfg(feature = "allocator_api")] A: Allocator + 'static> SetBufInit
445 for t_alloc!(Box, B, A)
446{
447 unsafe fn set_buf_init(&mut self, len: usize) {
448 (**self).set_buf_init(len)
449 }
450}
451
452impl<#[cfg(feature = "allocator_api")] A: Allocator + 'static> SetBufInit for t_alloc!(Vec, u8, A) {
453 unsafe fn set_buf_init(&mut self, len: usize) {
454 if (**self).buf_len() < len {
455 self.set_len(len);
456 }
457 }
458}
459
460impl SetBufInit for [u8] {
461 unsafe fn set_buf_init(&mut self, len: usize) {
462 debug_assert!(len <= self.len());
463 }
464}
465
466impl<const N: usize> SetBufInit for [u8; N] {
467 unsafe fn set_buf_init(&mut self, len: usize) {
468 debug_assert!(len <= N);
469 }
470}
471
472#[cfg(feature = "bytes")]
473impl SetBufInit for bytes::BytesMut {
474 unsafe fn set_buf_init(&mut self, len: usize) {
475 if (**self).buf_len() < len {
476 self.set_len(len);
477 }
478 }
479}
480
481#[cfg(feature = "read_buf")]
482impl SetBufInit for std::io::BorrowedBuf<'static> {
483 unsafe fn set_buf_init(&mut self, len: usize) {
484 let current_len = (*self).buf_len();
485 if current_len < len {
486 self.unfilled().advance(len - current_len);
487 }
488 }
489}
490
491#[cfg(feature = "arrayvec")]
492impl<const N: usize> SetBufInit for arrayvec::ArrayVec<u8, N> {
493 unsafe fn set_buf_init(&mut self, len: usize) {
494 if (**self).buf_len() < len {
495 self.set_len(len);
496 }
497 }
498}
499
500#[cfg(feature = "smallvec")]
501impl<const N: usize> SetBufInit for smallvec::SmallVec<[u8; N]>
502where
503 [u8; N]: smallvec::Array<Item = u8>,
504{
505 unsafe fn set_buf_init(&mut self, len: usize) {
506 if (**self).buf_len() < len {
507 self.set_len(len);
508 }
509 }
510}
511
512impl<T: IoBufMut> SetBufInit for [T] {
513 unsafe fn set_buf_init(&mut self, len: usize) {
514 default_set_buf_init(self.iter_mut(), len)
515 }
516}
517
518impl<T: IoBufMut, const N: usize> SetBufInit for [T; N] {
519 unsafe fn set_buf_init(&mut self, len: usize) {
520 default_set_buf_init(self.iter_mut(), len)
521 }
522}
523
524impl<T: IoBufMut, #[cfg(feature = "allocator_api")] A: Allocator + 'static> SetBufInit
525 for t_alloc!(Vec, T, A)
526{
527 unsafe fn set_buf_init(&mut self, len: usize) {
528 default_set_buf_init(self.iter_mut(), len)
529 }
530}
531
532#[cfg(feature = "arrayvec")]
533impl<T: IoBufMut, const N: usize> SetBufInit for arrayvec::ArrayVec<T, N> {
534 unsafe fn set_buf_init(&mut self, len: usize) {
535 default_set_buf_init(self.iter_mut(), len)
536 }
537}
538
539#[cfg(feature = "smallvec")]
540impl<T: IoBufMut, const N: usize> SetBufInit for smallvec::SmallVec<[T; N]>
541where
542 [T; N]: smallvec::Array<Item = T>,
543{
544 unsafe fn set_buf_init(&mut self, len: usize) {
545 default_set_buf_init(self.iter_mut(), len)
546 }
547}
548
549unsafe fn default_set_buf_init<'a, B: IoBufMut>(
550 iter: impl IntoIterator<Item = &'a mut B>,
551 mut len: usize,
552) {
553 for buf in iter {
554 let capacity = (*buf).buf_capacity();
555 if len >= capacity {
556 buf.set_buf_init(capacity);
557 len -= capacity;
558 } else {
559 buf.set_buf_init(len);
560 len = 0;
561 }
562 }
563}