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