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