blocked_vec/
io.rs

1use core::{
2    mem,
3    ops::{Deref, DerefMut},
4    slice,
5};
6
7pub trait IoSlice<'a>: Sized + Deref<Target = [u8]> {
8    fn advance(&mut self, n: usize);
9
10    fn advance_slices(bufs: &mut &mut [Self], n: usize) {
11        // Number of buffers to remove.
12        let mut remove = 0;
13        // Total length of all the to be removed buffers.
14        let mut accumulated_len = 0;
15        for buf in bufs.iter() {
16            if accumulated_len + buf.len() > n {
17                break;
18            } else {
19                accumulated_len += buf.len();
20                remove += 1;
21            }
22        }
23
24        *bufs = &mut mem::take(bufs)[remove..];
25        if bufs.is_empty() {
26            assert!(
27                n == accumulated_len,
28                "advancing io slices beyond their length"
29            );
30        } else {
31            bufs[0].advance(n - accumulated_len)
32        }
33    }
34}
35
36pub trait IoSliceMut<'a>: Sized + DerefMut<Target = [u8]> {
37    fn advance(&mut self, n: usize);
38
39    fn advance_slices(bufs: &mut &mut [Self], n: usize) {
40        // Number of buffers to remove.
41        let mut remove = 0;
42        // Total length of all the to be removed buffers.
43        let mut accumulated_len = 0;
44        for buf in bufs.iter() {
45            if accumulated_len + buf.len() > n {
46                break;
47            } else {
48                accumulated_len += buf.len();
49                remove += 1;
50            }
51        }
52
53        *bufs = &mut mem::take(bufs)[remove..];
54        if bufs.is_empty() {
55            assert!(
56                n == accumulated_len,
57                "advancing io slices beyond their length"
58            );
59        } else {
60            bufs[0].advance(n - accumulated_len)
61        }
62    }
63}
64
65#[derive(Copy, PartialEq, Eq, Clone, Debug)]
66pub enum SeekFrom {
67    Start(usize),
68    Current(isize),
69    End(isize),
70}
71
72impl<'a> IoSlice<'a> for &'a [u8] {
73    fn advance(&mut self, n: usize) {
74        *self = &self[n..];
75    }
76}
77
78impl<'a> IoSliceMut<'a> for &'a mut [u8] {
79    fn advance(&mut self, n: usize) {
80        *self = unsafe {
81            let (ptr, len) = (*self as *mut [u8]).to_raw_parts();
82            let ptr = ptr.cast::<u8>().add(n);
83            slice::from_raw_parts_mut(ptr, len - n)
84        };
85    }
86}
87
88#[cfg(feature = "std")]
89impl<'a> IoSlice<'a> for std::io::IoSlice<'a> {
90    fn advance(&mut self, n: usize) {
91        self.advance(n)
92    }
93
94    fn advance_slices(bufs: &mut &mut [Self], n: usize) {
95        std::io::IoSlice::advance_slices(bufs, n)
96    }
97}
98
99#[cfg(feature = "std")]
100impl<'a> IoSliceMut<'a> for std::io::IoSliceMut<'a> {
101    fn advance(&mut self, n: usize) {
102        self.advance(n)
103    }
104
105    fn advance_slices(bufs: &mut &mut [Self], n: usize) {
106        std::io::IoSliceMut::advance_slices(bufs, n)
107    }
108}
109
110#[cfg(feature = "std")]
111impl From<SeekFrom> for std::io::SeekFrom {
112    fn from(this: SeekFrom) -> Self {
113        match this {
114            SeekFrom::Start(pos) => std::io::SeekFrom::Start(pos as u64),
115            SeekFrom::Current(pos) => std::io::SeekFrom::Current(pos as i64),
116            SeekFrom::End(pos) => std::io::SeekFrom::End(pos as i64),
117        }
118    }
119}
120
121#[cfg(feature = "std")]
122impl From<std::io::SeekFrom> for SeekFrom {
123    fn from(this: std::io::SeekFrom) -> Self {
124        match this {
125            std::io::SeekFrom::Start(pos) => SeekFrom::Start(pos as usize),
126            std::io::SeekFrom::Current(pos) => SeekFrom::Current(pos as isize),
127            std::io::SeekFrom::End(pos) => SeekFrom::End(pos as isize),
128        }
129    }
130}