]>
Commit | Line | Data |
---|---|---|
1b1a35ee XL |
1 | #[cfg(test)] |
2 | mod tests; | |
3 | ||
532ac7d7 XL |
4 | use crate::io::prelude::*; |
5 | ||
5e7ed085 | 6 | use crate::alloc::Allocator; |
532ac7d7 | 7 | use crate::cmp; |
f2b60f7d | 8 | use crate::io::{self, BorrowedCursor, ErrorKind, IoSlice, IoSliceMut, SeekFrom}; |
85aaf69f | 9 | |
8faf50e0 | 10 | /// A `Cursor` wraps an in-memory buffer and provides it with a |
c30ab7b3 | 11 | /// [`Seek`] implementation. |
85aaf69f | 12 | /// |
8faf50e0 | 13 | /// `Cursor`s are used with in-memory buffers, anything implementing |
c295e0f8 | 14 | /// <code>[AsRef]<\[u8]></code>, to allow them to implement [`Read`] and/or [`Write`], |
8faf50e0 XL |
15 | /// allowing these buffers to be used anywhere you might use a reader or writer |
16 | /// that does actual I/O. | |
85aaf69f | 17 | /// |
c1a9b12d | 18 | /// The standard library implements some I/O traits on various types which |
c295e0f8 XL |
19 | /// are commonly used as a buffer, like <code>Cursor<[Vec]\<u8>></code> and |
20 | /// <code>Cursor<[&\[u8\]][bytes]></code>. | |
c1a9b12d SL |
21 | /// |
22 | /// # Examples | |
23 | /// | |
c30ab7b3 | 24 | /// We may want to write bytes to a [`File`] in our production |
c1a9b12d SL |
25 | /// code, but use an in-memory buffer in our tests. We can do this with |
26 | /// `Cursor`: | |
27 | /// | |
c295e0f8 | 28 | /// [bytes]: crate::slice "slice" |
3dfed10e | 29 | /// [`File`]: crate::fs::File |
c1a9b12d SL |
30 | /// |
31 | /// ```no_run | |
32 | /// use std::io::prelude::*; | |
33 | /// use std::io::{self, SeekFrom}; | |
34 | /// use std::fs::File; | |
35 | /// | |
36 | /// // a library function we've written | |
37 | /// fn write_ten_bytes_at_end<W: Write + Seek>(writer: &mut W) -> io::Result<()> { | |
32a655c1 | 38 | /// writer.seek(SeekFrom::End(-10))?; |
c1a9b12d SL |
39 | /// |
40 | /// for i in 0..10 { | |
32a655c1 | 41 | /// writer.write(&[i])?; |
c1a9b12d SL |
42 | /// } |
43 | /// | |
44 | /// // all went well | |
45 | /// Ok(()) | |
46 | /// } | |
47 | /// | |
48 | /// # fn foo() -> io::Result<()> { | |
49 | /// // Here's some code that uses this library function. | |
50 | /// // | |
51 | /// // We might want to use a BufReader here for efficiency, but let's | |
52 | /// // keep this example focused. | |
32a655c1 | 53 | /// let mut file = File::create("foo.txt")?; |
c1a9b12d | 54 | /// |
32a655c1 | 55 | /// write_ten_bytes_at_end(&mut file)?; |
c1a9b12d SL |
56 | /// # Ok(()) |
57 | /// # } | |
58 | /// | |
59 | /// // now let's write a test | |
60 | /// #[test] | |
61 | /// fn test_writes_bytes() { | |
3b2f2976 | 62 | /// // setting up a real File is much slower than an in-memory buffer, |
c1a9b12d SL |
63 | /// // let's use a cursor instead |
64 | /// use std::io::Cursor; | |
65 | /// let mut buff = Cursor::new(vec![0; 15]); | |
66 | /// | |
b039eaaf | 67 | /// write_ten_bytes_at_end(&mut buff).unwrap(); |
c1a9b12d SL |
68 | /// |
69 | /// assert_eq!(&buff.get_ref()[5..15], &[0, 1, 2, 3, 4, 5, 6, 7, 8, 9]); | |
70 | /// } | |
71 | /// ``` | |
c34b1796 | 72 | #[stable(feature = "rust1", since = "1.0.0")] |
17df50a5 | 73 | #[derive(Debug, Default, Eq, PartialEq)] |
85aaf69f SL |
74 | pub struct Cursor<T> { |
75 | inner: T, | |
76 | pos: u64, | |
77 | } | |
78 | ||
79 | impl<T> Cursor<T> { | |
8faf50e0 | 80 | /// Creates a new cursor wrapping the provided underlying in-memory buffer. |
c1a9b12d | 81 | /// |
3dfed10e XL |
82 | /// Cursor initial position is `0` even if underlying buffer (e.g., [`Vec`]) |
83 | /// is not empty. So writing to cursor starts with overwriting [`Vec`] | |
8faf50e0 | 84 | /// content, not with appending to it. |
cc61c64b | 85 | /// |
c1a9b12d SL |
86 | /// # Examples |
87 | /// | |
88 | /// ``` | |
89 | /// use std::io::Cursor; | |
90 | /// | |
91 | /// let buff = Cursor::new(Vec::new()); | |
92 | /// # fn force_inference(_: &Cursor<Vec<u8>>) {} | |
93 | /// # force_inference(&buff); | |
94 | /// ``` | |
c34b1796 | 95 | #[stable(feature = "rust1", since = "1.0.0")] |
29967ef6 XL |
96 | #[rustc_const_unstable(feature = "const_io_structs", issue = "78812")] |
97 | pub const fn new(inner: T) -> Cursor<T> { | |
74b04a01 | 98 | Cursor { pos: 0, inner } |
85aaf69f SL |
99 | } |
100 | ||
9346a6ac | 101 | /// Consumes this cursor, returning the underlying value. |
c1a9b12d SL |
102 | /// |
103 | /// # Examples | |
104 | /// | |
105 | /// ``` | |
106 | /// use std::io::Cursor; | |
107 | /// | |
108 | /// let buff = Cursor::new(Vec::new()); | |
109 | /// # fn force_inference(_: &Cursor<Vec<u8>>) {} | |
110 | /// # force_inference(&buff); | |
111 | /// | |
112 | /// let vec = buff.into_inner(); | |
113 | /// ``` | |
c34b1796 | 114 | #[stable(feature = "rust1", since = "1.0.0")] |
dfeec247 XL |
115 | pub fn into_inner(self) -> T { |
116 | self.inner | |
117 | } | |
85aaf69f | 118 | |
9346a6ac | 119 | /// Gets a reference to the underlying value in this cursor. |
c1a9b12d SL |
120 | /// |
121 | /// # Examples | |
122 | /// | |
123 | /// ``` | |
124 | /// use std::io::Cursor; | |
125 | /// | |
126 | /// let buff = Cursor::new(Vec::new()); | |
127 | /// # fn force_inference(_: &Cursor<Vec<u8>>) {} | |
128 | /// # force_inference(&buff); | |
129 | /// | |
130 | /// let reference = buff.get_ref(); | |
131 | /// ``` | |
c34b1796 | 132 | #[stable(feature = "rust1", since = "1.0.0")] |
29967ef6 XL |
133 | #[rustc_const_unstable(feature = "const_io_structs", issue = "78812")] |
134 | pub const fn get_ref(&self) -> &T { | |
dfeec247 XL |
135 | &self.inner |
136 | } | |
85aaf69f | 137 | |
9346a6ac | 138 | /// Gets a mutable reference to the underlying value in this cursor. |
85aaf69f SL |
139 | /// |
140 | /// Care should be taken to avoid modifying the internal I/O state of the | |
141 | /// underlying value as it may corrupt this cursor's position. | |
c1a9b12d SL |
142 | /// |
143 | /// # Examples | |
144 | /// | |
145 | /// ``` | |
146 | /// use std::io::Cursor; | |
147 | /// | |
148 | /// let mut buff = Cursor::new(Vec::new()); | |
149 | /// # fn force_inference(_: &Cursor<Vec<u8>>) {} | |
150 | /// # force_inference(&buff); | |
151 | /// | |
152 | /// let reference = buff.get_mut(); | |
153 | /// ``` | |
c34b1796 | 154 | #[stable(feature = "rust1", since = "1.0.0")] |
dfeec247 XL |
155 | pub fn get_mut(&mut self) -> &mut T { |
156 | &mut self.inner | |
157 | } | |
85aaf69f | 158 | |
c1a9b12d SL |
159 | /// Returns the current position of this cursor. |
160 | /// | |
161 | /// # Examples | |
162 | /// | |
163 | /// ``` | |
164 | /// use std::io::Cursor; | |
165 | /// use std::io::prelude::*; | |
166 | /// use std::io::SeekFrom; | |
167 | /// | |
168 | /// let mut buff = Cursor::new(vec![1, 2, 3, 4, 5]); | |
169 | /// | |
170 | /// assert_eq!(buff.position(), 0); | |
171 | /// | |
172 | /// buff.seek(SeekFrom::Current(2)).unwrap(); | |
173 | /// assert_eq!(buff.position(), 2); | |
174 | /// | |
175 | /// buff.seek(SeekFrom::Current(-1)).unwrap(); | |
176 | /// assert_eq!(buff.position(), 1); | |
177 | /// ``` | |
c34b1796 | 178 | #[stable(feature = "rust1", since = "1.0.0")] |
29967ef6 XL |
179 | #[rustc_const_unstable(feature = "const_io_structs", issue = "78812")] |
180 | pub const fn position(&self) -> u64 { | |
dfeec247 XL |
181 | self.pos |
182 | } | |
85aaf69f | 183 | |
c1a9b12d SL |
184 | /// Sets the position of this cursor. |
185 | /// | |
186 | /// # Examples | |
187 | /// | |
188 | /// ``` | |
189 | /// use std::io::Cursor; | |
190 | /// | |
191 | /// let mut buff = Cursor::new(vec![1, 2, 3, 4, 5]); | |
192 | /// | |
193 | /// assert_eq!(buff.position(), 0); | |
194 | /// | |
195 | /// buff.set_position(2); | |
196 | /// assert_eq!(buff.position(), 2); | |
197 | /// | |
198 | /// buff.set_position(4); | |
199 | /// assert_eq!(buff.position(), 4); | |
200 | /// ``` | |
c34b1796 | 201 | #[stable(feature = "rust1", since = "1.0.0")] |
dfeec247 XL |
202 | pub fn set_position(&mut self, pos: u64) { |
203 | self.pos = pos; | |
204 | } | |
85aaf69f SL |
205 | } |
206 | ||
136023e0 XL |
207 | impl<T> Cursor<T> |
208 | where | |
209 | T: AsRef<[u8]>, | |
210 | { | |
211 | /// Returns the remaining slice. | |
212 | /// | |
213 | /// # Examples | |
214 | /// | |
215 | /// ``` | |
216 | /// #![feature(cursor_remaining)] | |
217 | /// use std::io::Cursor; | |
218 | /// | |
219 | /// let mut buff = Cursor::new(vec![1, 2, 3, 4, 5]); | |
220 | /// | |
221 | /// assert_eq!(buff.remaining_slice(), &[1, 2, 3, 4, 5]); | |
222 | /// | |
223 | /// buff.set_position(2); | |
224 | /// assert_eq!(buff.remaining_slice(), &[3, 4, 5]); | |
225 | /// | |
226 | /// buff.set_position(4); | |
227 | /// assert_eq!(buff.remaining_slice(), &[5]); | |
228 | /// | |
229 | /// buff.set_position(6); | |
230 | /// assert_eq!(buff.remaining_slice(), &[]); | |
231 | /// ``` | |
232 | #[unstable(feature = "cursor_remaining", issue = "86369")] | |
233 | pub fn remaining_slice(&self) -> &[u8] { | |
234 | let len = self.pos.min(self.inner.as_ref().len() as u64); | |
235 | &self.inner.as_ref()[(len as usize)..] | |
236 | } | |
237 | ||
238 | /// Returns `true` if the remaining slice is empty. | |
239 | /// | |
240 | /// # Examples | |
241 | /// | |
242 | /// ``` | |
243 | /// #![feature(cursor_remaining)] | |
244 | /// use std::io::Cursor; | |
245 | /// | |
246 | /// let mut buff = Cursor::new(vec![1, 2, 3, 4, 5]); | |
247 | /// | |
248 | /// buff.set_position(2); | |
249 | /// assert!(!buff.is_empty()); | |
250 | /// | |
251 | /// buff.set_position(5); | |
252 | /// assert!(buff.is_empty()); | |
253 | /// | |
254 | /// buff.set_position(10); | |
255 | /// assert!(buff.is_empty()); | |
256 | /// ``` | |
257 | #[unstable(feature = "cursor_remaining", issue = "86369")] | |
258 | pub fn is_empty(&self) -> bool { | |
259 | self.pos >= self.inner.as_ref().len() as u64 | |
260 | } | |
261 | } | |
262 | ||
17df50a5 XL |
263 | #[stable(feature = "rust1", since = "1.0.0")] |
264 | impl<T> Clone for Cursor<T> | |
265 | where | |
266 | T: Clone, | |
267 | { | |
268 | #[inline] | |
269 | fn clone(&self) -> Self { | |
270 | Cursor { inner: self.inner.clone(), pos: self.pos } | |
271 | } | |
272 | ||
273 | #[inline] | |
274 | fn clone_from(&mut self, other: &Self) { | |
275 | self.inner.clone_from(&other.inner); | |
276 | self.pos = other.pos; | |
277 | } | |
278 | } | |
279 | ||
b039eaaf | 280 | #[stable(feature = "rust1", since = "1.0.0")] |
dfeec247 XL |
281 | impl<T> io::Seek for Cursor<T> |
282 | where | |
283 | T: AsRef<[u8]>, | |
284 | { | |
b039eaaf | 285 | fn seek(&mut self, style: SeekFrom) -> io::Result<u64> { |
8bb4bdeb | 286 | let (base_pos, offset) = match style { |
dfeec247 XL |
287 | SeekFrom::Start(n) => { |
288 | self.pos = n; | |
289 | return Ok(n); | |
290 | } | |
8bb4bdeb XL |
291 | SeekFrom::End(n) => (self.inner.as_ref().len() as u64, n), |
292 | SeekFrom::Current(n) => (self.pos, n), | |
b039eaaf | 293 | }; |
c295e0f8 | 294 | match base_pos.checked_add_signed(offset) { |
dfeec247 XL |
295 | Some(n) => { |
296 | self.pos = n; | |
297 | Ok(self.pos) | |
298 | } | |
5099ac24 | 299 | None => Err(io::const_io_error!( |
dfeec247 | 300 | ErrorKind::InvalidInput, |
5099ac24 | 301 | "invalid seek to a negative or overflowing position", |
dfeec247 | 302 | )), |
85aaf69f SL |
303 | } |
304 | } | |
532ac7d7 XL |
305 | |
306 | fn stream_len(&mut self) -> io::Result<u64> { | |
307 | Ok(self.inner.as_ref().len() as u64) | |
308 | } | |
309 | ||
310 | fn stream_position(&mut self) -> io::Result<u64> { | |
311 | Ok(self.pos) | |
312 | } | |
85aaf69f SL |
313 | } |
314 | ||
c34b1796 | 315 | #[stable(feature = "rust1", since = "1.0.0")] |
dfeec247 XL |
316 | impl<T> Read for Cursor<T> |
317 | where | |
318 | T: AsRef<[u8]>, | |
319 | { | |
b039eaaf | 320 | fn read(&mut self, buf: &mut [u8]) -> io::Result<usize> { |
136023e0 | 321 | let n = Read::read(&mut self.remaining_slice(), buf)?; |
b039eaaf SL |
322 | self.pos += n as u64; |
323 | Ok(n) | |
85aaf69f | 324 | } |
041b39d2 | 325 | |
f2b60f7d FG |
326 | fn read_buf(&mut self, mut cursor: BorrowedCursor<'_>) -> io::Result<()> { |
327 | let prev_written = cursor.written(); | |
a2a8927a | 328 | |
f2b60f7d | 329 | Read::read_buf(&mut self.fill_buf()?, cursor.reborrow())?; |
a2a8927a | 330 | |
f2b60f7d | 331 | self.pos += (cursor.written() - prev_written) as u64; |
a2a8927a XL |
332 | |
333 | Ok(()) | |
334 | } | |
335 | ||
48663c56 | 336 | fn read_vectored(&mut self, bufs: &mut [IoSliceMut<'_>]) -> io::Result<usize> { |
9fa01778 XL |
337 | let mut nread = 0; |
338 | for buf in bufs { | |
339 | let n = self.read(buf)?; | |
340 | nread += n; | |
341 | if n < buf.len() { | |
342 | break; | |
343 | } | |
344 | } | |
345 | Ok(nread) | |
346 | } | |
347 | ||
f9f354fc XL |
348 | fn is_read_vectored(&self) -> bool { |
349 | true | |
350 | } | |
351 | ||
ff7c6d11 XL |
352 | fn read_exact(&mut self, buf: &mut [u8]) -> io::Result<()> { |
353 | let n = buf.len(); | |
136023e0 | 354 | Read::read_exact(&mut self.remaining_slice(), buf)?; |
ff7c6d11 XL |
355 | self.pos += n as u64; |
356 | Ok(()) | |
357 | } | |
85aaf69f SL |
358 | } |
359 | ||
c34b1796 | 360 | #[stable(feature = "rust1", since = "1.0.0")] |
dfeec247 XL |
361 | impl<T> BufRead for Cursor<T> |
362 | where | |
363 | T: AsRef<[u8]>, | |
364 | { | |
b039eaaf | 365 | fn fill_buf(&mut self) -> io::Result<&[u8]> { |
136023e0 | 366 | Ok(self.remaining_slice()) |
85aaf69f | 367 | } |
dfeec247 XL |
368 | fn consume(&mut self, amt: usize) { |
369 | self.pos += amt as u64; | |
370 | } | |
85aaf69f SL |
371 | } |
372 | ||
2c00a5a8 | 373 | // Non-resizing write implementation |
48663c56 | 374 | #[inline] |
2c00a5a8 XL |
375 | fn slice_write(pos_mut: &mut u64, slice: &mut [u8], buf: &[u8]) -> io::Result<usize> { |
376 | let pos = cmp::min(*pos_mut, slice.len() as u64); | |
377 | let amt = (&mut slice[(pos as usize)..]).write(buf)?; | |
378 | *pos_mut += amt as u64; | |
379 | Ok(amt) | |
380 | } | |
381 | ||
48663c56 | 382 | #[inline] |
9fa01778 XL |
383 | fn slice_write_vectored( |
384 | pos_mut: &mut u64, | |
385 | slice: &mut [u8], | |
48663c56 | 386 | bufs: &[IoSlice<'_>], |
dfeec247 | 387 | ) -> io::Result<usize> { |
9fa01778 XL |
388 | let mut nwritten = 0; |
389 | for buf in bufs { | |
390 | let n = slice_write(pos_mut, slice, buf)?; | |
391 | nwritten += n; | |
392 | if n < buf.len() { | |
393 | break; | |
394 | } | |
395 | } | |
396 | Ok(nwritten) | |
397 | } | |
398 | ||
064997fb FG |
399 | /// Reserves the required space, and pads the vec with 0s if necessary. |
400 | fn reserve_and_pad<A: Allocator>( | |
401 | pos_mut: &mut u64, | |
402 | vec: &mut Vec<u8, A>, | |
403 | buf_len: usize, | |
404 | ) -> io::Result<usize> { | |
8faf50e0 | 405 | let pos: usize = (*pos_mut).try_into().map_err(|_| { |
5099ac24 | 406 | io::const_io_error!( |
dfeec247 | 407 | ErrorKind::InvalidInput, |
5099ac24 | 408 | "cursor position exceeds maximum possible vector length", |
dfeec247 | 409 | ) |
2c00a5a8 | 410 | })?; |
064997fb FG |
411 | |
412 | // For safety reasons, we don't want these numbers to overflow | |
413 | // otherwise our allocation won't be enough | |
414 | let desired_cap = pos.saturating_add(buf_len); | |
415 | if desired_cap > vec.capacity() { | |
416 | // We want our vec's total capacity | |
417 | // to have room for (pos+buf_len) bytes. Reserve allocates | |
418 | // based on additional elements from the length, so we need to | |
419 | // reserve the difference | |
420 | vec.reserve(desired_cap - vec.len()); | |
2c00a5a8 | 421 | } |
064997fb FG |
422 | // Pad if pos is above the current len. |
423 | if pos > vec.len() { | |
424 | let diff = pos - vec.len(); | |
425 | // Unfortunately, `resize()` would suffice but the optimiser does not | |
426 | // realise the `reserve` it does can be eliminated. So we do it manually | |
427 | // to eliminate that extra branch | |
428 | let spare = vec.spare_capacity_mut(); | |
429 | debug_assert!(spare.len() >= diff); | |
430 | // Safety: we have allocated enough capacity for this. | |
431 | // And we are only writing, not reading | |
432 | unsafe { | |
433 | spare.get_unchecked_mut(..diff).fill(core::mem::MaybeUninit::new(0)); | |
434 | vec.set_len(pos); | |
435 | } | |
2c00a5a8 XL |
436 | } |
437 | ||
064997fb FG |
438 | Ok(pos) |
439 | } | |
440 | ||
441 | /// Writes the slice to the vec without allocating | |
442 | /// # Safety: vec must have buf.len() spare capacity | |
443 | unsafe fn vec_write_unchecked<A>(pos: usize, vec: &mut Vec<u8, A>, buf: &[u8]) -> usize | |
444 | where | |
445 | A: Allocator, | |
446 | { | |
447 | debug_assert!(vec.capacity() >= pos + buf.len()); | |
448 | vec.as_mut_ptr().add(pos).copy_from(buf.as_ptr(), buf.len()); | |
449 | pos + buf.len() | |
450 | } | |
451 | ||
452 | /// Resizing write implementation for [`Cursor`] | |
453 | /// | |
454 | /// Cursor is allowed to have a pre-allocated and initialised | |
455 | /// vector body, but with a position of 0. This means the [`Write`] | |
456 | /// will overwrite the contents of the vec. | |
457 | /// | |
458 | /// This also allows for the vec body to be empty, but with a position of N. | |
459 | /// This means that [`Write`] will pad the vec with 0 initially, | |
460 | /// before writing anything from that point | |
461 | fn vec_write<A>(pos_mut: &mut u64, vec: &mut Vec<u8, A>, buf: &[u8]) -> io::Result<usize> | |
462 | where | |
463 | A: Allocator, | |
464 | { | |
465 | let buf_len = buf.len(); | |
466 | let mut pos = reserve_and_pad(pos_mut, vec, buf_len)?; | |
467 | ||
468 | // Write the buf then progress the vec forward if necessary | |
469 | // Safety: we have ensured that the capacity is available | |
470 | // and that all bytes get written up to pos | |
471 | unsafe { | |
472 | pos = vec_write_unchecked(pos, vec, buf); | |
473 | if pos > vec.len() { | |
474 | vec.set_len(pos); | |
475 | } | |
476 | }; | |
477 | ||
2c00a5a8 | 478 | // Bump us forward |
064997fb FG |
479 | *pos_mut += buf_len as u64; |
480 | Ok(buf_len) | |
2c00a5a8 XL |
481 | } |
482 | ||
064997fb FG |
483 | /// Resizing write_vectored implementation for [`Cursor`] |
484 | /// | |
485 | /// Cursor is allowed to have a pre-allocated and initialised | |
486 | /// vector body, but with a position of 0. This means the [`Write`] | |
487 | /// will overwrite the contents of the vec. | |
488 | /// | |
489 | /// This also allows for the vec body to be empty, but with a position of N. | |
490 | /// This means that [`Write`] will pad the vec with 0 initially, | |
491 | /// before writing anything from that point | |
5e7ed085 | 492 | fn vec_write_vectored<A>( |
9fa01778 | 493 | pos_mut: &mut u64, |
5e7ed085 | 494 | vec: &mut Vec<u8, A>, |
48663c56 | 495 | bufs: &[IoSlice<'_>], |
5e7ed085 FG |
496 | ) -> io::Result<usize> |
497 | where | |
498 | A: Allocator, | |
499 | { | |
064997fb FG |
500 | // For safety reasons, we don't want this sum to overflow ever. |
501 | // If this saturates, the reserve should panic to avoid any unsound writing. | |
502 | let buf_len = bufs.iter().fold(0usize, |a, b| a.saturating_add(b.len())); | |
503 | let mut pos = reserve_and_pad(pos_mut, vec, buf_len)?; | |
504 | ||
505 | // Write the buf then progress the vec forward if necessary | |
506 | // Safety: we have ensured that the capacity is available | |
507 | // and that all bytes get written up to the last pos | |
508 | unsafe { | |
509 | for buf in bufs { | |
510 | pos = vec_write_unchecked(pos, vec, buf); | |
511 | } | |
512 | if pos > vec.len() { | |
513 | vec.set_len(pos); | |
514 | } | |
9fa01778 | 515 | } |
064997fb FG |
516 | |
517 | // Bump us forward | |
518 | *pos_mut += buf_len as u64; | |
519 | Ok(buf_len) | |
9fa01778 XL |
520 | } |
521 | ||
c34b1796 | 522 | #[stable(feature = "rust1", since = "1.0.0")] |
9fa01778 | 523 | impl Write for Cursor<&mut [u8]> { |
3157f602 | 524 | #[inline] |
2c00a5a8 XL |
525 | fn write(&mut self, buf: &[u8]) -> io::Result<usize> { |
526 | slice_write(&mut self.pos, self.inner, buf) | |
527 | } | |
9fa01778 XL |
528 | |
529 | #[inline] | |
48663c56 | 530 | fn write_vectored(&mut self, bufs: &[IoSlice<'_>]) -> io::Result<usize> { |
9fa01778 XL |
531 | slice_write_vectored(&mut self.pos, self.inner, bufs) |
532 | } | |
533 | ||
f9f354fc XL |
534 | #[inline] |
535 | fn is_write_vectored(&self) -> bool { | |
536 | true | |
537 | } | |
538 | ||
48663c56 | 539 | #[inline] |
dfeec247 XL |
540 | fn flush(&mut self) -> io::Result<()> { |
541 | Ok(()) | |
542 | } | |
2c00a5a8 XL |
543 | } |
544 | ||
0531ce1d | 545 | #[stable(feature = "cursor_mut_vec", since = "1.25.0")] |
5e7ed085 FG |
546 | impl<A> Write for Cursor<&mut Vec<u8, A>> |
547 | where | |
548 | A: Allocator, | |
549 | { | |
2c00a5a8 XL |
550 | fn write(&mut self, buf: &[u8]) -> io::Result<usize> { |
551 | vec_write(&mut self.pos, self.inner, buf) | |
85aaf69f | 552 | } |
9fa01778 | 553 | |
48663c56 | 554 | fn write_vectored(&mut self, bufs: &[IoSlice<'_>]) -> io::Result<usize> { |
9fa01778 XL |
555 | vec_write_vectored(&mut self.pos, self.inner, bufs) |
556 | } | |
557 | ||
f9f354fc XL |
558 | #[inline] |
559 | fn is_write_vectored(&self) -> bool { | |
560 | true | |
561 | } | |
562 | ||
48663c56 | 563 | #[inline] |
dfeec247 XL |
564 | fn flush(&mut self) -> io::Result<()> { |
565 | Ok(()) | |
566 | } | |
85aaf69f SL |
567 | } |
568 | ||
c34b1796 | 569 | #[stable(feature = "rust1", since = "1.0.0")] |
5e7ed085 FG |
570 | impl<A> Write for Cursor<Vec<u8, A>> |
571 | where | |
572 | A: Allocator, | |
573 | { | |
85aaf69f | 574 | fn write(&mut self, buf: &[u8]) -> io::Result<usize> { |
2c00a5a8 | 575 | vec_write(&mut self.pos, &mut self.inner, buf) |
85aaf69f | 576 | } |
9fa01778 | 577 | |
48663c56 | 578 | fn write_vectored(&mut self, bufs: &[IoSlice<'_>]) -> io::Result<usize> { |
9fa01778 XL |
579 | vec_write_vectored(&mut self.pos, &mut self.inner, bufs) |
580 | } | |
581 | ||
f9f354fc XL |
582 | #[inline] |
583 | fn is_write_vectored(&self) -> bool { | |
584 | true | |
585 | } | |
586 | ||
48663c56 | 587 | #[inline] |
dfeec247 XL |
588 | fn flush(&mut self) -> io::Result<()> { |
589 | Ok(()) | |
590 | } | |
85aaf69f SL |
591 | } |
592 | ||
b039eaaf | 593 | #[stable(feature = "cursor_box_slice", since = "1.5.0")] |
5e7ed085 FG |
594 | impl<A> Write for Cursor<Box<[u8], A>> |
595 | where | |
596 | A: Allocator, | |
597 | { | |
598 | #[inline] | |
599 | fn write(&mut self, buf: &[u8]) -> io::Result<usize> { | |
600 | slice_write(&mut self.pos, &mut self.inner, buf) | |
601 | } | |
602 | ||
603 | #[inline] | |
604 | fn write_vectored(&mut self, bufs: &[IoSlice<'_>]) -> io::Result<usize> { | |
605 | slice_write_vectored(&mut self.pos, &mut self.inner, bufs) | |
606 | } | |
607 | ||
608 | #[inline] | |
609 | fn is_write_vectored(&self) -> bool { | |
610 | true | |
611 | } | |
612 | ||
613 | #[inline] | |
614 | fn flush(&mut self) -> io::Result<()> { | |
615 | Ok(()) | |
616 | } | |
617 | } | |
618 | ||
619 | #[stable(feature = "cursor_array", since = "1.61.0")] | |
620 | impl<const N: usize> Write for Cursor<[u8; N]> { | |
3157f602 | 621 | #[inline] |
b039eaaf | 622 | fn write(&mut self, buf: &[u8]) -> io::Result<usize> { |
2c00a5a8 | 623 | slice_write(&mut self.pos, &mut self.inner, buf) |
b039eaaf | 624 | } |
9fa01778 XL |
625 | |
626 | #[inline] | |
48663c56 | 627 | fn write_vectored(&mut self, bufs: &[IoSlice<'_>]) -> io::Result<usize> { |
9fa01778 XL |
628 | slice_write_vectored(&mut self.pos, &mut self.inner, bufs) |
629 | } | |
630 | ||
f9f354fc XL |
631 | #[inline] |
632 | fn is_write_vectored(&self) -> bool { | |
633 | true | |
634 | } | |
635 | ||
48663c56 | 636 | #[inline] |
dfeec247 XL |
637 | fn flush(&mut self) -> io::Result<()> { |
638 | Ok(()) | |
639 | } | |
b039eaaf | 640 | } |