]>
Commit | Line | Data |
---|---|---|
1 | use crate::io::prelude::*; | |
2 | ||
3 | use crate::cmp; | |
4 | use crate::io::{self, Error, ErrorKind, Initializer, IoSlice, IoSliceMut, SeekFrom}; | |
5 | ||
6 | use core::convert::TryInto; | |
7 | ||
8 | /// A `Cursor` wraps an in-memory buffer and provides it with a | |
9 | /// [`Seek`] implementation. | |
10 | /// | |
11 | /// `Cursor`s are used with in-memory buffers, anything implementing | |
12 | /// `AsRef<[u8]>`, to allow them to implement [`Read`] and/or [`Write`], | |
13 | /// allowing these buffers to be used anywhere you might use a reader or writer | |
14 | /// that does actual I/O. | |
15 | /// | |
16 | /// The standard library implements some I/O traits on various types which | |
17 | /// are commonly used as a buffer, like `Cursor<`[`Vec`]`<u8>>` and | |
18 | /// `Cursor<`[`&[u8]`][bytes]`>`. | |
19 | /// | |
20 | /// # Examples | |
21 | /// | |
22 | /// We may want to write bytes to a [`File`] in our production | |
23 | /// code, but use an in-memory buffer in our tests. We can do this with | |
24 | /// `Cursor`: | |
25 | /// | |
26 | /// [`Seek`]: trait.Seek.html | |
27 | /// [`Read`]: ../../std/io/trait.Read.html | |
28 | /// [`Write`]: ../../std/io/trait.Write.html | |
29 | /// [`Vec`]: ../../std/vec/struct.Vec.html | |
30 | /// [bytes]: ../../std/primitive.slice.html | |
31 | /// [`File`]: ../fs/struct.File.html | |
32 | /// | |
33 | /// ```no_run | |
34 | /// use std::io::prelude::*; | |
35 | /// use std::io::{self, SeekFrom}; | |
36 | /// use std::fs::File; | |
37 | /// | |
38 | /// // a library function we've written | |
39 | /// fn write_ten_bytes_at_end<W: Write + Seek>(writer: &mut W) -> io::Result<()> { | |
40 | /// writer.seek(SeekFrom::End(-10))?; | |
41 | /// | |
42 | /// for i in 0..10 { | |
43 | /// writer.write(&[i])?; | |
44 | /// } | |
45 | /// | |
46 | /// // all went well | |
47 | /// Ok(()) | |
48 | /// } | |
49 | /// | |
50 | /// # fn foo() -> io::Result<()> { | |
51 | /// // Here's some code that uses this library function. | |
52 | /// // | |
53 | /// // We might want to use a BufReader here for efficiency, but let's | |
54 | /// // keep this example focused. | |
55 | /// let mut file = File::create("foo.txt")?; | |
56 | /// | |
57 | /// write_ten_bytes_at_end(&mut file)?; | |
58 | /// # Ok(()) | |
59 | /// # } | |
60 | /// | |
61 | /// // now let's write a test | |
62 | /// #[test] | |
63 | /// fn test_writes_bytes() { | |
64 | /// // setting up a real File is much slower than an in-memory buffer, | |
65 | /// // let's use a cursor instead | |
66 | /// use std::io::Cursor; | |
67 | /// let mut buff = Cursor::new(vec![0; 15]); | |
68 | /// | |
69 | /// write_ten_bytes_at_end(&mut buff).unwrap(); | |
70 | /// | |
71 | /// assert_eq!(&buff.get_ref()[5..15], &[0, 1, 2, 3, 4, 5, 6, 7, 8, 9]); | |
72 | /// } | |
73 | /// ``` | |
74 | #[stable(feature = "rust1", since = "1.0.0")] | |
75 | #[derive(Clone, Debug, Default, Eq, PartialEq)] | |
76 | pub struct Cursor<T> { | |
77 | inner: T, | |
78 | pos: u64, | |
79 | } | |
80 | ||
81 | impl<T> Cursor<T> { | |
82 | /// Creates a new cursor wrapping the provided underlying in-memory buffer. | |
83 | /// | |
84 | /// Cursor initial position is `0` even if underlying buffer (e.g., `Vec`) | |
85 | /// is not empty. So writing to cursor starts with overwriting `Vec` | |
86 | /// content, not with appending to it. | |
87 | /// | |
88 | /// # Examples | |
89 | /// | |
90 | /// ``` | |
91 | /// use std::io::Cursor; | |
92 | /// | |
93 | /// let buff = Cursor::new(Vec::new()); | |
94 | /// # fn force_inference(_: &Cursor<Vec<u8>>) {} | |
95 | /// # force_inference(&buff); | |
96 | /// ``` | |
97 | #[stable(feature = "rust1", since = "1.0.0")] | |
98 | pub 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 | pub fn get_ref(&self) -> &T { | |
135 | &self.inner | |
136 | } | |
137 | ||
138 | /// Gets a mutable reference to the underlying value in this cursor. | |
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. | |
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 | /// ``` | |
154 | #[stable(feature = "rust1", since = "1.0.0")] | |
155 | pub fn get_mut(&mut self) -> &mut T { | |
156 | &mut self.inner | |
157 | } | |
158 | ||
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 | /// ``` | |
178 | #[stable(feature = "rust1", since = "1.0.0")] | |
179 | pub fn position(&self) -> u64 { | |
180 | self.pos | |
181 | } | |
182 | ||
183 | /// Sets the position of this cursor. | |
184 | /// | |
185 | /// # Examples | |
186 | /// | |
187 | /// ``` | |
188 | /// use std::io::Cursor; | |
189 | /// | |
190 | /// let mut buff = Cursor::new(vec![1, 2, 3, 4, 5]); | |
191 | /// | |
192 | /// assert_eq!(buff.position(), 0); | |
193 | /// | |
194 | /// buff.set_position(2); | |
195 | /// assert_eq!(buff.position(), 2); | |
196 | /// | |
197 | /// buff.set_position(4); | |
198 | /// assert_eq!(buff.position(), 4); | |
199 | /// ``` | |
200 | #[stable(feature = "rust1", since = "1.0.0")] | |
201 | pub fn set_position(&mut self, pos: u64) { | |
202 | self.pos = pos; | |
203 | } | |
204 | } | |
205 | ||
206 | #[stable(feature = "rust1", since = "1.0.0")] | |
207 | impl<T> io::Seek for Cursor<T> | |
208 | where | |
209 | T: AsRef<[u8]>, | |
210 | { | |
211 | fn seek(&mut self, style: SeekFrom) -> io::Result<u64> { | |
212 | let (base_pos, offset) = match style { | |
213 | SeekFrom::Start(n) => { | |
214 | self.pos = n; | |
215 | return Ok(n); | |
216 | } | |
217 | SeekFrom::End(n) => (self.inner.as_ref().len() as u64, n), | |
218 | SeekFrom::Current(n) => (self.pos, n), | |
219 | }; | |
220 | let new_pos = if offset >= 0 { | |
221 | base_pos.checked_add(offset as u64) | |
222 | } else { | |
223 | base_pos.checked_sub((offset.wrapping_neg()) as u64) | |
224 | }; | |
225 | match new_pos { | |
226 | Some(n) => { | |
227 | self.pos = n; | |
228 | Ok(self.pos) | |
229 | } | |
230 | None => Err(Error::new( | |
231 | ErrorKind::InvalidInput, | |
232 | "invalid seek to a negative or overflowing position", | |
233 | )), | |
234 | } | |
235 | } | |
236 | ||
237 | fn stream_len(&mut self) -> io::Result<u64> { | |
238 | Ok(self.inner.as_ref().len() as u64) | |
239 | } | |
240 | ||
241 | fn stream_position(&mut self) -> io::Result<u64> { | |
242 | Ok(self.pos) | |
243 | } | |
244 | } | |
245 | ||
246 | #[stable(feature = "rust1", since = "1.0.0")] | |
247 | impl<T> Read for Cursor<T> | |
248 | where | |
249 | T: AsRef<[u8]>, | |
250 | { | |
251 | fn read(&mut self, buf: &mut [u8]) -> io::Result<usize> { | |
252 | let n = Read::read(&mut self.fill_buf()?, buf)?; | |
253 | self.pos += n as u64; | |
254 | Ok(n) | |
255 | } | |
256 | ||
257 | fn read_vectored(&mut self, bufs: &mut [IoSliceMut<'_>]) -> io::Result<usize> { | |
258 | let mut nread = 0; | |
259 | for buf in bufs { | |
260 | let n = self.read(buf)?; | |
261 | nread += n; | |
262 | if n < buf.len() { | |
263 | break; | |
264 | } | |
265 | } | |
266 | Ok(nread) | |
267 | } | |
268 | ||
269 | fn is_read_vectored(&self) -> bool { | |
270 | true | |
271 | } | |
272 | ||
273 | fn read_exact(&mut self, buf: &mut [u8]) -> io::Result<()> { | |
274 | let n = buf.len(); | |
275 | Read::read_exact(&mut self.fill_buf()?, buf)?; | |
276 | self.pos += n as u64; | |
277 | Ok(()) | |
278 | } | |
279 | ||
280 | #[inline] | |
281 | unsafe fn initializer(&self) -> Initializer { | |
282 | Initializer::nop() | |
283 | } | |
284 | } | |
285 | ||
286 | #[stable(feature = "rust1", since = "1.0.0")] | |
287 | impl<T> BufRead for Cursor<T> | |
288 | where | |
289 | T: AsRef<[u8]>, | |
290 | { | |
291 | fn fill_buf(&mut self) -> io::Result<&[u8]> { | |
292 | let amt = cmp::min(self.pos, self.inner.as_ref().len() as u64); | |
293 | Ok(&self.inner.as_ref()[(amt as usize)..]) | |
294 | } | |
295 | fn consume(&mut self, amt: usize) { | |
296 | self.pos += amt as u64; | |
297 | } | |
298 | } | |
299 | ||
300 | // Non-resizing write implementation | |
301 | #[inline] | |
302 | fn slice_write(pos_mut: &mut u64, slice: &mut [u8], buf: &[u8]) -> io::Result<usize> { | |
303 | let pos = cmp::min(*pos_mut, slice.len() as u64); | |
304 | let amt = (&mut slice[(pos as usize)..]).write(buf)?; | |
305 | *pos_mut += amt as u64; | |
306 | Ok(amt) | |
307 | } | |
308 | ||
309 | #[inline] | |
310 | fn slice_write_vectored( | |
311 | pos_mut: &mut u64, | |
312 | slice: &mut [u8], | |
313 | bufs: &[IoSlice<'_>], | |
314 | ) -> io::Result<usize> { | |
315 | let mut nwritten = 0; | |
316 | for buf in bufs { | |
317 | let n = slice_write(pos_mut, slice, buf)?; | |
318 | nwritten += n; | |
319 | if n < buf.len() { | |
320 | break; | |
321 | } | |
322 | } | |
323 | Ok(nwritten) | |
324 | } | |
325 | ||
326 | // Resizing write implementation | |
327 | fn vec_write(pos_mut: &mut u64, vec: &mut Vec<u8>, buf: &[u8]) -> io::Result<usize> { | |
328 | let pos: usize = (*pos_mut).try_into().map_err(|_| { | |
329 | Error::new( | |
330 | ErrorKind::InvalidInput, | |
331 | "cursor position exceeds maximum possible vector length", | |
332 | ) | |
333 | })?; | |
334 | // Make sure the internal buffer is as least as big as where we | |
335 | // currently are | |
336 | let len = vec.len(); | |
337 | if len < pos { | |
338 | // use `resize` so that the zero filling is as efficient as possible | |
339 | vec.resize(pos, 0); | |
340 | } | |
341 | // Figure out what bytes will be used to overwrite what's currently | |
342 | // there (left), and what will be appended on the end (right) | |
343 | { | |
344 | let space = vec.len() - pos; | |
345 | let (left, right) = buf.split_at(cmp::min(space, buf.len())); | |
346 | vec[pos..pos + left.len()].copy_from_slice(left); | |
347 | vec.extend_from_slice(right); | |
348 | } | |
349 | ||
350 | // Bump us forward | |
351 | *pos_mut = (pos + buf.len()) as u64; | |
352 | Ok(buf.len()) | |
353 | } | |
354 | ||
355 | fn vec_write_vectored( | |
356 | pos_mut: &mut u64, | |
357 | vec: &mut Vec<u8>, | |
358 | bufs: &[IoSlice<'_>], | |
359 | ) -> io::Result<usize> { | |
360 | let mut nwritten = 0; | |
361 | for buf in bufs { | |
362 | nwritten += vec_write(pos_mut, vec, buf)?; | |
363 | } | |
364 | Ok(nwritten) | |
365 | } | |
366 | ||
367 | #[stable(feature = "rust1", since = "1.0.0")] | |
368 | impl Write for Cursor<&mut [u8]> { | |
369 | #[inline] | |
370 | fn write(&mut self, buf: &[u8]) -> io::Result<usize> { | |
371 | slice_write(&mut self.pos, self.inner, buf) | |
372 | } | |
373 | ||
374 | #[inline] | |
375 | fn write_vectored(&mut self, bufs: &[IoSlice<'_>]) -> io::Result<usize> { | |
376 | slice_write_vectored(&mut self.pos, self.inner, bufs) | |
377 | } | |
378 | ||
379 | #[inline] | |
380 | fn is_write_vectored(&self) -> bool { | |
381 | true | |
382 | } | |
383 | ||
384 | #[inline] | |
385 | fn flush(&mut self) -> io::Result<()> { | |
386 | Ok(()) | |
387 | } | |
388 | } | |
389 | ||
390 | #[stable(feature = "cursor_mut_vec", since = "1.25.0")] | |
391 | impl Write for Cursor<&mut Vec<u8>> { | |
392 | fn write(&mut self, buf: &[u8]) -> io::Result<usize> { | |
393 | vec_write(&mut self.pos, self.inner, buf) | |
394 | } | |
395 | ||
396 | fn write_vectored(&mut self, bufs: &[IoSlice<'_>]) -> io::Result<usize> { | |
397 | vec_write_vectored(&mut self.pos, self.inner, bufs) | |
398 | } | |
399 | ||
400 | #[inline] | |
401 | fn is_write_vectored(&self) -> bool { | |
402 | true | |
403 | } | |
404 | ||
405 | #[inline] | |
406 | fn flush(&mut self) -> io::Result<()> { | |
407 | Ok(()) | |
408 | } | |
409 | } | |
410 | ||
411 | #[stable(feature = "rust1", since = "1.0.0")] | |
412 | impl Write for Cursor<Vec<u8>> { | |
413 | fn write(&mut self, buf: &[u8]) -> io::Result<usize> { | |
414 | vec_write(&mut self.pos, &mut self.inner, buf) | |
415 | } | |
416 | ||
417 | fn write_vectored(&mut self, bufs: &[IoSlice<'_>]) -> io::Result<usize> { | |
418 | vec_write_vectored(&mut self.pos, &mut self.inner, bufs) | |
419 | } | |
420 | ||
421 | #[inline] | |
422 | fn is_write_vectored(&self) -> bool { | |
423 | true | |
424 | } | |
425 | ||
426 | #[inline] | |
427 | fn flush(&mut self) -> io::Result<()> { | |
428 | Ok(()) | |
429 | } | |
430 | } | |
431 | ||
432 | #[stable(feature = "cursor_box_slice", since = "1.5.0")] | |
433 | impl Write for Cursor<Box<[u8]>> { | |
434 | #[inline] | |
435 | fn write(&mut self, buf: &[u8]) -> io::Result<usize> { | |
436 | slice_write(&mut self.pos, &mut self.inner, buf) | |
437 | } | |
438 | ||
439 | #[inline] | |
440 | fn write_vectored(&mut self, bufs: &[IoSlice<'_>]) -> io::Result<usize> { | |
441 | slice_write_vectored(&mut self.pos, &mut self.inner, bufs) | |
442 | } | |
443 | ||
444 | #[inline] | |
445 | fn is_write_vectored(&self) -> bool { | |
446 | true | |
447 | } | |
448 | ||
449 | #[inline] | |
450 | fn flush(&mut self) -> io::Result<()> { | |
451 | Ok(()) | |
452 | } | |
453 | } | |
454 | ||
455 | #[cfg(test)] | |
456 | mod tests { | |
457 | use crate::io::prelude::*; | |
458 | use crate::io::{Cursor, IoSlice, IoSliceMut, SeekFrom}; | |
459 | ||
460 | #[test] | |
461 | fn test_vec_writer() { | |
462 | let mut writer = Vec::new(); | |
463 | assert_eq!(writer.write(&[0]).unwrap(), 1); | |
464 | assert_eq!(writer.write(&[1, 2, 3]).unwrap(), 3); | |
465 | assert_eq!(writer.write(&[4, 5, 6, 7]).unwrap(), 4); | |
466 | assert_eq!( | |
467 | writer | |
468 | .write_vectored(&[IoSlice::new(&[]), IoSlice::new(&[8, 9]), IoSlice::new(&[10])],) | |
469 | .unwrap(), | |
470 | 3 | |
471 | ); | |
472 | let b: &[_] = &[0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10]; | |
473 | assert_eq!(writer, b); | |
474 | } | |
475 | ||
476 | #[test] | |
477 | fn test_mem_writer() { | |
478 | let mut writer = Cursor::new(Vec::new()); | |
479 | assert_eq!(writer.write(&[0]).unwrap(), 1); | |
480 | assert_eq!(writer.write(&[1, 2, 3]).unwrap(), 3); | |
481 | assert_eq!(writer.write(&[4, 5, 6, 7]).unwrap(), 4); | |
482 | assert_eq!( | |
483 | writer | |
484 | .write_vectored(&[IoSlice::new(&[]), IoSlice::new(&[8, 9]), IoSlice::new(&[10])],) | |
485 | .unwrap(), | |
486 | 3 | |
487 | ); | |
488 | let b: &[_] = &[0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10]; | |
489 | assert_eq!(&writer.get_ref()[..], b); | |
490 | } | |
491 | ||
492 | #[test] | |
493 | fn test_mem_mut_writer() { | |
494 | let mut vec = Vec::new(); | |
495 | let mut writer = Cursor::new(&mut vec); | |
496 | assert_eq!(writer.write(&[0]).unwrap(), 1); | |
497 | assert_eq!(writer.write(&[1, 2, 3]).unwrap(), 3); | |
498 | assert_eq!(writer.write(&[4, 5, 6, 7]).unwrap(), 4); | |
499 | assert_eq!( | |
500 | writer | |
501 | .write_vectored(&[IoSlice::new(&[]), IoSlice::new(&[8, 9]), IoSlice::new(&[10])],) | |
502 | .unwrap(), | |
503 | 3 | |
504 | ); | |
505 | let b: &[_] = &[0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10]; | |
506 | assert_eq!(&writer.get_ref()[..], b); | |
507 | } | |
508 | ||
509 | #[test] | |
510 | fn test_box_slice_writer() { | |
511 | let mut writer = Cursor::new(vec![0u8; 9].into_boxed_slice()); | |
512 | assert_eq!(writer.position(), 0); | |
513 | assert_eq!(writer.write(&[0]).unwrap(), 1); | |
514 | assert_eq!(writer.position(), 1); | |
515 | assert_eq!(writer.write(&[1, 2, 3]).unwrap(), 3); | |
516 | assert_eq!(writer.write(&[4, 5, 6, 7]).unwrap(), 4); | |
517 | assert_eq!(writer.position(), 8); | |
518 | assert_eq!(writer.write(&[]).unwrap(), 0); | |
519 | assert_eq!(writer.position(), 8); | |
520 | ||
521 | assert_eq!(writer.write(&[8, 9]).unwrap(), 1); | |
522 | assert_eq!(writer.write(&[10]).unwrap(), 0); | |
523 | let b: &[_] = &[0, 1, 2, 3, 4, 5, 6, 7, 8]; | |
524 | assert_eq!(&**writer.get_ref(), b); | |
525 | } | |
526 | ||
527 | #[test] | |
528 | fn test_box_slice_writer_vectored() { | |
529 | let mut writer = Cursor::new(vec![0u8; 9].into_boxed_slice()); | |
530 | assert_eq!(writer.position(), 0); | |
531 | assert_eq!(writer.write_vectored(&[IoSlice::new(&[0])]).unwrap(), 1); | |
532 | assert_eq!(writer.position(), 1); | |
533 | assert_eq!( | |
534 | writer | |
535 | .write_vectored(&[IoSlice::new(&[1, 2, 3]), IoSlice::new(&[4, 5, 6, 7]),]) | |
536 | .unwrap(), | |
537 | 7, | |
538 | ); | |
539 | assert_eq!(writer.position(), 8); | |
540 | assert_eq!(writer.write_vectored(&[]).unwrap(), 0); | |
541 | assert_eq!(writer.position(), 8); | |
542 | ||
543 | assert_eq!(writer.write_vectored(&[IoSlice::new(&[8, 9])]).unwrap(), 1); | |
544 | assert_eq!(writer.write_vectored(&[IoSlice::new(&[10])]).unwrap(), 0); | |
545 | let b: &[_] = &[0, 1, 2, 3, 4, 5, 6, 7, 8]; | |
546 | assert_eq!(&**writer.get_ref(), b); | |
547 | } | |
548 | ||
549 | #[test] | |
550 | fn test_buf_writer() { | |
551 | let mut buf = [0 as u8; 9]; | |
552 | { | |
553 | let mut writer = Cursor::new(&mut buf[..]); | |
554 | assert_eq!(writer.position(), 0); | |
555 | assert_eq!(writer.write(&[0]).unwrap(), 1); | |
556 | assert_eq!(writer.position(), 1); | |
557 | assert_eq!(writer.write(&[1, 2, 3]).unwrap(), 3); | |
558 | assert_eq!(writer.write(&[4, 5, 6, 7]).unwrap(), 4); | |
559 | assert_eq!(writer.position(), 8); | |
560 | assert_eq!(writer.write(&[]).unwrap(), 0); | |
561 | assert_eq!(writer.position(), 8); | |
562 | ||
563 | assert_eq!(writer.write(&[8, 9]).unwrap(), 1); | |
564 | assert_eq!(writer.write(&[10]).unwrap(), 0); | |
565 | } | |
566 | let b: &[_] = &[0, 1, 2, 3, 4, 5, 6, 7, 8]; | |
567 | assert_eq!(buf, b); | |
568 | } | |
569 | ||
570 | #[test] | |
571 | fn test_buf_writer_vectored() { | |
572 | let mut buf = [0 as u8; 9]; | |
573 | { | |
574 | let mut writer = Cursor::new(&mut buf[..]); | |
575 | assert_eq!(writer.position(), 0); | |
576 | assert_eq!(writer.write_vectored(&[IoSlice::new(&[0])]).unwrap(), 1); | |
577 | assert_eq!(writer.position(), 1); | |
578 | assert_eq!( | |
579 | writer | |
580 | .write_vectored(&[IoSlice::new(&[1, 2, 3]), IoSlice::new(&[4, 5, 6, 7])],) | |
581 | .unwrap(), | |
582 | 7, | |
583 | ); | |
584 | assert_eq!(writer.position(), 8); | |
585 | assert_eq!(writer.write_vectored(&[]).unwrap(), 0); | |
586 | assert_eq!(writer.position(), 8); | |
587 | ||
588 | assert_eq!(writer.write_vectored(&[IoSlice::new(&[8, 9])]).unwrap(), 1); | |
589 | assert_eq!(writer.write_vectored(&[IoSlice::new(&[10])]).unwrap(), 0); | |
590 | } | |
591 | let b: &[_] = &[0, 1, 2, 3, 4, 5, 6, 7, 8]; | |
592 | assert_eq!(buf, b); | |
593 | } | |
594 | ||
595 | #[test] | |
596 | fn test_buf_writer_seek() { | |
597 | let mut buf = [0 as u8; 8]; | |
598 | { | |
599 | let mut writer = Cursor::new(&mut buf[..]); | |
600 | assert_eq!(writer.position(), 0); | |
601 | assert_eq!(writer.write(&[1]).unwrap(), 1); | |
602 | assert_eq!(writer.position(), 1); | |
603 | ||
604 | assert_eq!(writer.seek(SeekFrom::Start(2)).unwrap(), 2); | |
605 | assert_eq!(writer.position(), 2); | |
606 | assert_eq!(writer.write(&[2]).unwrap(), 1); | |
607 | assert_eq!(writer.position(), 3); | |
608 | ||
609 | assert_eq!(writer.seek(SeekFrom::Current(-2)).unwrap(), 1); | |
610 | assert_eq!(writer.position(), 1); | |
611 | assert_eq!(writer.write(&[3]).unwrap(), 1); | |
612 | assert_eq!(writer.position(), 2); | |
613 | ||
614 | assert_eq!(writer.seek(SeekFrom::End(-1)).unwrap(), 7); | |
615 | assert_eq!(writer.position(), 7); | |
616 | assert_eq!(writer.write(&[4]).unwrap(), 1); | |
617 | assert_eq!(writer.position(), 8); | |
618 | } | |
619 | let b: &[_] = &[1, 3, 2, 0, 0, 0, 0, 4]; | |
620 | assert_eq!(buf, b); | |
621 | } | |
622 | ||
623 | #[test] | |
624 | fn test_buf_writer_error() { | |
625 | let mut buf = [0 as u8; 2]; | |
626 | let mut writer = Cursor::new(&mut buf[..]); | |
627 | assert_eq!(writer.write(&[0]).unwrap(), 1); | |
628 | assert_eq!(writer.write(&[0, 0]).unwrap(), 1); | |
629 | assert_eq!(writer.write(&[0, 0]).unwrap(), 0); | |
630 | } | |
631 | ||
632 | #[test] | |
633 | fn test_mem_reader() { | |
634 | let mut reader = Cursor::new(vec![0, 1, 2, 3, 4, 5, 6, 7]); | |
635 | let mut buf = []; | |
636 | assert_eq!(reader.read(&mut buf).unwrap(), 0); | |
637 | assert_eq!(reader.position(), 0); | |
638 | let mut buf = [0]; | |
639 | assert_eq!(reader.read(&mut buf).unwrap(), 1); | |
640 | assert_eq!(reader.position(), 1); | |
641 | let b: &[_] = &[0]; | |
642 | assert_eq!(buf, b); | |
643 | let mut buf = [0; 4]; | |
644 | assert_eq!(reader.read(&mut buf).unwrap(), 4); | |
645 | assert_eq!(reader.position(), 5); | |
646 | let b: &[_] = &[1, 2, 3, 4]; | |
647 | assert_eq!(buf, b); | |
648 | assert_eq!(reader.read(&mut buf).unwrap(), 3); | |
649 | let b: &[_] = &[5, 6, 7]; | |
650 | assert_eq!(&buf[..3], b); | |
651 | assert_eq!(reader.read(&mut buf).unwrap(), 0); | |
652 | } | |
653 | ||
654 | #[test] | |
655 | fn test_mem_reader_vectored() { | |
656 | let mut reader = Cursor::new(vec![0, 1, 2, 3, 4, 5, 6, 7]); | |
657 | let mut buf = []; | |
658 | assert_eq!(reader.read_vectored(&mut [IoSliceMut::new(&mut buf)]).unwrap(), 0); | |
659 | assert_eq!(reader.position(), 0); | |
660 | let mut buf = [0]; | |
661 | assert_eq!( | |
662 | reader | |
663 | .read_vectored(&mut [IoSliceMut::new(&mut []), IoSliceMut::new(&mut buf),]) | |
664 | .unwrap(), | |
665 | 1, | |
666 | ); | |
667 | assert_eq!(reader.position(), 1); | |
668 | let b: &[_] = &[0]; | |
669 | assert_eq!(buf, b); | |
670 | let mut buf1 = [0; 4]; | |
671 | let mut buf2 = [0; 4]; | |
672 | assert_eq!( | |
673 | reader | |
674 | .read_vectored(&mut [IoSliceMut::new(&mut buf1), IoSliceMut::new(&mut buf2),]) | |
675 | .unwrap(), | |
676 | 7, | |
677 | ); | |
678 | let b1: &[_] = &[1, 2, 3, 4]; | |
679 | let b2: &[_] = &[5, 6, 7]; | |
680 | assert_eq!(buf1, b1); | |
681 | assert_eq!(&buf2[..3], b2); | |
682 | assert_eq!(reader.read(&mut buf).unwrap(), 0); | |
683 | } | |
684 | ||
685 | #[test] | |
686 | fn test_boxed_slice_reader() { | |
687 | let mut reader = Cursor::new(vec![0, 1, 2, 3, 4, 5, 6, 7].into_boxed_slice()); | |
688 | let mut buf = []; | |
689 | assert_eq!(reader.read(&mut buf).unwrap(), 0); | |
690 | assert_eq!(reader.position(), 0); | |
691 | let mut buf = [0]; | |
692 | assert_eq!(reader.read(&mut buf).unwrap(), 1); | |
693 | assert_eq!(reader.position(), 1); | |
694 | let b: &[_] = &[0]; | |
695 | assert_eq!(buf, b); | |
696 | let mut buf = [0; 4]; | |
697 | assert_eq!(reader.read(&mut buf).unwrap(), 4); | |
698 | assert_eq!(reader.position(), 5); | |
699 | let b: &[_] = &[1, 2, 3, 4]; | |
700 | assert_eq!(buf, b); | |
701 | assert_eq!(reader.read(&mut buf).unwrap(), 3); | |
702 | let b: &[_] = &[5, 6, 7]; | |
703 | assert_eq!(&buf[..3], b); | |
704 | assert_eq!(reader.read(&mut buf).unwrap(), 0); | |
705 | } | |
706 | ||
707 | #[test] | |
708 | fn test_boxed_slice_reader_vectored() { | |
709 | let mut reader = Cursor::new(vec![0, 1, 2, 3, 4, 5, 6, 7].into_boxed_slice()); | |
710 | let mut buf = []; | |
711 | assert_eq!(reader.read_vectored(&mut [IoSliceMut::new(&mut buf)]).unwrap(), 0); | |
712 | assert_eq!(reader.position(), 0); | |
713 | let mut buf = [0]; | |
714 | assert_eq!( | |
715 | reader | |
716 | .read_vectored(&mut [IoSliceMut::new(&mut []), IoSliceMut::new(&mut buf),]) | |
717 | .unwrap(), | |
718 | 1, | |
719 | ); | |
720 | assert_eq!(reader.position(), 1); | |
721 | let b: &[_] = &[0]; | |
722 | assert_eq!(buf, b); | |
723 | let mut buf1 = [0; 4]; | |
724 | let mut buf2 = [0; 4]; | |
725 | assert_eq!( | |
726 | reader | |
727 | .read_vectored(&mut [IoSliceMut::new(&mut buf1), IoSliceMut::new(&mut buf2)],) | |
728 | .unwrap(), | |
729 | 7, | |
730 | ); | |
731 | let b1: &[_] = &[1, 2, 3, 4]; | |
732 | let b2: &[_] = &[5, 6, 7]; | |
733 | assert_eq!(buf1, b1); | |
734 | assert_eq!(&buf2[..3], b2); | |
735 | assert_eq!(reader.read(&mut buf).unwrap(), 0); | |
736 | } | |
737 | ||
738 | #[test] | |
739 | fn read_to_end() { | |
740 | let mut reader = Cursor::new(vec![0, 1, 2, 3, 4, 5, 6, 7]); | |
741 | let mut v = Vec::new(); | |
742 | reader.read_to_end(&mut v).unwrap(); | |
743 | assert_eq!(v, [0, 1, 2, 3, 4, 5, 6, 7]); | |
744 | } | |
745 | ||
746 | #[test] | |
747 | fn test_slice_reader() { | |
748 | let in_buf = vec![0, 1, 2, 3, 4, 5, 6, 7]; | |
749 | let reader = &mut &in_buf[..]; | |
750 | let mut buf = []; | |
751 | assert_eq!(reader.read(&mut buf).unwrap(), 0); | |
752 | let mut buf = [0]; | |
753 | assert_eq!(reader.read(&mut buf).unwrap(), 1); | |
754 | assert_eq!(reader.len(), 7); | |
755 | let b: &[_] = &[0]; | |
756 | assert_eq!(&buf[..], b); | |
757 | let mut buf = [0; 4]; | |
758 | assert_eq!(reader.read(&mut buf).unwrap(), 4); | |
759 | assert_eq!(reader.len(), 3); | |
760 | let b: &[_] = &[1, 2, 3, 4]; | |
761 | assert_eq!(&buf[..], b); | |
762 | assert_eq!(reader.read(&mut buf).unwrap(), 3); | |
763 | let b: &[_] = &[5, 6, 7]; | |
764 | assert_eq!(&buf[..3], b); | |
765 | assert_eq!(reader.read(&mut buf).unwrap(), 0); | |
766 | } | |
767 | ||
768 | #[test] | |
769 | fn test_slice_reader_vectored() { | |
770 | let in_buf = vec![0, 1, 2, 3, 4, 5, 6, 7]; | |
771 | let reader = &mut &in_buf[..]; | |
772 | let mut buf = []; | |
773 | assert_eq!(reader.read_vectored(&mut [IoSliceMut::new(&mut buf)]).unwrap(), 0); | |
774 | let mut buf = [0]; | |
775 | assert_eq!( | |
776 | reader | |
777 | .read_vectored(&mut [IoSliceMut::new(&mut []), IoSliceMut::new(&mut buf),]) | |
778 | .unwrap(), | |
779 | 1, | |
780 | ); | |
781 | assert_eq!(reader.len(), 7); | |
782 | let b: &[_] = &[0]; | |
783 | assert_eq!(buf, b); | |
784 | let mut buf1 = [0; 4]; | |
785 | let mut buf2 = [0; 4]; | |
786 | assert_eq!( | |
787 | reader | |
788 | .read_vectored(&mut [IoSliceMut::new(&mut buf1), IoSliceMut::new(&mut buf2)],) | |
789 | .unwrap(), | |
790 | 7, | |
791 | ); | |
792 | let b1: &[_] = &[1, 2, 3, 4]; | |
793 | let b2: &[_] = &[5, 6, 7]; | |
794 | assert_eq!(buf1, b1); | |
795 | assert_eq!(&buf2[..3], b2); | |
796 | assert_eq!(reader.read(&mut buf).unwrap(), 0); | |
797 | } | |
798 | ||
799 | #[test] | |
800 | fn test_read_exact() { | |
801 | let in_buf = vec![0, 1, 2, 3, 4, 5, 6, 7]; | |
802 | let reader = &mut &in_buf[..]; | |
803 | let mut buf = []; | |
804 | assert!(reader.read_exact(&mut buf).is_ok()); | |
805 | let mut buf = [8]; | |
806 | assert!(reader.read_exact(&mut buf).is_ok()); | |
807 | assert_eq!(buf[0], 0); | |
808 | assert_eq!(reader.len(), 7); | |
809 | let mut buf = [0, 0, 0, 0, 0, 0, 0]; | |
810 | assert!(reader.read_exact(&mut buf).is_ok()); | |
811 | assert_eq!(buf, [1, 2, 3, 4, 5, 6, 7]); | |
812 | assert_eq!(reader.len(), 0); | |
813 | let mut buf = [0]; | |
814 | assert!(reader.read_exact(&mut buf).is_err()); | |
815 | } | |
816 | ||
817 | #[test] | |
818 | fn test_buf_reader() { | |
819 | let in_buf = vec![0, 1, 2, 3, 4, 5, 6, 7]; | |
820 | let mut reader = Cursor::new(&in_buf[..]); | |
821 | let mut buf = []; | |
822 | assert_eq!(reader.read(&mut buf).unwrap(), 0); | |
823 | assert_eq!(reader.position(), 0); | |
824 | let mut buf = [0]; | |
825 | assert_eq!(reader.read(&mut buf).unwrap(), 1); | |
826 | assert_eq!(reader.position(), 1); | |
827 | let b: &[_] = &[0]; | |
828 | assert_eq!(buf, b); | |
829 | let mut buf = [0; 4]; | |
830 | assert_eq!(reader.read(&mut buf).unwrap(), 4); | |
831 | assert_eq!(reader.position(), 5); | |
832 | let b: &[_] = &[1, 2, 3, 4]; | |
833 | assert_eq!(buf, b); | |
834 | assert_eq!(reader.read(&mut buf).unwrap(), 3); | |
835 | let b: &[_] = &[5, 6, 7]; | |
836 | assert_eq!(&buf[..3], b); | |
837 | assert_eq!(reader.read(&mut buf).unwrap(), 0); | |
838 | } | |
839 | ||
840 | #[test] | |
841 | fn seek_past_end() { | |
842 | let buf = [0xff]; | |
843 | let mut r = Cursor::new(&buf[..]); | |
844 | assert_eq!(r.seek(SeekFrom::Start(10)).unwrap(), 10); | |
845 | assert_eq!(r.read(&mut [0]).unwrap(), 0); | |
846 | ||
847 | let mut r = Cursor::new(vec![10]); | |
848 | assert_eq!(r.seek(SeekFrom::Start(10)).unwrap(), 10); | |
849 | assert_eq!(r.read(&mut [0]).unwrap(), 0); | |
850 | ||
851 | let mut buf = [0]; | |
852 | let mut r = Cursor::new(&mut buf[..]); | |
853 | assert_eq!(r.seek(SeekFrom::Start(10)).unwrap(), 10); | |
854 | assert_eq!(r.write(&[3]).unwrap(), 0); | |
855 | ||
856 | let mut r = Cursor::new(vec![10].into_boxed_slice()); | |
857 | assert_eq!(r.seek(SeekFrom::Start(10)).unwrap(), 10); | |
858 | assert_eq!(r.write(&[3]).unwrap(), 0); | |
859 | } | |
860 | ||
861 | #[test] | |
862 | fn seek_past_i64() { | |
863 | let buf = [0xff]; | |
864 | let mut r = Cursor::new(&buf[..]); | |
865 | assert_eq!(r.seek(SeekFrom::Start(6)).unwrap(), 6); | |
866 | assert_eq!(r.seek(SeekFrom::Current(0x7ffffffffffffff0)).unwrap(), 0x7ffffffffffffff6); | |
867 | assert_eq!(r.seek(SeekFrom::Current(0x10)).unwrap(), 0x8000000000000006); | |
868 | assert_eq!(r.seek(SeekFrom::Current(0)).unwrap(), 0x8000000000000006); | |
869 | assert!(r.seek(SeekFrom::Current(0x7ffffffffffffffd)).is_err()); | |
870 | assert_eq!(r.seek(SeekFrom::Current(-0x8000000000000000)).unwrap(), 6); | |
871 | ||
872 | let mut r = Cursor::new(vec![10]); | |
873 | assert_eq!(r.seek(SeekFrom::Start(6)).unwrap(), 6); | |
874 | assert_eq!(r.seek(SeekFrom::Current(0x7ffffffffffffff0)).unwrap(), 0x7ffffffffffffff6); | |
875 | assert_eq!(r.seek(SeekFrom::Current(0x10)).unwrap(), 0x8000000000000006); | |
876 | assert_eq!(r.seek(SeekFrom::Current(0)).unwrap(), 0x8000000000000006); | |
877 | assert!(r.seek(SeekFrom::Current(0x7ffffffffffffffd)).is_err()); | |
878 | assert_eq!(r.seek(SeekFrom::Current(-0x8000000000000000)).unwrap(), 6); | |
879 | ||
880 | let mut buf = [0]; | |
881 | let mut r = Cursor::new(&mut buf[..]); | |
882 | assert_eq!(r.seek(SeekFrom::Start(6)).unwrap(), 6); | |
883 | assert_eq!(r.seek(SeekFrom::Current(0x7ffffffffffffff0)).unwrap(), 0x7ffffffffffffff6); | |
884 | assert_eq!(r.seek(SeekFrom::Current(0x10)).unwrap(), 0x8000000000000006); | |
885 | assert_eq!(r.seek(SeekFrom::Current(0)).unwrap(), 0x8000000000000006); | |
886 | assert!(r.seek(SeekFrom::Current(0x7ffffffffffffffd)).is_err()); | |
887 | assert_eq!(r.seek(SeekFrom::Current(-0x8000000000000000)).unwrap(), 6); | |
888 | ||
889 | let mut r = Cursor::new(vec![10].into_boxed_slice()); | |
890 | assert_eq!(r.seek(SeekFrom::Start(6)).unwrap(), 6); | |
891 | assert_eq!(r.seek(SeekFrom::Current(0x7ffffffffffffff0)).unwrap(), 0x7ffffffffffffff6); | |
892 | assert_eq!(r.seek(SeekFrom::Current(0x10)).unwrap(), 0x8000000000000006); | |
893 | assert_eq!(r.seek(SeekFrom::Current(0)).unwrap(), 0x8000000000000006); | |
894 | assert!(r.seek(SeekFrom::Current(0x7ffffffffffffffd)).is_err()); | |
895 | assert_eq!(r.seek(SeekFrom::Current(-0x8000000000000000)).unwrap(), 6); | |
896 | } | |
897 | ||
898 | #[test] | |
899 | fn seek_before_0() { | |
900 | let buf = [0xff]; | |
901 | let mut r = Cursor::new(&buf[..]); | |
902 | assert!(r.seek(SeekFrom::End(-2)).is_err()); | |
903 | ||
904 | let mut r = Cursor::new(vec![10]); | |
905 | assert!(r.seek(SeekFrom::End(-2)).is_err()); | |
906 | ||
907 | let mut buf = [0]; | |
908 | let mut r = Cursor::new(&mut buf[..]); | |
909 | assert!(r.seek(SeekFrom::End(-2)).is_err()); | |
910 | ||
911 | let mut r = Cursor::new(vec![10].into_boxed_slice()); | |
912 | assert!(r.seek(SeekFrom::End(-2)).is_err()); | |
913 | } | |
914 | ||
915 | #[test] | |
916 | fn test_seekable_mem_writer() { | |
917 | let mut writer = Cursor::new(Vec::<u8>::new()); | |
918 | assert_eq!(writer.position(), 0); | |
919 | assert_eq!(writer.write(&[0]).unwrap(), 1); | |
920 | assert_eq!(writer.position(), 1); | |
921 | assert_eq!(writer.write(&[1, 2, 3]).unwrap(), 3); | |
922 | assert_eq!(writer.write(&[4, 5, 6, 7]).unwrap(), 4); | |
923 | assert_eq!(writer.position(), 8); | |
924 | let b: &[_] = &[0, 1, 2, 3, 4, 5, 6, 7]; | |
925 | assert_eq!(&writer.get_ref()[..], b); | |
926 | ||
927 | assert_eq!(writer.seek(SeekFrom::Start(0)).unwrap(), 0); | |
928 | assert_eq!(writer.position(), 0); | |
929 | assert_eq!(writer.write(&[3, 4]).unwrap(), 2); | |
930 | let b: &[_] = &[3, 4, 2, 3, 4, 5, 6, 7]; | |
931 | assert_eq!(&writer.get_ref()[..], b); | |
932 | ||
933 | assert_eq!(writer.seek(SeekFrom::Current(1)).unwrap(), 3); | |
934 | assert_eq!(writer.write(&[0, 1]).unwrap(), 2); | |
935 | let b: &[_] = &[3, 4, 2, 0, 1, 5, 6, 7]; | |
936 | assert_eq!(&writer.get_ref()[..], b); | |
937 | ||
938 | assert_eq!(writer.seek(SeekFrom::End(-1)).unwrap(), 7); | |
939 | assert_eq!(writer.write(&[1, 2]).unwrap(), 2); | |
940 | let b: &[_] = &[3, 4, 2, 0, 1, 5, 6, 1, 2]; | |
941 | assert_eq!(&writer.get_ref()[..], b); | |
942 | ||
943 | assert_eq!(writer.seek(SeekFrom::End(1)).unwrap(), 10); | |
944 | assert_eq!(writer.write(&[1]).unwrap(), 1); | |
945 | let b: &[_] = &[3, 4, 2, 0, 1, 5, 6, 1, 2, 0, 1]; | |
946 | assert_eq!(&writer.get_ref()[..], b); | |
947 | } | |
948 | ||
949 | #[test] | |
950 | fn vec_seek_past_end() { | |
951 | let mut r = Cursor::new(Vec::new()); | |
952 | assert_eq!(r.seek(SeekFrom::Start(10)).unwrap(), 10); | |
953 | assert_eq!(r.write(&[3]).unwrap(), 1); | |
954 | } | |
955 | ||
956 | #[test] | |
957 | fn vec_seek_before_0() { | |
958 | let mut r = Cursor::new(Vec::new()); | |
959 | assert!(r.seek(SeekFrom::End(-2)).is_err()); | |
960 | } | |
961 | ||
962 | #[test] | |
963 | #[cfg(target_pointer_width = "32")] | |
964 | fn vec_seek_and_write_past_usize_max() { | |
965 | let mut c = Cursor::new(Vec::new()); | |
966 | c.set_position(<usize>::max_value() as u64 + 1); | |
967 | assert!(c.write_all(&[1, 2, 3]).is_err()); | |
968 | } | |
969 | ||
970 | #[test] | |
971 | fn test_partial_eq() { | |
972 | assert_eq!(Cursor::new(Vec::<u8>::new()), Cursor::new(Vec::<u8>::new())); | |
973 | } | |
974 | ||
975 | #[test] | |
976 | fn test_eq() { | |
977 | struct AssertEq<T: Eq>(pub T); | |
978 | ||
979 | let _: AssertEq<Cursor<Vec<u8>>> = AssertEq(Cursor::new(Vec::new())); | |
980 | } | |
981 | } |