]> git.lizzy.rs Git - rust.git/blob - src/libstd/io/mem.rs
Tweak the interface of std::io
[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::max;
14 use cmp::min;
15 use container::Container;
16 use option::{Option, Some, None};
17 use super::{Reader, Writer, Seek, Buffer, IoError, SeekStyle, io_error,
18             OtherIoError};
19 use vec;
20 use vec::{Vector, ImmutableVector, MutableVector, OwnedCopyableVector};
21
22 /// Writes to an owned, growable byte vector
23 ///
24 /// # Example
25 ///
26 /// ```rust
27 /// use std::io::MemWriter;
28 ///
29 /// let mut w = MemWriter::new();
30 /// w.write([0, 1, 2]);
31 ///
32 /// assert_eq!(w.unwrap(), ~[0, 1, 2]);
33 /// ```
34 pub struct MemWriter {
35     priv buf: ~[u8],
36     priv pos: uint,
37 }
38
39 impl MemWriter {
40     /// Create a new `MemWriter`.
41     pub fn new() -> MemWriter {
42         MemWriter::with_capacity(128)
43     }
44     /// Create a new `MemWriter`, allocating at least `n` bytes for
45     /// the internal buffer.
46     pub fn with_capacity(n: uint) -> MemWriter {
47         MemWriter { buf: vec::with_capacity(n), pos: 0 }
48     }
49
50     /// Acquires an immutable reference to the underlying buffer of this
51     /// `MemWriter`.
52     ///
53     /// No method is exposed for acquiring a mutable reference to the buffer
54     /// because it could corrupt the state of this `MemWriter`.
55     pub fn get_ref<'a>(&'a self) -> &'a [u8] { self.buf.as_slice() }
56
57     /// Unwraps this `MemWriter`, returning the underlying buffer
58     pub fn unwrap(self) -> ~[u8] { self.buf }
59 }
60
61 impl Writer for MemWriter {
62     fn write(&mut self, buf: &[u8]) {
63         // Make sure the internal buffer is as least as big as where we
64         // currently are
65         let difference = self.pos as i64 - self.buf.len() as i64;
66         if difference > 0 {
67             self.buf.grow(difference as uint, &0);
68         }
69
70         // Figure out what bytes will be used to overwrite what's currently
71         // there (left), and what will be appended on the end (right)
72         let cap = self.buf.len() - self.pos;
73         let (left, right) = if cap <= buf.len() {
74             (buf.slice_to(cap), buf.slice_from(cap))
75         } else {
76             (buf, &[])
77         };
78
79         // Do the necessary writes
80         if left.len() > 0 {
81             vec::bytes::copy_memory(self.buf.mut_slice_from(self.pos), left);
82         }
83         if right.len() > 0 {
84             self.buf.push_all(right);
85         }
86
87         // Bump us forward
88         self.pos += buf.len();
89     }
90 }
91
92 // FIXME(#10432)
93 impl Seek for MemWriter {
94     fn tell(&self) -> u64 { self.pos as u64 }
95
96     fn seek(&mut self, pos: i64, style: SeekStyle) {
97         // compute offset as signed and clamp to prevent overflow
98         let offset = match style {
99             SeekSet => { 0 }
100             SeekEnd => { self.buf.len() }
101             SeekCur => { self.pos }
102         } as i64;
103
104         self.pos = max(0, offset+pos) as uint;
105     }
106 }
107
108 /// Reads from an owned byte vector
109 ///
110 /// # Example
111 ///
112 /// ```rust
113 /// use std::io::MemReader;
114 ///
115 /// let mut r = MemReader::new(~[0, 1, 2]);
116 ///
117 /// assert_eq!(r.read_to_end(), ~[0, 1, 2]);
118 /// ```
119 pub struct MemReader {
120     priv buf: ~[u8],
121     priv pos: uint
122 }
123
124 impl MemReader {
125     /// Creates a new `MemReader` which will read the buffer given. The buffer
126     /// can be re-acquired through `unwrap`
127     pub fn new(buf: ~[u8]) -> MemReader {
128         MemReader {
129             buf: buf,
130             pos: 0
131         }
132     }
133
134     /// Tests whether this reader has read all bytes in its buffer.
135     ///
136     /// If `true`, then this will no longer return bytes from `read`.
137     pub fn eof(&self) -> bool { self.pos == self.buf.len() }
138
139     /// Acquires an immutable reference to the underlying buffer of this
140     /// `MemReader`.
141     ///
142     /// No method is exposed for acquiring a mutable reference to the buffer
143     /// because it could corrupt the state of this `MemReader`.
144     pub fn get_ref<'a>(&'a self) -> &'a [u8] { self.buf.as_slice() }
145
146     /// Unwraps this `MemReader`, returning the underlying buffer
147     pub fn unwrap(self) -> ~[u8] { self.buf }
148 }
149
150 impl Reader for MemReader {
151     fn read(&mut self, buf: &mut [u8]) -> Option<uint> {
152         if self.eof() { return None }
153
154         let write_len = min(buf.len(), self.buf.len() - self.pos);
155         {
156             let input = self.buf.slice(self.pos, self.pos + write_len);
157             let output = buf.mut_slice(0, write_len);
158             assert_eq!(input.len(), output.len());
159             vec::bytes::copy_memory(output, input);
160         }
161         self.pos += write_len;
162         assert!(self.pos <= self.buf.len());
163
164         return Some(write_len);
165     }
166 }
167
168 impl Seek for MemReader {
169     fn tell(&self) -> u64 { self.pos as u64 }
170     fn seek(&mut self, _pos: i64, _style: SeekStyle) { fail!() }
171 }
172
173 impl Buffer for MemReader {
174     fn fill<'a>(&'a mut self) -> &'a [u8] { self.buf.slice_from(self.pos) }
175     fn consume(&mut self, amt: uint) { self.pos += amt; }
176 }
177
178 /// Writes to a fixed-size byte slice
179 ///
180 /// If a write will not fit in the buffer, it raises the `io_error`
181 /// condition and does not write any data.
182 ///
183 /// # Example
184 ///
185 /// ```rust
186 /// use std::io::BufWriter;
187 ///
188 /// let mut buf = [0, ..4];
189 /// {
190 ///     let mut w = BufWriter::new(buf);
191 ///     w.write([0, 1, 2]);
192 /// }
193 /// assert_eq!(buf, [0, 1, 2, 0]);
194 /// ```
195 pub struct BufWriter<'a> {
196     priv buf: &'a mut [u8],
197     priv pos: uint
198 }
199
200 impl<'a> BufWriter<'a> {
201     pub fn new<'a>(buf: &'a mut [u8]) -> BufWriter<'a> {
202         BufWriter {
203             buf: buf,
204             pos: 0
205         }
206     }
207 }
208
209 impl<'a> Writer for BufWriter<'a> {
210     fn write(&mut self, buf: &[u8]) {
211         // raises a condition if the entire write does not fit in the buffer
212         let max_size = self.buf.len();
213         if self.pos >= max_size || (self.pos + buf.len()) > max_size {
214             io_error::cond.raise(IoError {
215                 kind: OtherIoError,
216                 desc: "Trying to write past end of buffer",
217                 detail: None
218             });
219             return;
220         }
221
222         vec::bytes::copy_memory(self.buf.mut_slice_from(self.pos), buf);
223         self.pos += buf.len();
224     }
225 }
226
227 // FIXME(#10432)
228 impl<'a> Seek for BufWriter<'a> {
229     fn tell(&self) -> u64 { self.pos as u64 }
230
231     fn seek(&mut self, pos: i64, style: SeekStyle) {
232         // compute offset as signed and clamp to prevent overflow
233         let offset = match style {
234             SeekSet => { 0 }
235             SeekEnd => { self.buf.len() }
236             SeekCur => { self.pos }
237         } as i64;
238
239         self.pos = max(0, offset+pos) as uint;
240     }
241 }
242
243
244 /// Reads from a fixed-size byte slice
245 ///
246 /// # Example
247 ///
248 /// ```rust
249 /// use std::io::BufReader;
250 ///
251 /// let mut buf = [0, 1, 2, 3];
252 /// let mut r = BufReader::new(buf);
253 ///
254 /// assert_eq!(r.read_to_end(), ~[0, 1, 2, 3]);
255 /// ```
256 pub struct BufReader<'a> {
257     priv buf: &'a [u8],
258     priv pos: uint
259 }
260
261 impl<'a> BufReader<'a> {
262     /// Creates a new buffered reader which will read the specified buffer
263     pub fn new<'a>(buf: &'a [u8]) -> BufReader<'a> {
264         BufReader {
265             buf: buf,
266             pos: 0
267         }
268     }
269
270     /// Tests whether this reader has read all bytes in its buffer.
271     ///
272     /// If `true`, then this will no longer return bytes from `read`.
273     pub fn eof(&self) -> bool { self.pos == self.buf.len() }
274 }
275
276 impl<'a> Reader for BufReader<'a> {
277     fn read(&mut self, buf: &mut [u8]) -> Option<uint> {
278         if self.eof() { return None }
279
280         let write_len = min(buf.len(), self.buf.len() - self.pos);
281         {
282             let input = self.buf.slice(self.pos, self.pos + write_len);
283             let output = buf.mut_slice(0, write_len);
284             assert_eq!(input.len(), output.len());
285             vec::bytes::copy_memory(output, input);
286         }
287         self.pos += write_len;
288         assert!(self.pos <= self.buf.len());
289
290         return Some(write_len);
291      }
292 }
293
294 impl<'a> Seek for BufReader<'a> {
295     fn tell(&self) -> u64 { self.pos as u64 }
296
297     fn seek(&mut self, _pos: i64, _style: SeekStyle) { fail!() }
298 }
299
300 impl<'a> Buffer for BufReader<'a> {
301     fn fill<'a>(&'a mut self) -> &'a [u8] { self.buf.slice_from(self.pos) }
302     fn consume(&mut self, amt: uint) { self.pos += amt; }
303 }
304
305 #[cfg(test)]
306 mod test {
307     use prelude::*;
308     use super::*;
309     use io::*;
310
311     #[test]
312     fn test_mem_writer() {
313         let mut writer = MemWriter::new();
314         assert_eq!(writer.tell(), 0);
315         writer.write([0]);
316         assert_eq!(writer.tell(), 1);
317         writer.write([1, 2, 3]);
318         writer.write([4, 5, 6, 7]);
319         assert_eq!(writer.tell(), 8);
320         assert_eq!(writer.get_ref(), [0, 1, 2, 3, 4, 5, 6, 7]);
321
322         writer.seek(0, SeekSet);
323         assert_eq!(writer.tell(), 0);
324         writer.write([3, 4]);
325         assert_eq!(writer.get_ref(), [3, 4, 2, 3, 4, 5, 6, 7]);
326
327         writer.seek(1, SeekCur);
328         writer.write([0, 1]);
329         assert_eq!(writer.get_ref(), [3, 4, 2, 0, 1, 5, 6, 7]);
330
331         writer.seek(-1, SeekEnd);
332         writer.write([1, 2]);
333         assert_eq!(writer.get_ref(), [3, 4, 2, 0, 1, 5, 6, 1, 2]);
334
335         writer.seek(1, SeekEnd);
336         writer.write([1]);
337         assert_eq!(writer.get_ref(), [3, 4, 2, 0, 1, 5, 6, 1, 2, 0, 1]);
338     }
339
340     #[test]
341     fn test_buf_writer() {
342         let mut buf = [0 as u8, ..8];
343         {
344             let mut writer = BufWriter::new(buf);
345             assert_eq!(writer.tell(), 0);
346             writer.write([0]);
347             assert_eq!(writer.tell(), 1);
348             writer.write([1, 2, 3]);
349             writer.write([4, 5, 6, 7]);
350             assert_eq!(writer.tell(), 8);
351         }
352         assert_eq!(buf, [0, 1, 2, 3, 4, 5, 6, 7]);
353     }
354
355     #[test]
356     fn test_buf_writer_seek() {
357         let mut buf = [0 as u8, ..8];
358         {
359             let mut writer = BufWriter::new(buf);
360             assert_eq!(writer.tell(), 0);
361             writer.write([1]);
362             assert_eq!(writer.tell(), 1);
363
364             writer.seek(2, SeekSet);
365             assert_eq!(writer.tell(), 2);
366             writer.write([2]);
367             assert_eq!(writer.tell(), 3);
368
369             writer.seek(-2, SeekCur);
370             assert_eq!(writer.tell(), 1);
371             writer.write([3]);
372             assert_eq!(writer.tell(), 2);
373
374             writer.seek(-1, SeekEnd);
375             assert_eq!(writer.tell(), 7);
376             writer.write([4]);
377             assert_eq!(writer.tell(), 8);
378
379         }
380         assert_eq!(buf, [1, 3, 2, 0, 0, 0, 0, 4]);
381     }
382
383     #[test]
384     fn test_buf_writer_error() {
385         let mut buf = [0 as u8, ..2];
386         let mut writer = BufWriter::new(buf);
387         writer.write([0]);
388
389         let mut called = false;
390         io_error::cond.trap(|err| {
391             assert_eq!(err.kind, OtherIoError);
392             called = true;
393         }).inside(|| {
394             writer.write([0, 0]);
395         });
396         assert!(called);
397     }
398
399     #[test]
400     fn test_mem_reader() {
401         let mut reader = MemReader::new(~[0, 1, 2, 3, 4, 5, 6, 7]);
402         let mut buf = [];
403         assert_eq!(reader.read(buf), Some(0));
404         assert_eq!(reader.tell(), 0);
405         let mut buf = [0];
406         assert_eq!(reader.read(buf), Some(1));
407         assert_eq!(reader.tell(), 1);
408         assert_eq!(buf, [0]);
409         let mut buf = [0, ..4];
410         assert_eq!(reader.read(buf), Some(4));
411         assert_eq!(reader.tell(), 5);
412         assert_eq!(buf, [1, 2, 3, 4]);
413         assert_eq!(reader.read(buf), Some(3));
414         assert_eq!(buf.slice(0, 3), [5, 6, 7]);
415         assert_eq!(reader.read(buf), None);
416     }
417
418     #[test]
419     fn test_buf_reader() {
420         let in_buf = ~[0, 1, 2, 3, 4, 5, 6, 7];
421         let mut reader = BufReader::new(in_buf);
422         let mut buf = [];
423         assert_eq!(reader.read(buf), Some(0));
424         assert_eq!(reader.tell(), 0);
425         let mut buf = [0];
426         assert_eq!(reader.read(buf), Some(1));
427         assert_eq!(reader.tell(), 1);
428         assert_eq!(buf, [0]);
429         let mut buf = [0, ..4];
430         assert_eq!(reader.read(buf), Some(4));
431         assert_eq!(reader.tell(), 5);
432         assert_eq!(buf, [1, 2, 3, 4]);
433         assert_eq!(reader.read(buf), Some(3));
434         assert_eq!(buf.slice(0, 3), [5, 6, 7]);
435         assert_eq!(reader.read(buf), None);
436     }
437
438     #[test]
439     fn test_read_char() {
440         let mut r = BufReader::new(bytes!("Việt"));
441         assert_eq!(r.read_char(), Some('V'));
442         assert_eq!(r.read_char(), Some('i'));
443         assert_eq!(r.read_char(), Some('ệ'));
444         assert_eq!(r.read_char(), Some('t'));
445         assert_eq!(r.read_char(), None);
446     }
447
448     #[test]
449     fn test_read_bad_char() {
450         let mut r = BufReader::new(bytes!(0x80));
451         assert_eq!(r.read_char(), None);
452     }
453
454     #[test]
455     fn test_write_strings() {
456         let mut writer = MemWriter::new();
457         writer.write_str("testing");
458         writer.write_line("testing");
459         writer.write_str("testing");
460         let mut r = BufReader::new(writer.get_ref());
461         assert_eq!(r.read_to_str(), ~"testingtesting\ntesting");
462     }
463
464     #[test]
465     fn test_write_char() {
466         let mut writer = MemWriter::new();
467         writer.write_char('a');
468         writer.write_char('\n');
469         writer.write_char('ệ');
470         let mut r = BufReader::new(writer.get_ref());
471         assert_eq!(r.read_to_str(), ~"a\nệ");
472     }
473
474     #[test]
475     fn test_read_whole_string_bad() {
476         let buf = [0xff];
477         let mut r = BufReader::new(buf);
478         match result(|| r.read_to_str()) {
479             Ok(..) => fail!(),
480             Err(..) => {}
481         }
482     }
483 }