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