2019-09-20 20:42:45 +00:00
|
|
|
use std::io::{Read, ErrorKind};
|
2019-09-09 21:08:26 +00:00
|
|
|
use std::convert::TryInto;
|
2019-09-15 15:16:17 +00:00
|
|
|
use std::convert::TryFrom;
|
2019-10-12 20:50:24 +00:00
|
|
|
use crate::value::{Value, NestedValue, Set, Map};
|
2019-09-09 21:08:26 +00:00
|
|
|
use num::bigint::BigInt;
|
2019-09-15 15:16:17 +00:00
|
|
|
use crate::value::constants::{Op, InvalidOp, AtomMinor, CompoundMinor};
|
2019-09-09 21:08:26 +00:00
|
|
|
|
|
|
|
pub type Result<V> = std::result::Result<V, Error>;
|
|
|
|
|
|
|
|
#[derive(Debug)]
|
|
|
|
pub enum Error {
|
|
|
|
Io(std::io::Error),
|
|
|
|
Syntax(&'static str),
|
|
|
|
Eof,
|
|
|
|
}
|
|
|
|
|
2019-09-20 20:42:45 +00:00
|
|
|
impl From<Error> for std::io::Error {
|
|
|
|
fn from(v: Error) -> Self {
|
|
|
|
match v {
|
|
|
|
Error::Io(e) => e,
|
|
|
|
Error::Syntax(msg) => Self::new(ErrorKind::InvalidData, msg),
|
|
|
|
Error::Eof => Self::new(ErrorKind::UnexpectedEof, "Unexpected EOF"),
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2019-09-09 21:08:26 +00:00
|
|
|
impl From<std::io::Error> for Error {
|
|
|
|
fn from(v: std::io::Error) -> Self {
|
|
|
|
Error::Io(v)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
impl From<std::str::Utf8Error> for Error {
|
|
|
|
fn from(_v: std::str::Utf8Error) -> Self {
|
|
|
|
Error::Syntax("Invalid UTF-8")
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2019-09-15 15:16:17 +00:00
|
|
|
impl From<InvalidOp> for Error {
|
|
|
|
fn from(_v: InvalidOp) -> Self {
|
|
|
|
Error::Syntax("Invalid lead byte major value")
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2019-09-09 21:08:26 +00:00
|
|
|
impl Error {
|
|
|
|
pub fn is_io(&self) -> bool { if let Error::Io(_) = *self { true } else { false } }
|
|
|
|
pub fn is_syntax(&self) -> bool { if let Error::Syntax(_) = *self { true } else { false } }
|
|
|
|
pub fn is_eof(&self) -> bool { if let Error::Eof = *self { true } else { false } }
|
|
|
|
}
|
|
|
|
|
2019-10-12 20:50:24 +00:00
|
|
|
pub type DecodePlaceholderMap<N> = Map<usize, Value<N>>;
|
2019-09-09 21:08:26 +00:00
|
|
|
|
2019-10-12 14:40:35 +00:00
|
|
|
pub struct Decoder<'a, 'b, R: Read, N: NestedValue> {
|
2019-09-20 20:42:09 +00:00
|
|
|
read: &'a mut R,
|
2019-09-09 21:08:26 +00:00
|
|
|
index: usize,
|
|
|
|
buf: Box<Option<Option<u8>>>,
|
2019-10-12 14:40:35 +00:00
|
|
|
placeholders: Option<&'b DecodePlaceholderMap<N>>,
|
2019-09-15 11:25:23 +00:00
|
|
|
read_annotations: bool,
|
2019-09-09 21:08:26 +00:00
|
|
|
}
|
|
|
|
|
2019-09-20 20:42:09 +00:00
|
|
|
fn decodeint(bs: &[u8]) -> BigInt {
|
|
|
|
BigInt::from_signed_bytes_be(bs)
|
|
|
|
}
|
|
|
|
|
2019-10-12 14:40:35 +00:00
|
|
|
impl<'a, 'b, R: Read, N: NestedValue> Decoder<'a, 'b, R, N> {
|
|
|
|
pub fn new(read: &'a mut R, placeholders: Option<&'b DecodePlaceholderMap<N>>) -> Self {
|
2019-09-09 21:08:26 +00:00
|
|
|
Decoder{
|
|
|
|
read,
|
|
|
|
index: 0,
|
|
|
|
buf: Box::new(None),
|
2019-09-17 10:27:44 +00:00
|
|
|
placeholders,
|
2019-09-15 11:25:23 +00:00
|
|
|
read_annotations: true,
|
2019-09-09 21:08:26 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2019-09-15 11:25:23 +00:00
|
|
|
pub fn set_read_annotations(&mut self, read_annotations: bool) -> () {
|
|
|
|
self.read_annotations = read_annotations
|
|
|
|
}
|
|
|
|
|
|
|
|
fn prime(&mut self) -> Result<()> {
|
2019-09-09 21:08:26 +00:00
|
|
|
match *self.buf {
|
|
|
|
None => {
|
|
|
|
let bs = &mut [0];
|
|
|
|
*self.buf = Some(match self.read.read(bs)? {
|
|
|
|
0 => None,
|
|
|
|
1 => {
|
|
|
|
self.index = self.index + 1;
|
|
|
|
Some(bs[0])
|
|
|
|
},
|
|
|
|
_ => panic!("buffer overrun")
|
|
|
|
})
|
|
|
|
}
|
|
|
|
Some(_) => ()
|
|
|
|
}
|
|
|
|
Ok(())
|
|
|
|
}
|
|
|
|
|
|
|
|
pub fn skip(&mut self) -> Result<()> {
|
2019-09-15 11:25:23 +00:00
|
|
|
self.prime()?;
|
2019-09-09 21:08:26 +00:00
|
|
|
*self.buf = None;
|
|
|
|
Ok(())
|
|
|
|
}
|
|
|
|
|
|
|
|
pub fn peek(&mut self) -> Result<u8> {
|
2019-09-15 11:25:23 +00:00
|
|
|
self.prime()?;
|
2019-09-09 21:08:26 +00:00
|
|
|
match *self.buf {
|
|
|
|
Some(Some(v)) => Ok(v),
|
|
|
|
Some(None) => Err(Error::Eof),
|
2019-09-20 20:43:08 +00:00
|
|
|
None => unreachable!()
|
2019-09-09 21:08:26 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
pub fn read(&mut self) -> Result<u8> {
|
|
|
|
let v = self.peek()?;
|
|
|
|
self.skip()?;
|
|
|
|
Ok(v)
|
|
|
|
}
|
|
|
|
|
|
|
|
pub fn readbytes(&mut self, n: usize) -> Result<Vec<u8>> {
|
|
|
|
if (*self.buf).is_some() {
|
2019-09-20 20:43:08 +00:00
|
|
|
unreachable!();
|
2019-09-09 21:08:26 +00:00
|
|
|
}
|
|
|
|
let mut bs = vec![0; n];
|
|
|
|
match self.read.read_exact(&mut bs) {
|
|
|
|
Ok(()) => Ok(bs),
|
|
|
|
Err(e) =>
|
|
|
|
if e.kind() == std::io::ErrorKind::UnexpectedEof {
|
|
|
|
Err(Error::Eof)
|
|
|
|
} else {
|
|
|
|
Err(Error::from(e))
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2019-10-12 14:40:35 +00:00
|
|
|
pub fn readvalues(&mut self, mut count: usize) -> Result<Vec<N>> {
|
|
|
|
let mut pieces: Vec<N> = Vec::with_capacity(count);
|
2019-09-09 21:08:26 +00:00
|
|
|
while count > 0 {
|
|
|
|
pieces.push(self.next()?);
|
|
|
|
count = count - 1;
|
|
|
|
}
|
|
|
|
Ok(pieces)
|
|
|
|
}
|
|
|
|
|
2019-09-15 15:16:17 +00:00
|
|
|
pub fn decodeop(b: u8) -> Result<(Op, u8)> {
|
|
|
|
Ok((Op::try_from(b >> 4)?, b & 15))
|
2019-09-15 11:25:23 +00:00
|
|
|
}
|
|
|
|
|
2019-09-15 15:16:17 +00:00
|
|
|
pub fn nextop(&mut self) -> Result<(Op, u8)> {
|
|
|
|
Self::decodeop(self.read()?)
|
2019-09-09 21:08:26 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
pub fn varint(&mut self) -> Result<usize> {
|
|
|
|
let v = self.read()?;
|
|
|
|
if v < 128 {
|
|
|
|
Ok(usize::from(v))
|
|
|
|
} else {
|
|
|
|
Ok(self.varint()? * 128 + usize::from(v - 128))
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
pub fn wirelength(&mut self, arg: u8) -> Result<usize> {
|
|
|
|
if arg < 15 {
|
|
|
|
Ok(usize::from(arg))
|
|
|
|
} else {
|
|
|
|
self.varint()
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
pub fn peekend(&mut self) -> Result<bool> {
|
|
|
|
if self.peek()? == 4 {
|
|
|
|
self.skip()?;
|
|
|
|
Ok(true)
|
|
|
|
} else {
|
|
|
|
Ok(false)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2019-10-12 14:40:35 +00:00
|
|
|
pub fn decodebinary(minor: AtomMinor, bs: Vec<u8>) -> Result<N> {
|
2019-09-09 21:08:26 +00:00
|
|
|
Ok(match minor {
|
2019-09-20 20:42:09 +00:00
|
|
|
AtomMinor::SignedInteger => Value::from(decodeint(&bs)).wrap(),
|
2019-09-15 15:16:17 +00:00
|
|
|
AtomMinor::String => Value::from(std::str::from_utf8(&bs)?).wrap(),
|
|
|
|
AtomMinor::ByteString => Value::from(bs).wrap(),
|
|
|
|
AtomMinor::Symbol => Value::symbol(std::str::from_utf8(&bs)?).wrap(),
|
2019-09-09 21:08:26 +00:00
|
|
|
})
|
|
|
|
}
|
|
|
|
|
2019-10-12 14:40:35 +00:00
|
|
|
pub fn decodecompound(minor: CompoundMinor, mut pieces: Vec<N>) -> Result<N> {
|
2019-09-09 21:08:26 +00:00
|
|
|
match minor {
|
2019-09-15 15:16:17 +00:00
|
|
|
CompoundMinor::Record =>
|
2019-09-09 21:08:26 +00:00
|
|
|
if pieces.len() == 0 {
|
|
|
|
Err(Error::Syntax("Too few elements in encoded record"))
|
|
|
|
} else {
|
2019-09-19 20:35:00 +00:00
|
|
|
let label = pieces.remove(0);
|
|
|
|
Ok(Value::record(label, pieces).wrap())
|
2019-09-09 21:08:26 +00:00
|
|
|
},
|
2019-10-12 14:40:35 +00:00
|
|
|
CompoundMinor::Sequence => Ok(Value::Sequence(pieces).wrap()),
|
2019-09-15 15:16:17 +00:00
|
|
|
CompoundMinor::Set => {
|
2019-09-09 21:08:26 +00:00
|
|
|
let mut s = Set::new();
|
|
|
|
while let Some(v) = pieces.pop() {
|
|
|
|
s.insert(v);
|
|
|
|
}
|
|
|
|
Ok(Value::Set(s).wrap())
|
|
|
|
}
|
2019-09-15 15:16:17 +00:00
|
|
|
CompoundMinor::Dictionary =>
|
2019-09-09 21:08:26 +00:00
|
|
|
if pieces.len() % 2 != 0 {
|
|
|
|
Err(Error::Syntax("Missing dictionary value"))
|
|
|
|
} else {
|
2019-10-12 14:40:35 +00:00
|
|
|
let mut d = Map::new();
|
2019-09-09 21:08:26 +00:00
|
|
|
while let Some(v) = pieces.pop() {
|
|
|
|
let k = pieces.pop().unwrap();
|
|
|
|
d.insert(k, v);
|
|
|
|
}
|
|
|
|
Ok(Value::Dictionary(d).wrap())
|
|
|
|
},
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2019-10-12 14:40:35 +00:00
|
|
|
pub fn binarystream(&mut self, minor: AtomMinor) -> Result<N> {
|
2019-09-09 21:08:26 +00:00
|
|
|
let mut bs: Vec<u8> = Vec::new();
|
|
|
|
while !self.peekend()? {
|
2019-10-12 14:40:35 +00:00
|
|
|
match self.next()?.value().as_bytestring() {
|
2019-09-09 21:08:26 +00:00
|
|
|
Some(chunk) => bs.extend_from_slice(chunk),
|
|
|
|
None => return Err(Error::Syntax("Unexpected non-binary chunk")),
|
|
|
|
}
|
|
|
|
}
|
|
|
|
Self::decodebinary(minor, bs)
|
|
|
|
}
|
|
|
|
|
2019-10-12 14:40:35 +00:00
|
|
|
pub fn valuestream(&mut self, minor: CompoundMinor) -> Result<N> {
|
|
|
|
let mut pieces: Vec<N> = Vec::new();
|
2019-09-09 21:08:26 +00:00
|
|
|
while !self.peekend()? {
|
|
|
|
pieces.push(self.next()?);
|
|
|
|
}
|
|
|
|
Self::decodecompound(minor, pieces)
|
|
|
|
}
|
|
|
|
|
2019-10-12 14:40:35 +00:00
|
|
|
pub fn next(&mut self) -> Result<N> {
|
2019-09-09 21:08:26 +00:00
|
|
|
match self.nextop()? {
|
2019-09-15 15:16:17 +00:00
|
|
|
(Op::Misc(0), 0) => Ok(Value::from(false).wrap()),
|
|
|
|
(Op::Misc(0), 1) => Ok(Value::from(true).wrap()),
|
|
|
|
(Op::Misc(0), 2) => {
|
2019-09-09 21:08:26 +00:00
|
|
|
let bs: &[u8] = &self.readbytes(4)?;
|
|
|
|
Ok(Value::from(f32::from_bits(u32::from_be_bytes(bs.try_into().unwrap()))).wrap())
|
|
|
|
}
|
2019-09-15 15:16:17 +00:00
|
|
|
(Op::Misc(0), 3) => {
|
2019-09-09 21:08:26 +00:00
|
|
|
let bs: &[u8] = &self.readbytes(8)?;
|
|
|
|
Ok(Value::from(f64::from_bits(u64::from_be_bytes(bs.try_into().unwrap()))).wrap())
|
|
|
|
}
|
2019-09-15 15:16:17 +00:00
|
|
|
(Op::Misc(0), 5) => {
|
2019-09-15 11:25:23 +00:00
|
|
|
if self.read_annotations {
|
|
|
|
let mut annotations = vec![self.next()?];
|
2019-09-15 15:16:17 +00:00
|
|
|
while Self::decodeop(self.peek()?).ok() == Some((Op::Misc(0), 5)) {
|
2019-09-15 11:25:23 +00:00
|
|
|
self.skip()?;
|
|
|
|
annotations.push(self.next()?);
|
|
|
|
}
|
2019-10-12 20:50:24 +00:00
|
|
|
let v = self.next()?;
|
|
|
|
assert!(v.annotations().len() == 0);
|
|
|
|
Ok(N::wrap_ann(annotations, v.value_owned()))
|
2019-09-15 11:25:23 +00:00
|
|
|
} else {
|
|
|
|
self.next()?;
|
|
|
|
self.next()
|
|
|
|
}
|
2019-09-09 21:08:26 +00:00
|
|
|
}
|
2019-09-15 15:16:17 +00:00
|
|
|
(Op::Misc(0), _) => Err(Error::Syntax("Invalid format A encoding")),
|
|
|
|
(Op::Misc(1), arg) => {
|
2019-09-09 21:08:26 +00:00
|
|
|
let n = self.wirelength(arg)?;
|
2019-09-17 10:27:44 +00:00
|
|
|
match self.placeholders.and_then(|m| m.get(&n)) {
|
2019-09-09 21:08:26 +00:00
|
|
|
Some(v) => Ok(v.clone().wrap()),
|
|
|
|
None => Err(Error::Syntax("Invalid Preserves placeholder")),
|
|
|
|
}
|
|
|
|
}
|
2019-09-15 15:16:17 +00:00
|
|
|
(Op::Misc(2), arg) => {
|
|
|
|
match Op::try_from(arg)? {
|
|
|
|
Op::Atom(minor) => self.binarystream(minor),
|
|
|
|
Op::Compound(minor) => self.valuestream(minor),
|
2019-09-09 21:08:26 +00:00
|
|
|
_ => Err(Error::Syntax("Invalid format C start byte")),
|
|
|
|
}
|
|
|
|
}
|
2019-09-15 15:16:17 +00:00
|
|
|
(Op::Misc(3), arg) => {
|
2019-09-09 21:08:26 +00:00
|
|
|
let n = if arg > 12 { i32::from(arg) - 16 } else { i32::from(arg) };
|
|
|
|
Ok(Value::from(n).wrap())
|
|
|
|
}
|
2019-09-20 20:43:08 +00:00
|
|
|
(Op::Misc(_), _) => unreachable!(),
|
2019-09-15 15:16:17 +00:00
|
|
|
(Op::Atom(minor), arg) => {
|
|
|
|
let count = self.wirelength(arg)?;
|
|
|
|
Self::decodebinary(minor, self.readbytes(count)?)
|
2019-09-09 21:08:26 +00:00
|
|
|
}
|
2019-09-15 15:16:17 +00:00
|
|
|
(Op::Compound(minor), arg) => {
|
|
|
|
let count = self.wirelength(arg)?;
|
|
|
|
Self::decodecompound(minor, self.readvalues(count)?)
|
2019-09-09 21:08:26 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|