ckb_rust_std/io/cherry_picking/
borrowed_buf.rs1use 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 #[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 #[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 #[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 #[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}