use num::bigint::BigInt; use num::traits::cast::{FromPrimitive, ToPrimitive}; use std::borrow::Cow; use std::convert::TryFrom; use std::convert::TryInto; use std::io::{Read, Error}; use std::marker::PhantomData; use super::constants::{Op, InvalidOp, AtomMinor, CompoundMinor}; use super::signed_integer::SignedInteger; use super::value::{Value, NestedValue, IOValue, FALSE, TRUE, Map, Set, Record, Annotations}; use crate::error::{self, ExpectedKind, Received, is_eof_io_error, io_eof, io_syntax_error}; pub type IOResult = std::result::Result; pub type ReaderResult = std::result::Result; #[derive(Debug)] pub struct CompoundBody { minor: CompoundMinor, limit: CompoundLimit, } #[derive(Debug)] pub enum CompoundLimit { Counted(usize), Streaming, Finished, } impl CompoundBody { pub fn counted(minor: CompoundMinor, size: usize) -> Self { CompoundBody { minor, limit: CompoundLimit::Counted(size) } } pub fn streaming(minor: CompoundMinor) -> Self { CompoundBody { minor, limit: CompoundLimit::Streaming } } pub fn more_expected<'de, R: Reader<'de>>(&mut self, read: &mut R) -> ReaderResult { match self.limit { CompoundLimit::Counted(ref mut n) => if *n == 0 { read.close_compound_counted(self.minor)?; self.limit = CompoundLimit::Finished; Ok(false) } else { *n = *n - 1; Ok(true) }, CompoundLimit::Streaming => Ok(!read.close_compound_stream(self.minor)?), CompoundLimit::Finished => Ok(false), } } pub fn next_symbol<'de, R: Reader<'de>>(&mut self, read: &mut R) -> ReaderResult>> { match self.more_expected(read)? { false => Ok(None), true => Ok(Some(read.next_symbol()?)), } } pub fn next_value<'de, R: Reader<'de>>(&mut self, read: &mut R, read_annotations: bool) -> ReaderResult> { match self.more_expected(read)? { false => Ok(None), true => Ok(Some(read.demand_next(read_annotations)?.into_owned())), } } pub fn remainder<'de, R: Reader<'de>>(&mut self, read: &mut R, read_annotations: bool) -> ReaderResult> { let mut result = Vec::new(); while let Some(v) = self.next_value(read, read_annotations)? { result.push(v); } Ok(result) } pub fn skip_remainder<'de, R: Reader<'de>>(&mut self, read: &mut R) -> ReaderResult<()> { while let true = self.more_expected(read)? { read.skip_value()?; } Ok(()) } pub fn ensure_more_expected<'de, R: Reader<'de>>(&mut self, read: &mut R) -> ReaderResult<()> { if self.more_expected(read)? { Ok(()) } else { Err(error::Error::MissingItem) } } pub fn ensure_complete<'de, R: Reader<'de>>(&mut self, read: &mut R) -> ReaderResult<()> { if self.more_expected(read)? { Err(error::Error::MissingCloseDelimiter) } else { Ok(()) } } } pub trait Reader<'de> { fn next(&mut self, read_annotations: bool) -> IOResult>>; fn open_record(&mut self, arity: Option) -> ReaderResult; fn open_sequence_or_set(&mut self) -> ReaderResult; fn open_sequence(&mut self) -> ReaderResult; fn open_set(&mut self) -> ReaderResult; fn open_dictionary(&mut self) -> ReaderResult; fn close_compound_counted(&mut self, minor: CompoundMinor) -> ReaderResult<()>; fn close_compound_stream(&mut self, minor: CompoundMinor) -> ReaderResult; //--------------------------------------------------------------------------- fn skip_value(&mut self) -> IOResult<()> { // TODO efficient skipping in specific impls of this trait let _ = self.demand_next(false)?; Ok(()) } fn demand_next(&mut self, read_annotations: bool) -> IOResult> { match self.next(read_annotations)? { None => Err(io_eof()), Some(v) => Ok(v) } } fn next_boolean(&mut self) -> ReaderResult { self.demand_next(false)?.value().to_boolean() } fn next_i8(&mut self) -> ReaderResult { self.demand_next(false)?.value().to_i8() } fn next_u8(&mut self) -> ReaderResult { self.demand_next(false)?.value().to_u8() } fn next_i16(&mut self) -> ReaderResult { self.demand_next(false)?.value().to_i16() } fn next_u16(&mut self) -> ReaderResult { self.demand_next(false)?.value().to_u16() } fn next_i32(&mut self) -> ReaderResult { self.demand_next(false)?.value().to_i32() } fn next_u32(&mut self) -> ReaderResult { self.demand_next(false)?.value().to_u32() } fn next_i64(&mut self) -> ReaderResult { self.demand_next(false)?.value().to_i64() } fn next_u64(&mut self) -> ReaderResult { self.demand_next(false)?.value().to_u64() } fn next_i128(&mut self) -> ReaderResult { self.demand_next(false)?.value().to_i128() } fn next_u128(&mut self) -> ReaderResult { self.demand_next(false)?.value().to_u128() } fn next_float(&mut self) -> ReaderResult { self.demand_next(false)?.value().to_float() } fn next_double(&mut self) -> ReaderResult { self.demand_next(false)?.value().to_double() } fn next_char(&mut self) -> ReaderResult { self.demand_next(false)?.value().to_char() } fn next_str(&mut self) -> ReaderResult> { Ok(Cow::Owned(self.demand_next(false)?.value().to_string()?.to_owned())) } fn next_bytestring(&mut self) -> ReaderResult> { Ok(Cow::Owned(self.demand_next(false)?.value().to_bytestring()?.to_owned())) } fn next_symbol(&mut self) -> ReaderResult> { Ok(Cow::Owned(self.demand_next(false)?.value().to_symbol()?.to_owned())) } fn open_option(&mut self) -> ReaderResult<(bool, CompoundBody)> where Self: Sized { let mut compound_body = self.open_record(None)?; let label: &str = &compound_body.next_symbol(self)?.ok_or(error::Error::MissingItem)?; match label { "None" => Ok((false, compound_body)), "Some" => Ok((true, compound_body)), _ => Err(error::Error::Expected(ExpectedKind::Option, Received::ReceivedRecordWithLabel(label.to_owned()))), } } fn open_simple_record(&mut self, name: &str, arity: Option) -> ReaderResult where Self: Sized { let mut compound_body = self.open_record(arity)?; let label: &str = &compound_body.next_symbol(self)?.ok_or(error::Error::MissingItem)?; if label == name { Ok(compound_body) } else { Err(error::Error::Expected(ExpectedKind::SimpleRecord(name.to_owned(), arity), Received::ReceivedRecordWithLabel(label.to_owned()))) } } } impl<'r, 'de, R: Reader<'de>> Reader<'de> for &'r mut R { fn next(&mut self, read_annotations: bool) -> IOResult>> { (*self).next(read_annotations) } fn open_record(&mut self, arity: Option) -> ReaderResult { (*self).open_record(arity) } fn open_sequence_or_set(&mut self) -> ReaderResult { (*self).open_sequence_or_set() } fn open_sequence(&mut self) -> ReaderResult { (*self).open_sequence() } fn open_set(&mut self) -> ReaderResult { (*self).open_set() } fn open_dictionary(&mut self) -> ReaderResult { (*self).open_dictionary() } fn close_compound_counted(&mut self, minor: CompoundMinor) -> ReaderResult<()> { (*self).close_compound_counted(minor) } fn close_compound_stream(&mut self, minor: CompoundMinor) -> ReaderResult { (*self).close_compound_stream(minor) } } pub trait BinarySource<'de> { fn skip(&mut self) -> IOResult<()>; fn peek(&mut self) -> IOResult; fn readbytes(&mut self, count: usize) -> IOResult>; fn readbytes_into(&mut self, bs: &mut [u8]) -> IOResult<()>; } pub struct IOBinarySource<'a, R: Read> { pub read: &'a mut R, pub buf: Option, } impl<'a, R: Read> IOBinarySource<'a, R> { pub fn new(read: &'a mut R) -> Self { IOBinarySource { read, buf: None } } } impl<'de, 'a, R: Read> BinarySource<'de> for IOBinarySource<'a, R> { fn skip(&mut self) -> IOResult<()> { if let None = self.buf { unreachable!(); } self.buf = None; Ok(()) } fn peek(&mut self) -> IOResult { match self.buf { Some(b) => Ok(b), None => { let b = &mut [0]; match self.read.read(b)? { 0 => Err(io_eof()), 1 => { self.buf = Some(b[0]); Ok(b[0]) } _ => unreachable!(), } } } } fn readbytes(&mut self, count: usize) -> IOResult> { if let Some(_) = self.buf { unreachable!(); } let mut bs = vec![0; count]; self.read.read_exact(&mut bs)?; Ok(Cow::Owned(bs)) } fn readbytes_into(&mut self, bs: &mut [u8]) -> IOResult<()> { if let Some(_) = self.buf { unreachable!(); } self.read.read_exact(bs) } } pub struct BytesBinarySource<'de> { pub bytes: &'de [u8], pub index: usize, } impl<'de> BytesBinarySource<'de> { pub fn new(bytes: &'de [u8]) -> Self { BytesBinarySource { bytes, index: 0 } } } impl<'de> BinarySource<'de> for BytesBinarySource<'de> { fn skip(&mut self) -> IOResult<()> { if self.index >= self.bytes.len() { unreachable!(); } self.index += 1; Ok(()) } fn peek(&mut self) -> IOResult { if self.index >= self.bytes.len() { Err(io_eof()) } else { Ok(self.bytes[self.index]) } } fn readbytes(&mut self, count: usize) -> IOResult> { if self.index + count > self.bytes.len() { Err(io_eof()) } else { let bs = &self.bytes[self.index..self.index+count]; self.index += count; Ok(Cow::Borrowed(bs)) } } fn readbytes_into(&mut self, bs: &mut [u8]) -> IOResult<()> { let count = bs.len(); if self.index + count > self.bytes.len() { Err(io_eof()) } else { bs.copy_from_slice(&self.bytes[self.index..self.index+count]); self.index += count; Ok(()) } } } pub struct BinaryReader<'de, S: BinarySource<'de>> { pub source: S, phantom: PhantomData<&'de ()>, } impl<'de, S: BinarySource<'de>> BinarySource<'de> for BinaryReader<'de, S> { fn skip(&mut self) -> IOResult<()> { self.source.skip() } fn peek(&mut self) -> IOResult { self.source.peek() } fn readbytes(&mut self, count: usize) -> IOResult> { self.source.readbytes(count) } fn readbytes_into(&mut self, bs: &mut [u8]) -> IOResult<()> { self.source.readbytes_into(bs) } } pub fn from_bytes<'de>(bytes: &'de [u8]) -> BinaryReader<'de, BytesBinarySource<'de>> { BinaryReader::new(BytesBinarySource::new(bytes)) } pub fn from_read<'de, 'a, IOR: std::io::Read>(read: &'a mut IOR) -> BinaryReader<'de, IOBinarySource<'a, IOR>> { BinaryReader::new(IOBinarySource::new(read)) } fn out_of_range>(i: I) -> error::Error { error::Error::NumberOutOfRange(i.into()) } impl<'de, S: BinarySource<'de>> BinaryReader<'de, S> { pub fn new(source: S) -> Self { BinaryReader { source, phantom: PhantomData } } fn read(&mut self) -> IOResult { let v = self.peek()?; self.skip()?; Ok(v) } fn expected(&mut self, k: ExpectedKind) -> error::Error { match self.demand_next(true) { Ok(v) => error::Error::Expected(k, Received::ReceivedOtherValue(v.into_owned())), Err(e) => e.into() } } fn varint(&mut self) -> IOResult { let v = self.read()?; if v < 128 { Ok(usize::from(v)) } else { Ok(self.varint()? * 128 + usize::from(v - 128)) } } fn wirelength(&mut self, arg: u8) -> IOResult { if arg < 15 { Ok(usize::from(arg)) } else { self.varint() } } fn peekend(&mut self) -> IOResult { if self.peek()? == 4 { self.skip()?; Ok(true) } else { Ok(false) } } fn gather_chunks(&mut self) -> IOResult> { let mut bs = Vec::with_capacity(256); while !self.peekend()? { match decodeop(self.peek()?)? { (Op::Atom(AtomMinor::ByteString), arg) => { self.skip()?; let count = self.wirelength(arg)?; if count == 0 { return Err(io_syntax_error("Empty binary chunks are forbidden")); } bs.extend_from_slice(&self.readbytes(count)?) }, _ => return Err(io_syntax_error("Unexpected non-format-B-ByteString chunk")) } } Ok(bs) } fn peek_next_nonannotation_op(&mut self) -> ReaderResult<(Op, u8)> { loop { match decodeop(self.peek()?)? { (Op::Misc(0), 5) => { self.skip()?; self.skip_value()?; }, other => return Ok(other), } } } fn next_atomic(&mut self, minor: AtomMinor, k: ExpectedKind) -> ReaderResult> { match self.peek_next_nonannotation_op()? { (Op::Atom(actual_minor), arg) if actual_minor == minor => { self.skip()?; let count = self.wirelength(arg)?; Ok(self.readbytes(count)?) } (Op::Misc(2), arg) => match Op::try_from(arg)? { Op::Atom(actual_minor) if actual_minor == minor => { self.skip()?; Ok(Cow::Owned(self.gather_chunks()?)) } _ => Err(self.expected(k)), }, _ => Err(self.expected(k)), } } fn next_compound(&mut self, minor: CompoundMinor, k: ExpectedKind) -> ReaderResult { match self.peek_next_nonannotation_op()? { (Op::Compound(actual_minor), arg) if actual_minor == minor => { self.skip()?; Ok(CompoundBody::counted(minor, self.wirelength(arg)?)) } (Op::Misc(2), arg) => match Op::try_from(arg)? { Op::Compound(actual_minor) if actual_minor == minor => { self.skip()?; Ok(CompoundBody::streaming(minor)) } _ => Err(self.expected(k)), }, _ => Err(self.expected(k)), } } fn read_number_format_b(&mut self, count: usize) -> IOResult { if count == 0 { return Ok(SignedInteger::from(0 as i128)); } if count > 16 { let bs = self.readbytes(count)?; if (bs[0] & 0x80) == 0 { // Positive or zero. let mut i = 0; while i < count && bs[i] == 0 { i = i + 1; } if count - i <= 16 { Ok(SignedInteger::from(u128::from_be_bytes(bs[bs.len() - 16..].try_into().unwrap()))) } else { Ok(SignedInteger::from(Cow::Owned(BigInt::from_bytes_be(num::bigint::Sign::Plus, &bs[i..])))) } } else { // Negative. let mut i = 0; while i < count && bs[i] == 0xff { i = i + 1; } if count - i <= 16 { Ok(SignedInteger::from(i128::from_be_bytes(bs[bs.len() - 16..].try_into().unwrap()))) } else { Ok(SignedInteger::from(Cow::Owned(BigInt::from_signed_bytes_be(&bs)))) } } } else { let first_byte = self.read()?; let prefix_byte = if (first_byte & 0x80) == 0 { 0x00 } else { 0xff }; let mut bs = [prefix_byte; 16]; bs[16 - count] = first_byte; self.readbytes_into(&mut bs[16 - (count - 1)..])?; Ok(SignedInteger::from(i128::from_be_bytes(bs))) } } fn next_unsigned(&mut self, f: F) -> ReaderResult where F: FnOnce(u128) -> Option { match self.peek_next_nonannotation_op()? { (Op::Misc(3), arg) => { self.skip()?; if arg > 12 { Err(out_of_range((arg as i8) - 16)) } else { f(arg as u128).ok_or_else(|| out_of_range(arg)) } } (Op::Atom(AtomMinor::SignedInteger), arg) => { self.skip()?; let count = self.wirelength(arg)?; let n = &self.read_number_format_b(count)?; let i = n.try_into().or_else(|_| Err(out_of_range(n)))?; f(i).ok_or_else(|| out_of_range(i)) } _ => { let n_value = self.demand_next(false)?; let n = n_value.value().to_signedinteger()?; let i = n.try_into().or_else(|_| Err(out_of_range(n)))?; f(i).ok_or_else(|| out_of_range(i)) } } } fn next_signed(&mut self, f: F) -> ReaderResult where F: FnOnce(i128) -> Option { match self.peek_next_nonannotation_op()? { (Op::Misc(3), arg) => { self.skip()?; let n = arg as i128; let n = if n > 12 { n - 16 } else { n }; f(n).ok_or_else(|| out_of_range(n)) } (Op::Atom(AtomMinor::SignedInteger), arg) => { self.skip()?; let count = self.wirelength(arg)?; let n = &self.read_number_format_b(count)?; let i = n.try_into().or_else(|_| Err(out_of_range(n)))?; f(i).ok_or_else(|| out_of_range(i)) } _ => { let n_value = self.demand_next(false)?; let n = n_value.value().to_signedinteger()?; let i = n.try_into().or_else(|_| Err(out_of_range(n)))?; f(i).ok_or_else(|| out_of_range(i)) } } } } impl<'de, S: BinarySource<'de>> Reader<'de> for BinaryReader<'de, S> { fn next(&mut self, read_annotations: bool) -> IOResult>> { match self.peek() { Err(e) if is_eof_io_error(&e) => return Ok(None), Err(e) => return Err(e), Ok(_) => (), } loop { return Ok(Some(match decodeop(self.read()?)? { (Op::Misc(0), 0) => Cow::Borrowed(&FALSE), (Op::Misc(0), 1) => Cow::Borrowed(&TRUE), (Op::Misc(0), 2) => { let bs: &[u8] = &self.readbytes(4)?; Cow::Owned(Value::from(f32::from_bits(u32::from_be_bytes(bs.try_into().unwrap()))).wrap()) } (Op::Misc(0), 3) => { let bs: &[u8] = &self.readbytes(8)?; Cow::Owned(Value::from(f64::from_bits(u64::from_be_bytes(bs.try_into().unwrap()))).wrap()) } (Op::Misc(0), 5) => { if read_annotations { let mut annotations = vec![self.demand_next(read_annotations)?.into_owned()]; while decodeop(self.peek()?)? == (Op::Misc(0), 5) { self.skip()?; annotations.push(self.demand_next(read_annotations)?.into_owned()); } let (existing_annotations, v) = self.demand_next(read_annotations)?.into_owned().pieces(); annotations.extend_from_slice(existing_annotations.slice()); Cow::Owned(IOValue::wrap(Annotations::new(Some(annotations)), v)) } else { self.skip_value()?; continue; } } (Op::Misc(0), _) => Err(io_syntax_error("Invalid format A encoding"))?, (Op::Misc(1), _) => Err(io_syntax_error("Invalid format A encoding"))?, (Op::Misc(2), arg) => match Op::try_from(arg)? { Op::Atom(minor) => Cow::Owned(decodebinary(minor, Cow::Owned(self.gather_chunks()?))?), Op::Compound(minor) => Cow::Owned(decodecompound(minor, DelimitedStream { reader: ConfiguredBinaryReader { reader: self, read_annotations, phantom: PhantomData, }, })?), _ => Err(io_syntax_error("Invalid format C start byte"))?, } (Op::Misc(3), arg) => { let n = if arg > 12 { i32::from(arg) - 16 } else { i32::from(arg) }; // TODO: prebuild these in value.rs Cow::Owned(Value::from(n).wrap()) } (Op::Misc(_), _) => unreachable!(), (Op::Atom(AtomMinor::SignedInteger), arg) => { let count = self.wirelength(arg)?; let n = self.read_number_format_b(count)?; Cow::Owned(Value::SignedInteger(n).wrap()) } (Op::Atom(minor), arg) => { let count = self.wirelength(arg)?; Cow::Owned(decodebinary(minor, self.readbytes(count)?)?) } (Op::Compound(minor), arg) => { let count = self.wirelength(arg)?; Cow::Owned(decodecompound(minor, CountedStream { reader: ConfiguredBinaryReader { reader: self, read_annotations, phantom: PhantomData, }, count, })?) } (Op::Reserved(3), 15) => continue, (Op::Reserved(_), _) => return Err(InvalidOp.into()), })) } } fn open_record(&mut self, arity: Option) -> ReaderResult { if let Some(expected_arity) = arity { let compound_format = self.next_compound(CompoundMinor::Record, ExpectedKind::Record(arity))?; if let CompoundLimit::Counted(count) = compound_format.limit { if count != expected_arity + 1 /* we add 1 for the label */ { return Err(error::Error::Expected(ExpectedKind::Record(arity), Received::ReceivedSomethingElse)); } } Ok(compound_format) } else { self.next_compound(CompoundMinor::Record, ExpectedKind::Record(None)) } } fn open_sequence_or_set(&mut self) -> ReaderResult { match self.peek_next_nonannotation_op()? { (Op::Compound(minor), arg) if CompoundMinor::Sequence == minor || CompoundMinor::Set == minor => { self.skip()?; Ok(CompoundBody::counted(minor, self.wirelength(arg)?)) } (Op::Misc(2), arg) => match Op::try_from(arg)? { Op::Compound(minor) if CompoundMinor::Sequence == minor || CompoundMinor::Set == minor => { self.skip()?; Ok(CompoundBody::streaming(minor)) } _ => Err(self.expected(ExpectedKind::SequenceOrSet)), } _ => Err(self.expected(ExpectedKind::SequenceOrSet)), } } fn open_sequence(&mut self) -> ReaderResult { self.next_compound(CompoundMinor::Sequence, ExpectedKind::Sequence) } fn open_set(&mut self) -> ReaderResult { self.next_compound(CompoundMinor::Set, ExpectedKind::Set) } fn open_dictionary(&mut self) -> ReaderResult { self.next_compound(CompoundMinor::Dictionary, ExpectedKind::Dictionary) } fn close_compound_counted(&mut self, _minor: CompoundMinor) -> ReaderResult<()> { // Nothing to do -- no close delimiter to consume Ok(()) } fn close_compound_stream(&mut self, _minor: CompoundMinor) -> ReaderResult { Ok(self.peekend()?) } fn next_boolean(&mut self) -> ReaderResult { match self.peek_next_nonannotation_op()? { (Op::Misc(0), 0) => { self.skip()?; Ok(false) } (Op::Misc(0), 1) => { self.skip()?; Ok(true) } _ => Err(self.expected(ExpectedKind::Boolean)), } } fn next_i8(&mut self) -> ReaderResult { self.next_signed(|n| n.to_i8()) } fn next_i16(&mut self) -> ReaderResult { self.next_signed(|n| n.to_i16()) } fn next_i32(&mut self) -> ReaderResult { self.next_signed(|n| n.to_i32()) } fn next_i64(&mut self) -> ReaderResult { self.next_signed(|n| n.to_i64()) } fn next_i128(&mut self) -> ReaderResult { self.next_signed(|n| n.to_i128()) } fn next_u8(&mut self) -> ReaderResult { self.next_unsigned(|n| n.to_u8()) } fn next_u16(&mut self) -> ReaderResult { self.next_unsigned(|n| n.to_u16()) } fn next_u32(&mut self) -> ReaderResult { self.next_unsigned(|n| n.to_u32()) } fn next_u64(&mut self) -> ReaderResult { self.next_unsigned(|n| n.to_u64()) } fn next_u128(&mut self) -> ReaderResult { self.next_unsigned(|n| n.to_u128()) } fn next_float(&mut self) -> ReaderResult { match self.peek_next_nonannotation_op()? { (Op::Misc(0), 2) => { self.skip()?; let bs: &[u8] = &self.readbytes(4)?; Ok(f32::from_bits(u32::from_be_bytes(bs.try_into().unwrap()))) }, (Op::Misc(0), 3) => { self.skip()?; let bs: &[u8] = &self.readbytes(8)?; Ok(f64::from_bits(u64::from_be_bytes(bs.try_into().unwrap())) as f32) }, _ => Err(self.expected(ExpectedKind::Float)), } } fn next_double(&mut self) -> ReaderResult { match self.peek_next_nonannotation_op()? { (Op::Misc(0), 2) => { self.skip()?; let bs: &[u8] = &self.readbytes(4)?; Ok(f32::from_bits(u32::from_be_bytes(bs.try_into().unwrap())) as f64) }, (Op::Misc(0), 3) => { self.skip()?; let bs: &[u8] = &self.readbytes(8)?; Ok(f64::from_bits(u64::from_be_bytes(bs.try_into().unwrap()))) }, _ => Err(self.expected(ExpectedKind::Double)), } } fn next_str(&mut self) -> ReaderResult> { Ok(decodestr(self.next_atomic(AtomMinor::String, ExpectedKind::Symbol)?)?) } fn next_bytestring(&mut self) -> ReaderResult> { self.next_atomic(AtomMinor::ByteString, ExpectedKind::Symbol) } fn next_symbol(&mut self) -> ReaderResult> { Ok(decodestr(self.next_atomic(AtomMinor::Symbol, ExpectedKind::Symbol)?)?) } } struct ConfiguredBinaryReader<'de, 'a, S: BinarySource<'de>> { reader: &'a mut BinaryReader<'de, S>, read_annotations: bool, phantom: PhantomData<&'de ()>, } struct CountedStream<'de, 'a, S: BinarySource<'de>> { reader: ConfiguredBinaryReader<'de, 'a, S>, count: usize, } impl<'de, 'a, S: BinarySource<'de>> Iterator for CountedStream<'de, 'a, S> { type Item = IOResult>; fn next(&mut self) -> Option { if self.count == 0 { return None } self.count -= 1; Some(self.reader.reader.demand_next(self.reader.read_annotations)) } } struct DelimitedStream<'de, 'a, S: BinarySource<'de>> { reader: ConfiguredBinaryReader<'de, 'a, S>, } impl<'de, 'a, S: BinarySource<'de>> Iterator for DelimitedStream<'de, 'a, S> { type Item = IOResult>; fn next(&mut self) -> Option { match self.reader.reader.peekend() { Err(e) => Some(Err(e)), Ok(true) => None, Ok(false) => Some(self.reader.reader.demand_next(self.reader.read_annotations)), } } } pub fn decodeop(b: u8) -> IOResult<(Op, u8)> { Ok((Op::try_from(b >> 4)?, b & 15)) } pub fn decodestr<'de>(cow: Cow<'de, [u8]>) -> IOResult> { match cow { Cow::Borrowed(bs) => Ok(Cow::Borrowed(std::str::from_utf8(bs).map_err(|_| io_syntax_error("Invalid UTF-8"))?)), Cow::Owned(bs) => Ok(Cow::Owned(std::str::from_utf8(&bs).map_err(|_| io_syntax_error("Invalid UTF-8"))?.to_owned())), } } pub fn decodebinary<'de>(minor: AtomMinor, bs: Cow<'de, [u8]>) -> IOResult { Ok(match minor { AtomMinor::SignedInteger => Value::from(&BigInt::from_signed_bytes_be(&bs)).wrap(), AtomMinor::String => Value::String(decodestr(bs)?.into_owned()).wrap(), AtomMinor::ByteString => Value::ByteString(bs.into_owned()).wrap(), AtomMinor::Symbol => Value::symbol(&decodestr(bs)?).wrap(), }) } pub fn decodecompound<'de, I: Iterator>>>( minor: CompoundMinor, mut iter: I ) -> IOResult { match minor { CompoundMinor::Record => { let vs = iter.map(|r| r.map(|c| c.into_owned())).collect::>>()?; if vs.len() < 1 { Err(io_syntax_error("Too few elements in encoded record")) } else { Ok(Value::Record(Record(vs)).wrap()) } } CompoundMinor::Sequence => { let vs = iter.map(|r| r.map(|c| c.into_owned())).collect::>>()?; Ok(Value::Sequence(vs).wrap()) } CompoundMinor::Set => { let mut s = Set::new(); for res in iter { s.insert(res?.into_owned()); } Ok(Value::Set(s).wrap()) } CompoundMinor::Dictionary => { let mut d = Map::new(); while let Some(kres) = iter.next() { let k = kres?.into_owned(); match iter.next() { Some(vres) => { let v = vres?.into_owned(); d.insert(k, v); } None => return Err(io_syntax_error("Missing dictionary value")), } } Ok(Value::Dictionary(d).wrap()) } } }