png/
traits.rs

1use std::io;
2
3/// Configuration parameter trait
4pub trait Parameter<Object> {
5    fn set_param(self, &mut Object);
6}
7
8/// Object has parameters
9pub trait HasParameters: Sized {
10    fn set<T: Parameter<Self>>(&mut self, value: T) -> &mut Self {
11        value.set_param(self);
12        self
13    }
14}
15
16
17// Will be replaced by stdlib solution
18fn read_all<R: io::Read + ?Sized>(this: &mut R, buf: &mut [u8]) -> io::Result<()> {
19    let mut total = 0;
20    while total < buf.len() {
21        match this.read(&mut buf[total..]) {
22            Ok(0) => return Err(io::Error::new(io::ErrorKind::Other,
23                                               "failed to read the whole buffer")),
24            Ok(n) => total += n,
25            Err(ref e) if e.kind() == io::ErrorKind::Interrupted => {}
26            Err(e) => return Err(e),
27        }
28    }
29    Ok(())
30}
31
32/// Read extension to read big endian data
33pub trait ReadBytesExt<T>: io::Read {
34    /// Read `T` from a bytes stream. Most significant byte first.
35    fn read_be(&mut self) -> io::Result<T>;
36
37}
38
39/// Write extension to write big endian data
40pub trait WriteBytesExt<T>: io::Write {
41    /// Writes `T` to a bytes stream. Most significant byte first.
42    fn write_be(&mut self, T) -> io::Result<()>;
43
44}
45
46impl<W: io::Read + ?Sized> ReadBytesExt<u8> for W {
47	#[inline]
48	fn read_be(&mut self) -> io::Result<u8> {
49        let mut byte = [0];
50		try!(read_all(self, &mut byte));
51        Ok(byte[0])
52	}
53}
54impl<W: io::Read + ?Sized> ReadBytesExt<u16> for W {
55	#[inline]
56	fn read_be(&mut self) -> io::Result<u16> {
57        let mut bytes = [0, 0];
58		try!(read_all(self, &mut bytes));
59        Ok((bytes[0] as u16) << 8 | bytes[1] as u16)
60	}
61}
62
63impl<W: io::Read + ?Sized> ReadBytesExt<u32> for W {
64	#[inline]
65	fn read_be(&mut self) -> io::Result<u32> {
66        let mut bytes = [0, 0, 0, 0];
67		try!(read_all(self, &mut bytes));
68        Ok(  (bytes[0] as u32) << 24 
69           | (bytes[1] as u32) << 16
70           | (bytes[2] as u32) << 8
71           |  bytes[3] as u32
72        )
73	}
74}
75
76impl<W: io::Write + ?Sized> WriteBytesExt<u32> for W {
77    #[inline]
78    fn write_be(&mut self, n: u32) -> io::Result<()> {
79        self.write_all(&[
80            (n >> 24) as u8,
81            (n >> 16) as u8,
82            (n >>  8) as u8,
83            n         as u8
84        ])
85    }
86}