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