]> git.lizzy.rs Git - rust.git/blob - src/libstd/io/mem.rs
e6866f45948565a23db43eeba6ec9eb4a2b68c7c
[rust.git] / src / libstd / io / mem.rs
1 // Copyright 2013 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 //
11 // ignore-lexer-test FIXME #15679
12
13 //! Readers and Writers for in-memory buffers
14
15 use cmp::min;
16 use collections::Collection;
17 use option::None;
18 use result::{Err, Ok};
19 use io;
20 use io::{Reader, Writer, Seek, Buffer, IoError, SeekStyle, IoResult};
21 use slice;
22 use slice::{Vector, ImmutableSlice, MutableSlice};
23 use vec::Vec;
24
25 static BUF_CAPACITY: uint = 128;
26
27 fn combine(seek: SeekStyle, cur: uint, end: uint, offset: i64) -> IoResult<u64> {
28     // compute offset as signed and clamp to prevent overflow
29     let pos = match seek {
30         io::SeekSet => 0,
31         io::SeekEnd => end,
32         io::SeekCur => cur,
33     } as i64;
34
35     if offset + pos < 0 {
36         Err(IoError {
37             kind: io::InvalidInput,
38             desc: "invalid seek to a negative offset",
39             detail: None
40         })
41     } else {
42         Ok((offset + pos) as u64)
43     }
44 }
45
46 /// Writes to an owned, growable byte vector
47 ///
48 /// # Example
49 ///
50 /// ```rust
51 /// # #![allow(unused_must_use)]
52 /// use std::io::MemWriter;
53 ///
54 /// let mut w = MemWriter::new();
55 /// w.write([0, 1, 2]);
56 ///
57 /// assert_eq!(w.unwrap(), vec!(0, 1, 2));
58 /// ```
59 #[deriving(Clone)]
60 pub struct MemWriter {
61     buf: Vec<u8>,
62 }
63
64 impl MemWriter {
65     /// Create a new `MemWriter`.
66     #[inline]
67     pub fn new() -> MemWriter {
68         MemWriter::with_capacity(BUF_CAPACITY)
69     }
70     /// Create a new `MemWriter`, allocating at least `n` bytes for
71     /// the internal buffer.
72     #[inline]
73     pub fn with_capacity(n: uint) -> MemWriter {
74         MemWriter { buf: Vec::with_capacity(n) }
75     }
76
77     /// Acquires an immutable reference to the underlying buffer of this
78     /// `MemWriter`.
79     #[inline]
80     pub fn get_ref<'a>(&'a self) -> &'a [u8] { self.buf.as_slice() }
81
82     /// Unwraps this `MemWriter`, returning the underlying buffer
83     #[inline]
84     pub fn unwrap(self) -> Vec<u8> { self.buf }
85 }
86
87 impl Writer for MemWriter {
88     #[inline]
89     fn write(&mut self, buf: &[u8]) -> IoResult<()> {
90         self.buf.push_all(buf);
91         Ok(())
92     }
93 }
94
95 /// Reads from an owned byte vector
96 ///
97 /// # Example
98 ///
99 /// ```rust
100 /// # #![allow(unused_must_use)]
101 /// use std::io::MemReader;
102 ///
103 /// let mut r = MemReader::new(vec!(0, 1, 2));
104 ///
105 /// assert_eq!(r.read_to_end().unwrap(), vec!(0, 1, 2));
106 /// ```
107 pub struct MemReader {
108     buf: Vec<u8>,
109     pos: uint
110 }
111
112 impl MemReader {
113     /// Creates a new `MemReader` which will read the buffer given. The buffer
114     /// can be re-acquired through `unwrap`
115     #[inline]
116     pub fn new(buf: Vec<u8>) -> MemReader {
117         MemReader {
118             buf: buf,
119             pos: 0
120         }
121     }
122
123     /// Tests whether this reader has read all bytes in its buffer.
124     ///
125     /// If `true`, then this will no longer return bytes from `read`.
126     #[inline]
127     pub fn eof(&self) -> bool { self.pos >= self.buf.len() }
128
129     /// Acquires an immutable reference to the underlying buffer of this
130     /// `MemReader`.
131     ///
132     /// No method is exposed for acquiring a mutable reference to the buffer
133     /// because it could corrupt the state of this `MemReader`.
134     #[inline]
135     pub fn get_ref<'a>(&'a self) -> &'a [u8] { self.buf.as_slice() }
136
137     /// Unwraps this `MemReader`, returning the underlying buffer
138     #[inline]
139     pub fn unwrap(self) -> Vec<u8> { self.buf }
140 }
141
142 impl Reader for MemReader {
143     #[inline]
144     fn read(&mut self, buf: &mut [u8]) -> IoResult<uint> {
145         if self.eof() { return Err(io::standard_error(io::EndOfFile)) }
146
147         let write_len = min(buf.len(), self.buf.len() - self.pos);
148         {
149             let input = self.buf.slice(self.pos, self.pos + write_len);
150             let output = buf.mut_slice(0, write_len);
151             assert_eq!(input.len(), output.len());
152             slice::bytes::copy_memory(output, input);
153         }
154         self.pos += write_len;
155         assert!(self.pos <= self.buf.len());
156
157         return Ok(write_len);
158     }
159 }
160
161 impl Seek for MemReader {
162     #[inline]
163     fn tell(&self) -> IoResult<u64> { Ok(self.pos as u64) }
164
165     #[inline]
166     fn seek(&mut self, pos: i64, style: SeekStyle) -> IoResult<()> {
167         let new = try!(combine(style, self.pos, self.buf.len(), pos));
168         self.pos = new as uint;
169         Ok(())
170     }
171 }
172
173 impl Buffer for MemReader {
174     #[inline]
175     fn fill_buf<'a>(&'a mut self) -> IoResult<&'a [u8]> {
176         if self.pos < self.buf.len() {
177             Ok(self.buf.slice_from(self.pos))
178         } else {
179             Err(io::standard_error(io::EndOfFile))
180         }
181     }
182
183     #[inline]
184     fn consume(&mut self, amt: uint) { self.pos += amt; }
185 }
186
187 /// Writes to a fixed-size byte slice
188 ///
189 /// If a write will not fit in the buffer, it returns an error and does not
190 /// write any data.
191 ///
192 /// # Example
193 ///
194 /// ```rust
195 /// # #![allow(unused_must_use)]
196 /// use std::io::BufWriter;
197 ///
198 /// let mut buf = [0, ..4];
199 /// {
200 ///     let mut w = BufWriter::new(buf);
201 ///     w.write([0, 1, 2]);
202 /// }
203 /// assert!(buf == [0, 1, 2, 0]);
204 /// ```
205 pub struct BufWriter<'a> {
206     buf: &'a mut [u8],
207     pos: uint
208 }
209
210 impl<'a> BufWriter<'a> {
211     /// Creates a new `BufWriter` which will wrap the specified buffer. The
212     /// writer initially starts at position 0.
213     #[inline]
214     pub fn new<'a>(buf: &'a mut [u8]) -> BufWriter<'a> {
215         BufWriter {
216             buf: buf,
217             pos: 0
218         }
219     }
220 }
221
222 impl<'a> Writer for BufWriter<'a> {
223     #[inline]
224     fn write(&mut self, buf: &[u8]) -> IoResult<()> {
225         // return an error if the entire write does not fit in the buffer
226         let cap = if self.pos >= self.buf.len() { 0 } else { self.buf.len() - self.pos };
227         if buf.len() > cap {
228             return Err(IoError {
229                 kind: io::OtherIoError,
230                 desc: "Trying to write past end of buffer",
231                 detail: None
232             })
233         }
234
235         slice::bytes::copy_memory(self.buf.mut_slice_from(self.pos), buf);
236         self.pos += buf.len();
237         Ok(())
238     }
239 }
240
241 impl<'a> Seek for BufWriter<'a> {
242     #[inline]
243     fn tell(&self) -> IoResult<u64> { Ok(self.pos as u64) }
244
245     #[inline]
246     fn seek(&mut self, pos: i64, style: SeekStyle) -> IoResult<()> {
247         let new = try!(combine(style, self.pos, self.buf.len(), pos));
248         self.pos = new as uint;
249         Ok(())
250     }
251 }
252
253 /// Reads from a fixed-size byte slice
254 ///
255 /// # Example
256 ///
257 /// ```rust
258 /// # #![allow(unused_must_use)]
259 /// use std::io::BufReader;
260 ///
261 /// let mut buf = [0, 1, 2, 3];
262 /// let mut r = BufReader::new(buf);
263 ///
264 /// assert_eq!(r.read_to_end().unwrap(), vec!(0, 1, 2, 3));
265 /// ```
266 pub struct BufReader<'a> {
267     buf: &'a [u8],
268     pos: uint
269 }
270
271 impl<'a> BufReader<'a> {
272     /// Creates a new buffered reader which will read the specified buffer
273     #[inline]
274     pub fn new<'a>(buf: &'a [u8]) -> BufReader<'a> {
275         BufReader {
276             buf: buf,
277             pos: 0
278         }
279     }
280
281     /// Tests whether this reader has read all bytes in its buffer.
282     ///
283     /// If `true`, then this will no longer return bytes from `read`.
284     #[inline]
285     pub fn eof(&self) -> bool { self.pos >= self.buf.len() }
286 }
287
288 impl<'a> Reader for BufReader<'a> {
289     #[inline]
290     fn read(&mut self, buf: &mut [u8]) -> IoResult<uint> {
291         if self.eof() { return Err(io::standard_error(io::EndOfFile)) }
292
293         let write_len = min(buf.len(), self.buf.len() - self.pos);
294         {
295             let input = self.buf.slice(self.pos, self.pos + write_len);
296             let output = buf.mut_slice(0, write_len);
297             assert_eq!(input.len(), output.len());
298             slice::bytes::copy_memory(output, input);
299         }
300         self.pos += write_len;
301         assert!(self.pos <= self.buf.len());
302
303         return Ok(write_len);
304      }
305 }
306
307 impl<'a> Seek for BufReader<'a> {
308     #[inline]
309     fn tell(&self) -> IoResult<u64> { Ok(self.pos as u64) }
310
311     #[inline]
312     fn seek(&mut self, pos: i64, style: SeekStyle) -> IoResult<()> {
313         let new = try!(combine(style, self.pos, self.buf.len(), pos));
314         self.pos = new as uint;
315         Ok(())
316     }
317 }
318
319 impl<'a> Buffer for BufReader<'a> {
320     #[inline]
321     fn fill_buf<'a>(&'a mut self) -> IoResult<&'a [u8]> {
322         if self.pos < self.buf.len() {
323             Ok(self.buf.slice_from(self.pos))
324         } else {
325             Err(io::standard_error(io::EndOfFile))
326         }
327     }
328
329     #[inline]
330     fn consume(&mut self, amt: uint) { self.pos += amt; }
331 }
332
333 #[cfg(test)]
334 mod test {
335     extern crate test;
336     use prelude::*;
337     use super::*;
338     use io::*;
339     use io;
340     use self::test::Bencher;
341     use str::StrSlice;
342
343     #[test]
344     fn test_mem_writer() {
345         let mut writer = MemWriter::new();
346         writer.write([0]).unwrap();
347         writer.write([1, 2, 3]).unwrap();
348         writer.write([4, 5, 6, 7]).unwrap();
349         assert_eq!(writer.get_ref(), &[0, 1, 2, 3, 4, 5, 6, 7]);
350     }
351
352     #[test]
353     fn test_buf_writer() {
354         let mut buf = [0 as u8, ..8];
355         {
356             let mut writer = BufWriter::new(buf);
357             assert_eq!(writer.tell(), Ok(0));
358             writer.write([0]).unwrap();
359             assert_eq!(writer.tell(), Ok(1));
360             writer.write([1, 2, 3]).unwrap();
361             writer.write([4, 5, 6, 7]).unwrap();
362             assert_eq!(writer.tell(), Ok(8));
363             writer.write([]).unwrap();
364             assert_eq!(writer.tell(), Ok(8));
365         }
366         assert_eq!(buf.as_slice(), &[0, 1, 2, 3, 4, 5, 6, 7]);
367     }
368
369     #[test]
370     fn test_buf_writer_seek() {
371         let mut buf = [0 as u8, ..8];
372         {
373             let mut writer = BufWriter::new(buf);
374             assert_eq!(writer.tell(), Ok(0));
375             writer.write([1]).unwrap();
376             assert_eq!(writer.tell(), Ok(1));
377
378             writer.seek(2, SeekSet).unwrap();
379             assert_eq!(writer.tell(), Ok(2));
380             writer.write([2]).unwrap();
381             assert_eq!(writer.tell(), Ok(3));
382
383             writer.seek(-2, SeekCur).unwrap();
384             assert_eq!(writer.tell(), Ok(1));
385             writer.write([3]).unwrap();
386             assert_eq!(writer.tell(), Ok(2));
387
388             writer.seek(-1, SeekEnd).unwrap();
389             assert_eq!(writer.tell(), Ok(7));
390             writer.write([4]).unwrap();
391             assert_eq!(writer.tell(), Ok(8));
392
393         }
394         assert_eq!(buf.as_slice(), &[1, 3, 2, 0, 0, 0, 0, 4]);
395     }
396
397     #[test]
398     fn test_buf_writer_error() {
399         let mut buf = [0 as u8, ..2];
400         let mut writer = BufWriter::new(buf);
401         writer.write([0]).unwrap();
402
403         match writer.write([0, 0]) {
404             Ok(..) => fail!(),
405             Err(e) => assert_eq!(e.kind, io::OtherIoError),
406         }
407     }
408
409     #[test]
410     fn test_mem_reader() {
411         let mut reader = MemReader::new(vec!(0, 1, 2, 3, 4, 5, 6, 7));
412         let mut buf = [];
413         assert_eq!(reader.read(buf), Ok(0));
414         assert_eq!(reader.tell(), Ok(0));
415         let mut buf = [0];
416         assert_eq!(reader.read(buf), Ok(1));
417         assert_eq!(reader.tell(), Ok(1));
418         assert_eq!(buf.as_slice(), &[0]);
419         let mut buf = [0, ..4];
420         assert_eq!(reader.read(buf), Ok(4));
421         assert_eq!(reader.tell(), Ok(5));
422         assert_eq!(buf.as_slice(), &[1, 2, 3, 4]);
423         assert_eq!(reader.read(buf), Ok(3));
424         assert_eq!(buf.slice(0, 3), &[5, 6, 7]);
425         assert!(reader.read(buf).is_err());
426         let mut reader = MemReader::new(vec!(0, 1, 2, 3, 4, 5, 6, 7));
427         assert_eq!(reader.read_until(3).unwrap(), vec!(0, 1, 2, 3));
428         assert_eq!(reader.read_until(3).unwrap(), vec!(4, 5, 6, 7));
429         assert!(reader.read(buf).is_err());
430     }
431
432     #[test]
433     fn test_buf_reader() {
434         let in_buf = vec![0, 1, 2, 3, 4, 5, 6, 7];
435         let mut reader = BufReader::new(in_buf.as_slice());
436         let mut buf = [];
437         assert_eq!(reader.read(buf), Ok(0));
438         assert_eq!(reader.tell(), Ok(0));
439         let mut buf = [0];
440         assert_eq!(reader.read(buf), Ok(1));
441         assert_eq!(reader.tell(), Ok(1));
442         assert_eq!(buf.as_slice(), &[0]);
443         let mut buf = [0, ..4];
444         assert_eq!(reader.read(buf), Ok(4));
445         assert_eq!(reader.tell(), Ok(5));
446         assert_eq!(buf.as_slice(), &[1, 2, 3, 4]);
447         assert_eq!(reader.read(buf), Ok(3));
448         assert_eq!(buf.slice(0, 3), &[5, 6, 7]);
449         assert!(reader.read(buf).is_err());
450         let mut reader = BufReader::new(in_buf.as_slice());
451         assert_eq!(reader.read_until(3).unwrap(), vec!(0, 1, 2, 3));
452         assert_eq!(reader.read_until(3).unwrap(), vec!(4, 5, 6, 7));
453         assert!(reader.read(buf).is_err());
454     }
455
456     #[test]
457     fn test_read_char() {
458         let b = b"Vi\xE1\xBB\x87t";
459         let mut r = BufReader::new(b);
460         assert_eq!(r.read_char(), Ok('V'));
461         assert_eq!(r.read_char(), Ok('i'));
462         assert_eq!(r.read_char(), Ok('ệ'));
463         assert_eq!(r.read_char(), Ok('t'));
464         assert!(r.read_char().is_err());
465     }
466
467     #[test]
468     fn test_read_bad_char() {
469         let b = b"\x80";
470         let mut r = BufReader::new(b);
471         assert!(r.read_char().is_err());
472     }
473
474     #[test]
475     fn test_write_strings() {
476         let mut writer = MemWriter::new();
477         writer.write_str("testing").unwrap();
478         writer.write_line("testing").unwrap();
479         writer.write_str("testing").unwrap();
480         let mut r = BufReader::new(writer.get_ref());
481         assert_eq!(r.read_to_string().unwrap(), "testingtesting\ntesting".to_string());
482     }
483
484     #[test]
485     fn test_write_char() {
486         let mut writer = MemWriter::new();
487         writer.write_char('a').unwrap();
488         writer.write_char('\n').unwrap();
489         writer.write_char('ệ').unwrap();
490         let mut r = BufReader::new(writer.get_ref());
491         assert_eq!(r.read_to_string().unwrap(), "a\nệ".to_string());
492     }
493
494     #[test]
495     fn test_read_whole_string_bad() {
496         let buf = [0xff];
497         let mut r = BufReader::new(buf);
498         match r.read_to_string() {
499             Ok(..) => fail!(),
500             Err(..) => {}
501         }
502     }
503
504     #[test]
505     fn seek_past_end() {
506         let buf = [0xff];
507         let mut r = BufReader::new(buf);
508         r.seek(10, SeekSet).unwrap();
509         assert!(r.read(&mut []).is_err());
510
511         let mut r = MemReader::new(vec!(10));
512         r.seek(10, SeekSet).unwrap();
513         assert!(r.read(&mut []).is_err());
514
515         let mut buf = [0];
516         let mut r = BufWriter::new(buf);
517         r.seek(10, SeekSet).unwrap();
518         assert!(r.write([3]).is_err());
519     }
520
521     #[test]
522     fn seek_before_0() {
523         let buf = [0xff];
524         let mut r = BufReader::new(buf);
525         assert!(r.seek(-1, SeekSet).is_err());
526
527         let mut r = MemReader::new(vec!(10));
528         assert!(r.seek(-1, SeekSet).is_err());
529
530         let mut buf = [0];
531         let mut r = BufWriter::new(buf);
532         assert!(r.seek(-1, SeekSet).is_err());
533     }
534
535     #[test]
536     fn io_read_at_least() {
537         let mut r = MemReader::new(vec![1, 2, 3, 4, 5, 6, 7, 8]);
538         let mut buf = [0, ..3];
539         assert!(r.read_at_least(buf.len(), buf).is_ok());
540         assert_eq!(buf.as_slice(), &[1, 2, 3]);
541         assert!(r.read_at_least(0, buf.mut_slice_to(0)).is_ok());
542         assert_eq!(buf.as_slice(), &[1, 2, 3]);
543         assert!(r.read_at_least(buf.len(), buf).is_ok());
544         assert_eq!(buf.as_slice(), &[4, 5, 6]);
545         assert!(r.read_at_least(buf.len(), buf).is_err());
546         assert_eq!(buf.as_slice(), &[7, 8, 6]);
547     }
548
549     fn do_bench_mem_writer(b: &mut Bencher, times: uint, len: uint) {
550         let src: Vec<u8> = Vec::from_elem(len, 5);
551
552         b.bytes = (times * len) as u64;
553         b.iter(|| {
554             let mut wr = MemWriter::new();
555             for _ in range(0, times) {
556                 wr.write(src.as_slice()).unwrap();
557             }
558
559             let v = wr.unwrap();
560             assert_eq!(v.len(), times * len);
561             assert!(v.iter().all(|x| *x == 5));
562         });
563     }
564
565     #[bench]
566     fn bench_mem_writer_001_0000(b: &mut Bencher) {
567         do_bench_mem_writer(b, 1, 0)
568     }
569
570     #[bench]
571     fn bench_mem_writer_001_0010(b: &mut Bencher) {
572         do_bench_mem_writer(b, 1, 10)
573     }
574
575     #[bench]
576     fn bench_mem_writer_001_0100(b: &mut Bencher) {
577         do_bench_mem_writer(b, 1, 100)
578     }
579
580     #[bench]
581     fn bench_mem_writer_001_1000(b: &mut Bencher) {
582         do_bench_mem_writer(b, 1, 1000)
583     }
584
585     #[bench]
586     fn bench_mem_writer_100_0000(b: &mut Bencher) {
587         do_bench_mem_writer(b, 100, 0)
588     }
589
590     #[bench]
591     fn bench_mem_writer_100_0010(b: &mut Bencher) {
592         do_bench_mem_writer(b, 100, 10)
593     }
594
595     #[bench]
596     fn bench_mem_writer_100_0100(b: &mut Bencher) {
597         do_bench_mem_writer(b, 100, 100)
598     }
599
600     #[bench]
601     fn bench_mem_writer_100_1000(b: &mut Bencher) {
602         do_bench_mem_writer(b, 100, 1000)
603     }
604
605     #[bench]
606     fn bench_mem_reader(b: &mut Bencher) {
607         b.iter(|| {
608             let buf = Vec::from_slice([5 as u8, ..100]);
609             {
610                 let mut rdr = MemReader::new(buf);
611                 for _i in range(0u, 10) {
612                     let mut buf = [0 as u8, .. 10];
613                     rdr.read(buf).unwrap();
614                     assert_eq!(buf.as_slice(), [5, .. 10].as_slice());
615                 }
616             }
617         });
618     }
619
620     #[bench]
621     fn bench_buf_writer(b: &mut Bencher) {
622         b.iter(|| {
623             let mut buf = [0 as u8, ..100];
624             {
625                 let mut wr = BufWriter::new(buf);
626                 for _i in range(0u, 10) {
627                     wr.write([5, .. 10]).unwrap();
628                 }
629             }
630             assert_eq!(buf.as_slice(), [5, .. 100].as_slice());
631         });
632     }
633
634     #[bench]
635     fn bench_buf_reader(b: &mut Bencher) {
636         b.iter(|| {
637             let buf = [5 as u8, ..100];
638             {
639                 let mut rdr = BufReader::new(buf);
640                 for _i in range(0u, 10) {
641                     let mut buf = [0 as u8, .. 10];
642                     rdr.read(buf).unwrap();
643                     assert_eq!(buf.as_slice(), [5, .. 10].as_slice());
644                 }
645             }
646         });
647     }
648 }