]>
Commit | Line | Data |
---|---|---|
85aaf69f SL |
1 | // Copyright 2015 The Rust Project Developers. See the COPYRIGHT |
2 | // file at the top-level directory of this distribution and at | |
3 | // http://rust-lang.org/COPYRIGHT. | |
4 | // | |
5 | // Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or | |
6 | // http://www.apache.org/licenses/LICENSE-2.0> or the MIT license | |
7 | // <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your | |
8 | // option. This file may not be copied, modified, or distributed | |
9 | // except according to those terms. | |
10 | ||
85aaf69f SL |
11 | use io::prelude::*; |
12 | ||
c30ab7b3 | 13 | use core::convert::TryInto; |
85aaf69f SL |
14 | use cmp; |
15 | use io::{self, SeekFrom, Error, ErrorKind}; | |
85aaf69f | 16 | |
c1a9b12d | 17 | /// A `Cursor` wraps another type and provides it with a |
c30ab7b3 | 18 | /// [`Seek`] implementation. |
85aaf69f | 19 | /// |
c30ab7b3 SL |
20 | /// `Cursor`s are typically used with in-memory buffers to allow them to |
21 | /// implement [`Read`] and/or [`Write`], allowing these buffers to be used | |
c1a9b12d | 22 | /// anywhere you might use a reader or writer that does actual I/O. |
85aaf69f | 23 | /// |
c1a9b12d | 24 | /// The standard library implements some I/O traits on various types which |
c30ab7b3 SL |
25 | /// are commonly used as a buffer, like `Cursor<`[`Vec`]`<u8>>` and |
26 | /// `Cursor<`[`&[u8]`][bytes]`>`. | |
c1a9b12d SL |
27 | /// |
28 | /// # Examples | |
29 | /// | |
c30ab7b3 | 30 | /// We may want to write bytes to a [`File`] in our production |
c1a9b12d SL |
31 | /// code, but use an in-memory buffer in our tests. We can do this with |
32 | /// `Cursor`: | |
33 | /// | |
c30ab7b3 SL |
34 | /// [`Seek`]: trait.Seek.html |
35 | /// [`Read`]: ../../std/io/trait.Read.html | |
36 | /// [`Write`]: ../../std/io/trait.Write.html | |
37 | /// [`Vec`]: ../../std/vec/struct.Vec.html | |
38 | /// [bytes]: ../../std/primitive.slice.html | |
39 | /// [`File`]: ../fs/struct.File.html | |
c1a9b12d SL |
40 | /// |
41 | /// ```no_run | |
42 | /// use std::io::prelude::*; | |
43 | /// use std::io::{self, SeekFrom}; | |
44 | /// use std::fs::File; | |
45 | /// | |
46 | /// // a library function we've written | |
47 | /// fn write_ten_bytes_at_end<W: Write + Seek>(writer: &mut W) -> io::Result<()> { | |
32a655c1 | 48 | /// writer.seek(SeekFrom::End(-10))?; |
c1a9b12d SL |
49 | /// |
50 | /// for i in 0..10 { | |
32a655c1 | 51 | /// writer.write(&[i])?; |
c1a9b12d SL |
52 | /// } |
53 | /// | |
54 | /// // all went well | |
55 | /// Ok(()) | |
56 | /// } | |
57 | /// | |
58 | /// # fn foo() -> io::Result<()> { | |
59 | /// // Here's some code that uses this library function. | |
60 | /// // | |
61 | /// // We might want to use a BufReader here for efficiency, but let's | |
62 | /// // keep this example focused. | |
32a655c1 | 63 | /// let mut file = File::create("foo.txt")?; |
c1a9b12d | 64 | /// |
32a655c1 | 65 | /// write_ten_bytes_at_end(&mut file)?; |
c1a9b12d SL |
66 | /// # Ok(()) |
67 | /// # } | |
68 | /// | |
69 | /// // now let's write a test | |
70 | /// #[test] | |
71 | /// fn test_writes_bytes() { | |
72 | /// // setting up a real File is much more slow than an in-memory buffer, | |
73 | /// // let's use a cursor instead | |
74 | /// use std::io::Cursor; | |
75 | /// let mut buff = Cursor::new(vec![0; 15]); | |
76 | /// | |
b039eaaf | 77 | /// write_ten_bytes_at_end(&mut buff).unwrap(); |
c1a9b12d SL |
78 | /// |
79 | /// assert_eq!(&buff.get_ref()[5..15], &[0, 1, 2, 3, 4, 5, 6, 7, 8, 9]); | |
80 | /// } | |
81 | /// ``` | |
c34b1796 AL |
82 | #[stable(feature = "rust1", since = "1.0.0")] |
83 | #[derive(Clone, Debug)] | |
85aaf69f SL |
84 | pub struct Cursor<T> { |
85 | inner: T, | |
86 | pos: u64, | |
87 | } | |
88 | ||
89 | impl<T> Cursor<T> { | |
9346a6ac | 90 | /// Creates a new cursor wrapping the provided underlying I/O object. |
c1a9b12d SL |
91 | /// |
92 | /// # Examples | |
93 | /// | |
94 | /// ``` | |
95 | /// use std::io::Cursor; | |
96 | /// | |
97 | /// let buff = Cursor::new(Vec::new()); | |
98 | /// # fn force_inference(_: &Cursor<Vec<u8>>) {} | |
99 | /// # force_inference(&buff); | |
100 | /// ``` | |
c34b1796 | 101 | #[stable(feature = "rust1", since = "1.0.0")] |
85aaf69f SL |
102 | pub fn new(inner: T) -> Cursor<T> { |
103 | Cursor { pos: 0, inner: inner } | |
104 | } | |
105 | ||
9346a6ac | 106 | /// Consumes this cursor, returning the underlying value. |
c1a9b12d SL |
107 | /// |
108 | /// # Examples | |
109 | /// | |
110 | /// ``` | |
111 | /// use std::io::Cursor; | |
112 | /// | |
113 | /// let buff = Cursor::new(Vec::new()); | |
114 | /// # fn force_inference(_: &Cursor<Vec<u8>>) {} | |
115 | /// # force_inference(&buff); | |
116 | /// | |
117 | /// let vec = buff.into_inner(); | |
118 | /// ``` | |
c34b1796 | 119 | #[stable(feature = "rust1", since = "1.0.0")] |
85aaf69f SL |
120 | pub fn into_inner(self) -> T { self.inner } |
121 | ||
9346a6ac | 122 | /// Gets a reference to the underlying value in this cursor. |
c1a9b12d SL |
123 | /// |
124 | /// # Examples | |
125 | /// | |
126 | /// ``` | |
127 | /// use std::io::Cursor; | |
128 | /// | |
129 | /// let buff = Cursor::new(Vec::new()); | |
130 | /// # fn force_inference(_: &Cursor<Vec<u8>>) {} | |
131 | /// # force_inference(&buff); | |
132 | /// | |
133 | /// let reference = buff.get_ref(); | |
134 | /// ``` | |
c34b1796 | 135 | #[stable(feature = "rust1", since = "1.0.0")] |
85aaf69f SL |
136 | pub fn get_ref(&self) -> &T { &self.inner } |
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")] |
85aaf69f SL |
155 | pub fn get_mut(&mut self) -> &mut T { &mut self.inner } |
156 | ||
c1a9b12d SL |
157 | /// Returns the current position of this cursor. |
158 | /// | |
159 | /// # Examples | |
160 | /// | |
161 | /// ``` | |
162 | /// use std::io::Cursor; | |
163 | /// use std::io::prelude::*; | |
164 | /// use std::io::SeekFrom; | |
165 | /// | |
166 | /// let mut buff = Cursor::new(vec![1, 2, 3, 4, 5]); | |
167 | /// | |
168 | /// assert_eq!(buff.position(), 0); | |
169 | /// | |
170 | /// buff.seek(SeekFrom::Current(2)).unwrap(); | |
171 | /// assert_eq!(buff.position(), 2); | |
172 | /// | |
173 | /// buff.seek(SeekFrom::Current(-1)).unwrap(); | |
174 | /// assert_eq!(buff.position(), 1); | |
175 | /// ``` | |
c34b1796 | 176 | #[stable(feature = "rust1", since = "1.0.0")] |
85aaf69f SL |
177 | pub fn position(&self) -> u64 { self.pos } |
178 | ||
c1a9b12d SL |
179 | /// Sets the position of this cursor. |
180 | /// | |
181 | /// # Examples | |
182 | /// | |
183 | /// ``` | |
184 | /// use std::io::Cursor; | |
185 | /// | |
186 | /// let mut buff = Cursor::new(vec![1, 2, 3, 4, 5]); | |
187 | /// | |
188 | /// assert_eq!(buff.position(), 0); | |
189 | /// | |
190 | /// buff.set_position(2); | |
191 | /// assert_eq!(buff.position(), 2); | |
192 | /// | |
193 | /// buff.set_position(4); | |
194 | /// assert_eq!(buff.position(), 4); | |
195 | /// ``` | |
c34b1796 | 196 | #[stable(feature = "rust1", since = "1.0.0")] |
85aaf69f SL |
197 | pub fn set_position(&mut self, pos: u64) { self.pos = pos; } |
198 | } | |
199 | ||
b039eaaf SL |
200 | #[stable(feature = "rust1", since = "1.0.0")] |
201 | impl<T> io::Seek for Cursor<T> where T: AsRef<[u8]> { | |
202 | fn seek(&mut self, style: SeekFrom) -> io::Result<u64> { | |
203 | let pos = match style { | |
204 | SeekFrom::Start(n) => { self.pos = n; return Ok(n) } | |
205 | SeekFrom::End(n) => self.inner.as_ref().len() as i64 + n, | |
206 | SeekFrom::Current(n) => self.pos as i64 + n, | |
207 | }; | |
208 | ||
209 | if pos < 0 { | |
210 | Err(Error::new(ErrorKind::InvalidInput, | |
211 | "invalid seek to a negative position")) | |
212 | } else { | |
213 | self.pos = pos as u64; | |
214 | Ok(self.pos) | |
85aaf69f SL |
215 | } |
216 | } | |
217 | } | |
218 | ||
c34b1796 | 219 | #[stable(feature = "rust1", since = "1.0.0")] |
b039eaaf SL |
220 | impl<T> Read for Cursor<T> where T: AsRef<[u8]> { |
221 | fn read(&mut self, buf: &mut [u8]) -> io::Result<usize> { | |
54a0048b | 222 | let n = Read::read(&mut self.fill_buf()?, buf)?; |
b039eaaf SL |
223 | self.pos += n as u64; |
224 | Ok(n) | |
85aaf69f SL |
225 | } |
226 | } | |
227 | ||
c34b1796 | 228 | #[stable(feature = "rust1", since = "1.0.0")] |
b039eaaf SL |
229 | impl<T> BufRead for Cursor<T> where T: AsRef<[u8]> { |
230 | fn fill_buf(&mut self) -> io::Result<&[u8]> { | |
231 | let amt = cmp::min(self.pos, self.inner.as_ref().len() as u64); | |
232 | Ok(&self.inner.as_ref()[(amt as usize)..]) | |
85aaf69f | 233 | } |
b039eaaf | 234 | fn consume(&mut self, amt: usize) { self.pos += amt as u64; } |
85aaf69f SL |
235 | } |
236 | ||
c34b1796 | 237 | #[stable(feature = "rust1", since = "1.0.0")] |
85aaf69f | 238 | impl<'a> Write for Cursor<&'a mut [u8]> { |
3157f602 | 239 | #[inline] |
85aaf69f SL |
240 | fn write(&mut self, data: &[u8]) -> io::Result<usize> { |
241 | let pos = cmp::min(self.pos, self.inner.len() as u64); | |
54a0048b | 242 | let amt = (&mut self.inner[(pos as usize)..]).write(data)?; |
85aaf69f SL |
243 | self.pos += amt as u64; |
244 | Ok(amt) | |
245 | } | |
246 | fn flush(&mut self) -> io::Result<()> { Ok(()) } | |
247 | } | |
248 | ||
c34b1796 | 249 | #[stable(feature = "rust1", since = "1.0.0")] |
85aaf69f SL |
250 | impl Write for Cursor<Vec<u8>> { |
251 | fn write(&mut self, buf: &[u8]) -> io::Result<usize> { | |
c30ab7b3 SL |
252 | let pos: usize = self.position().try_into().map_err(|_| { |
253 | Error::new(ErrorKind::InvalidInput, | |
254 | "cursor position exceeds maximum possible vector length") | |
255 | })?; | |
85aaf69f SL |
256 | // Make sure the internal buffer is as least as big as where we |
257 | // currently are | |
c1a9b12d | 258 | let len = self.inner.len(); |
c30ab7b3 SL |
259 | if len < pos { |
260 | // use `resize` so that the zero filling is as efficient as possible | |
261 | self.inner.resize(pos, 0); | |
262 | } | |
85aaf69f SL |
263 | // Figure out what bytes will be used to overwrite what's currently |
264 | // there (left), and what will be appended on the end (right) | |
9cc50fc6 | 265 | { |
9cc50fc6 SL |
266 | let space = self.inner.len() - pos; |
267 | let (left, right) = buf.split_at(cmp::min(space, buf.len())); | |
7453a54e | 268 | self.inner[pos..pos + left.len()].copy_from_slice(left); |
9cc50fc6 SL |
269 | self.inner.extend_from_slice(right); |
270 | } | |
85aaf69f SL |
271 | |
272 | // Bump us forward | |
c30ab7b3 | 273 | self.set_position((pos + buf.len()) as u64); |
85aaf69f SL |
274 | Ok(buf.len()) |
275 | } | |
276 | fn flush(&mut self) -> io::Result<()> { Ok(()) } | |
277 | } | |
278 | ||
b039eaaf SL |
279 | #[stable(feature = "cursor_box_slice", since = "1.5.0")] |
280 | impl Write for Cursor<Box<[u8]>> { | |
3157f602 | 281 | #[inline] |
b039eaaf SL |
282 | fn write(&mut self, buf: &[u8]) -> io::Result<usize> { |
283 | let pos = cmp::min(self.pos, self.inner.len() as u64); | |
54a0048b | 284 | let amt = (&mut self.inner[(pos as usize)..]).write(buf)?; |
b039eaaf SL |
285 | self.pos += amt as u64; |
286 | Ok(amt) | |
287 | } | |
288 | fn flush(&mut self) -> io::Result<()> { Ok(()) } | |
289 | } | |
85aaf69f SL |
290 | |
291 | #[cfg(test)] | |
292 | mod tests { | |
85aaf69f SL |
293 | use io::prelude::*; |
294 | use io::{Cursor, SeekFrom}; | |
85aaf69f SL |
295 | |
296 | #[test] | |
297 | fn test_vec_writer() { | |
298 | let mut writer = Vec::new(); | |
c34b1796 AL |
299 | assert_eq!(writer.write(&[0]).unwrap(), 1); |
300 | assert_eq!(writer.write(&[1, 2, 3]).unwrap(), 3); | |
301 | assert_eq!(writer.write(&[4, 5, 6, 7]).unwrap(), 4); | |
85aaf69f SL |
302 | let b: &[_] = &[0, 1, 2, 3, 4, 5, 6, 7]; |
303 | assert_eq!(writer, b); | |
304 | } | |
305 | ||
306 | #[test] | |
307 | fn test_mem_writer() { | |
308 | let mut writer = Cursor::new(Vec::new()); | |
c34b1796 AL |
309 | assert_eq!(writer.write(&[0]).unwrap(), 1); |
310 | assert_eq!(writer.write(&[1, 2, 3]).unwrap(), 3); | |
311 | assert_eq!(writer.write(&[4, 5, 6, 7]).unwrap(), 4); | |
85aaf69f | 312 | let b: &[_] = &[0, 1, 2, 3, 4, 5, 6, 7]; |
c34b1796 | 313 | assert_eq!(&writer.get_ref()[..], b); |
85aaf69f SL |
314 | } |
315 | ||
b039eaaf SL |
316 | #[test] |
317 | fn test_box_slice_writer() { | |
318 | let mut writer = Cursor::new(vec![0u8; 9].into_boxed_slice()); | |
319 | assert_eq!(writer.position(), 0); | |
320 | assert_eq!(writer.write(&[0]).unwrap(), 1); | |
321 | assert_eq!(writer.position(), 1); | |
322 | assert_eq!(writer.write(&[1, 2, 3]).unwrap(), 3); | |
323 | assert_eq!(writer.write(&[4, 5, 6, 7]).unwrap(), 4); | |
324 | assert_eq!(writer.position(), 8); | |
325 | assert_eq!(writer.write(&[]).unwrap(), 0); | |
326 | assert_eq!(writer.position(), 8); | |
327 | ||
328 | assert_eq!(writer.write(&[8, 9]).unwrap(), 1); | |
329 | assert_eq!(writer.write(&[10]).unwrap(), 0); | |
330 | let b: &[_] = &[0, 1, 2, 3, 4, 5, 6, 7, 8]; | |
331 | assert_eq!(&**writer.get_ref(), b); | |
332 | } | |
333 | ||
85aaf69f SL |
334 | #[test] |
335 | fn test_buf_writer() { | |
336 | let mut buf = [0 as u8; 9]; | |
337 | { | |
338 | let mut writer = Cursor::new(&mut buf[..]); | |
339 | assert_eq!(writer.position(), 0); | |
c34b1796 | 340 | assert_eq!(writer.write(&[0]).unwrap(), 1); |
85aaf69f | 341 | assert_eq!(writer.position(), 1); |
c34b1796 AL |
342 | assert_eq!(writer.write(&[1, 2, 3]).unwrap(), 3); |
343 | assert_eq!(writer.write(&[4, 5, 6, 7]).unwrap(), 4); | |
85aaf69f | 344 | assert_eq!(writer.position(), 8); |
c34b1796 | 345 | assert_eq!(writer.write(&[]).unwrap(), 0); |
85aaf69f SL |
346 | assert_eq!(writer.position(), 8); |
347 | ||
c34b1796 AL |
348 | assert_eq!(writer.write(&[8, 9]).unwrap(), 1); |
349 | assert_eq!(writer.write(&[10]).unwrap(), 0); | |
85aaf69f SL |
350 | } |
351 | let b: &[_] = &[0, 1, 2, 3, 4, 5, 6, 7, 8]; | |
352 | assert_eq!(buf, b); | |
353 | } | |
354 | ||
355 | #[test] | |
356 | fn test_buf_writer_seek() { | |
357 | let mut buf = [0 as u8; 8]; | |
358 | { | |
359 | let mut writer = Cursor::new(&mut buf[..]); | |
360 | assert_eq!(writer.position(), 0); | |
c34b1796 | 361 | assert_eq!(writer.write(&[1]).unwrap(), 1); |
85aaf69f SL |
362 | assert_eq!(writer.position(), 1); |
363 | ||
c34b1796 | 364 | assert_eq!(writer.seek(SeekFrom::Start(2)).unwrap(), 2); |
85aaf69f | 365 | assert_eq!(writer.position(), 2); |
c34b1796 | 366 | assert_eq!(writer.write(&[2]).unwrap(), 1); |
85aaf69f SL |
367 | assert_eq!(writer.position(), 3); |
368 | ||
c34b1796 | 369 | assert_eq!(writer.seek(SeekFrom::Current(-2)).unwrap(), 1); |
85aaf69f | 370 | assert_eq!(writer.position(), 1); |
c34b1796 | 371 | assert_eq!(writer.write(&[3]).unwrap(), 1); |
85aaf69f SL |
372 | assert_eq!(writer.position(), 2); |
373 | ||
c34b1796 | 374 | assert_eq!(writer.seek(SeekFrom::End(-1)).unwrap(), 7); |
85aaf69f | 375 | assert_eq!(writer.position(), 7); |
c34b1796 | 376 | assert_eq!(writer.write(&[4]).unwrap(), 1); |
85aaf69f SL |
377 | assert_eq!(writer.position(), 8); |
378 | ||
379 | } | |
380 | let b: &[_] = &[1, 3, 2, 0, 0, 0, 0, 4]; | |
381 | assert_eq!(buf, b); | |
382 | } | |
383 | ||
384 | #[test] | |
385 | fn test_buf_writer_error() { | |
386 | let mut buf = [0 as u8; 2]; | |
387 | let mut writer = Cursor::new(&mut buf[..]); | |
c34b1796 AL |
388 | assert_eq!(writer.write(&[0]).unwrap(), 1); |
389 | assert_eq!(writer.write(&[0, 0]).unwrap(), 1); | |
390 | assert_eq!(writer.write(&[0, 0]).unwrap(), 0); | |
85aaf69f SL |
391 | } |
392 | ||
393 | #[test] | |
394 | fn test_mem_reader() { | |
c30ab7b3 | 395 | let mut reader = Cursor::new(vec![0, 1, 2, 3, 4, 5, 6, 7]); |
85aaf69f | 396 | let mut buf = []; |
c34b1796 | 397 | assert_eq!(reader.read(&mut buf).unwrap(), 0); |
85aaf69f SL |
398 | assert_eq!(reader.position(), 0); |
399 | let mut buf = [0]; | |
c34b1796 | 400 | assert_eq!(reader.read(&mut buf).unwrap(), 1); |
85aaf69f SL |
401 | assert_eq!(reader.position(), 1); |
402 | let b: &[_] = &[0]; | |
403 | assert_eq!(buf, b); | |
404 | let mut buf = [0; 4]; | |
c34b1796 | 405 | assert_eq!(reader.read(&mut buf).unwrap(), 4); |
85aaf69f SL |
406 | assert_eq!(reader.position(), 5); |
407 | let b: &[_] = &[1, 2, 3, 4]; | |
408 | assert_eq!(buf, b); | |
c34b1796 | 409 | assert_eq!(reader.read(&mut buf).unwrap(), 3); |
85aaf69f SL |
410 | let b: &[_] = &[5, 6, 7]; |
411 | assert_eq!(&buf[..3], b); | |
c34b1796 | 412 | assert_eq!(reader.read(&mut buf).unwrap(), 0); |
85aaf69f SL |
413 | } |
414 | ||
b039eaaf SL |
415 | #[test] |
416 | fn test_boxed_slice_reader() { | |
c30ab7b3 | 417 | let mut reader = Cursor::new(vec![0, 1, 2, 3, 4, 5, 6, 7].into_boxed_slice()); |
b039eaaf SL |
418 | let mut buf = []; |
419 | assert_eq!(reader.read(&mut buf).unwrap(), 0); | |
420 | assert_eq!(reader.position(), 0); | |
421 | let mut buf = [0]; | |
422 | assert_eq!(reader.read(&mut buf).unwrap(), 1); | |
423 | assert_eq!(reader.position(), 1); | |
424 | let b: &[_] = &[0]; | |
425 | assert_eq!(buf, b); | |
426 | let mut buf = [0; 4]; | |
427 | assert_eq!(reader.read(&mut buf).unwrap(), 4); | |
428 | assert_eq!(reader.position(), 5); | |
429 | let b: &[_] = &[1, 2, 3, 4]; | |
430 | assert_eq!(buf, b); | |
431 | assert_eq!(reader.read(&mut buf).unwrap(), 3); | |
432 | let b: &[_] = &[5, 6, 7]; | |
433 | assert_eq!(&buf[..3], b); | |
434 | assert_eq!(reader.read(&mut buf).unwrap(), 0); | |
435 | } | |
436 | ||
85aaf69f SL |
437 | #[test] |
438 | fn read_to_end() { | |
c30ab7b3 | 439 | let mut reader = Cursor::new(vec![0, 1, 2, 3, 4, 5, 6, 7]); |
85aaf69f | 440 | let mut v = Vec::new(); |
c34b1796 | 441 | reader.read_to_end(&mut v).unwrap(); |
85aaf69f SL |
442 | assert_eq!(v, [0, 1, 2, 3, 4, 5, 6, 7]); |
443 | } | |
444 | ||
445 | #[test] | |
446 | fn test_slice_reader() { | |
c34b1796 AL |
447 | let in_buf = vec![0, 1, 2, 3, 4, 5, 6, 7]; |
448 | let mut reader = &mut &in_buf[..]; | |
85aaf69f | 449 | let mut buf = []; |
c34b1796 | 450 | assert_eq!(reader.read(&mut buf).unwrap(), 0); |
85aaf69f | 451 | let mut buf = [0]; |
c34b1796 | 452 | assert_eq!(reader.read(&mut buf).unwrap(), 1); |
85aaf69f SL |
453 | assert_eq!(reader.len(), 7); |
454 | let b: &[_] = &[0]; | |
c34b1796 | 455 | assert_eq!(&buf[..], b); |
85aaf69f | 456 | let mut buf = [0; 4]; |
c34b1796 | 457 | assert_eq!(reader.read(&mut buf).unwrap(), 4); |
85aaf69f SL |
458 | assert_eq!(reader.len(), 3); |
459 | let b: &[_] = &[1, 2, 3, 4]; | |
c34b1796 AL |
460 | assert_eq!(&buf[..], b); |
461 | assert_eq!(reader.read(&mut buf).unwrap(), 3); | |
85aaf69f SL |
462 | let b: &[_] = &[5, 6, 7]; |
463 | assert_eq!(&buf[..3], b); | |
c34b1796 | 464 | assert_eq!(reader.read(&mut buf).unwrap(), 0); |
85aaf69f SL |
465 | } |
466 | ||
467 | #[test] | |
468 | fn test_buf_reader() { | |
c34b1796 AL |
469 | let in_buf = vec![0, 1, 2, 3, 4, 5, 6, 7]; |
470 | let mut reader = Cursor::new(&in_buf[..]); | |
85aaf69f | 471 | let mut buf = []; |
c34b1796 | 472 | assert_eq!(reader.read(&mut buf).unwrap(), 0); |
85aaf69f SL |
473 | assert_eq!(reader.position(), 0); |
474 | let mut buf = [0]; | |
c34b1796 | 475 | assert_eq!(reader.read(&mut buf).unwrap(), 1); |
85aaf69f SL |
476 | assert_eq!(reader.position(), 1); |
477 | let b: &[_] = &[0]; | |
478 | assert_eq!(buf, b); | |
479 | let mut buf = [0; 4]; | |
c34b1796 | 480 | assert_eq!(reader.read(&mut buf).unwrap(), 4); |
85aaf69f SL |
481 | assert_eq!(reader.position(), 5); |
482 | let b: &[_] = &[1, 2, 3, 4]; | |
483 | assert_eq!(buf, b); | |
c34b1796 | 484 | assert_eq!(reader.read(&mut buf).unwrap(), 3); |
85aaf69f SL |
485 | let b: &[_] = &[5, 6, 7]; |
486 | assert_eq!(&buf[..3], b); | |
c34b1796 | 487 | assert_eq!(reader.read(&mut buf).unwrap(), 0); |
85aaf69f SL |
488 | } |
489 | ||
490 | #[test] | |
491 | fn test_read_char() { | |
c34b1796 | 492 | let b = &b"Vi\xE1\xBB\x87t"[..]; |
85aaf69f | 493 | let mut c = Cursor::new(b).chars(); |
c34b1796 AL |
494 | assert_eq!(c.next().unwrap().unwrap(), 'V'); |
495 | assert_eq!(c.next().unwrap().unwrap(), 'i'); | |
496 | assert_eq!(c.next().unwrap().unwrap(), 'ệ'); | |
497 | assert_eq!(c.next().unwrap().unwrap(), 't'); | |
498 | assert!(c.next().is_none()); | |
85aaf69f SL |
499 | } |
500 | ||
501 | #[test] | |
502 | fn test_read_bad_char() { | |
c34b1796 | 503 | let b = &b"\x80"[..]; |
85aaf69f SL |
504 | let mut c = Cursor::new(b).chars(); |
505 | assert!(c.next().unwrap().is_err()); | |
506 | } | |
507 | ||
508 | #[test] | |
509 | fn seek_past_end() { | |
510 | let buf = [0xff]; | |
511 | let mut r = Cursor::new(&buf[..]); | |
c34b1796 AL |
512 | assert_eq!(r.seek(SeekFrom::Start(10)).unwrap(), 10); |
513 | assert_eq!(r.read(&mut [0]).unwrap(), 0); | |
85aaf69f | 514 | |
c30ab7b3 | 515 | let mut r = Cursor::new(vec![10]); |
c34b1796 AL |
516 | assert_eq!(r.seek(SeekFrom::Start(10)).unwrap(), 10); |
517 | assert_eq!(r.read(&mut [0]).unwrap(), 0); | |
85aaf69f SL |
518 | |
519 | let mut buf = [0]; | |
520 | let mut r = Cursor::new(&mut buf[..]); | |
c34b1796 AL |
521 | assert_eq!(r.seek(SeekFrom::Start(10)).unwrap(), 10); |
522 | assert_eq!(r.write(&[3]).unwrap(), 0); | |
b039eaaf SL |
523 | |
524 | let mut r = Cursor::new(vec![10].into_boxed_slice()); | |
525 | assert_eq!(r.seek(SeekFrom::Start(10)).unwrap(), 10); | |
526 | assert_eq!(r.write(&[3]).unwrap(), 0); | |
85aaf69f SL |
527 | } |
528 | ||
529 | #[test] | |
530 | fn seek_before_0() { | |
c34b1796 | 531 | let buf = [0xff]; |
85aaf69f SL |
532 | let mut r = Cursor::new(&buf[..]); |
533 | assert!(r.seek(SeekFrom::End(-2)).is_err()); | |
534 | ||
c30ab7b3 | 535 | let mut r = Cursor::new(vec![10]); |
85aaf69f SL |
536 | assert!(r.seek(SeekFrom::End(-2)).is_err()); |
537 | ||
538 | let mut buf = [0]; | |
539 | let mut r = Cursor::new(&mut buf[..]); | |
540 | assert!(r.seek(SeekFrom::End(-2)).is_err()); | |
b039eaaf | 541 | |
c30ab7b3 | 542 | let mut r = Cursor::new(vec![10].into_boxed_slice()); |
b039eaaf | 543 | assert!(r.seek(SeekFrom::End(-2)).is_err()); |
85aaf69f SL |
544 | } |
545 | ||
546 | #[test] | |
547 | fn test_seekable_mem_writer() { | |
548 | let mut writer = Cursor::new(Vec::<u8>::new()); | |
549 | assert_eq!(writer.position(), 0); | |
c34b1796 | 550 | assert_eq!(writer.write(&[0]).unwrap(), 1); |
85aaf69f | 551 | assert_eq!(writer.position(), 1); |
c34b1796 AL |
552 | assert_eq!(writer.write(&[1, 2, 3]).unwrap(), 3); |
553 | assert_eq!(writer.write(&[4, 5, 6, 7]).unwrap(), 4); | |
85aaf69f SL |
554 | assert_eq!(writer.position(), 8); |
555 | let b: &[_] = &[0, 1, 2, 3, 4, 5, 6, 7]; | |
c34b1796 | 556 | assert_eq!(&writer.get_ref()[..], b); |
85aaf69f | 557 | |
c34b1796 | 558 | assert_eq!(writer.seek(SeekFrom::Start(0)).unwrap(), 0); |
85aaf69f | 559 | assert_eq!(writer.position(), 0); |
c34b1796 | 560 | assert_eq!(writer.write(&[3, 4]).unwrap(), 2); |
85aaf69f | 561 | let b: &[_] = &[3, 4, 2, 3, 4, 5, 6, 7]; |
c34b1796 | 562 | assert_eq!(&writer.get_ref()[..], b); |
85aaf69f | 563 | |
c34b1796 AL |
564 | assert_eq!(writer.seek(SeekFrom::Current(1)).unwrap(), 3); |
565 | assert_eq!(writer.write(&[0, 1]).unwrap(), 2); | |
85aaf69f | 566 | let b: &[_] = &[3, 4, 2, 0, 1, 5, 6, 7]; |
c34b1796 | 567 | assert_eq!(&writer.get_ref()[..], b); |
85aaf69f | 568 | |
c34b1796 AL |
569 | assert_eq!(writer.seek(SeekFrom::End(-1)).unwrap(), 7); |
570 | assert_eq!(writer.write(&[1, 2]).unwrap(), 2); | |
85aaf69f | 571 | let b: &[_] = &[3, 4, 2, 0, 1, 5, 6, 1, 2]; |
c34b1796 | 572 | assert_eq!(&writer.get_ref()[..], b); |
85aaf69f | 573 | |
c34b1796 AL |
574 | assert_eq!(writer.seek(SeekFrom::End(1)).unwrap(), 10); |
575 | assert_eq!(writer.write(&[1]).unwrap(), 1); | |
85aaf69f | 576 | let b: &[_] = &[3, 4, 2, 0, 1, 5, 6, 1, 2, 0, 1]; |
c34b1796 | 577 | assert_eq!(&writer.get_ref()[..], b); |
85aaf69f SL |
578 | } |
579 | ||
580 | #[test] | |
581 | fn vec_seek_past_end() { | |
582 | let mut r = Cursor::new(Vec::new()); | |
c34b1796 AL |
583 | assert_eq!(r.seek(SeekFrom::Start(10)).unwrap(), 10); |
584 | assert_eq!(r.write(&[3]).unwrap(), 1); | |
85aaf69f SL |
585 | } |
586 | ||
587 | #[test] | |
588 | fn vec_seek_before_0() { | |
589 | let mut r = Cursor::new(Vec::new()); | |
590 | assert!(r.seek(SeekFrom::End(-2)).is_err()); | |
591 | } | |
c30ab7b3 SL |
592 | |
593 | #[test] | |
594 | #[cfg(target_pointer_width = "32")] | |
595 | fn vec_seek_and_write_past_usize_max() { | |
596 | let mut c = Cursor::new(Vec::new()); | |
597 | c.set_position(<usize>::max_value() as u64 + 1); | |
598 | assert!(c.write_all(&[1, 2, 3]).is_err()); | |
599 | } | |
85aaf69f | 600 | } |