Packed
This commit is contained in:
parent
1fc7b5b404
commit
66b37bd70a
|
@ -36,6 +36,7 @@ pub enum ExpectedKind {
|
|||
|
||||
Option,
|
||||
UnicodeScalar,
|
||||
Annotation,
|
||||
}
|
||||
|
||||
impl From<io::Error> for Error {
|
||||
|
|
|
@ -2,14 +2,23 @@ pub mod boundary;
|
|||
pub mod domain;
|
||||
pub mod error;
|
||||
pub mod float;
|
||||
pub mod hex;
|
||||
pub mod packed;
|
||||
pub mod reader;
|
||||
pub mod repr;
|
||||
pub mod signed_integer;
|
||||
pub mod source;
|
||||
// pub mod text;
|
||||
pub mod types;
|
||||
pub mod writer;
|
||||
|
||||
pub use domain::*;
|
||||
pub use packed::PackedReader;
|
||||
pub use packed::PackedWriter;
|
||||
pub use packed::annotated_from_bytes;
|
||||
pub use packed::annotated_iovalue_from_bytes;
|
||||
pub use packed::from_bytes;
|
||||
pub use packed::iovalue_from_bytes;
|
||||
pub use reader::Reader;
|
||||
pub use repr::Annotations;
|
||||
pub use repr::Atom;
|
||||
|
@ -28,6 +37,12 @@ pub use signed_integer::SignedInteger;
|
|||
pub use source::BinarySource;
|
||||
pub use source::BytesBinarySource;
|
||||
pub use source::IOBinarySource;
|
||||
// pub use text::TextReader;
|
||||
// pub use text::TextWriter;
|
||||
// pub use text::annotated_from_str;
|
||||
// pub use text::annotated_iovalue_from_str;
|
||||
// pub use text::from_str;
|
||||
// pub use text::iovalue_from_str;
|
||||
pub use types::AtomClass;
|
||||
pub use types::CompoundClass;
|
||||
pub use types::ValueClass;
|
||||
|
|
|
@ -7,26 +7,32 @@ pub use writer::PackedWriter;
|
|||
|
||||
use std::io;
|
||||
|
||||
use super::{BinarySource, DomainDecode, IOValue, IOValueDomainCodec, NestedValue, Reader};
|
||||
use crate::BinarySource;
|
||||
use crate::BytesBinarySource;
|
||||
use crate::Domain;
|
||||
use crate::DomainDecode;
|
||||
use crate::IOValue;
|
||||
use crate::Reader;
|
||||
use crate::Value;
|
||||
|
||||
pub fn from_bytes<'de, N: NestedValue, Dec: DomainDecode<N::Embedded>>(
|
||||
pub fn from_bytes<'de, D: Domain + 'static, Dec: DomainDecode<D>>(
|
||||
bs: &'de [u8],
|
||||
decode_embedded: &mut Dec,
|
||||
) -> io::Result<N> {
|
||||
super::BytesBinarySource::new(bs).packed().demand_next_domain(false, decode_embedded)
|
||||
) -> io::Result<Box<dyn Value<D>>> {
|
||||
BytesBinarySource::new(bs).packed().next(false, decode_embedded)
|
||||
}
|
||||
|
||||
pub fn iovalue_from_bytes(bs: &[u8]) -> io::Result<IOValue> {
|
||||
from_bytes(bs, &mut IOValueDomainCodec)
|
||||
super::BytesBinarySource::new(bs).packed().next_iovalue(false)
|
||||
}
|
||||
|
||||
pub fn annotated_from_bytes<'de, N: NestedValue, Dec: DomainDecode<N::Embedded>>(
|
||||
pub fn annotated_from_bytes<'de, D: Domain + 'static, Dec: DomainDecode<D>>(
|
||||
bs: &'de [u8],
|
||||
decode_embedded: &mut Dec,
|
||||
) -> io::Result<N> {
|
||||
super::BytesBinarySource::new(bs).packed().demand_next_domain(true, decode_embedded)
|
||||
) -> io::Result<Box<dyn Value<D>>> {
|
||||
super::BytesBinarySource::new(bs).packed().next(true, decode_embedded)
|
||||
}
|
||||
|
||||
pub fn annotated_iovalue_from_bytes(bs: &[u8]) -> io::Result<IOValue> {
|
||||
annotated_from_bytes(bs, &mut IOValueDomainCodec)
|
||||
super::BytesBinarySource::new(bs).packed().next_iovalue(true)
|
||||
}
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
use crate::{ValueClass, AtomClass, Atom};
|
||||
use crate::error::{self, ExpectedKind, io_eof};
|
||||
use crate::value::Domain;
|
||||
|
||||
use num::bigint::BigInt;
|
||||
use num::traits::cast::{FromPrimitive, ToPrimitive};
|
||||
|
@ -13,16 +13,11 @@ use std::marker::PhantomData;
|
|||
use super::constants::Tag;
|
||||
use super::super::{
|
||||
CompoundClass,
|
||||
DomainDecode,
|
||||
Map,
|
||||
NestedValue,
|
||||
Record,
|
||||
Set,
|
||||
Value,
|
||||
|
||||
boundary as B,
|
||||
reader::{
|
||||
Token,
|
||||
NextToken,
|
||||
Reader,
|
||||
ReaderResult,
|
||||
},
|
||||
|
@ -36,13 +31,12 @@ pub struct PackedReader<'de, 'src, S: BinarySource<'de>> {
|
|||
}
|
||||
|
||||
impl<'de, 'src, S: BinarySource<'de>> BinarySource<'de> for PackedReader<'de, 'src, S> {
|
||||
type Mark = S::Mark;
|
||||
#[inline(always)]
|
||||
fn mark(&mut self) -> io::Result<Self::Mark> {
|
||||
fn mark(&mut self) -> io::Result<usize> {
|
||||
self.source.mark()
|
||||
}
|
||||
#[inline(always)]
|
||||
fn restore(&mut self, mark: &Self::Mark) -> io::Result<()> {
|
||||
fn restore(&mut self, mark: usize) -> io::Result<()> {
|
||||
self.source.restore(mark)
|
||||
}
|
||||
#[inline(always)]
|
||||
|
@ -257,38 +251,6 @@ impl<'de, 'src, S: BinarySource<'de>> PackedReader<'de, 'src, S> {
|
|||
}
|
||||
}
|
||||
|
||||
fn gather_annotations<N: NestedValue, Dec: DomainDecode<N::Embedded>>(
|
||||
&mut self,
|
||||
dec: &mut Dec,
|
||||
) -> io::Result<Vec<N>> {
|
||||
let mut annotations = vec![self.demand_next_domain(true, dec)?];
|
||||
while Tag::try_from(self.peek_noeof()?)? == Tag::Annotation {
|
||||
self.skip()?;
|
||||
annotations.push(self.demand_next_domain(true, dec)?);
|
||||
}
|
||||
Ok(annotations)
|
||||
}
|
||||
|
||||
fn skip_annotations(&mut self) -> io::Result<()> {
|
||||
self.skip_value()?;
|
||||
while Tag::try_from(self.peek_noeof()?)? == Tag::Annotation {
|
||||
self.skip()?;
|
||||
self.skip_value()?;
|
||||
}
|
||||
Ok(())
|
||||
}
|
||||
|
||||
fn next_upto_end<N: NestedValue, Dec: DomainDecode<N::Embedded>>(
|
||||
&mut self,
|
||||
read_annotations: bool,
|
||||
dec: &mut Dec,
|
||||
) -> io::Result<Option<N>> {
|
||||
match self.peekend()? {
|
||||
true => Ok(None),
|
||||
false => Ok(Some(self.demand_next_domain(read_annotations, dec)?)),
|
||||
}
|
||||
}
|
||||
|
||||
#[inline(always)]
|
||||
fn decodestr<'a>(&mut self, cow: Cow<'a, [u8]>) -> io::Result<Cow<'a, str>> {
|
||||
match cow {
|
||||
|
@ -301,103 +263,72 @@ impl<'de, 'src, S: BinarySource<'de>> PackedReader<'de, 'src, S> {
|
|||
}
|
||||
|
||||
impl<'de, 'src, S: BinarySource<'de>> Reader<'de> for PackedReader<'de, 'src, S> {
|
||||
fn next_domain<N: NestedValue, Dec: DomainDecode<N::Embedded>>(
|
||||
&mut self,
|
||||
read_annotations: bool,
|
||||
dec: &mut Dec,
|
||||
) -> io::Result<Option<N>> {
|
||||
match self.peek()? {
|
||||
fn peek_class(&mut self) -> io::Result<Option<NextToken>> {
|
||||
match Tag::try_from(match self.peek()? {
|
||||
None => return Ok(None),
|
||||
Some(_) => (),
|
||||
Some(b) => b,
|
||||
})? {
|
||||
Tag::False => Ok(Some(NextToken::Value(ValueClass::Atomic(AtomClass::Boolean)))),
|
||||
Tag::True => Ok(Some(NextToken::Value(ValueClass::Atomic(AtomClass::Boolean)))),
|
||||
Tag::Float => Ok(Some(NextToken::Value(ValueClass::Atomic(AtomClass::Float)))),
|
||||
Tag::Double => Ok(Some(NextToken::Value(ValueClass::Atomic(AtomClass::Double)))),
|
||||
Tag::Annotation => Ok(Some(NextToken::Annotation)),
|
||||
Tag::Embedded => Ok(Some(NextToken::Value(ValueClass::Embedded))),
|
||||
Tag::SmallInteger(_) => Ok(Some(NextToken::Value(ValueClass::Atomic(AtomClass::SignedInteger)))),
|
||||
Tag::MediumInteger(_) => Ok(Some(NextToken::Value(ValueClass::Atomic(AtomClass::SignedInteger)))),
|
||||
Tag::SignedInteger => Ok(Some(NextToken::Value(ValueClass::Atomic(AtomClass::SignedInteger)))),
|
||||
Tag::String => Ok(Some(NextToken::Value(ValueClass::Atomic(AtomClass::String)))),
|
||||
Tag::ByteString => Ok(Some(NextToken::Value(ValueClass::Atomic(AtomClass::ByteString)))),
|
||||
Tag::Symbol => Ok(Some(NextToken::Value(ValueClass::Atomic(AtomClass::Symbol)))),
|
||||
Tag::Record => Ok(Some(NextToken::Value(ValueClass::Compound(CompoundClass::Record)))),
|
||||
Tag::Sequence => Ok(Some(NextToken::Value(ValueClass::Compound(CompoundClass::Sequence)))),
|
||||
Tag::Set => Ok(Some(NextToken::Value(ValueClass::Compound(CompoundClass::Set)))),
|
||||
Tag::Dictionary => Ok(Some(NextToken::Value(ValueClass::Compound(CompoundClass::Dictionary)))),
|
||||
tag @ Tag::End => Err(self.syntax_error(&format!("Invalid tag: {:?}", tag))),
|
||||
}
|
||||
Ok(Some(match Tag::try_from(self.read()?)? {
|
||||
Tag::False => N::new(false),
|
||||
Tag::True => N::new(true),
|
||||
}
|
||||
|
||||
fn next_atom(&mut self) -> ReaderResult<Atom<'de>> {
|
||||
match Tag::try_from(self.read()?)? {
|
||||
Tag::False => Ok(Atom::Boolean(false)),
|
||||
Tag::True => Ok(Atom::Boolean(true)),
|
||||
Tag::Float => {
|
||||
let mut bs = [0; 4];
|
||||
self.readbytes_into(&mut bs)?;
|
||||
Value::from(f32::from_bits(u32::from_be_bytes(bs))).wrap()
|
||||
Ok(Atom::Float(f32::from_bits(u32::from_be_bytes(bs))))
|
||||
}
|
||||
Tag::Double => {
|
||||
let mut bs = [0; 8];
|
||||
self.readbytes_into(&mut bs)?;
|
||||
Value::from(f64::from_bits(u64::from_be_bytes(bs))).wrap()
|
||||
}
|
||||
Tag::Annotation => {
|
||||
if read_annotations {
|
||||
let mut annotations = self.gather_annotations(dec)?;
|
||||
let (existing_annotations, v) = self.demand_next_domain::<N, _>(read_annotations, dec)?.pieces();
|
||||
if let Some(vs) = existing_annotations {
|
||||
annotations.extend_from_slice(&vs[..]);
|
||||
}
|
||||
N::wrap(Some(Box::new(annotations)), v)
|
||||
} else {
|
||||
self.skip_annotations()?;
|
||||
self.demand_next_domain(read_annotations, dec)?
|
||||
}
|
||||
}
|
||||
Tag::Embedded => {
|
||||
Value::Embedded(dec.decode_embedded(self, read_annotations)?).wrap()
|
||||
}
|
||||
Tag::SmallInteger(v) => {
|
||||
// TODO: prebuild these in value.rs
|
||||
Value::from(v).wrap()
|
||||
}
|
||||
Tag::MediumInteger(count) => {
|
||||
let n = self.read_signed_integer(count.into())?;
|
||||
Value::SignedInteger(n).wrap()
|
||||
Ok(Atom::Double(f64::from_bits(u64::from_be_bytes(bs))))
|
||||
}
|
||||
Tag::SmallInteger(v) => Ok(Atom::SignedInteger(v.into())),
|
||||
Tag::MediumInteger(count) => Ok(Atom::SignedInteger(self.read_signed_integer(count.into())?)),
|
||||
Tag::SignedInteger => {
|
||||
let count = self.varint()?;
|
||||
let n = self.read_signed_integer(count)?;
|
||||
Value::SignedInteger(n).wrap()
|
||||
Ok(Atom::SignedInteger(self.read_signed_integer(count)?))
|
||||
}
|
||||
Tag::String => {
|
||||
let count = self.varint()?;
|
||||
let bs = self.readbytes(count)?;
|
||||
Value::String(self.decodestr(bs)?.into_owned()).wrap()
|
||||
Ok(Atom::String(self.decodestr(bs)?))
|
||||
}
|
||||
Tag::ByteString => {
|
||||
let count = self.varint()?;
|
||||
Value::ByteString(self.readbytes(count)?.into_owned()).wrap()
|
||||
Ok(Atom::ByteString(self.readbytes(count)?))
|
||||
}
|
||||
Tag::Symbol => {
|
||||
let count = self.varint()?;
|
||||
let bs = self.readbytes(count)?;
|
||||
Value::Symbol(self.decodestr(bs)?.into_owned()).wrap()
|
||||
Ok(Atom::Symbol(self.decodestr(bs)?))
|
||||
}
|
||||
Tag::Record => {
|
||||
let mut vs = Vec::new();
|
||||
while let Some(v) = self.next_upto_end(read_annotations, dec)? { vs.push(v); }
|
||||
if vs.is_empty() {
|
||||
return Err(self.syntax_error("Too few elements in encoded record"))
|
||||
}
|
||||
Value::Record(Record(vs)).wrap()
|
||||
}
|
||||
Tag::Sequence => {
|
||||
let mut vs = Vec::new();
|
||||
while let Some(v) = self.next_upto_end(read_annotations, dec)? { vs.push(v); }
|
||||
Value::Sequence(vs).wrap()
|
||||
}
|
||||
Tag::Set => {
|
||||
let mut s = Set::new();
|
||||
while let Some(v) = self.next_upto_end(read_annotations, dec)? { s.insert(v); }
|
||||
Value::Set(s).wrap()
|
||||
}
|
||||
Tag::Dictionary => {
|
||||
let mut d = Map::new();
|
||||
while let Some(k) = self.next_upto_end(read_annotations, dec)? {
|
||||
match self.next_upto_end(read_annotations, dec)? {
|
||||
Some(v) => { d.insert(k, v); }
|
||||
None => return Err(self.syntax_error("Missing dictionary value")),
|
||||
}
|
||||
}
|
||||
Value::Dictionary(d).wrap()
|
||||
}
|
||||
tag @ Tag::End => {
|
||||
return Err(self.syntax_error(&format!("Invalid tag: {:?}", tag)));
|
||||
}
|
||||
}))
|
||||
_ => Err(self.syntax_error("Expected atomic value"))?,
|
||||
}
|
||||
}
|
||||
|
||||
#[inline(always)]
|
||||
fn boundary(&mut self, _b: &B::Type) -> ReaderResult<()> {
|
||||
Ok(())
|
||||
}
|
||||
|
||||
#[inline(always)]
|
||||
|
@ -420,11 +351,6 @@ impl<'de, 'src, S: BinarySource<'de>> Reader<'de> for PackedReader<'de, 'src, S>
|
|||
self.next_compound(Tag::Dictionary, ExpectedKind::Dictionary)
|
||||
}
|
||||
|
||||
#[inline(always)]
|
||||
fn boundary(&mut self, _b: &B::Type) -> ReaderResult<()> {
|
||||
Ok(())
|
||||
}
|
||||
|
||||
#[inline(always)]
|
||||
fn close_compound(&mut self, _b: &mut B::Type, _i: &B::Item) -> ReaderResult<bool> {
|
||||
Ok(self.peekend()?)
|
||||
|
@ -440,57 +366,16 @@ impl<'de, 'src, S: BinarySource<'de>> Reader<'de> for PackedReader<'de, 'src, S>
|
|||
Ok(())
|
||||
}
|
||||
|
||||
type Mark = S::Mark;
|
||||
|
||||
#[inline(always)]
|
||||
fn mark(&mut self) -> io::Result<Self::Mark> {
|
||||
fn mark(&mut self) -> io::Result<usize> {
|
||||
self.source.mark()
|
||||
}
|
||||
|
||||
#[inline(always)]
|
||||
fn restore(&mut self, mark: &Self::Mark) -> io::Result<()> {
|
||||
fn restore(&mut self, mark: usize) -> io::Result<()> {
|
||||
self.source.restore(mark)
|
||||
}
|
||||
|
||||
fn next_token<D: Domain, Dec: DomainDecode<D>>(
|
||||
&mut self,
|
||||
read_embedded_annotations: bool,
|
||||
decode_embedded: &mut Dec,
|
||||
) -> io::Result<Token<D>> {
|
||||
loop {
|
||||
return Ok(match Tag::try_from(self.peek_noeof()?)? {
|
||||
Tag::Embedded => {
|
||||
self.skip()?;
|
||||
Token::Embedded(decode_embedded.decode_embedded(self, read_embedded_annotations)?)
|
||||
}
|
||||
Tag::False |
|
||||
Tag::True |
|
||||
Tag::Float |
|
||||
Tag::Double |
|
||||
Tag::SmallInteger(_) |
|
||||
Tag::MediumInteger(_) |
|
||||
Tag::SignedInteger |
|
||||
Tag::String |
|
||||
Tag::ByteString |
|
||||
Tag::Symbol =>
|
||||
Token::Atom(self.demand_next_domain(false, decode_embedded)?),
|
||||
|
||||
Tag::Record => { self.skip()?; Token::Compound(CompoundClass::Record) }
|
||||
Tag::Sequence => { self.skip()?; Token::Compound(CompoundClass::Sequence) }
|
||||
Tag::Set => { self.skip()?; Token::Compound(CompoundClass::Set) }
|
||||
Tag::Dictionary => { self.skip()?; Token::Compound(CompoundClass::Dictionary) }
|
||||
|
||||
Tag::End => { self.skip()?; Token::End }
|
||||
|
||||
Tag::Annotation => {
|
||||
self.skip()?;
|
||||
self.skip_annotations()?;
|
||||
continue
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
#[inline(always)]
|
||||
fn next_boolean(&mut self) -> ReaderResult<bool> {
|
||||
match self.peek_next_nonannotation_tag()? {
|
||||
|
@ -532,7 +417,7 @@ impl<'de, 'src, S: BinarySource<'de>> Reader<'de> for PackedReader<'de, 'src, S>
|
|||
fn next_u64(&mut self) -> ReaderResult<u64> { self.next_unsigned(|n| n.to_u64()) }
|
||||
fn next_u128(&mut self) -> ReaderResult<u128> { self.next_unsigned(|n| n.to_u128()) }
|
||||
|
||||
fn next_f32(&mut self) -> ReaderResult<f32> {
|
||||
fn next_float(&mut self) -> ReaderResult<f32> {
|
||||
match self.peek_next_nonannotation_tag()? {
|
||||
Tag::Float => {
|
||||
self.skip()?;
|
||||
|
@ -550,7 +435,7 @@ impl<'de, 'src, S: BinarySource<'de>> Reader<'de> for PackedReader<'de, 'src, S>
|
|||
}
|
||||
}
|
||||
|
||||
fn next_f64(&mut self) -> ReaderResult<f64> {
|
||||
fn next_double(&mut self) -> ReaderResult<f64> {
|
||||
match self.peek_next_nonannotation_tag()? {
|
||||
Tag::Float => {
|
||||
self.skip()?;
|
||||
|
@ -581,4 +466,12 @@ impl<'de, 'src, S: BinarySource<'de>> Reader<'de> for PackedReader<'de, 'src, S>
|
|||
let bs = self.next_atomic(Tag::Symbol, ExpectedKind::Symbol)?;
|
||||
Ok(self.decodestr(bs)?)
|
||||
}
|
||||
|
||||
fn open_annotation(&mut self) -> ReaderResult<()> {
|
||||
self.next_compound(Tag::Annotation, ExpectedKind::Annotation)
|
||||
}
|
||||
|
||||
fn close_annotation(&mut self) -> ReaderResult<()> {
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
|
|
|
@ -4,12 +4,7 @@ use std::convert::TryInto;
|
|||
use std::io;
|
||||
use std::io::Write;
|
||||
use super::constants::Tag;
|
||||
use super::super::DomainEncode;
|
||||
use super::super::IOValue;
|
||||
use super::super::IOValueDomainCodec;
|
||||
use super::super::NestedValue;
|
||||
use super::super::boundary as B;
|
||||
use super::super::writer::Writer;
|
||||
use crate::{boundary as B, Value, Domain, DomainEncode, IOValue, IOValueDomainCodec, Writer};
|
||||
|
||||
struct Buffers<W: io::Write> {
|
||||
base: W,
|
||||
|
@ -41,12 +36,12 @@ pub struct PackedWriter<W: io::Write>(Buffers<W>);
|
|||
|
||||
impl PackedWriter<&mut Vec<u8>> {
|
||||
#[inline(always)]
|
||||
pub fn encode<N: NestedValue, Enc: DomainEncode<N::Embedded>>(
|
||||
pub fn encode<D: Domain, Enc: DomainEncode<D>>(
|
||||
enc: &mut Enc,
|
||||
v: &N,
|
||||
v: &dyn Value<D>,
|
||||
) -> io::Result<Vec<u8>> {
|
||||
let mut buf: Vec<u8> = Vec::new();
|
||||
PackedWriter::new(&mut buf).write(enc, v)?;
|
||||
v.write(&mut PackedWriter::new(&mut buf), enc)?;
|
||||
Ok(buf)
|
||||
}
|
||||
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
use std::borrow::Cow;
|
||||
use std::convert::TryFrom;
|
||||
use std::io;
|
||||
use std::marker::PhantomData;
|
||||
|
||||
use crate::CompoundClass;
|
||||
use crate::SignedInteger;
|
||||
|
@ -286,6 +287,7 @@ pub trait Reader<'de> {
|
|||
pub struct IOValues<'de, R: Reader<'de>> {
|
||||
pub reader: R,
|
||||
pub read_annotations: bool,
|
||||
phantom: PhantomData<&'de ()>,
|
||||
}
|
||||
|
||||
impl<'de, R: Reader<'de>> IOValues<'de, R> {
|
||||
|
@ -293,6 +295,7 @@ impl<'de, R: Reader<'de>> IOValues<'de, R> {
|
|||
IOValues {
|
||||
reader,
|
||||
read_annotations: false,
|
||||
phantom: PhantomData,
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -4,9 +4,8 @@ use std::borrow::Cow;
|
|||
use std::io;
|
||||
|
||||
pub trait BinarySource<'de>: Sized {
|
||||
type Mark;
|
||||
fn mark(&mut self) -> io::Result<Self::Mark>;
|
||||
fn restore(&mut self, mark: &Self::Mark) -> io::Result<()>;
|
||||
fn mark(&mut self) -> io::Result<usize>;
|
||||
fn restore(&mut self, mark: usize) -> io::Result<()>;
|
||||
fn input_position(&mut self) -> io::Result<Option<usize>>;
|
||||
|
||||
fn skip(&mut self) -> io::Result<()>;
|
||||
|
@ -27,6 +26,14 @@ pub trait BinarySource<'de>: Sized {
|
|||
message: message.to_owned(),
|
||||
})
|
||||
}
|
||||
|
||||
fn packed(&mut self) -> super::PackedReader<'de, '_, Self> {
|
||||
super::PackedReader::new(self)
|
||||
}
|
||||
|
||||
// fn text(&mut self) -> super::TextReader<'de, '_, Self> {
|
||||
// super::TextReader::new(self)
|
||||
// }
|
||||
}
|
||||
|
||||
#[derive(Debug)]
|
||||
|
@ -61,16 +68,15 @@ impl<R: io::Read + io::Seek> IOBinarySource<R> {
|
|||
}
|
||||
|
||||
impl<'de, R: io::Read + io::Seek> BinarySource<'de> for IOBinarySource<R> {
|
||||
type Mark = u64;
|
||||
|
||||
#[inline(always)]
|
||||
fn mark(&mut self) -> io::Result<Self::Mark> {
|
||||
Ok(self.read.stream_position()? - (if self.buf.is_some() { 1 } else { 0 }))
|
||||
fn mark(&mut self) -> io::Result<usize> {
|
||||
let pos = self.read.stream_position()? - (if self.buf.is_some() { 1 } else { 0 });
|
||||
Ok(pos as usize)
|
||||
}
|
||||
|
||||
#[inline(always)]
|
||||
fn restore(&mut self, mark: &Self::Mark) -> io::Result<()> {
|
||||
self.read.seek(io::SeekFrom::Start(*mark))?;
|
||||
fn restore(&mut self, mark: usize) -> io::Result<()> {
|
||||
self.read.seek(io::SeekFrom::Start(mark as u64))?;
|
||||
self.buf = None;
|
||||
Ok(())
|
||||
}
|
||||
|
@ -146,16 +152,14 @@ impl<'de> BytesBinarySource<'de> {
|
|||
}
|
||||
|
||||
impl<'de> BinarySource<'de> for BytesBinarySource<'de> {
|
||||
type Mark = u64;
|
||||
|
||||
#[inline(always)]
|
||||
fn mark(&mut self) -> io::Result<Self::Mark> {
|
||||
Ok(self.index)
|
||||
fn mark(&mut self) -> io::Result<usize> {
|
||||
Ok(self.index as usize)
|
||||
}
|
||||
|
||||
#[inline(always)]
|
||||
fn restore(&mut self, mark: &Self::Mark) -> io::Result<()> {
|
||||
self.index = *mark;
|
||||
fn restore(&mut self, mark: usize) -> io::Result<()> {
|
||||
self.index = mark as u64;
|
||||
Ok(())
|
||||
}
|
||||
|
||||
|
|
|
@ -1,33 +1,36 @@
|
|||
use std::io;
|
||||
|
||||
pub mod reader;
|
||||
pub mod writer;
|
||||
|
||||
pub use reader::TextReader;
|
||||
pub use writer::TextWriter;
|
||||
|
||||
use crate::value::source::BytesBinarySource;
|
||||
use crate::BytesBinarySource;
|
||||
use crate::Domain;
|
||||
use crate::DomainDecode;
|
||||
use crate::IOValue;
|
||||
use crate::Reader;
|
||||
use crate::Value;
|
||||
|
||||
use std::io;
|
||||
|
||||
use super::{IOValue, IOValueDomainCodec, NestedValue, Reader, DomainDecode};
|
||||
|
||||
pub fn from_str<'de, N: NestedValue, Dec: DomainDecode<N::Embedded>>(
|
||||
pub fn from_str<'de, D: Domain + 'static, Dec: DomainDecode<D>>(
|
||||
s: &'de str,
|
||||
decode_embedded: &mut Dec,
|
||||
) -> io::Result<N> {
|
||||
TextReader::new(&mut BytesBinarySource::new(s.as_bytes())).demand_next_domain(false, decode_embedded)
|
||||
) -> io::Result<Box<dyn Value<D>>> {
|
||||
BytesBinarySource::new(s.as_bytes()).text().next(false, decode_embedded)
|
||||
}
|
||||
|
||||
pub fn iovalue_from_str(s: &str) -> io::Result<IOValue> {
|
||||
from_str(s, &mut IOValueDomainCodec)
|
||||
BytesBinarySource::new(s.as_bytes()).text().next_iovalue(false)
|
||||
}
|
||||
|
||||
pub fn annotated_from_str<'de, N: NestedValue, Dec: DomainDecode<N::Embedded>>(
|
||||
pub fn annotated_from_str<'de, D: Domain + 'static, Dec: DomainDecode<D>>(
|
||||
s: &'de str,
|
||||
decode_embedded: &mut Dec,
|
||||
) -> io::Result<N> {
|
||||
TextReader::new(&mut BytesBinarySource::new(s.as_bytes())).demand_next_domain(true, decode_embedded)
|
||||
) -> io::Result<Box<dyn Value<D>>> {
|
||||
BytesBinarySource::new(s.as_bytes()).text().next(true, decode_embedded)
|
||||
}
|
||||
|
||||
pub fn annotated_iovalue_from_str(s: &str) -> io::Result<IOValue> {
|
||||
annotated_from_str(s, &mut IOValueDomainCodec)
|
||||
BytesBinarySource::new(s.as_bytes()).text().next_iovalue(true)
|
||||
}
|
||||
|
|
|
@ -1,22 +1,21 @@
|
|||
use crate::Atom;
|
||||
use crate::error::Error;
|
||||
use crate::error::ExpectedKind;
|
||||
use crate::error::io_eof;
|
||||
|
||||
use crate::hex;
|
||||
|
||||
use crate::value::CompoundClass;
|
||||
use crate::value::Domain;
|
||||
use crate::value::DomainDecode;
|
||||
use crate::value::Map;
|
||||
use crate::value::NestedValue;
|
||||
use crate::value::Reader;
|
||||
use crate::value::Record;
|
||||
use crate::value::Set;
|
||||
use crate::value::Token;
|
||||
use crate::value::Value;
|
||||
use crate::value::boundary as B;
|
||||
use crate::value::reader::ReaderResult;
|
||||
use crate::value::source::BinarySource;
|
||||
use crate::CompoundClass;
|
||||
use crate::Domain;
|
||||
use crate::DomainDecode;
|
||||
use crate::Map;
|
||||
use crate::Reader;
|
||||
use crate::Record;
|
||||
use crate::Set;
|
||||
use crate::Value;
|
||||
use crate::boundary as B;
|
||||
use crate::reader::ReaderResult;
|
||||
use crate::source::BinarySource;
|
||||
|
||||
use num::bigint::BigInt;
|
||||
|
||||
|
@ -74,32 +73,6 @@ impl<'de, 'src, S: BinarySource<'de>> TextReader<'de, 'src, S>
|
|||
}
|
||||
}
|
||||
|
||||
fn gather_annotations<N: NestedValue, Dec: DomainDecode<N::Embedded>>(
|
||||
&mut self,
|
||||
decode_embedded: &mut Dec,
|
||||
) -> ReaderResult<Vec<N>> {
|
||||
let mut vs = Vec::new();
|
||||
loop {
|
||||
self.skip_whitespace();
|
||||
match self.peek_noeof()? {
|
||||
b';' => { self.skip()?; vs.push(N::new(self.comment_line()?)) }
|
||||
b'@' => { self.skip()?; vs.push(self.demand_next_domain(true, decode_embedded)?) }
|
||||
_ => return Ok(vs),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fn skip_annotations(&mut self) -> ReaderResult<()> {
|
||||
loop {
|
||||
self.skip_whitespace();
|
||||
match self.peek_noeof()? {
|
||||
b';' => { self.skip()?; self.comment_line()?; },
|
||||
b'@' => { self.skip()?; self.skip_value()?; },
|
||||
_ => return Ok(()),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fn decode_utf8(&mut self, bs: Vec<u8>) -> io::Result<String> {
|
||||
String::from_utf8(bs).map_err(|_| self.syntax_error("Invalid UTF-8"))
|
||||
}
|
||||
|
@ -116,7 +89,7 @@ impl<'de, 'src, S: BinarySource<'de>> TextReader<'de, 'src, S>
|
|||
}
|
||||
}
|
||||
|
||||
fn read_intpart<N: NestedValue>(&mut self, mut bs: Vec<u8>, c: u8) -> io::Result<N> {
|
||||
fn read_intpart(&mut self, mut bs: Vec<u8>, c: u8) -> io::Result<Atom<'de>> {
|
||||
match c {
|
||||
b'0' => {
|
||||
bs.push(c);
|
||||
|
@ -129,7 +102,7 @@ impl<'de, 'src, S: BinarySource<'de>> TextReader<'de, 'src, S>
|
|||
}
|
||||
}
|
||||
|
||||
fn read_fracexp<N: NestedValue>(&mut self, mut bs: Vec<u8>) -> io::Result<N> {
|
||||
fn read_fracexp(&mut self, mut bs: Vec<u8>) -> io::Result<Atom<'de>> {
|
||||
let mut is_float = false;
|
||||
match self.peek_noeof() {
|
||||
Ok(b'.') => {
|
||||
|
@ -149,7 +122,7 @@ impl<'de, 'src, S: BinarySource<'de>> TextReader<'de, 'src, S>
|
|||
}
|
||||
}
|
||||
|
||||
fn read_sign_and_exp<N: NestedValue>(&mut self, mut bs: Vec<u8>) -> io::Result<N> {
|
||||
fn read_sign_and_exp(&mut self, mut bs: Vec<u8>) -> io::Result<Atom<'de>> {
|
||||
match self.peek_noeof()? {
|
||||
b'+' | b'-' => bs.push(self.next_byte()?),
|
||||
_ => (),
|
||||
|
@ -159,23 +132,23 @@ impl<'de, 'src, S: BinarySource<'de>> TextReader<'de, 'src, S>
|
|||
self.finish_number(bs, true)
|
||||
}
|
||||
|
||||
fn finish_number<N: NestedValue>(&mut self, bs: Vec<u8>, is_float: bool) -> io::Result<N> {
|
||||
fn finish_number(&mut self, bs: Vec<u8>, is_float: bool) -> io::Result<Atom<'de>> {
|
||||
let s = self.decode_utf8(bs)?;
|
||||
if is_float {
|
||||
match self.peek_noeof() {
|
||||
Ok(b'f') | Ok(b'F') => {
|
||||
self.skip()?;
|
||||
Ok(N::new(s.parse::<f32>().map_err(
|
||||
Ok(Atom::Float(s.parse::<f32>().map_err(
|
||||
|_| self.syntax_error(&format!(
|
||||
"Invalid single-precision number: {:?}", s)))?))
|
||||
}
|
||||
_ =>
|
||||
Ok(N::new(s.parse::<f64>().map_err(
|
||||
Ok(Atom::Double(s.parse::<f64>().map_err(
|
||||
|_| self.syntax_error(&format!(
|
||||
"Invalid double-precision number: {:?}", s)))?))
|
||||
}
|
||||
} else {
|
||||
Ok(N::new(s.parse::<BigInt>().map_err(
|
||||
Ok(Atom::SignedInteger(s.parse::<BigInt>().map_err(
|
||||
|_| self.syntax_error(&format!(
|
||||
"Invalid signed-integer number: {:?}", s)))?))
|
||||
}
|
||||
|
@ -278,8 +251,8 @@ impl<'de, 'src, S: BinarySource<'de>> TextReader<'de, 'src, S>
|
|||
self.decode_utf8(raw)
|
||||
}
|
||||
|
||||
fn read_literal_binary<N: NestedValue>(&mut self) -> io::Result<N> {
|
||||
Ok(N::new(&self.read_stringlike(
|
||||
fn read_literal_binary(&mut self) -> io::Result<Atom<'de>> {
|
||||
Ok(Atom::Bytes(&self.read_stringlike(
|
||||
Vec::new(),
|
||||
|_r, bs, b| Ok(bs.push(b)),
|
||||
b'"',
|
||||
|
@ -287,14 +260,14 @@ impl<'de, 'src, S: BinarySource<'de>> TextReader<'de, 'src, S>
|
|||
|r, bs| Ok(bs.push(r.hexnum(2)? as u8)))?[..]))
|
||||
}
|
||||
|
||||
fn read_hex_binary<N: NestedValue>(&mut self) -> io::Result<N> {
|
||||
fn read_hex_binary(&mut self) -> io::Result<Atom<'de>> {
|
||||
let mut s = String::new();
|
||||
loop {
|
||||
self.skip_whitespace();
|
||||
let c1 = self.next_byte()? as char;
|
||||
if c1 == '"' {
|
||||
let bs = hex::HexParser::Strict.decode(&s).unwrap();
|
||||
return Ok(N::new(&bs[..]));
|
||||
return Ok(Atom::Bytes(&bs[..]));
|
||||
}
|
||||
let c2 = self.next_byte()? as char;
|
||||
if !(c1.is_digit(16) && c2.is_digit(16)) {
|
||||
|
@ -305,7 +278,7 @@ impl<'de, 'src, S: BinarySource<'de>> TextReader<'de, 'src, S>
|
|||
}
|
||||
}
|
||||
|
||||
fn read_base64_binary<N: NestedValue>(&mut self) -> io::Result<N> {
|
||||
fn read_base64_binary(&mut self) -> io::Result<Atom<'de>> {
|
||||
let mut bs = Vec::new();
|
||||
loop {
|
||||
self.skip_whitespace();
|
||||
|
@ -313,7 +286,7 @@ impl<'de, 'src, S: BinarySource<'de>> TextReader<'de, 'src, S>
|
|||
if c == b']' {
|
||||
let bs = base64::decode_config(&self.decode_utf8(bs)?, base64::STANDARD_NO_PAD)
|
||||
.map_err(|_| self.syntax_error("Invalid base64 character"))?;
|
||||
return Ok(N::new(&bs[..]));
|
||||
return Ok(Atom::Bytes(&bs[..]));
|
||||
}
|
||||
if c == b'-' { c = b'+'; }
|
||||
if c == b'_' { c = b'/'; }
|
||||
|
@ -322,46 +295,7 @@ impl<'de, 'src, S: BinarySource<'de>> TextReader<'de, 'src, S>
|
|||
}
|
||||
}
|
||||
|
||||
fn upto<N: NestedValue, Dec: DomainDecode<N::Embedded>>(
|
||||
&mut self,
|
||||
delimiter: u8,
|
||||
read_annotations: bool,
|
||||
decode_embedded: &mut Dec,
|
||||
) -> io::Result<Vec<N>> {
|
||||
let mut vs = Vec::new();
|
||||
loop {
|
||||
self.skip_whitespace();
|
||||
if self.peek()? == Some(delimiter) {
|
||||
self.skip()?;
|
||||
return Ok(vs);
|
||||
}
|
||||
vs.push(self.demand_next_domain(read_annotations, decode_embedded)?);
|
||||
}
|
||||
}
|
||||
|
||||
fn read_dictionary<N: NestedValue, Dec: DomainDecode<N::Embedded>>(
|
||||
&mut self,
|
||||
read_annotations: bool,
|
||||
decode_embedded: &mut Dec,
|
||||
) -> io::Result<N> {
|
||||
let mut d = Map::new();
|
||||
loop {
|
||||
self.skip_whitespace();
|
||||
if self.peek_noeof()? == b'}' {
|
||||
self.skip()?;
|
||||
return Ok(N::new(d));
|
||||
}
|
||||
let k = self.demand_next_domain(read_annotations, decode_embedded)?;
|
||||
self.skip_whitespace();
|
||||
if self.next_byte()? != b':' {
|
||||
return Err(self.syntax_error("Missing expected key/value separator"));
|
||||
}
|
||||
let v = self.demand_next_domain(read_annotations, decode_embedded)?;
|
||||
d.insert(k, v);
|
||||
}
|
||||
}
|
||||
|
||||
fn read_raw_symbol<N: NestedValue>(&mut self, mut bs: Vec<u8>) -> io::Result<N> {
|
||||
fn read_raw_symbol(&mut self, mut bs: Vec<u8>) -> io::Result<Atom<'de>> {
|
||||
loop {
|
||||
let c = match self.peek()? {
|
||||
None => b' ',
|
||||
|
@ -371,7 +305,7 @@ impl<'de, 'src, S: BinarySource<'de>> TextReader<'de, 'src, S>
|
|||
match c {
|
||||
b'(' | b')' | b'{' | b'}' | b'[' | b']' | b'<' | b'>' |
|
||||
b'"' | b';' | b',' | b'@' | b'#' | b':' | b'|' | b' ' =>
|
||||
return Ok(N::symbol(&self.decode_utf8(bs)?)),
|
||||
return Ok(Atom::Symbol(&self.decode_utf8(bs)?)),
|
||||
c => {
|
||||
self.skip()?;
|
||||
bs.push(c)
|
||||
|
@ -383,17 +317,13 @@ impl<'de, 'src, S: BinarySource<'de>> TextReader<'de, 'src, S>
|
|||
|
||||
impl<'de, 'src, S: BinarySource<'de>> Reader<'de> for TextReader<'de, 'src, S>
|
||||
{
|
||||
fn next_domain<N: NestedValue, Dec: DomainDecode<N::Embedded>>(
|
||||
&mut self,
|
||||
read_annotations: bool,
|
||||
decode_embedded: &mut Dec,
|
||||
) -> io::Result<Option<N>> {
|
||||
fn peek_class(&mut self) -> io::Result<Option<crate::reader::NextToken>> {
|
||||
self.skip_whitespace();
|
||||
let c = match self.peek()? {
|
||||
None => return Ok(None),
|
||||
Some(c) => c,
|
||||
};
|
||||
Ok(Some(match c {
|
||||
XX Ok(Some(match c {
|
||||
b'-' => {
|
||||
self.skip()?;
|
||||
let c1 = self.next_byte()?;
|
||||
|
|
|
@ -6,6 +6,8 @@ use crate::boundary as B;
|
|||
use crate::signed_integer::SignedIntegerRepr;
|
||||
|
||||
pub trait Writer {
|
||||
fn boundary(&mut self, b: &B::Type) -> io::Result<()>;
|
||||
|
||||
fn start_annotations(&mut self) -> io::Result<()>;
|
||||
fn end_annotations(&mut self) -> io::Result<()>;
|
||||
|
||||
|
@ -22,8 +24,6 @@ pub trait Writer {
|
|||
fn write_bytes(&mut self, v: &[u8]) -> io::Result<()>;
|
||||
fn write_symbol(&mut self, v: &str) -> io::Result<()>;
|
||||
|
||||
fn boundary(&mut self, b: &B::Type) -> io::Result<()>;
|
||||
|
||||
fn start_record(&mut self) -> io::Result<()>;
|
||||
fn end_record(&mut self) -> io::Result<()>;
|
||||
|
||||
|
|
Loading…
Reference in New Issue