use std;
use std::io::{Write, Error, ErrorKind};
pub trait Writer {
fn write_u8(&mut self, v: u8) -> std::io::Result<()>;
fn write_u16(&mut self, v: u16) -> std::io::Result<()>;
fn write_u32(&mut self, v: u32) -> std::io::Result<()>;
fn write_u64(&mut self, v: u64) -> std::io::Result<()>;
fn write_bytes(&mut self, v: &[u8]) -> std::io::Result<()>;
fn write_str(&mut self, v: &str) -> std::io::Result<()>;
fn write_string(&mut self, v: &String) -> std::io::Result<()>;
}
pub struct CountWriter {
count: usize
}
impl CountWriter {
pub fn new() -> CountWriter {
CountWriter {
count: 0
}
}
pub fn count(&self) -> usize {
return self.count
}
}
impl Writer for CountWriter {
fn write_u8(&mut self, _: u8) -> std::io::Result<()> {
self.count += 1;
Ok(())
}
fn write_u16(&mut self, _: u16) -> std::io::Result<()> {
self.count += 2;
Ok(())
}
fn write_u32(&mut self, _: u32) -> std::io::Result<()> {
self.count += 4;
Ok(())
}
fn write_u64(&mut self, _: u64) -> std::io::Result<()> {
self.count += 8;
Ok(())
}
fn write_bytes(&mut self, v: &[u8]) -> std::io::Result<()> {
self.count += v.len();
Ok(())
}
fn write_str(&mut self, v: &str) -> std::io::Result<()> {
self.count += 2 + v.len();
Ok(())
}
fn write_string(&mut self, v: &String) -> std::io::Result<()> {
match std::str::from_utf8(v.as_bytes()) {
Ok(s) => self.write_str(s),
Err(err) => {
Err(Error::new(ErrorKind::Other, format!("encoding error: {}", err)))
}
}
}
}
pub struct BasicWriter<'a> {
write: &'a mut Write
}
impl<'a> BasicWriter<'a> {
pub fn new(write: &mut Write) -> BasicWriter {
BasicWriter {
write: write
}
}
}
impl<'a> Writer for BasicWriter<'a> {
fn write_u8(&mut self, v: u8) -> std::io::Result<()> {
self.write.write_all(&[v])
}
fn write_u16(&mut self, v: u16) -> std::io::Result<()> {
self.write.write_all(&[(v >> 8) as u8, (v & 0xff) as u8])
}
fn write_u32(&mut self, v: u32) -> std::io::Result<()> {
self.write.write_all(&[
(v >> 24) as u8,
((v >> 16) & 0xff) as u8,
((v >> 8) & 0xff) as u8,
(v & 0xff) as u8
])
}
fn write_u64(&mut self, v: u64) -> std::io::Result<()> {
self.write.write_all(&[
(v >> 56) as u8,
((v >> 48) & 0xff) as u8,
((v >> 40) & 0xff) as u8,
((v >> 32) & 0xff) as u8,
((v >> 24) & 0xff) as u8,
((v >> 16) & 0xff) as u8,
((v >> 8) & 0xff) as u8,
(v & 0xff) as u8
])
}
fn write_bytes(&mut self, buf: &[u8]) -> std::io::Result<()> {
self.write.write_all(buf)
}
fn write_str(&mut self, buf: &str) -> std::io::Result<()> {
try!(self.write_u16(buf.len() as u16));
self.write_bytes(buf.as_bytes())
}
fn write_string(&mut self, v: &String) -> std::io::Result<()> {
match std::str::from_utf8(v.as_bytes()) {
Ok(s) => self.write_str(s),
Err(err) => {
Err(Error::new(ErrorKind::Other, format!("encoding error: {}", err)))
}
}
}
}