#![deny(warnings, missing_docs)]
extern crate untrusted;
use untrusted::Reader;
pub use error::Error;
use std::net::{Ipv4Addr, Ipv6Addr};
pub trait ReaderExt {
fn read_byte(&mut self) -> Result<u8, untrusted::EndOfInput>;
#[inline]
fn read_u8(&mut self) -> Result<u8, Error> {
self.read_byte().map_err(From::from)
}
#[inline]
fn read_u16be(&mut self) -> Result<u16, Error> {
let b1 = self.read_u8()? as u16;
let b2 = self.read_u8()? as u16;
Ok((b1 << 8) + b2)
}
#[inline]
fn read_u32be(&mut self) -> Result<u32, Error> {
let b1 = self.read_u16be()? as u32;
let b2 = self.read_u16be()? as u32;
Ok((b1 << 16) + b2)
}
#[inline]
fn read_u64be(&mut self) -> Result<u64, Error> {
let b1 = self.read_u32be()? as u64;
let b2 = self.read_u32be()? as u64;
Ok((b1 << 32) + b2)
}
#[inline]
fn read_u16le(&mut self) -> Result<u16, Error> {
let b2 = self.read_u8()? as u16;
let b1 = self.read_u8()? as u16;
Ok((b1 << 8) + b2)
}
#[inline]
fn read_u32le(&mut self) -> Result<u32, Error> {
let b2 = self.read_u16le()? as u32;
let b1 = self.read_u16le()? as u32;
Ok((b1 << 16) + b2)
}
#[inline]
fn read_u64le(&mut self) -> Result<u64, Error> {
let b2 = self.read_u32le()? as u64;
let b1 = self.read_u32le()? as u64;
Ok((b1 << 32) + b2)
}
#[inline]
fn read_i16be(&mut self) -> Result<i16, Error> {
let b1 = self.read_u8()? as i16;
let b2 = self.read_u8()? as i16;
Ok((b1 << 8) + b2)
}
#[inline]
fn read_i32be(&mut self) -> Result<i32, Error> {
let b1 = self.read_u16be()? as i32;
let b2 = self.read_u16be()? as i32;
Ok((b1 << 16) + b2)
}
#[inline]
fn read_i64be(&mut self) -> Result<i64, Error> {
let b1 = self.read_u32be()? as i64;
let b2 = self.read_u32be()? as i64;
Ok((b1 << 32) + b2)
}
#[inline]
fn read_i16le(&mut self) -> Result<i16, Error> {
let b2 = self.read_u8()? as i16;
let b1 = self.read_u8()? as i16;
Ok((b1 << 8) + b2)
}
#[inline]
fn read_i32le(&mut self) -> Result<i32, Error> {
let b2 = self.read_u16le()? as i32;
let b1 = self.read_u16le()? as i32;
Ok((b1 << 16) + b2)
}
#[inline]
fn read_i64le(&mut self) -> Result<i64, Error> {
let b2 = self.read_u32le()? as i64;
let b1 = self.read_u32le()? as i64;
Ok((b1 << 32) + b2)
}
#[inline]
fn read_bytes(&mut self, length: usize) -> Result<Vec<u8>, Error> {
let mut buf = Vec::with_capacity(length);
for _ in 0..length {
let b = self.read_byte()?;
buf.push(b);
}
Ok(buf)
}
#[inline]
fn read_utf8(&mut self, length: usize) -> Result<String, Error> {
let buf = self.read_bytes(length)?;
String::from_utf8(buf).map_err(From::from)
}
#[inline]
fn read_utf16(&mut self, length: usize) -> Result<String, Error> {
if (length % 2) != 0 {
return Err(Error::ParseError);
}
let len16 = length / 2;
let mut buf: Vec<u16> = Vec::with_capacity(len16);
for _ in 0..len16 {
let b = self.read_u16be()?;
buf.push(b);
}
String::from_utf16(&buf).map_err(From::from)
}
fn read_ipv4addr(&mut self) -> Result<Ipv4Addr, Error> {
let bytes = self.read_u32be()?;
Ok(Ipv4Addr::from(bytes))
}
fn read_ipv6addr(&mut self) -> Result<Ipv6Addr, Error> {
let mut b = [0u16; 8];
for i in &mut b {
*i = self.read_u16be()?;
}
let ip = Ipv6Addr::new(b[0], b[1], b[2], b[3], b[4], b[5], b[6], b[7]);
Ok(ip)
}
}
impl<'a> ReaderExt for Reader<'a> {
#[inline]
fn read_byte(&mut self) -> Result<u8, untrusted::EndOfInput> {
self.read_byte()
}
}
mod error {
use std::fmt;
use std::string::{FromUtf8Error, FromUtf16Error};
use untrusted::EndOfInput;
#[derive(Debug, PartialEq)]
pub enum Error {
EndOfInput,
ParseError,
UnknownError,
}
impl fmt::Display for Error {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
write!(f, "reading failed with {:?}", self)
}
}
impl From<EndOfInput> for Error {
fn from(_: EndOfInput) -> Self {
Error::EndOfInput
}
}
impl From<FromUtf8Error> for Error {
fn from(_: FromUtf8Error) -> Self {
Error::ParseError
}
}
impl From<FromUtf16Error> for Error {
fn from(_: FromUtf16Error) -> Self {
Error::ParseError
}
}
}