use std::io::{Read, ErrorKind}; use std::convert::TryInto; use std::convert::TryFrom; use crate::value::{Value, NestedValue, Set, Map, Domain}; use num::bigint::BigInt; use crate::value::constants::{Op, InvalidOp, AtomMinor, CompoundMinor}; pub type Result = std::result::Result; #[derive(Debug)] pub enum Error { Io(std::io::Error), Syntax(&'static str), Eof, } impl From 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"), } } } impl From for Error { fn from(v: std::io::Error) -> Self { Error::Io(v) } } impl From for Error { fn from(_v: std::str::Utf8Error) -> Self { Error::Syntax("Invalid UTF-8") } } impl From for Error { fn from(_v: InvalidOp) -> Self { Error::Syntax("Invalid lead byte major value") } } 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 } } } pub type DecodePlaceholderMap = Map>; #[derive(PartialEq, Eq)] enum PeekState { Empty, Eof, Full(u8), } pub struct Decoder<'a, 'b, R: Read, N: NestedValue, D: Domain> { read: &'a mut R, index: usize, buf: Box, placeholders: Option<&'b DecodePlaceholderMap>, read_annotations: bool, } struct CountedStream<'de, 'a, 'b, R: Read, N: NestedValue, D: Domain> { count: usize, decoder: &'de mut Decoder<'a, 'b, R, N, D>, } impl<'de, 'a, 'b, R: Read, N: NestedValue, D: Domain> Iterator for CountedStream<'de, 'a, 'b, R, N, D> { type Item = Result; fn next(&mut self) -> Option { if self.count == 0 { return None } self.count -= 1; Some(self.decoder.next()) } } struct DelimitedStream<'de, 'a, 'b, R: Read, N: NestedValue, D: Domain> { decoder: &'de mut Decoder<'a, 'b, R, N, D>, } impl<'de, 'a, 'b, R: Read, N: NestedValue, D: Domain> Iterator for DelimitedStream<'de, 'a, 'b, R, N, D> { type Item = Result; fn next(&mut self) -> Option { match self.decoder.peekend() { Err(e) => Some(Err(e)), Ok(true) => None, Ok(false) => Some(self.decoder.next()), } } } fn decodeint(bs: &[u8]) -> BigInt { BigInt::from_signed_bytes_be(bs) } impl<'a, 'b, R: Read, N: NestedValue, D: Domain> Decoder<'a, 'b, R, N, D> { pub fn new(read: &'a mut R, placeholders: Option<&'b DecodePlaceholderMap>) -> Self { Decoder{ read, index: 0, buf: Box::new(PeekState::Empty), placeholders, read_annotations: true, } } pub fn set_read_annotations(&mut self, read_annotations: bool) { self.read_annotations = read_annotations } fn prime(&mut self) -> Result<()> { match *self.buf { PeekState::Empty => { let bs = &mut [0]; *self.buf = match self.read.read(bs)? { 0 => PeekState::Eof, 1 => { self.index += 1; PeekState::Full(bs[0]) }, _ => panic!("buffer overrun") } } PeekState::Eof => (), PeekState::Full(_) => (), } Ok(()) } pub fn skip(&mut self) -> Result<()> { self.prime()?; *self.buf = PeekState::Empty; Ok(()) } pub fn peek(&mut self) -> Result { self.prime()?; match *self.buf { PeekState::Full(v) => Ok(v), PeekState::Eof => Err(Error::Eof), PeekState::Empty => unreachable!() } } pub fn read(&mut self) -> Result { let v = self.peek()?; self.skip()?; Ok(v) } pub fn readbytes(&mut self, bs: &mut [u8]) -> Result<()> { if *self.buf != PeekState::Empty { unreachable!(); } match self.read.read_exact(bs) { Ok(()) => { self.index += bs.len(); Ok(()) } Err(e) => if e.kind() == std::io::ErrorKind::UnexpectedEof { Err(Error::Eof) } else { Err(Error::from(e)) } } } pub fn decodeop(b: u8) -> Result<(Op, u8)> { Ok((Op::try_from(b >> 4)?, b & 15)) } pub fn nextop(&mut self) -> Result<(Op, u8)> { Self::decodeop(self.read()?) } pub fn varint(&mut self) -> Result { 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 { if arg < 15 { Ok(usize::from(arg)) } else { self.varint() } } pub fn peekend(&mut self) -> Result { if self.peek()? == 4 { self.skip()?; Ok(true) } else { Ok(false) } } pub fn decodebinary(minor: AtomMinor, bs: Vec) -> Result { Ok(match minor { AtomMinor::SignedInteger => Value::from(decodeint(&bs)).wrap(), AtomMinor::String => Value::from(std::str::from_utf8(&bs)?).wrap(), AtomMinor::ByteString => Value::from(&bs as &[u8]).wrap(), AtomMinor::Symbol => Value::symbol(std::str::from_utf8(&bs)?).wrap(), }) } pub fn decodecompound>>(minor: CompoundMinor, mut pieces: I) -> Result { match minor { CompoundMinor::Record => match pieces.next() { None => Err(Error::Syntax("Too few elements in encoded record")), Some(labelres) => { let label = labelres?; Ok(Value::record(label, pieces.collect::>>()?).wrap()) } }, CompoundMinor::Sequence => { Ok(Value::Sequence(pieces.collect::>>()?).wrap()) } CompoundMinor::Set => { let mut s = Set::new(); for res in pieces { s.insert(res?); } Ok(Value::Set(s).wrap()) } CompoundMinor::Dictionary => { let mut d = Map::new(); while let Some(kres) = pieces.next() { let k = kres?; match pieces.next() { Some(vres) => { d.insert(k, vres?); } None => return Err(Error::Syntax("Missing dictionary value")), } } Ok(Value::Dictionary(d).wrap()) } } } pub fn binarystream(&mut self, minor: AtomMinor) -> Result { let mut bs: Vec = Vec::new(); while !self.peekend()? { match self.next()?.value().as_bytestring() { Some(chunk) => bs.extend_from_slice(chunk), None => return Err(Error::Syntax("Unexpected non-binary chunk")), } } Self::decodebinary(minor, bs) } pub fn valuestream(&mut self, minor: CompoundMinor) -> Result { Self::decodecompound(minor, DelimitedStream { decoder: self }) } pub fn next(&mut self) -> Result { loop { return match self.nextop()? { (Op::Misc(0), 0) => Ok(Value::from(false).wrap()), (Op::Misc(0), 1) => Ok(Value::from(true).wrap()), (Op::Misc(0), 2) => { let mut bs: [u8; 4] = Default::default(); self.readbytes(&mut bs)?; Ok(Value::from(f32::from_bits(u32::from_be_bytes(bs.try_into().unwrap()))).wrap()) } (Op::Misc(0), 3) => { let mut bs: [u8; 8] = Default::default(); self.readbytes(&mut bs)?; Ok(Value::from(f64::from_bits(u64::from_be_bytes(bs.try_into().unwrap()))).wrap()) } (Op::Misc(0), 5) => { if self.read_annotations { let mut annotations = vec![self.next()?]; while Self::decodeop(self.peek()?).ok() == Some((Op::Misc(0), 5)) { self.skip()?; annotations.push(self.next()?); } let v = self.next()?; assert!(v.annotations().is_empty()); Ok(N::wrap_ann(annotations, v.value_owned())) } else { self.next()?; self.next() } } (Op::Misc(0), _) => Err(Error::Syntax("Invalid format A encoding")), (Op::Misc(1), arg) => { let n = self.wirelength(arg)?; match self.placeholders.and_then(|m| m.get(&n)) { Some(v) => Ok(v.clone().wrap()), None => Err(Error::Syntax("Invalid Preserves placeholder")), } } (Op::Misc(2), arg) => { match Op::try_from(arg)? { Op::Atom(minor) => self.binarystream(minor), Op::Compound(minor) => self.valuestream(minor), _ => Err(Error::Syntax("Invalid format C start byte")), } } (Op::Misc(3), arg) => { let n = if arg > 12 { i32::from(arg) - 16 } else { i32::from(arg) }; Ok(Value::from(n).wrap()) } (Op::Misc(_), _) => unreachable!(), (Op::Atom(minor), arg) => { let count = self.wirelength(arg)?; let mut bs = vec![0; count]; self.readbytes(&mut bs)?; Self::decodebinary(minor, bs) } (Op::Compound(minor), arg) => { let count = self.wirelength(arg)?; Self::decodecompound(minor, CountedStream { count, decoder: self }) } (Op::Reserved(3), 15) => continue, (Op::Reserved(_), _) => Err(InvalidOp.into()), } } } }