1use crate::buffer_allocator::BufferAllocator as PoolBufferAllocator;
6use std::borrow::Borrow;
7use std::marker::PhantomData;
8use std::ops::{Bound, Range, RangeBounds};
9use std::slice::SliceIndex;
10use storage_ptr_slice::{MutPtrByteSlice, PtrByteSlice};
11
12pub use crate::buffer_allocator::{BufferFuture, TryAllocateBuffer};
13
14#[cfg(target_os = "fuchsia")]
15use zx::sys::zx_paddr_t;
16
17pub trait BufferAllocator: Send + Sync + std::fmt::Debug + 'static {
19 fn free_buffer(&self, range: Range<usize>);
21
22 fn identifier(&self) -> usize {
24 std::ptr::from_ref(self).addr()
25 }
26
27 fn is_trusted(&self) -> bool {
29 false
30 }
31
32 #[cfg(target_os = "fuchsia")]
37 fn vmo(&self) -> Option<Arc<zx::Vmo>> {
38 None
39 }
40
41 #[cfg(target_os = "fuchsia")]
43 fn paddrs(&self, _range: &Range<usize>) -> Option<(&[zx_paddr_t], u64)> {
44 None
45 }
46}
47
48pub(super) fn round_down<T>(value: T, granularity: T) -> T
49where
50 T: num::Num + Copy,
51{
52 value - value % granularity
53}
54
55pub(super) fn round_up<T>(value: T, granularity: T) -> T
56where
57 T: num::Num + Copy,
58{
59 round_down(value + granularity - T::one(), granularity)
60}
61
62fn subrange<R: RangeBounds<usize>>(source: &Range<usize>, bounds: &R) -> Range<usize> {
65 let subrange = (match bounds.start_bound() {
66 Bound::Included(&s) => source.start + s,
67 Bound::Excluded(&s) => source.start + s + 1,
68 Bound::Unbounded => source.start,
69 })..(match bounds.end_bound() {
70 Bound::Included(&e) => source.start + e + 1,
71 Bound::Excluded(&e) => source.start + e,
72 Bound::Unbounded => source.end,
73 });
74 assert!(subrange.end <= source.end);
75 subrange
76}
77
78fn split_range(range: &Range<usize>, mid: usize) -> (Range<usize>, Range<usize>) {
79 let l = range.end - range.start;
80 let base = range.start;
81 (base..base + mid, base + mid..base + l)
82}
83
84use std::sync::Arc;
100
101#[derive(Debug)]
102pub struct BufferImpl<'a, H: Borrow<A>, A: ?Sized + BufferAllocator> {
103 slice: MutPtrByteSlice<'a>,
104 range: Range<usize>,
105 pub(super) allocator: H,
106 _phantom: PhantomData<fn() -> &'a A>,
107}
108
109pub type Buffer<'a> = BufferImpl<'a, &'a PoolBufferAllocator, PoolBufferAllocator>;
110pub type OwnedBuffer = BufferImpl<'static, Arc<dyn BufferAllocator>, dyn BufferAllocator>;
111
112pub trait SliceRange: Clone + RangeBounds<usize> + SliceIndex<[u8], Output = [u8]> {}
115impl<T> SliceRange for T where T: Clone + RangeBounds<usize> + SliceIndex<[u8], Output = [u8]> {}
116
117impl<'a, H: Borrow<A>, A: ?Sized + BufferAllocator> BufferImpl<'a, H, A> {
118 pub(super) fn new(slice: MutPtrByteSlice<'a>, range: Range<usize>, allocator: H) -> Self {
119 assert_eq!(slice.len(), range.end - range.start);
120 Self { slice, range, allocator, _phantom: PhantomData }
121 }
122
123 pub fn as_ref(&self) -> BufferRef<'_> {
125 self.subslice(..)
126 }
127
128 pub fn subslice<R: SliceRange>(&self, range: R) -> BufferRef<'_> {
131 let new_range = subrange(&self.range, &range);
132 let relative_range =
133 (new_range.start - self.range.start)..(new_range.end - self.range.start);
134 let slice = self.slice.as_ptr_slice().subslice(relative_range);
135 BufferRef {
136 slice,
137 start: new_range.start,
138 end: new_range.end,
139 allocator_id: self.allocator.borrow().identifier(),
140 trusted: self.allocator.borrow().is_trusted(),
141 }
142 }
143
144 pub fn as_mut(&mut self) -> MutableBufferRef<'_> {
146 self.subslice_mut(..)
147 }
148
149 pub fn writer(&mut self) -> storage_ptr_slice::Writer<'_> {
151 self.slice.reborrow().writer()
152 }
153
154 pub fn subslice_mut<R: SliceRange>(&mut self, range: R) -> MutableBufferRef<'_> {
157 let new_range = subrange(&self.range, &range);
158 let relative_range =
159 (new_range.start - self.range.start)..(new_range.end - self.range.start);
160 let slice = self.slice.reborrow().subslice_mut(relative_range);
161 MutableBufferRef {
162 slice,
163 range: new_range,
164 allocator_id: self.allocator.borrow().identifier(),
165 trusted: self.allocator.borrow().is_trusted(),
166 }
167 }
168
169 pub fn len(&self) -> usize {
171 self.range.end - self.range.start
172 }
173
174 #[cfg(target_os = "fuchsia")]
176 pub fn paddrs(&self) -> Option<&[zx_paddr_t]> {
177 self.allocator.borrow().paddrs(&self.range).map(|(paddrs, _)| paddrs)
178 }
179
180 #[cfg(target_os = "fuchsia")]
182 pub fn contiguity(&self) -> Option<u64> {
183 self.allocator.borrow().paddrs(&self.range).map(|(_, contig)| contig)
184 }
185
186 #[cfg(target_os = "fuchsia")]
190 pub fn vmo(&self) -> Option<Arc<zx::Vmo>> {
191 self.allocator.borrow().vmo()
192 }
193
194 pub fn try_as_slice(&self) -> Option<&[u8]> {
197 if self.allocator.borrow().is_trusted() {
198 Some(unsafe { std::slice::from_raw_parts(self.slice.as_ptr(), self.len()) })
200 } else {
201 None
202 }
203 }
204
205 pub fn try_as_mut_slice(&mut self) -> Option<&mut [u8]> {
208 if self.allocator.borrow().is_trusted() {
209 Some(unsafe { std::slice::from_raw_parts_mut(self.slice.as_mut_ptr(), self.len()) })
211 } else {
212 None
213 }
214 }
215
216 pub fn copy_to_slice(&self, dest: &mut [u8]) {
222 self.slice.as_ptr_slice().copy_to_slice(dest);
223 }
224
225 pub fn copy_from_slice(&mut self, src: &[u8]) {
231 self.slice.copy_from_ptr_slice(src.into());
232 }
233
234 pub fn copy_from_buffer(&mut self, src: BufferRef<'_>) {
240 self.as_mut().copy_from_buffer(src);
241 }
242
243 pub fn fill(&mut self, val: u8) {
245 self.slice.fill(val);
246 }
247
248 pub fn range(&self) -> Range<usize> {
250 self.range.clone()
251 }
252
253 pub fn allocator(&self) -> &A {
255 self.allocator.borrow()
256 }
257
258 pub fn to_vec(&self) -> Vec<u8> {
260 self.as_ref().to_vec()
261 }
262
263 pub fn append_to(&self, vec: &mut Vec<u8>) {
265 self.as_ref().append_to(vec)
266 }
267
268 pub fn as_ptr(&self) -> *const u8 {
270 self.slice.as_ptr()
271 }
272
273 pub fn as_mut_ptr(&mut self) -> *mut u8 {
275 self.slice.as_mut_ptr()
276 }
277
278 pub fn as_ptr_slice(&self) -> PtrByteSlice<'_> {
280 self.slice.as_ptr_slice()
281 }
282
283 pub fn as_mut_ptr_slice(&mut self) -> MutPtrByteSlice<'_> {
285 self.slice.reborrow()
286 }
287}
288
289impl<'a, H: Borrow<A>, A: ?Sized + BufferAllocator> Drop for BufferImpl<'a, H, A> {
290 fn drop(&mut self) {
291 self.allocator.borrow().free_buffer(self.range.clone());
292 }
293}
294
295#[derive(Clone, Copy, Debug)]
297pub struct BufferRef<'a> {
298 slice: PtrByteSlice<'a>,
299 start: usize, end: usize,
301 allocator_id: usize,
304 trusted: bool,
305}
306
307impl<'a> BufferRef<'a> {
308 pub fn len(&self) -> usize {
310 self.end - self.start
311 }
312
313 pub fn is_empty(&self) -> bool {
314 self.end == self.start
315 }
316
317 #[cfg(target_os = "fuchsia")]
318 pub(crate) fn allocator_id(&self) -> usize {
319 self.allocator_id
320 }
321
322 pub fn try_as_slice(&self) -> Option<&[u8]> {
325 if self.trusted {
326 Some(unsafe { std::slice::from_raw_parts(self.slice.as_ptr(), self.len()) })
328 } else {
329 None
330 }
331 }
332
333 pub fn subslice<R: SliceRange>(&self, range: R) -> BufferRef<'_> {
335 let new_range = subrange(&self.range(), &range);
336 let relative_range = (new_range.start - self.start)..(new_range.end - self.start);
337 let slice = self.slice.subslice(relative_range);
338 BufferRef {
339 slice,
340 start: new_range.start,
341 end: new_range.end,
342 allocator_id: self.allocator_id,
343 trusted: self.trusted,
344 }
345 }
346
347 pub fn split_at(&self, mid: usize) -> (BufferRef<'a>, BufferRef<'a>) {
349 let ranges = split_range(&self.range(), mid);
350 let (left_slice, right_slice) = self.slice.split_at(mid);
351 (
352 BufferRef {
353 slice: left_slice,
354 start: ranges.0.start,
355 end: ranges.0.end,
356 allocator_id: self.allocator_id,
357 trusted: self.trusted,
358 },
359 BufferRef {
360 slice: right_slice,
361 start: ranges.1.start,
362 end: ranges.1.end,
363 allocator_id: self.allocator_id,
364 trusted: self.trusted,
365 },
366 )
367 }
368
369 pub fn chunks(self, chunk_size: usize) -> Chunks<'a> {
375 Chunks {
376 inner: self.slice.chunks(chunk_size),
377 start: self.start,
378 allocator_id: self.allocator_id,
379 trusted: self.trusted,
380 }
381 }
382
383 pub fn range(&self) -> Range<usize> {
385 self.start..self.end
386 }
387
388 pub fn copy_to_slice(&self, dest: &mut [u8]) {
394 self.slice.copy_to_slice(dest);
395 }
396
397 pub fn to_vec(&self) -> Vec<u8> {
399 self.slice.to_vec()
400 }
401
402 pub fn append_to(&self, vec: &mut Vec<u8>) {
404 self.slice.append_to(vec);
405 }
406
407 pub fn as_ptr(&self) -> *const u8 {
409 self.slice.as_ptr()
410 }
411
412 pub fn as_ptr_slice(&self) -> PtrByteSlice<'a> {
414 self.slice
415 }
416}
417
418#[derive(Debug)]
420pub struct MutableBufferRef<'a> {
421 slice: MutPtrByteSlice<'a>,
422 range: Range<usize>,
423 allocator_id: usize,
426 trusted: bool,
427}
428
429impl<'a> MutableBufferRef<'a> {
430 pub fn len(&self) -> usize {
432 self.range.end - self.range.start
433 }
434
435 pub fn is_empty(&self) -> bool {
436 self.range.end == self.range.start
437 }
438
439 #[cfg(target_os = "fuchsia")]
440 pub(crate) fn allocator_id(&self) -> usize {
441 self.allocator_id
442 }
443
444 pub fn as_ref(&self) -> BufferRef<'_> {
446 BufferRef {
447 slice: self.slice.as_ptr_slice(),
448 start: self.range.start,
449 end: self.range.end,
450 allocator_id: self.allocator_id,
451 trusted: self.trusted,
452 }
453 }
454
455 pub fn into_ref(self) -> BufferRef<'a> {
457 BufferRef {
458 slice: self.slice.into(),
459 start: self.range.start,
460 end: self.range.end,
461 allocator_id: self.allocator_id,
462 trusted: self.trusted,
463 }
464 }
465
466 pub fn try_as_slice(&self) -> Option<&[u8]> {
469 if self.trusted {
470 Some(unsafe { std::slice::from_raw_parts(self.slice.as_ptr(), self.len()) })
472 } else {
473 None
474 }
475 }
476
477 pub fn try_as_mut_slice(&mut self) -> Option<&mut [u8]> {
480 if self.trusted {
481 Some(unsafe { std::slice::from_raw_parts_mut(self.slice.as_mut_ptr(), self.len()) })
483 } else {
484 None
485 }
486 }
487
488 pub fn reborrow(&mut self) -> MutableBufferRef<'_> {
498 MutableBufferRef {
499 slice: self.slice.reborrow(),
500 range: self.range.clone(),
501 allocator_id: self.allocator_id,
502 trusted: self.trusted,
503 }
504 }
505
506 pub fn writer(&mut self) -> storage_ptr_slice::Writer<'_> {
508 self.slice.reborrow().writer()
509 }
510
511 pub fn subslice<R: SliceRange>(&self, range: R) -> BufferRef<'_> {
513 let new_range = subrange(&self.range, &range);
514 let relative_range =
515 (new_range.start - self.range.start)..(new_range.end - self.range.start);
516 let slice = self.slice.as_ptr_slice().subslice(relative_range);
517 BufferRef {
518 slice,
519 start: new_range.start,
520 end: new_range.end,
521 allocator_id: self.allocator_id,
522 trusted: self.trusted,
523 }
524 }
525
526 pub fn subslice_mut<R: SliceRange>(mut self, range: R) -> MutableBufferRef<'a> {
528 let new_range = subrange(&self.range, &range);
529 let relative_range =
530 (new_range.start - self.range.start)..(new_range.end - self.range.start);
531 self.slice = self.slice.subslice_mut(relative_range);
532 self.range = new_range;
533 self
534 }
535
536 pub fn split_at(&self, mid: usize) -> (BufferRef<'_>, BufferRef<'_>) {
538 let ranges = split_range(&self.range, mid);
539 let (left_slice, right_slice) = self.slice.as_ptr_slice().split_at(mid);
540 (
541 BufferRef {
542 slice: left_slice,
543 start: ranges.0.start,
544 end: ranges.0.end,
545 allocator_id: self.allocator_id,
546 trusted: self.trusted,
547 },
548 BufferRef {
549 slice: right_slice,
550 start: ranges.1.start,
551 end: ranges.1.end,
552 allocator_id: self.allocator_id,
553 trusted: self.trusted,
554 },
555 )
556 }
557
558 pub fn split_at_mut(self, mid: usize) -> (MutableBufferRef<'a>, MutableBufferRef<'a>) {
561 let ranges = split_range(&self.range, mid);
562 let (left_slice, right_slice) = self.slice.split_at_mut(mid);
563 (
564 MutableBufferRef {
565 slice: left_slice,
566 range: ranges.0,
567 allocator_id: self.allocator_id,
568 trusted: self.trusted,
569 },
570 MutableBufferRef {
571 slice: right_slice,
572 range: ranges.1,
573 allocator_id: self.allocator_id,
574 trusted: self.trusted,
575 },
576 )
577 }
578
579 pub fn range(&self) -> Range<usize> {
581 self.range.clone()
582 }
583
584 pub fn copy_to_slice(&self, dest: &mut [u8]) {
590 self.slice.copy_to_slice(dest);
591 }
592
593 pub fn copy_from_slice(&mut self, src: &[u8]) {
599 self.slice.copy_from_ptr_slice(src.into());
600 }
601
602 pub fn copy_from_buffer(&mut self, src: BufferRef<'_>) {
608 self.slice.copy_from_ptr_slice(src.as_ptr_slice());
609 }
610
611 pub fn fill(&mut self, val: u8) {
613 self.slice.fill(val);
614 }
615
616 pub fn to_vec(&self) -> Vec<u8> {
618 self.slice.to_vec()
619 }
620
621 pub fn append_to(&self, vec: &mut Vec<u8>) {
623 self.slice.append_to(vec);
624 }
625
626 pub fn as_ptr(&self) -> *const u8 {
628 self.slice.as_ptr()
629 }
630
631 pub fn as_mut_ptr(&mut self) -> *mut u8 {
633 self.slice.as_mut_ptr()
634 }
635
636 pub fn as_ptr_slice(&self) -> PtrByteSlice<'_> {
638 self.slice.as_ptr_slice()
639 }
640
641 pub fn as_mut_ptr_slice(&mut self) -> MutPtrByteSlice<'_> {
643 self.slice.reborrow()
644 }
645
646 pub fn chunks_mut(self, chunk_size: usize) -> ChunksMut<'a> {
652 ChunksMut {
653 inner: self.slice.into_chunks_mut(chunk_size),
654 start: self.range.start,
655 allocator_id: self.allocator_id,
656 trusted: self.trusted,
657 }
658 }
659
660 pub fn into_mut_ptr_slice(self) -> MutPtrByteSlice<'a> {
662 self.slice
663 }
664}
665
666#[derive(Debug)]
668pub struct Chunks<'a> {
669 inner: storage_ptr_slice::Chunks<'a>,
670 start: usize,
671 allocator_id: usize,
672 trusted: bool,
673}
674
675impl<'a> Iterator for Chunks<'a> {
676 type Item = BufferRef<'a>;
677
678 fn next(&mut self) -> Option<Self::Item> {
679 let slice = self.inner.next()?;
680 let len = slice.len();
681 let start = self.start;
682 self.start += len;
683 Some(BufferRef {
684 slice,
685 start,
686 end: start + len,
687 allocator_id: self.allocator_id,
688 trusted: self.trusted,
689 })
690 }
691
692 fn size_hint(&self) -> (usize, Option<usize>) {
693 self.inner.size_hint()
694 }
695}
696
697impl ExactSizeIterator for Chunks<'_> {
698 fn len(&self) -> usize {
699 self.inner.len()
700 }
701}
702
703impl std::iter::FusedIterator for Chunks<'_> {}
704
705#[derive(Debug)]
707pub struct ChunksMut<'a> {
708 inner: storage_ptr_slice::ChunksMut<'a>,
709 start: usize,
710 allocator_id: usize,
711 trusted: bool,
712}
713
714impl<'a> Iterator for ChunksMut<'a> {
715 type Item = MutableBufferRef<'a>;
716
717 fn next(&mut self) -> Option<Self::Item> {
718 let slice = self.inner.next()?;
719 let len = slice.len();
720 let start = self.start;
721 self.start += len;
722 Some(MutableBufferRef {
723 slice,
724 range: start..start + len,
725 allocator_id: self.allocator_id,
726 trusted: self.trusted,
727 })
728 }
729
730 fn size_hint(&self) -> (usize, Option<usize>) {
731 self.inner.size_hint()
732 }
733}
734
735impl ExactSizeIterator for ChunksMut<'_> {
736 fn len(&self) -> usize {
737 self.inner.len()
738 }
739}
740
741impl std::iter::FusedIterator for ChunksMut<'_> {}
742
743#[cfg(test)]
744mod tests {
745 use crate::buffer_allocator::{BufferAllocator, BufferSource};
746
747 #[test]
748 fn test_buffer_refs_are_send_and_sync() {
749 fn check<'a>() {
750 fn assert_send_sync<T: Send + Sync>() {}
751 assert_send_sync::<super::BufferRef<'a>>();
752 assert_send_sync::<super::MutableBufferRef<'a>>();
753 }
754 check();
755 }
756
757 #[fuchsia::test]
758 async fn test_chunks() {
759 let source = BufferSource::new(1024 * 1024);
760 let allocator = BufferAllocator::new(512, source);
761 let mut buf = allocator.allocate_buffer(1000).await;
762 let init_data: Vec<u8> = (0..1000).map(|i| (i % 256) as u8).collect();
763 buf.as_mut().copy_from_slice(&init_data);
764
765 let bref = buf.as_ref();
766 let chunks: Vec<_> = bref.chunks(300).collect();
767 assert_eq!(chunks.len(), 4);
768 assert_eq!(chunks[0].len(), 300);
769 assert_eq!(chunks[1].len(), 300);
770 assert_eq!(chunks[2].len(), 300);
771 assert_eq!(chunks[3].len(), 100);
772
773 let mut data = vec![0u8; 300];
774 chunks[0].copy_to_slice(&mut data);
775 assert_eq!(data, (0..300).map(|i| (i % 256) as u8).collect::<Vec<u8>>());
776
777 let mut data_last = vec![0u8; 100];
778 chunks[3].copy_to_slice(&mut data_last);
779 assert_eq!(data_last, (900..1000).map(|i| (i % 256) as u8).collect::<Vec<u8>>());
780
781 let bref_exact = buf.subslice(0..600);
783 let chunks_exact: Vec<_> = bref_exact.chunks(200).collect();
784 assert_eq!(chunks_exact.len(), 3);
785 assert_eq!(chunks_exact.iter().map(|c| c.len()).collect::<Vec<_>>(), vec![200, 200, 200]);
786
787 let bref_empty = buf.subslice(0..0);
789 assert_eq!(bref_empty.chunks(100).count(), 0);
790 assert_eq!(bref_empty.chunks(100).len(), 0);
791
792 let chunks_large: Vec<_> = bref.chunks(2000).collect();
794 assert_eq!(chunks_large.len(), 1);
795 assert_eq!(chunks_large[0].len(), 1000);
796
797 let mut iter = bref.chunks(300);
799 assert_eq!(iter.len(), 4);
800 assert_eq!(iter.size_hint(), (4, Some(4)));
801 assert_eq!(iter.next().unwrap().len(), 300);
802 assert_eq!(iter.len(), 3);
803 assert_eq!(iter.size_hint(), (3, Some(3)));
804 assert_eq!(iter.next().unwrap().len(), 300);
805 assert_eq!(iter.len(), 2);
806 assert_eq!(iter.size_hint(), (2, Some(2)));
807 assert_eq!(iter.next().unwrap().len(), 300);
808 assert_eq!(iter.len(), 1);
809 assert_eq!(iter.size_hint(), (1, Some(1)));
810 assert_eq!(iter.next().unwrap().len(), 100);
811 assert_eq!(iter.len(), 0);
812 assert_eq!(iter.size_hint(), (0, Some(0)));
813 assert!(iter.next().is_none());
814 }
815
816 #[fuchsia::test]
817 async fn test_chunks_mut() {
818 let source = BufferSource::new(1024 * 1024);
819 let allocator = BufferAllocator::new(512, source);
820 let mut buf = allocator.allocate_buffer(1000).await;
821
822 for (i, mut chunk) in buf.as_mut().chunks_mut(300).enumerate() {
823 chunk.fill(i as u8 + 1);
824 }
825
826 let mut data = vec![0u8; 1000];
827 buf.copy_to_slice(&mut data);
828 assert_eq!(&data[0..300], &[1u8; 300]);
829 assert_eq!(&data[300..600], &[2u8; 300]);
830 assert_eq!(&data[600..900], &[3u8; 300]);
831 assert_eq!(&data[900..1000], &[4u8; 100]);
832
833 let mut buf_exact = allocator.allocate_buffer(600).await;
835 for (i, mut chunk) in buf_exact.as_mut().chunks_mut(200).enumerate() {
836 chunk.fill((i + 10) as u8);
837 }
838 let mut data_exact = vec![0u8; 600];
839 buf_exact.copy_to_slice(&mut data_exact);
840 assert_eq!(&data_exact[0..200], &[10u8; 200]);
841 assert_eq!(&data_exact[200..400], &[11u8; 200]);
842 assert_eq!(&data_exact[400..600], &[12u8; 200]);
843
844 let mut buf_empty = allocator.allocate_buffer(512).await;
846 let empty_ref = buf_empty.subslice_mut(0..0);
847 assert_eq!(empty_ref.chunks_mut(100).count(), 0);
848
849 let mut buf_exact_iter = allocator.allocate_buffer(1000).await;
851 let mut iter = buf_exact_iter.as_mut().chunks_mut(300);
852 assert_eq!(iter.len(), 4);
853 assert_eq!(iter.size_hint(), (4, Some(4)));
854 let mut c1 = iter.next().unwrap();
855 c1.fill(0x11);
856 assert_eq!(iter.len(), 3);
857 assert_eq!(iter.size_hint(), (3, Some(3)));
858 let mut c2 = iter.next().unwrap();
859 c2.fill(0x22);
860 assert_eq!(iter.len(), 2);
861 assert_eq!(iter.size_hint(), (2, Some(2)));
862 let mut c3 = iter.next().unwrap();
863 c3.fill(0x33);
864 assert_eq!(iter.len(), 1);
865 assert_eq!(iter.size_hint(), (1, Some(1)));
866 let mut c4 = iter.next().unwrap();
867 c4.fill(0x44);
868 assert_eq!(iter.len(), 0);
869 assert_eq!(iter.size_hint(), (0, Some(0)));
870 assert!(iter.next().is_none());
871
872 let mut data_iter = vec![0u8; 1000];
873 buf_exact_iter.copy_to_slice(&mut data_iter);
874 assert_eq!(&data_iter[0..300], &[0x11; 300]);
875 assert_eq!(&data_iter[300..600], &[0x22; 300]);
876 assert_eq!(&data_iter[600..900], &[0x33; 300]);
877 assert_eq!(&data_iter[900..1000], &[0x44; 100]);
878 }
879}