asn1_cereal/
byte.rs

1//! Constructs for reading and writing bytes used by this crate.
2use std::io;
3
4#[inline]
5/// Read a byte from an iterator, and translate Eof into an `UnexpectedEof` error.
6pub fn read_byte<I: Iterator<Item=io::Result<u8>>>(iter: &mut I) -> io::Result<u8> {
7  match iter.next() {
8    Some(res) => res,
9    None => Err(io::Error::new(io::ErrorKind::UnexpectedEof, "Got unexpected EOF while reading stream")),
10  }
11}
12
13/// A reader to easily read a byte from a reader, while keeping a read count.
14pub struct ByteReader<I: Iterator<Item=io::Result<u8>>> {
15  reader: I,
16  pub count: u64,
17  limit: Option<u64>,
18}
19
20impl<I: Iterator<Item=io::Result<u8>>> ByteReader<I> {
21  /// Create a new ByteReader from an Iterator.
22  pub fn new(reader: I) -> ByteReader<I> {
23    ByteReader {
24      reader: reader,
25      count: 0,
26      limit: None
27    }
28  }
29
30  /*
31  /// Create a new ByteReader from an Iterator, and add
32  /// a maximum length that can be read from it.
33  pub fn new_limit(reader: I, limit: u64) -> ByteReader<I> {
34    ByteReader {
35      reader: reader,
36      count: 0,
37      limit: Some(limit),
38    }
39  }
40  */
41
42  /// Read a byte, and translate Eof into an UnxpectedEof error.
43  pub fn read(&mut self) -> io::Result<u8> {
44    read_byte(self)
45  }
46}
47
48impl<I: Iterator<Item=io::Result<u8>>> Iterator for ByteReader<I> {
49  type Item = io::Result<u8>;
50
51  fn next(&mut self) -> Option<Self::Item> {
52    let val = self.reader.next();
53    if val.is_some() {
54      self.count += 1;
55      // Return None if we've exceeded our limit.
56      if let Some(l) = self.limit {
57        if l > self.count {
58          return None;
59        }
60      }
61    }
62    val
63  }
64}
65
66impl<I: Iterator<Item=io::Result<u8>>> From<I> for ByteReader<I> {
67  fn from(iter: I) -> Self {
68    ByteReader::new(iter)
69  }
70}
71
72#[inline]
73/// Write a byte to a writer, and return an error when nothing was written.
74pub fn write_byte<W: io::Write>(writer: &mut W, byte: u8) -> io::Result<()> {
75  let buf = [byte];
76  match try!(writer.write(&buf)) {
77    0 => Err(io::Error::new(io::ErrorKind::Other, "Wrote zero bytes")),
78    1 => {
79      Ok(())
80    },
81    _ => Err(io::Error::new(io::ErrorKind::Other, "Wrote more than one byte")),
82  }
83}
84
85/// A writer to easily write a byte to a writer, while keeping a write count.
86pub struct ByteWriter<W: io::Write> {
87  writer: W,
88  pub count: u64,
89}
90
91impl<W: io::Write> ByteWriter<W> {
92  pub fn new(writer: W) -> ByteWriter<W> {
93    ByteWriter {
94      writer: writer,
95      count: 0
96    }
97  }
98
99  /// Write a byte, failing if no data was written.
100  pub fn write_byte(&mut self, byte: u8) -> io::Result<()> {
101    write_byte(self, byte)
102  }
103}
104
105impl<W: io::Write> io::Write for ByteWriter<W> {
106  fn write(&mut self, buf: &[u8]) -> io::Result<usize> {
107    let res = self.writer.write(buf);
108    if let Ok(c) = res {
109      self.count += c as u64;
110    }
111    res
112  }
113
114  fn flush(&mut self) -> io::Result<()> {
115    self.writer.flush()
116  }
117}