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