1use core::mem::MaybeUninit;
2
3use crate::buffer::Buffer;
4use crate::initializer::BuffersInitializer;
5use crate::traits::{Initialize, InitializeVectored};
6use crate::wrappers::{AssertInit, SingleVector};
7
8pub struct Buffers<T> {
9 initializer: BuffersInitializer<T>,
10 items_filled_for_vector: usize,
17 vectors_filled: usize,
19}
20
21impl<T> Buffers<T> {
22 #[inline]
23 pub const fn from_initializer(initializer: BuffersInitializer<T>) -> Self {
24 Self {
25 initializer,
26 items_filled_for_vector: 0,
27 vectors_filled: 0,
28 }
29 }
30 #[inline]
31 pub const fn new(inner: T) -> Self {
32 Self::from_initializer(BuffersInitializer::uninit(inner))
33 }
34 #[inline]
35 pub const fn initializer(&self) -> &BuffersInitializer<T> {
36 &self.initializer
37 }
38 #[inline]
39 pub fn initializer_mut(&mut self) -> &mut BuffersInitializer<T> {
40 &mut self.initializer
41 }
42 #[inline]
43 pub fn into_initializer(self) -> BuffersInitializer<T> {
44 let Self { initializer, .. } = self;
45
46 initializer
47 }
48 #[inline]
49 pub fn into_inner(self) -> T {
50 self.into_initializer().into_inner()
51 }
52 #[inline]
53 pub const fn vectors_filled(&self) -> usize {
54 self.vectors_filled
55 }
56}
57impl<T, Item> Buffers<T>
58where
59 T: InitializeVectored,
60 T::UninitVector: Initialize<Item = Item>,
61{
62 #[inline]
63 pub fn all_previously_filled_vectors(&self) -> &[AssertInit<T::UninitVector>] {
64 self.debug_assert_validity();
65
66 unsafe {
67 let filled = {
68 let src = self.initializer().all_uninit_vectors();
69
70 core::slice::from_raw_parts(src.as_ptr(), self.vectors_filled())
71 };
72
73 AssertInit::cast_from_slices(filled)
74 }
75 }
76 #[inline]
77 pub fn all_previously_filled_vectors_mut(&mut self) -> &[AssertInit<T::UninitVector>] {
78 self.debug_assert_validity();
79
80 unsafe {
81 let ptr = { self.initializer_mut().all_uninit_vectors_mut().as_mut_ptr() };
82 let filled = core::slice::from_raw_parts_mut(ptr, self.vectors_filled());
83 AssertInit::cast_from_slices_mut(filled)
84 }
85 }
86 #[inline]
87 pub fn current_vector_all(&self) -> Option<&[MaybeUninit<Item>]> {
88 self.debug_assert_validity();
89
90 let all_vectors = self.initializer().all_uninit_vectors();
91
92 if self.vectors_filled == all_vectors.len() {
93 None
94 } else {
95 Some(unsafe { all_vectors.get_unchecked(self.vectors_filled) }.as_maybe_uninit_slice())
96 }
97 }
98 #[inline]
105 pub unsafe fn current_vector_all_mut(&mut self) -> Option<&mut [MaybeUninit<Item>]> {
106 self.debug_assert_validity();
107
108 let all_vectors_mut = self.initializer.all_uninit_vectors_mut();
109
110 if self.vectors_filled == all_vectors_mut.len() {
111 None
112 } else {
113 Some(
114 all_vectors_mut
115 .get_unchecked_mut(self.vectors_filled)
116 .as_maybe_uninit_slice_mut(),
117 )
118 }
119 }
120 #[inline]
121 pub fn current_vector_init_uninit_parts(&self) -> Option<(&[Item], &[MaybeUninit<Item>])> {
122 self.debug_assert_validity();
123
124 let ordering = self
125 .vectors_filled()
126 .cmp(&self.initializer().vectors_initialized());
127
128 match ordering {
129 core::cmp::Ordering::Less => Some((
133 unsafe { crate::cast_uninit_to_init_slice(self.current_vector_all()?) },
134 &[],
135 )),
136
137 core::cmp::Ordering::Greater => unsafe { core::hint::unreachable_unchecked() },
140
141 core::cmp::Ordering::Equal => self.initializer().current_vector_init_uninit_parts(),
144 }
145 }
146 #[inline]
147 pub fn current_vector_init_uninit_parts_mut(
148 &mut self,
149 ) -> Option<(&mut [Item], &mut [MaybeUninit<Item>])> {
150 self.debug_assert_validity();
151
152 let ordering = self
153 .vectors_filled()
154 .cmp(&self.initializer().vectors_initialized());
155
156 match ordering {
157 core::cmp::Ordering::Less => Some((
160 unsafe { crate::cast_uninit_to_init_slice_mut(self.current_vector_all_mut()?) },
161 &mut [],
162 )),
163 core::cmp::Ordering::Greater => unsafe { core::hint::unreachable_unchecked() },
164 core::cmp::Ordering::Equal => self
165 .initializer_mut()
166 .current_vector_init_uninit_parts_mut(),
167 }
168 }
169 #[inline]
170 pub fn current_vector_filled_part(&self) -> Option<&[Item]> {
171 self.debug_assert_validity();
172
173 let base_ptr = { self.current_vector_all()?.as_ptr() };
174
175 Some(unsafe {
176 core::slice::from_raw_parts(base_ptr as *const Item, self.items_filled_for_vector)
177 })
178 }
179 #[inline]
180 pub fn current_vector_filled_part_mut(&mut self) -> Option<&mut [Item]> {
181 self.debug_assert_validity();
182
183 unsafe {
184 let base_ptr = { self.current_vector_all_mut()?.as_mut_ptr() };
185 Some(core::slice::from_raw_parts_mut(
186 base_ptr as *mut Item,
187 self.items_filled_for_vector,
188 ))
189 }
190 }
191 #[inline]
192 pub fn current_vector_unfilled_all_part(&self) -> Option<&[MaybeUninit<Item>]> {
193 self.debug_assert_validity();
194
195 let (base_ptr, base_len) = {
196 let all = self.current_vector_all()?;
197 (all.as_ptr(), all.len())
198 };
199
200 Some(unsafe {
201 let ptr = base_ptr.add(self.items_filled_for_vector);
202 let len = base_len - self.items_filled_for_vector;
203
204 core::slice::from_raw_parts(ptr, len)
205 })
206 }
207 #[inline]
215 pub unsafe fn current_vector_unfilled_all_part_mut(
216 &mut self,
217 ) -> Option<&mut [MaybeUninit<Item>]> {
218 self.debug_assert_validity();
219
220 let (base_ptr, base_len) = {
221 let all = self.current_vector_all_mut()?;
222 (all.as_mut_ptr(), all.len())
223 };
224
225 Some({
226 let ptr = base_ptr.add(self.items_filled_for_vector);
227 let len = base_len - self.items_filled_for_vector;
228
229 core::slice::from_raw_parts_mut(ptr, len)
230 })
231 }
232 #[inline]
233 pub fn all_next_unfilled_vectors(&self) -> &[T::UninitVector] {
234 self.debug_assert_validity();
235
236 let total_vector_count = self.total_vector_count();
237 let vectors_filled = self.vectors_filled();
238 let after_vectors_filled = vectors_filled + 1;
239
240 let is_within =
241 vectors_filled != total_vector_count && after_vectors_filled != total_vector_count;
242
243 if is_within {
244 unsafe {
245 let (src_ptr, src_len) = {
246 let src = self.initializer().all_uninit_vectors();
247
248 (src.as_ptr(), src.len())
249 };
250
251 let ptr = src_ptr.add(after_vectors_filled);
253 let len = src_len - after_vectors_filled;
254
255 core::slice::from_raw_parts(ptr, len)
256 }
257 } else {
258 &[]
259 }
260 }
261 #[inline]
262 pub fn all_next_unfilled_vectors_mut(&mut self) -> &mut [T::UninitVector] {
263 self.debug_assert_validity();
264
265 let total_vector_count = self.total_vector_count();
266 let vectors_filled = self.vectors_filled();
267 let after_vectors_filled = vectors_filled + 1;
268
269 let is_within =
270 vectors_filled != total_vector_count && after_vectors_filled != total_vector_count;
271
272 if is_within {
273 unsafe {
274 let src_ptr = { self.initializer_mut().all_uninit_vectors_mut().as_mut_ptr() };
275 let ptr = src_ptr.add(after_vectors_filled);
280 let len = total_vector_count - after_vectors_filled;
281
282 core::slice::from_raw_parts_mut(ptr, len)
283 }
284 } else {
285 &mut []
286 }
287 }
288 pub fn all_filled_vectors(&self) -> (&[AssertInit<T::UninitVector>], &[Item]) {
291 (
294 self.all_previously_filled_vectors(),
295 self.current_vector_filled_part().unwrap_or(&[]),
296 )
297 }
298 pub fn current_vector_parts(&self) -> Option<VectorParts<'_, Item>> {
307 self.debug_assert_validity();
308
309 unsafe {
310 let (src_ptr, src_len) = {
311 let src = self.current_vector_all()?;
312
313 (src.as_ptr(), src.len())
314 };
315
316 let filled_base_ptr = src_ptr as *const Item;
317 let filled_len = self.items_filled_for_vector;
318
319 let init_len = self
320 .initializer()
321 .items_initialized_for_vector_unchecked(self.vectors_filled);
322
323 let unfilled_init_base_ptr = src_ptr.add(self.items_filled_for_vector) as *const Item;
324 let unfilled_init_len = init_len - filled_len;
325
326 let unfilled_uninit_base_ptr = src_ptr.add(init_len);
327 let unfilled_uninit_len = src_len - init_len;
328
329 let filled = core::slice::from_raw_parts(filled_base_ptr, filled_len);
330 let unfilled_init =
331 core::slice::from_raw_parts(unfilled_init_base_ptr, unfilled_init_len);
332 let unfilled_uninit =
333 core::slice::from_raw_parts(unfilled_uninit_base_ptr, unfilled_uninit_len);
334
335 Some(VectorParts {
336 filled,
337 unfilled_init,
338 unfilled_uninit,
339 })
340 }
341 }
342 pub fn current_vector_parts_mut(&mut self) -> Option<VectorPartsMut<'_, Item>> {
345 self.debug_assert_validity();
346
347 unsafe {
348 let (src_ptr, src_len) = {
349 let src = self.current_vector_all_mut()?;
350
351 (src.as_mut_ptr(), src.len())
352 };
353
354 let filled_base_ptr = src_ptr as *mut Item;
355 let filled_len = self.items_filled_for_vector;
356
357 let init_len = self
358 .initializer()
359 .items_initialized_for_vector_unchecked(self.vectors_filled);
360
361 let unfilled_init_base_ptr = src_ptr.add(self.items_filled_for_vector) as *mut Item;
362 let unfilled_init_len = init_len - filled_len;
363
364 let unfilled_uninit_base_ptr = src_ptr.add(init_len);
365 let unfilled_uninit_len = src_len - init_len;
366
367 let filled = core::slice::from_raw_parts_mut(filled_base_ptr, filled_len);
368 let unfilled_init =
369 core::slice::from_raw_parts_mut(unfilled_init_base_ptr, unfilled_init_len);
370 let unfilled_uninit =
371 core::slice::from_raw_parts_mut(unfilled_uninit_base_ptr, unfilled_uninit_len);
372
373 Some(VectorPartsMut {
374 filled,
375 unfilled_init,
376 unfilled_uninit,
377 })
378 }
379 }
380 fn debug_assert_validity(&self) {
381 debug_assert!(self.items_filled_for_vector <= isize::MAX as usize);
382 debug_assert!(self.vectors_filled <= self.initializer().total_vector_count());
383 debug_assert!(self.vectors_filled <= self.initializer().vectors_initialized());
384 }
386 #[inline]
387 pub fn total_vector_count(&self) -> usize {
388 self.initializer().total_vector_count()
389 }
390 #[inline]
391 pub fn vectors_remaining(&self) -> usize {
392 self.total_vector_count()
393 .wrapping_sub(self.vectors_filled())
394 }
395 pub fn count_remaining_items_to_fill(&self) -> usize {
396 self.remaining_for_current_vector()
397 + self
398 .all_next_unfilled_vectors()
399 .iter()
400 .map(|unfilled_vector| unfilled_vector.as_maybe_uninit_slice().len())
401 .sum::<usize>()
402 }
403 pub fn count_total_items_in_all_vectors(&self) -> usize {
404 self.initializer().count_total_items_in_all_vectors()
405 }
406 #[inline]
411 pub fn remaining_for_current_vector(&self) -> usize {
412 self.current_vector_all().map_or(0, |current_vector| {
413 current_vector.len() - self.items_filled_for_vector
414 })
415 }
416 pub fn advance_current_vector(&mut self, count: usize) {
424 let current_vector_all_len = match self.current_vector_all() {
425 Some(current) => current.len(),
426 None => panic!(
427 "cannot advance the current vector by {} B, since no vectors were left",
428 count
429 ),
430 };
431
432 let ordering = Ord::cmp(
433 &self.vectors_filled(),
434 &self.initializer().vectors_initialized(),
435 );
436
437 let end = self.items_filled_for_vector + count;
438
439 match ordering {
440 core::cmp::Ordering::Equal => {
441 assert!(
442 end <= self.initializer().items_initialized_for_current_vector(),
443 "cannot advance the fill count beyond the initialized part"
444 );
445 debug_assert!(end <= current_vector_all_len);
446 }
447 core::cmp::Ordering::Less => {
448 assert!(
449 end <= current_vector_all_len,
450 "cannot advance the current vector beyond the end"
451 );
452 }
453 core::cmp::Ordering::Greater => unsafe { core::hint::unreachable_unchecked() },
454 }
455
456 self.items_filled_for_vector += end;
457
458 if self.items_filled_for_vector == current_vector_all_len {
459 self.vectors_filled += 1;
460 self.items_filled_for_vector = 0;
461 }
462 }
463 pub fn advance_to_current_vector_end(&mut self) {
464 let current_vector_all = match self.current_vector_all() {
465 Some(current) => current,
466 None => {
467 panic!("cannot advance the current vector to end, when there are no vectors left")
468 }
469 };
470
471 let ordering = Ord::cmp(
472 &self.vectors_filled(),
473 &self.initializer().vectors_initialized(),
474 );
475
476 match ordering {
477 core::cmp::Ordering::Equal => assert_eq!(
478 self.initializer().items_initialized_for_current_vector(),
479 current_vector_all.len()
480 ),
481 core::cmp::Ordering::Less => (),
482 core::cmp::Ordering::Greater => unsafe { core::hint::unreachable_unchecked() },
483 }
484
485 self.vectors_filled += 1;
486 self.items_filled_for_vector = 0;
487 }
488}
489impl<T> Buffers<T>
490where
491 T: InitializeVectored,
492 T::UninitVector: Initialize<Item = u8>,
493{
494 pub fn with_current_vector_unfilled_zeroed(&mut self) -> Option<&mut [u8]> {
495 let _ = self.current_vector_all()?;
496
497 let ordering = Ord::cmp(
498 &self.vectors_filled(),
499 &self.initializer().vectors_initialized(),
500 );
501
502 match ordering {
503 core::cmp::Ordering::Equal => {
506 self.initializer_mut().zero_current_vector_uninit_part();
507 }
508 core::cmp::Ordering::Less => (),
511 core::cmp::Ordering::Greater => unsafe { core::hint::unreachable_unchecked() },
512 }
513
514 Some(unsafe {
515 let current_vector_all = self.current_vector_all_mut().expect(
516 "expected the current vector to exist, since an earlier check has been done",
517 );
518
519 crate::cast_uninit_to_init_slice_mut(current_vector_all)
520 })
521 }
522}
523impl<T> Buffers<SingleVector<T>>
524where
525 T: Initialize,
526{
527 pub fn from_single_buffer(buffer: Buffer<T>) -> Self {
528 let Buffer {
529 initializer,
530 items_filled,
531 } = buffer;
532
533 Self {
534 initializer: BuffersInitializer::from_single_buffer_initializer(initializer),
535 items_filled_for_vector: items_filled,
536 vectors_filled: 0,
537 }
538 }
539}
540#[derive(Clone, Copy, Debug, Default)]
541pub struct VectorParts<'a, Item> {
542 pub filled: &'a [Item],
543 pub unfilled_init: &'a [Item],
544 pub unfilled_uninit: &'a [MaybeUninit<Item>],
545}
546#[derive(Debug, Default)]
547pub struct VectorPartsMut<'a, Item> {
548 pub filled: &'a mut [Item],
549 pub unfilled_init: &'a mut [Item],
550 pub unfilled_uninit: &'a mut [MaybeUninit<Item>],
551}
552
553pub struct BuffersRef<'buffers, T> {
554 inner: &'buffers mut Buffers<T>,
555}
556impl<T> Buffers<T> {
557 #[inline]
558 pub fn by_ref(&mut self) -> BuffersRef<'_, T> {
559 BuffersRef { inner: self }
560 }
561}
562impl<'buffers, T> BuffersRef<'buffers, T> {
563 #[inline]
564 pub fn by_ref(&mut self) -> BuffersRef<'_, T> {
565 BuffersRef { inner: self.inner }
566 }
567}
568impl<'buffers, T> BuffersRef<'buffers, T>
569where
570 T: InitializeVectored,
571{
572 pub fn with_current_vector_unfilled_zeroed(&mut self) -> Option<&mut [u8]>
573 where
574 T::UninitVector: Initialize<Item = u8>,
575 {
576 self.inner.with_current_vector_unfilled_zeroed()
577 }
578 pub fn advance_current_vector(&mut self, count: usize) {
579 self.inner.advance_current_vector(count)
580 }
581 pub fn advance_to_current_vector_end(&mut self) {
582 self.inner.advance_to_current_vector_end()
583 }
584}
585
586#[cfg(test)]
587mod tests {
588 use super::*;
589
590 #[test]
591 fn baisc_buffers_ops() {
592 let mut a = [MaybeUninit::<u8>::uninit(); 32];
593 let mut b = [MaybeUninit::uninit(); 8];
594 let mut c = [MaybeUninit::uninit(); 16];
595 let mut d = [MaybeUninit::uninit(); 9];
596
597 let vectors = [&mut a[..], &mut b[..], &mut c[..], &mut d[..]];
598 let buffers = Buffers::new(vectors);
599
600 assert_eq!(buffers.vectors_filled(), 0);
601 }
603 #[test]
604 fn with_current_vector_unfilled_zeroed() {
605 let mut a = [MaybeUninit::<u8>::uninit(); 32];
606 let mut b = [MaybeUninit::uninit(); 8];
607 let mut c = [MaybeUninit::uninit(); 16];
608 let mut d = [MaybeUninit::uninit(); 9];
609
610 let mut vectors = [&mut a[..], &mut b[..], &mut c[..], &mut d[..]];
611 let mut buffers = Buffers::new(&mut vectors[..]);
612 let text = b"Hello, world!";
613
614 while let Some(slice) = buffers.with_current_vector_unfilled_zeroed() {
615 let to_copy = core::cmp::min(slice.len(), text.len());
616 slice[..to_copy].copy_from_slice(&text[..to_copy]);
617 buffers.advance_to_current_vector_end();
618 }
619 }
621}