use std::io::{Result, Read, Write, Error, ErrorKind};
use byteorder::{BigEndian, LittleEndian, ReadBytesExt, WriteBytesExt};
pub trait ReadExt: Read {
fn read_u8(&mut self) -> Result<u8> {
let mut buf = [0; 1];
self.read_exact(&mut buf)?;
Ok(buf[0])
}
fn read_u16be(&mut self) -> Result<u16> {
self.read_u16::<BigEndian>()
}
fn read_u16le(&mut self) -> Result<u16> {
self.read_u16::<LittleEndian>()
}
fn read_u24be(&mut self) -> Result<u32> {
self.read_uint::<BigEndian>(3).map(|n| n as u32)
}
fn read_u24le(&mut self) -> Result<u32> {
self.read_uint::<LittleEndian>(3).map(|n| n as u32)
}
fn read_u32be(&mut self) -> Result<u32> {
self.read_u32::<BigEndian>()
}
fn read_u32le(&mut self) -> Result<u32> {
self.read_u32::<LittleEndian>()
}
fn read_u40be(&mut self) -> Result<u64> {
self.read_uint::<BigEndian>(5)
}
fn read_u40le(&mut self) -> Result<u64> {
self.read_uint::<LittleEndian>(5)
}
fn read_u48be(&mut self) -> Result<u64> {
self.read_uint::<BigEndian>(6)
}
fn read_u48le(&mut self) -> Result<u64> {
self.read_uint::<LittleEndian>(6)
}
fn read_u56be(&mut self) -> Result<u64> {
self.read_uint::<BigEndian>(7)
}
fn read_u56le(&mut self) -> Result<u64> {
self.read_uint::<LittleEndian>(7)
}
fn read_u64be(&mut self) -> Result<u64> {
self.read_u64::<BigEndian>()
}
fn read_u64le(&mut self) -> Result<u64> {
self.read_u64::<LittleEndian>()
}
fn read_string(&mut self, length: usize) -> Result<String> {
let bytes = self.read_bytes(length)?;
let string = String::from_utf8(bytes).map_err(|e| {
Error::new(ErrorKind::InvalidData, e)
})?;
Ok(string)
}
fn read_bytes(&mut self, length: usize) -> Result<Vec<u8>> {
let mut buf = vec![0; length];
self.read_exact(&mut buf)?;
Ok(buf)
}
fn read_all_string(&mut self) -> Result<String> {
let mut buf = String::new();
self.read_to_string(&mut buf)?;
Ok(buf)
}
fn read_all_bytes(&mut self) -> Result<Vec<u8>> {
let mut buf = Vec::new();
self.read_to_end(&mut buf)?;
Ok(buf)
}
}
impl<R: Read> ReadExt for R {}
pub trait WriteExt: Write {
fn write_u8(&mut self, n: u8) -> Result<()> {
self.write_all(&[n][..])?;
Ok(())
}
fn write_u16be(&mut self, n: u16) -> Result<()> {
self.write_u16::<BigEndian>(n)
}
fn write_u16le(&mut self, n: u16) -> Result<()> {
self.write_u16::<LittleEndian>(n)
}
fn write_u24be(&mut self, n: u32) -> Result<()> {
self.write_uint::<BigEndian>(u64::from(n), 3)
}
fn write_u24le(&mut self, n: u32) -> Result<()> {
self.write_uint::<LittleEndian>(u64::from(n), 3)
}
fn write_u32be(&mut self, n: u32) -> Result<()> {
self.write_u32::<BigEndian>(n)
}
fn write_u32le(&mut self, n: u32) -> Result<()> {
self.write_u32::<LittleEndian>(n)
}
fn write_u40be(&mut self, n: u64) -> Result<()> {
self.write_uint::<BigEndian>(n, 5)
}
fn write_u40le(&mut self, n: u64) -> Result<()> {
self.write_uint::<LittleEndian>(n, 5)
}
fn write_u48be(&mut self, n: u64) -> Result<()> {
self.write_uint::<BigEndian>(n, 6)
}
fn write_u48le(&mut self, n: u64) -> Result<()> {
self.write_uint::<LittleEndian>(n, 6)
}
fn write_u56be(&mut self, n: u64) -> Result<()> {
self.write_uint::<BigEndian>(n, 7)
}
fn write_u56le(&mut self, n: u64) -> Result<()> {
self.write_uint::<LittleEndian>(n, 7)
}
fn write_u64be(&mut self, n: u64) -> Result<()> {
self.write_u64::<BigEndian>(n)
}
fn write_u64le(&mut self, n: u64) -> Result<()> {
self.write_u64::<LittleEndian>(n)
}
}
impl<W: Write> WriteExt for W {}