ckb_rust_std/io/cherry_picking/
borrowed_buf.rs

1use alloc::fmt::{self, Debug, Formatter};
2use core::mem::{self, MaybeUninit};
3use core::{cmp, ptr};
4
5pub struct BorrowedBuf<'data> {
6    buf: &'data mut [MaybeUninit<u8>],
7    filled: usize,
8    init: usize,
9}
10
11impl Debug for BorrowedBuf<'_> {
12    fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result {
13        f.debug_struct("BorrowedBuf")
14            .field("init", &self.init)
15            .field("filled", &self.filled)
16            .field("capacity", &self.capacity())
17            .finish()
18    }
19}
20
21impl<'data> From<&'data mut [u8]> for BorrowedBuf<'data> {
22    #[inline]
23    fn from(slice: &'data mut [u8]) -> BorrowedBuf<'data> {
24        let len = slice.len();
25        BorrowedBuf {
26            buf: unsafe { &mut *(slice as *mut [u8] as *mut [MaybeUninit<u8>]) },
27            filled: 0,
28            init: len,
29        }
30    }
31}
32
33impl<'data> From<&'data mut [MaybeUninit<u8>]> for BorrowedBuf<'data> {
34    #[inline]
35    fn from(buf: &'data mut [MaybeUninit<u8>]) -> BorrowedBuf<'data> {
36        BorrowedBuf {
37            buf,
38            filled: 0,
39            init: 0,
40        }
41    }
42}
43
44impl<'data> BorrowedBuf<'data> {
45    #[inline]
46    pub fn capacity(&self) -> usize {
47        self.buf.len()
48    }
49
50    #[inline]
51    pub fn len(&self) -> usize {
52        self.filled
53    }
54
55    #[inline]
56    pub fn is_empty(&self) -> bool {
57        self.filled == 0
58    }
59
60    #[inline]
61    pub fn init_len(&self) -> usize {
62        self.init
63    }
64
65    #[inline]
66    pub fn filled(&self) -> &[u8] {
67        unsafe {
68            let buf = self.buf.get_unchecked(..self.filled);
69            &*(buf as *const [MaybeUninit<u8>] as *const [u8])
70        }
71    }
72    #[inline]
73    pub fn filled_mut(&mut self) -> &mut [u8] {
74        unsafe {
75            let buf = self.buf.get_unchecked_mut(..self.filled);
76            &mut *(buf as *mut [MaybeUninit<u8>] as *mut [u8])
77        }
78    }
79
80    #[inline]
81    pub fn unfilled<'this>(&'this mut self) -> BorrowedCursor<'this> {
82        BorrowedCursor {
83            start: self.filled,
84            buf: unsafe {
85                mem::transmute::<&'this mut BorrowedBuf<'data>, &'this mut BorrowedBuf<'this>>(self)
86            },
87        }
88    }
89    #[inline]
90    pub fn clear(&mut self) -> &mut Self {
91        self.filled = 0;
92        self
93    }
94
95    /// # Safety
96    #[inline]
97    pub unsafe fn set_init(&mut self, n: usize) -> &mut Self {
98        self.init = cmp::max(self.init, n);
99        self
100    }
101}
102
103#[derive(Debug)]
104pub struct BorrowedCursor<'a> {
105    buf: &'a mut BorrowedBuf<'a>,
106    start: usize,
107}
108
109impl<'a> BorrowedCursor<'a> {
110    #[inline]
111    pub fn reborrow<'this>(&'this mut self) -> BorrowedCursor<'this> {
112        BorrowedCursor {
113            buf: unsafe {
114                mem::transmute::<&'this mut BorrowedBuf<'a>, &'this mut BorrowedBuf<'this>>(
115                    self.buf,
116                )
117            },
118            start: self.start,
119        }
120    }
121    #[inline]
122    pub fn capacity(&self) -> usize {
123        self.buf.capacity() - self.buf.filled
124    }
125
126    #[inline]
127    pub fn written(&self) -> usize {
128        self.buf.filled - self.start
129    }
130
131    #[inline]
132    pub fn init_ref(&self) -> &[u8] {
133        unsafe {
134            let buf = self.buf.buf.get_unchecked(self.buf.filled..self.buf.init);
135            &*(buf as *const [MaybeUninit<u8>] as *const [u8])
136        }
137    }
138    #[inline]
139    pub fn init_mut(&mut self) -> &mut [u8] {
140        unsafe {
141            let buf = self
142                .buf
143                .buf
144                .get_unchecked_mut(self.buf.filled..self.buf.init);
145            &mut *(buf as *mut [MaybeUninit<u8>] as *mut [u8])
146        }
147    }
148    #[inline]
149    pub fn uninit_mut(&mut self) -> &mut [MaybeUninit<u8>] {
150        unsafe { self.buf.buf.get_unchecked_mut(self.buf.init..) }
151    }
152    /// # Safety
153    #[inline]
154    pub unsafe fn as_mut(&mut self) -> &mut [MaybeUninit<u8>] {
155        unsafe { self.buf.buf.get_unchecked_mut(self.buf.filled..) }
156    }
157    #[inline]
158    pub fn advance(&mut self, n: usize) -> &mut Self {
159        let filled = self.buf.filled.checked_add(n).unwrap();
160        assert!(filled <= self.buf.init);
161
162        self.buf.filled = filled;
163        self
164    }
165    /// # Safety
166    #[inline]
167    pub unsafe fn advance_unchecked(&mut self, n: usize) -> &mut Self {
168        self.buf.filled += n;
169        self.buf.init = cmp::max(self.buf.init, self.buf.filled);
170        self
171    }
172
173    #[inline]
174    pub fn ensure_init(&mut self) -> &mut Self {
175        let uninit = self.uninit_mut();
176        unsafe {
177            ptr::write_bytes(uninit.as_mut_ptr(), 0, uninit.len());
178        }
179        self.buf.init = self.buf.capacity();
180
181        self
182    }
183    /// # Safety
184    #[inline]
185    pub unsafe fn set_init(&mut self, n: usize) -> &mut Self {
186        self.buf.init = cmp::max(self.buf.init, self.buf.filled + n);
187        self
188    }
189    #[inline]
190    pub fn append(&mut self, buf: &[u8]) {
191        assert!(self.capacity() >= buf.len());
192        unsafe {
193            ptr::copy(
194                buf.as_ptr(),
195                self.as_mut().as_mut_ptr() as *mut u8,
196                buf.len(),
197            );
198        }
199        unsafe {
200            self.set_init(buf.len());
201        }
202        self.buf.filled += buf.len();
203    }
204}