1use crate::alloc::Allocator;
2use crate::boxed::Box;
3use crate::io::{
4 self, Cursor, ErrorKind, IoSlice, WriteThroughCursor, slice_write, slice_write_all,
5 slice_write_all_vectored, slice_write_vectored,
6};
7use crate::vec::Vec;
8
9fn reserve_and_pad<A: Allocator>(
11 pos_mut: &mut u64,
12 vec: &mut Vec<u8, A>,
13 buf_len: usize,
14) -> io::Result<usize> {
15 let pos: usize = (*pos_mut).try_into().map_err(|_| {
16 io::const_error!(
17 ErrorKind::InvalidInput,
18 "cursor position exceeds maximum possible vector length",
19 )
20 })?;
21
22 let desired_cap = pos.saturating_add(buf_len);
25 if desired_cap > vec.capacity() {
26 cfg_select! {
31 no_global_oom_handling => {
32 vec.try_reserve(desired_cap - vec.len())?;
33 }
34 _ => {
35 vec.reserve(desired_cap - vec.len());
36 }
37 }
38 }
39 if pos > vec.len() {
41 let diff = pos - vec.len();
42 let spare = vec.spare_capacity_mut();
46 debug_assert!(spare.len() >= diff);
47 unsafe {
50 spare.get_unchecked_mut(..diff).fill(core::mem::MaybeUninit::new(0));
51 vec.set_len(pos);
52 }
53 }
54
55 Ok(pos)
56}
57
58unsafe fn vec_write_all_unchecked<A>(pos: usize, vec: &mut Vec<u8, A>, buf: &[u8]) -> usize
64where
65 A: Allocator,
66{
67 debug_assert!(vec.capacity() >= pos + buf.len());
68 unsafe { vec.as_mut_ptr().add(pos).copy_from(buf.as_ptr(), buf.len()) };
69 pos + buf.len()
70}
71
72fn vec_write_all<A>(pos_mut: &mut u64, vec: &mut Vec<u8, A>, buf: &[u8]) -> io::Result<usize>
84where
85 A: Allocator,
86{
87 let buf_len = buf.len();
88 let mut pos = reserve_and_pad(pos_mut, vec, buf_len)?;
89
90 unsafe {
94 pos = vec_write_all_unchecked(pos, vec, buf);
95 if pos > vec.len() {
96 vec.set_len(pos);
97 }
98 };
99
100 *pos_mut += buf_len as u64;
102 Ok(buf_len)
103}
104
105fn vec_write_all_vectored<A>(
117 pos_mut: &mut u64,
118 vec: &mut Vec<u8, A>,
119 bufs: &[IoSlice<'_>],
120) -> io::Result<usize>
121where
122 A: Allocator,
123{
124 let buf_len = bufs.iter().fold(0usize, |a, b| a.saturating_add(b.len()));
127 let mut pos = reserve_and_pad(pos_mut, vec, buf_len)?;
128
129 unsafe {
133 for buf in bufs {
134 pos = vec_write_all_unchecked(pos, vec, buf);
135 }
136 if pos > vec.len() {
137 vec.set_len(pos);
138 }
139 }
140
141 *pos_mut += buf_len as u64;
143 Ok(buf_len)
144}
145
146#[stable(feature = "cursor_mut_vec", since = "1.25.0")]
147impl<A> WriteThroughCursor for &mut Vec<u8, A>
148where
149 A: Allocator,
150{
151 fn write(this: &mut Cursor<Self>, buf: &[u8]) -> io::Result<usize> {
152 let (pos, inner) = this.into_parts_mut();
153 vec_write_all(pos, inner, buf)
154 }
155
156 fn write_vectored(this: &mut Cursor<Self>, bufs: &[IoSlice<'_>]) -> io::Result<usize> {
157 let (pos, inner) = this.into_parts_mut();
158 vec_write_all_vectored(pos, inner, bufs)
159 }
160
161 #[inline]
162 fn is_write_vectored(_this: &Cursor<Self>) -> bool {
163 true
164 }
165
166 fn write_all(this: &mut Cursor<Self>, buf: &[u8]) -> io::Result<()> {
167 let (pos, inner) = this.into_parts_mut();
168 vec_write_all(pos, inner, buf)?;
169 Ok(())
170 }
171
172 fn write_all_vectored(this: &mut Cursor<Self>, bufs: &mut [IoSlice<'_>]) -> io::Result<()> {
173 let (pos, inner) = this.into_parts_mut();
174 vec_write_all_vectored(pos, inner, bufs)?;
175 Ok(())
176 }
177
178 #[inline]
179 fn flush(_this: &mut Cursor<Self>) -> io::Result<()> {
180 Ok(())
181 }
182}
183
184#[stable(feature = "rust1", since = "1.0.0")]
185impl<A> WriteThroughCursor for Vec<u8, A>
186where
187 A: Allocator,
188{
189 fn write(this: &mut Cursor<Self>, buf: &[u8]) -> io::Result<usize> {
190 let (pos, inner) = this.into_parts_mut();
191 vec_write_all(pos, inner, buf)
192 }
193
194 fn write_vectored(this: &mut Cursor<Self>, bufs: &[IoSlice<'_>]) -> io::Result<usize> {
195 let (pos, inner) = this.into_parts_mut();
196 vec_write_all_vectored(pos, inner, bufs)
197 }
198
199 #[inline]
200 fn is_write_vectored(_this: &Cursor<Self>) -> bool {
201 true
202 }
203
204 fn write_all(this: &mut Cursor<Self>, buf: &[u8]) -> io::Result<()> {
205 let (pos, inner) = this.into_parts_mut();
206 vec_write_all(pos, inner, buf)?;
207 Ok(())
208 }
209
210 fn write_all_vectored(this: &mut Cursor<Self>, bufs: &mut [IoSlice<'_>]) -> io::Result<()> {
211 let (pos, inner) = this.into_parts_mut();
212 vec_write_all_vectored(pos, inner, bufs)?;
213 Ok(())
214 }
215
216 #[inline]
217 fn flush(_this: &mut Cursor<Self>) -> io::Result<()> {
218 Ok(())
219 }
220}
221
222#[stable(feature = "cursor_box_slice", since = "1.5.0")]
223impl<A> WriteThroughCursor for Box<[u8], A>
224where
225 A: Allocator,
226{
227 #[inline]
228 fn write(this: &mut Cursor<Self>, buf: &[u8]) -> io::Result<usize> {
229 let (pos, inner) = this.into_parts_mut();
230 slice_write(pos, inner, buf)
231 }
232
233 #[inline]
234 fn write_vectored(this: &mut Cursor<Self>, bufs: &[IoSlice<'_>]) -> io::Result<usize> {
235 let (pos, inner) = this.into_parts_mut();
236 slice_write_vectored(pos, inner, bufs)
237 }
238
239 #[inline]
240 fn is_write_vectored(_this: &Cursor<Self>) -> bool {
241 true
242 }
243
244 #[inline]
245 fn write_all(this: &mut Cursor<Self>, buf: &[u8]) -> io::Result<()> {
246 let (pos, inner) = this.into_parts_mut();
247 slice_write_all(pos, inner, buf)
248 }
249
250 #[inline]
251 fn write_all_vectored(this: &mut Cursor<Self>, bufs: &mut [IoSlice<'_>]) -> io::Result<()> {
252 let (pos, inner) = this.into_parts_mut();
253 slice_write_all_vectored(pos, inner, bufs)
254 }
255
256 #[inline]
257 fn flush(_this: &mut Cursor<Self>) -> io::Result<()> {
258 Ok(())
259 }
260}