use std::net::{Ipv4Addr, Ipv6Addr};
use bytes::{BigEndian, ByteOrder, Bytes};
use failure::Fail;
#[derive(Clone, Debug)]
pub struct Parser {
bytes: Bytes,
pos: usize
}
impl Parser {
pub fn from_bytes(bytes: Bytes) -> Self {
Parser { bytes, pos: 0 }
}
pub fn from_static(slice: &'static [u8]) -> Self {
Self::from_bytes(Bytes::from_static(slice))
}
pub fn unwrap(self) -> Bytes {
self.bytes
}
}
impl Parser {
pub fn as_bytes(&self) -> &Bytes {
&self.bytes
}
pub fn as_slice(&self) -> &[u8] {
self.bytes.as_ref()
}
pub fn pos(&self) -> usize {
self.pos
}
pub fn remaining(&self) -> usize {
self.bytes.len() - self.pos
}
pub fn peek(&self, len: usize) -> Result<&[u8], ShortBuf> {
self.check_len(len)?;
Ok(&self.peek_all()[..len])
}
pub fn peek_all(&self) -> &[u8] {
&self.bytes.as_ref()[self.pos..]
}
pub fn seek(&mut self, pos: usize) -> Result<(), ShortBuf> {
if pos > self.bytes.len() {
Err(ShortBuf)
}
else {
self.pos = pos;
Ok(())
}
}
pub fn advance(&mut self, len: usize) -> Result<(), ShortBuf> {
if len > self.remaining() {
Err(ShortBuf)
}
else {
self.pos += len;
Ok(())
}
}
pub fn check_len(&self, len: usize) -> Result<(), ShortBuf> {
if self.remaining() < len {
Err(ShortBuf)
}
else {
Ok(())
}
}
pub fn parse_bytes(&mut self, len: usize) -> Result<Bytes, ShortBuf> {
let end = self.pos + len;
if end > self.bytes.len() {
return Err(ShortBuf)
}
let res = self.bytes.slice(self.pos, end);
self.pos = end;
Ok(res)
}
pub fn parse_buf(&mut self, buf: &mut [u8]) -> Result<(), ShortBuf> {
let pos = self.pos;
self.advance(buf.len())?;
buf.copy_from_slice(&self.bytes.as_ref()[pos..self.pos]);
Ok(())
}
pub fn parse_i8(&mut self) -> Result<i8, ShortBuf> {
let res = self.peek(1)?[0] as i8;
self.pos += 1;
Ok(res)
}
pub fn parse_u8(&mut self) -> Result<u8, ShortBuf> {
let res = self.peek(1)?[0];
self.pos += 1;
Ok(res)
}
pub fn parse_i16(&mut self) -> Result<i16, ShortBuf> {
let res = BigEndian::read_i16(self.peek(2)?);
self.pos += 2;
Ok(res)
}
pub fn parse_u16(&mut self) -> Result<u16, ShortBuf> {
let res = BigEndian::read_u16(self.peek(2)?);
self.pos += 2;
Ok(res)
}
pub fn parse_i32(&mut self) -> Result<i32, ShortBuf> {
let res = BigEndian::read_i32(self.peek(4)?);
self.pos += 4;
Ok(res)
}
pub fn parse_u32(&mut self) -> Result<u32, ShortBuf> {
let res = BigEndian::read_u32(self.peek(4)?);
self.pos += 4;
Ok(res)
}
}
pub trait Parse: Sized {
type Err: From<ShortBuf>;
fn parse(parser: &mut Parser) -> Result<Self, Self::Err>;
fn skip(parser: &mut Parser) -> Result<(), Self::Err>;
}
impl Parse for i8 {
type Err = ShortBuf;
fn parse(parser: &mut Parser) -> Result<Self, ShortBuf> {
parser.parse_i8()
}
fn skip(parser: &mut Parser) -> Result<(), ShortBuf> {
parser.advance(1)
}
}
impl Parse for u8 {
type Err = ShortBuf;
fn parse(parser: &mut Parser) -> Result<Self, ShortBuf> {
parser.parse_u8()
}
fn skip(parser: &mut Parser) -> Result<(), ShortBuf> {
parser.advance(1)
}
}
impl Parse for i16 {
type Err = ShortBuf;
fn parse(parser: &mut Parser) -> Result<Self, ShortBuf> {
parser.parse_i16()
}
fn skip(parser: &mut Parser) -> Result<(), ShortBuf> {
parser.advance(2)
}
}
impl Parse for u16 {
type Err = ShortBuf;
fn parse(parser: &mut Parser) -> Result<Self, ShortBuf> {
parser.parse_u16()
}
fn skip(parser: &mut Parser) -> Result<(), ShortBuf> {
parser.advance(2)
}
}
impl Parse for i32 {
type Err = ShortBuf;
fn parse(parser: &mut Parser) -> Result<Self, ShortBuf> {
parser.parse_i32()
}
fn skip(parser: &mut Parser) -> Result<(), ShortBuf> {
parser.advance(4)
}
}
impl Parse for u32 {
type Err = ShortBuf;
fn parse(parser: &mut Parser) -> Result<Self, ShortBuf> {
parser.parse_u32()
}
fn skip(parser: &mut Parser) -> Result<(), ShortBuf> {
parser.advance(4)
}
}
impl Parse for Ipv4Addr {
type Err = ShortBuf;
fn parse(parser: &mut Parser) -> Result<Self, ShortBuf> {
Ok(Self::new(
u8::parse(parser)?,
u8::parse(parser)?,
u8::parse(parser)?,
u8::parse(parser)?
))
}
fn skip(parser: &mut Parser) -> Result<(), ShortBuf> {
parser.advance(4)
}
}
impl Parse for Ipv6Addr {
type Err = ShortBuf;
fn parse(parser: &mut Parser) -> Result<Self, Self::Err> {
let mut buf = [0u8; 16];
parser.parse_buf(&mut buf)?;
Ok(buf.into())
}
fn skip(parser: &mut Parser) -> Result<(), ShortBuf> {
parser.advance(16)
}
}
pub trait ParseAll: Sized {
type Err: From<ShortBuf> + Fail;
fn parse_all(parser: &mut Parser, len: usize)
-> Result<Self, Self::Err>;
}
impl ParseAll for u8 {
type Err = ParseAllError;
fn parse_all(parser: &mut Parser, len: usize) -> Result<Self, Self::Err> {
if len < 1 {
Err(ParseAllError::ShortField)
}
else if len > 1 {
Err(ParseAllError::TrailingData)
}
else {
Ok(Self::parse(parser)?)
}
}
}
impl ParseAll for u16 {
type Err = ParseAllError;
fn parse_all(parser: &mut Parser, len: usize) -> Result<Self, Self::Err> {
if len < 2 {
Err(ParseAllError::ShortField)
}
else if len > 2 {
Err(ParseAllError::TrailingData)
}
else {
Ok(Self::parse(parser)?)
}
}
}
impl ParseAll for u32 {
type Err = ParseAllError;
fn parse_all(parser: &mut Parser, len: usize) -> Result<Self, Self::Err> {
if len < 4 {
Err(ParseAllError::ShortField)
}
else if len > 4 {
Err(ParseAllError::TrailingData)
}
else {
Ok(Self::parse(parser)?)
}
}
}
impl ParseAll for Bytes {
type Err = ShortBuf;
fn parse_all(parser: &mut Parser, len: usize) -> Result<Self, Self::Err> {
parser.parse_bytes(len)
}
}
impl ParseAll for Ipv4Addr {
type Err = ParseAllError;
fn parse_all(parser: &mut Parser, len: usize) -> Result<Self, Self::Err> {
if len < 4 {
Err(ParseAllError::ShortField)
}
else if len > 4 {
Err(ParseAllError::TrailingData)
}
else {
Ok(Self::parse(parser)?)
}
}
}
impl ParseAll for Ipv6Addr {
type Err = ParseAllError;
fn parse_all(parser: &mut Parser, len: usize) -> Result<Self, Self::Err> {
if len < 16 {
Err(ParseAllError::ShortField)
}
else if len > 16 {
Err(ParseAllError::TrailingData)
}
else {
Ok(Self::parse(parser)?)
}
}
}
#[derive(Clone, Copy, Debug, Eq, Fail, PartialEq)]
pub enum ParseOpenError {
#[fail(display="short field")]
ShortField,
#[fail(display="unexpected end of buffer")]
ShortBuf
}
impl From<ShortBuf> for ParseOpenError {
fn from(_: ShortBuf) -> Self {
ParseOpenError::ShortBuf
}
}
#[derive(Clone, Debug, Eq, Fail, PartialEq)]
#[fail(display="unexpected end of buffer")]
pub struct ShortBuf;
#[derive(Clone, Copy, Debug, Eq, Fail, PartialEq)]
pub enum ParseAllError {
#[fail(display="trailing data")]
TrailingData,
#[fail(display="short field")]
ShortField,
#[fail(display="unexpected end of buffer")]
ShortBuf
}
impl ParseAllError {
pub fn check(expected: usize, got: usize) -> Result<(), Self> {
if expected < got {
Err(ParseAllError::TrailingData)
}
else if expected > got {
Err(ParseAllError::ShortField)
}
else {
Ok(())
}
}
}
impl From<ShortBuf> for ParseAllError {
fn from(_: ShortBuf) -> Self {
ParseAllError::ShortBuf
}
}
#[cfg(test)]
mod test {
use super::*;
#[test]
fn pos_seek_remaining() {
let mut parser = Parser::from_static(b"0123456789");
assert_eq!(parser.peek(1).unwrap(), b"0");
assert_eq!(parser.pos(), 0);
assert_eq!(parser.remaining(), 10);
assert_eq!(parser.seek(2), Ok(()));
assert_eq!(parser.pos(), 2);
assert_eq!(parser.remaining(), 8);
assert_eq!(parser.peek(1).unwrap(), b"2");
assert_eq!(parser.seek(10), Ok(()));
assert_eq!(parser.pos(), 10);
assert_eq!(parser.remaining(), 0);
assert_eq!(parser.peek_all(), b"");
assert_eq!(parser.seek(11), Err(ShortBuf));
assert_eq!(parser.pos(), 10);
assert_eq!(parser.remaining(), 0);
}
#[test]
fn peek_check_len() {
let mut parser = Parser::from_static(b"0123456789");
assert_eq!(parser.peek(2), Ok(b"01".as_ref()));
assert_eq!(parser.check_len(2), Ok(()));
assert_eq!(parser.peek(10), Ok(b"0123456789".as_ref()));
assert_eq!(parser.check_len(10), Ok(()));
assert_eq!(parser.peek(11), Err(ShortBuf));
assert_eq!(parser.check_len(11), Err(ShortBuf));
parser.advance(2).unwrap();
assert_eq!(parser.peek(2), Ok(b"23".as_ref()));
assert_eq!(parser.check_len(2), Ok(()));
assert_eq!(parser.peek(8), Ok(b"23456789".as_ref()));
assert_eq!(parser.check_len(8), Ok(()));
assert_eq!(parser.peek(9), Err(ShortBuf));
assert_eq!(parser.check_len(9), Err(ShortBuf));
}
#[test]
fn peek_all() {
let mut parser = Parser::from_static(b"0123456789");
assert_eq!(parser.peek_all(), b"0123456789");
parser.advance(2).unwrap();
assert_eq!(parser.peek_all(), b"23456789");
}
#[test]
fn advance() {
let mut parser = Parser::from_static(b"0123456789");
assert_eq!(parser.pos(), 0);
assert_eq!(parser.peek(1).unwrap(), b"0");
assert_eq!(parser.advance(2), Ok(()));
assert_eq!(parser.pos(), 2);
assert_eq!(parser.peek(1).unwrap(), b"2");
assert_eq!(parser.advance(9), Err(ShortBuf));
assert_eq!(parser.advance(8), Ok(()));
assert_eq!(parser.pos(), 10);
assert_eq!(parser.peek_all(), b"");
}
#[test]
fn parse_bytes() {
let mut parser = Parser::from_static(b"0123456789");
assert_eq!(parser.parse_bytes(2).unwrap().as_ref(), b"01");
assert_eq!(parser.parse_bytes(2).unwrap().as_ref(), b"23");
assert_eq!(parser.parse_bytes(7), Err(ShortBuf));
assert_eq!(parser.parse_bytes(6).unwrap().as_ref(), b"456789");
}
#[test]
fn parse_buf() {
let mut parser = Parser::from_static(b"0123456789");
let mut buf = [0u8; 2];
assert_eq!(parser.parse_buf(&mut buf), Ok(()));
assert_eq!(&buf, b"01");
assert_eq!(parser.parse_buf(&mut buf), Ok(()));
assert_eq!(&buf, b"23");
let mut buf = [0u8; 7];
assert_eq!(parser.parse_buf(&mut buf), Err(ShortBuf));
let mut buf = [0u8; 6];
assert_eq!(parser.parse_buf(&mut buf), Ok(()));
assert_eq!(&buf, b"456789");
}
#[test]
fn parse_i8() {
let mut parser = Parser::from_static(b"\x12\xd6");
assert_eq!(parser.parse_i8(), Ok(0x12));
assert_eq!(parser.parse_i8(), Ok(-42));
assert_eq!(parser.parse_i8(), Err(ShortBuf));
}
#[test]
fn parse_u8() {
let mut parser = Parser::from_static(b"\x12\xd6");
assert_eq!(parser.parse_u8(), Ok(0x12));
assert_eq!(parser.parse_u8(), Ok(0xd6));
assert_eq!(parser.parse_u8(), Err(ShortBuf));
}
#[test]
fn parse_i16() {
let mut parser = Parser::from_static(b"\x12\x34\xef\x6e\0");
assert_eq!(parser.parse_i16(), Ok(0x1234));
assert_eq!(parser.parse_i16(), Ok(-4242));
assert_eq!(parser.parse_i16(), Err(ShortBuf));
}
#[test]
fn parse_u16() {
let mut parser = Parser::from_static(b"\x12\x34\xef\x6e\0");
assert_eq!(parser.parse_u16(), Ok(0x1234));
assert_eq!(parser.parse_u16(), Ok(0xef6e));
assert_eq!(parser.parse_u16(), Err(ShortBuf));
}
#[test]
fn parse_i32() {
let mut parser = Parser::from_static(
b"\x12\x34\x56\x78\xfd\x78\xa8\x4e\0\0\0");
assert_eq!(parser.parse_i32(), Ok(0x12345678));
assert_eq!(parser.parse_i32(), Ok(-42424242));
assert_eq!(parser.parse_i32(), Err(ShortBuf));
}
#[test]
fn parse_u32() {
let mut parser = Parser::from_static(
b"\x12\x34\x56\x78\xfd\x78\xa8\x4e\0\0\0");
assert_eq!(parser.parse_u32(), Ok(0x12345678));
assert_eq!(parser.parse_u32(), Ok(0xfd78a84e));
assert_eq!(parser.parse_u32(), Err(ShortBuf));
}
}