Remove decoder/encoder; undoes performance regression
This commit is contained in:
parent
28101cc7d1
commit
9f83756931
|
@ -1,5 +1,5 @@
|
|||
use criterion::{criterion_group, criterion_main, Criterion};
|
||||
use preserves::value::{self, decoder, encoder, PackedReader, PackedWriter, reader::Reader};
|
||||
use preserves::value::{self, Reader, Writer, PackedReader, PackedWriter};
|
||||
use preserves::{de, ser};
|
||||
use std::io::Read;
|
||||
use std::io::BufReader;
|
||||
|
@ -14,14 +14,14 @@ pub fn bench_decoder_bytes(c: &mut Criterion) {
|
|||
let mut bs = vec![];
|
||||
fh.read_to_end(&mut bs).ok();
|
||||
c.bench_function("decode samples.bin via bytes", |b| b.iter_with_large_drop(
|
||||
|| decoder::from_bytes(&bs[..]).demand_next().unwrap()));
|
||||
|| PackedReader::decode_bytes(&bs[..]).demand_next(true).unwrap()));
|
||||
}
|
||||
|
||||
pub fn bench_decoder_file(c: &mut Criterion) {
|
||||
let mut fh = std::fs::File::open("../../tests/samples.bin").unwrap();
|
||||
c.bench_function("decode samples.bin via file", |b| b.iter_with_large_drop(|| {
|
||||
fh.seek(SeekFrom::Start(0)).ok();
|
||||
decoder::from_read(&mut fh).demand_next().unwrap()
|
||||
PackedReader::decode_read(&mut fh).demand_next(true).unwrap()
|
||||
}));
|
||||
}
|
||||
|
||||
|
@ -29,16 +29,16 @@ pub fn bench_decoder_buffered_file(c: &mut Criterion) {
|
|||
let mut fh = BufReader::new(std::fs::File::open("../../tests/samples.bin").unwrap());
|
||||
c.bench_function("decode samples.bin via buffered file", |b| b.iter_with_large_drop(|| {
|
||||
fh.seek(SeekFrom::Start(0)).ok();
|
||||
decoder::from_read(&mut fh).demand_next().unwrap()
|
||||
PackedReader::decode_read(&mut fh).demand_next(true).unwrap()
|
||||
}));
|
||||
}
|
||||
|
||||
pub fn bench_encoder(c: &mut Criterion) {
|
||||
let mut fh = std::fs::File::open("../../tests/samples.bin").unwrap();
|
||||
let v = decoder::from_read(&mut fh).demand_next().unwrap();
|
||||
let v = PackedReader::decode_read(&mut fh).demand_next(true).unwrap();
|
||||
c.bench_function("encode samples.bin", |b| b.iter_with_large_drop(|| {
|
||||
let mut bs = vec![];
|
||||
encoder::Encoder::new(&mut PackedWriter(&mut bs)).write(&v).unwrap();
|
||||
PackedWriter(&mut bs).write(&v).unwrap();
|
||||
bs
|
||||
}));
|
||||
}
|
||||
|
@ -66,7 +66,7 @@ pub fn bench_decoder_de(c: &mut Criterion) {
|
|||
let mut bs = vec![];
|
||||
fh.read_to_end(&mut bs).ok();
|
||||
c.bench_function("decode-then-deserialize samples.bin", |b| b.iter_with_large_drop(
|
||||
|| value::de::from_value::<TestCases>(&decoder::from_bytes(&bs[..]).demand_next().unwrap()).unwrap()));
|
||||
|| value::de::from_value::<TestCases>(&PackedReader::decode_bytes(&bs[..]).demand_next(true).unwrap()).unwrap()));
|
||||
}
|
||||
|
||||
pub fn bench_ser_encoder(c: &mut Criterion) {
|
||||
|
@ -74,7 +74,7 @@ pub fn bench_ser_encoder(c: &mut Criterion) {
|
|||
let v: TestCases = de::from_read(&mut fh).unwrap();
|
||||
c.bench_function("serialize-then-encode samples.bin", |b| b.iter_with_large_drop(|| {
|
||||
let mut bs = vec![];
|
||||
encoder::Encoder::new(&mut PackedWriter(&mut bs)).write(&value::ser::to_value(&v)).unwrap();
|
||||
PackedWriter(&mut bs).write(&value::ser::to_value(&v)).unwrap();
|
||||
bs
|
||||
}));
|
||||
}
|
||||
|
@ -85,7 +85,7 @@ pub fn large_testdata_decoder_with_ann(c: &mut Criterion) {
|
|||
let mut bs = vec![];
|
||||
fh.read_to_end(&mut bs).ok();
|
||||
b.iter(|| {
|
||||
let mut r = PackedReader::from_bytes(&bs[..]);
|
||||
let mut r = PackedReader::decode_bytes(&bs[..]);
|
||||
while let Some(_) = r.next(true).unwrap() {}
|
||||
})
|
||||
});
|
||||
|
@ -97,7 +97,7 @@ pub fn large_testdata_decoder_without_ann(c: &mut Criterion) {
|
|||
let mut bs = vec![];
|
||||
fh.read_to_end(&mut bs).ok();
|
||||
b.iter(|| {
|
||||
let mut r = PackedReader::from_bytes(&bs[..]);
|
||||
let mut r = PackedReader::decode_bytes(&bs[..]);
|
||||
while let Some(_) = r.next(false).unwrap() {}
|
||||
})
|
||||
});
|
||||
|
@ -107,16 +107,15 @@ pub fn large_testdata_encoder(c: &mut Criterion) {
|
|||
c.bench_function("encode testdata.bin", |b| {
|
||||
let mut fh = BufReader::new(std::fs::File::open("benches/testdata.bin").unwrap());
|
||||
let mut vs = vec![];
|
||||
let mut r = PackedReader::from_read(&mut fh);
|
||||
let mut r = PackedReader::decode_read(&mut fh);
|
||||
while let Some(v) = r.next(true).unwrap() {
|
||||
vs.push(v);
|
||||
}
|
||||
b.iter_with_large_drop(|| {
|
||||
let mut bs = vec![];
|
||||
let mut w = PackedWriter(&mut bs);
|
||||
let mut e = encoder::Encoder::new(&mut w);
|
||||
for v in &vs {
|
||||
e.write(&v).unwrap();
|
||||
w.write(&v).unwrap();
|
||||
}
|
||||
bs
|
||||
})
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
use preserves::{de, value, value::decoder};
|
||||
use preserves::{de, value::{self, Reader, PackedReader}};
|
||||
use serde::{Serialize, Deserialize};
|
||||
use std::fs::File;
|
||||
use std::io::Error;
|
||||
|
@ -33,7 +33,7 @@ enum Variety {
|
|||
}
|
||||
|
||||
fn try_file(kind: &str, path: &str) -> Result<(), Error> {
|
||||
let fruits_value = decoder::from_read(&mut File::open(path)?).demand_next()?;
|
||||
let fruits_value = PackedReader::decode_read(&mut File::open(path)?).demand_next(true)?;
|
||||
println!("{:?}", fruits_value);
|
||||
|
||||
let fruits1: Vec<Fruit> = value::de::from_value(&fruits_value)?;
|
||||
|
|
|
@ -12,7 +12,7 @@ pub mod value;
|
|||
mod dom {
|
||||
use super::value::{
|
||||
Value, IOValue, NestedValue, PlainValue, Domain,
|
||||
encoder::encode_bytes,
|
||||
PackedWriter,
|
||||
};
|
||||
|
||||
#[derive(Debug, Hash, Clone, Ord, PartialEq, Eq, PartialOrd)]
|
||||
|
@ -36,7 +36,7 @@ mod dom {
|
|||
Value::Domain(Dom::One).wrap(),
|
||||
Value::from(2).wrap()])
|
||||
.wrap();
|
||||
assert_eq!(encode_bytes(&v.to_io_value()).unwrap(),
|
||||
assert_eq!(PackedWriter::encode(&v.to_io_value()).unwrap(),
|
||||
[147, 49, 100, 255, 255, 255, 255, 50]);
|
||||
}
|
||||
|
||||
|
@ -45,7 +45,7 @@ mod dom {
|
|||
Value::Domain(Dom::Two).wrap(),
|
||||
Value::from(2).wrap()])
|
||||
.wrap();
|
||||
assert_eq!(encode_bytes(&v.to_io_value()).unwrap(),
|
||||
assert_eq!(PackedWriter::encode(&v.to_io_value()).unwrap(),
|
||||
[147, 49, 120, 68, 111, 109, 58, 58, 84, 119, 111, 50]);
|
||||
}
|
||||
}
|
||||
|
@ -229,7 +229,7 @@ mod value_tests {
|
|||
|
||||
#[cfg(test)]
|
||||
mod decoder_tests {
|
||||
use crate::value::{Value, NestedValue, decoder};
|
||||
use crate::value::{Value, NestedValue, PackedReader, ConfiguredReader};
|
||||
use crate::de::from_bytes;
|
||||
use crate::error::{Error, ExpectedKind, is_eof_io_error};
|
||||
|
||||
|
@ -251,7 +251,7 @@ mod decoder_tests {
|
|||
|
||||
#[test] fn skip_annotations_noskip() {
|
||||
let mut buf = &b"\x0521"[..];
|
||||
let mut d = decoder::from_bytes(&mut buf);
|
||||
let mut d = ConfiguredReader::new(PackedReader::decode_bytes(&mut buf));
|
||||
let v = d.demand_next().unwrap();
|
||||
assert_eq!(v.annotations().slice().len(), 1);
|
||||
assert_eq!(v.annotations().slice()[0], Value::from(2).wrap());
|
||||
|
@ -260,7 +260,7 @@ mod decoder_tests {
|
|||
|
||||
#[test] fn skip_annotations_skip() {
|
||||
let mut buf = &b"\x0521"[..];
|
||||
let mut d = decoder::from_bytes(&mut buf);
|
||||
let mut d = ConfiguredReader::new(PackedReader::decode_bytes(&mut buf));
|
||||
d.set_read_annotations(false);
|
||||
let v = d.demand_next().unwrap();
|
||||
assert_eq!(v.annotations().slice().len(), 0);
|
||||
|
@ -270,12 +270,12 @@ mod decoder_tests {
|
|||
#[test] fn multiple_values_buf_advanced() {
|
||||
let mut buf = &b"\x81tPing\x81tPong"[..];
|
||||
assert_eq!(buf.len(), 12);
|
||||
let mut d = decoder::from_bytes(&mut buf);
|
||||
assert_eq!(d.read.source.index, 0);
|
||||
let mut d = ConfiguredReader::new(PackedReader::decode_bytes(&mut buf));
|
||||
assert_eq!(d.reader.source.index, 0);
|
||||
assert_eq!(d.demand_next().unwrap().value(), &Value::simple_record0("Ping"));
|
||||
assert_eq!(d.read.source.index, 6);
|
||||
assert_eq!(d.reader.source.index, 6);
|
||||
assert_eq!(d.demand_next().unwrap().value(), &Value::simple_record0("Pong"));
|
||||
assert_eq!(d.read.source.index, 12);
|
||||
assert_eq!(d.reader.source.index, 12);
|
||||
assert!(d.next().is_none());
|
||||
assert!(if let Err(e) = d.demand_next() { is_eof_io_error(&e) } else { false });
|
||||
}
|
||||
|
@ -387,7 +387,6 @@ mod serde_tests {
|
|||
use crate::symbol::Symbol;
|
||||
use crate::de::from_bytes as deserialize_from_bytes;
|
||||
use crate::value::de::from_value as deserialize_from_value;
|
||||
use crate::value::encoder::encode_bytes;
|
||||
use crate::value::to_value;
|
||||
use crate::value::{Value, IOValue, Map, Set};
|
||||
use crate::value::packed::PackedWriter;
|
||||
|
@ -476,7 +475,7 @@ mod serde_tests {
|
|||
0x3, 0x40, 0x28, 0xb0, 0xfc, 0xd3, 0x24, 0xd5, 0xa2, // 12.3456789
|
||||
];
|
||||
|
||||
let v_bytes_1 = encode_bytes(&w).unwrap();
|
||||
let v_bytes_1 = PackedWriter::encode(&w).unwrap();
|
||||
println!("== w bytes = {:?}", v_bytes_1);
|
||||
assert_eq!(expected_bytes, v_bytes_1);
|
||||
|
||||
|
|
|
@ -1,6 +1,5 @@
|
|||
use serde::Serialize;
|
||||
use super::value::writer::Writer;
|
||||
use super::value::Encoder;
|
||||
|
||||
pub use super::error::Error;
|
||||
type Result<T> = std::result::Result<T, Error>;
|
||||
|
@ -148,7 +147,7 @@ impl<'a, 'b, W: Writer> serde::Serializer for &'a mut Serializer<'b, W> {
|
|||
{
|
||||
match super::value::magic::receive_output_value(name, value) {
|
||||
Some(v) => {
|
||||
Ok(Encoder::new(self.write).write(&v)?)
|
||||
Ok(self.write.write(&v)?)
|
||||
}
|
||||
None => {
|
||||
// TODO: This is apparently discouraged, and we should apparently just serialize `value`?
|
||||
|
|
|
@ -1,49 +0,0 @@
|
|||
use std::marker::PhantomData;
|
||||
use super::packed::PackedReader;
|
||||
use super::reader::{self, Reader};
|
||||
use super::value::IOValue;
|
||||
|
||||
pub use super::reader::IOResult as Result;
|
||||
|
||||
pub struct Decoder<'de, R: Reader<'de>> {
|
||||
pub read: R,
|
||||
read_annotations: bool,
|
||||
phantom: PhantomData<&'de ()>,
|
||||
}
|
||||
|
||||
pub fn from_bytes<'de>(bytes: &'de [u8]) ->
|
||||
Decoder<'de, PackedReader<'de, reader::BytesBinarySource<'de>>>
|
||||
{
|
||||
Decoder::new(PackedReader::from_bytes(bytes))
|
||||
}
|
||||
|
||||
pub fn from_read<'de, 'a, IOR: std::io::Read>(read: &'a mut IOR) ->
|
||||
Decoder<'de, PackedReader<'de, reader::IOBinarySource<'a, IOR>>>
|
||||
{
|
||||
Decoder::new(PackedReader::from_read(read))
|
||||
}
|
||||
|
||||
impl<'de, R: Reader<'de>> Decoder<'de, R> {
|
||||
pub fn new(read: R) -> Self {
|
||||
Decoder { read, read_annotations: true, phantom: PhantomData }
|
||||
}
|
||||
|
||||
pub fn set_read_annotations(&mut self, read_annotations: bool) {
|
||||
self.read_annotations = read_annotations
|
||||
}
|
||||
|
||||
pub fn demand_next(&mut self) -> Result<IOValue> {
|
||||
self.read.demand_next(self.read_annotations)
|
||||
}
|
||||
}
|
||||
|
||||
impl<'de, R: Reader<'de>> std::iter::Iterator for Decoder<'de, R> {
|
||||
type Item = Result<IOValue>;
|
||||
fn next(&mut self) -> Option<Self::Item> {
|
||||
match self.read.next(self.read_annotations) {
|
||||
Err(e) => Some(Err(e)),
|
||||
Ok(None) => None,
|
||||
Ok(Some(v)) => Some(Ok(v)),
|
||||
}
|
||||
}
|
||||
}
|
|
@ -1,89 +0,0 @@
|
|||
use super::value::{Value, NestedValue, Domain, IOValue, UnwrappedIOValue, Float, Double};
|
||||
use super::signed_integer::SignedIntegerRepr;
|
||||
use super::writer::Writer;
|
||||
use super::packed::PackedWriter;
|
||||
|
||||
pub use super::writer::Result;
|
||||
|
||||
pub struct Encoder<'a, W: Writer> {
|
||||
pub write: &'a mut W,
|
||||
}
|
||||
|
||||
pub fn encode_bytes(v: &IOValue) -> std::io::Result<Vec<u8>> {
|
||||
let mut buf: Vec<u8> = Vec::new();
|
||||
Encoder::new(&mut PackedWriter(&mut buf)).write(v)?;
|
||||
Ok(buf)
|
||||
}
|
||||
|
||||
impl<'a, W: Writer> Encoder<'a, W> {
|
||||
pub fn new(write: &'a mut W) -> Self {
|
||||
Encoder { write }
|
||||
}
|
||||
|
||||
pub fn write(&mut self, v: &IOValue) -> Result<W::Pointer> {
|
||||
match v.annotations().maybe_slice() {
|
||||
None => self.write_value(v.value()),
|
||||
Some(anns) => {
|
||||
let mut a = self.write.start_annotation()?;
|
||||
for ann in anns {
|
||||
self.write.extend_annotation(&mut a, ann)?;
|
||||
}
|
||||
let p = self.write_value(v.value())?;
|
||||
self.write.end_annotation(a, p)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
pub fn write_value(&mut self, v: &UnwrappedIOValue) -> Result<W::Pointer> {
|
||||
match v {
|
||||
Value::Boolean(b) => self.write.write_bool(*b),
|
||||
Value::Float(Float(f)) => self.write.write_f32(*f),
|
||||
Value::Double(Double(d)) => self.write.write_f64(*d),
|
||||
Value::SignedInteger(n) => match n.repr() {
|
||||
SignedIntegerRepr::I128(i) => self.write.write_i128(*i),
|
||||
SignedIntegerRepr::U128(u) => self.write.write_u128(*u),
|
||||
SignedIntegerRepr::Big(ref n) => self.write.write_int(n),
|
||||
}
|
||||
Value::String(ref s) => self.write.write_string(s),
|
||||
Value::ByteString(ref bs) => self.write.write_bytes(bs),
|
||||
Value::Symbol(ref s) => self.write.write_symbol(s),
|
||||
Value::Record(r) => {
|
||||
let mut c = self.write.start_record(r.arity() as u64)?;
|
||||
let p = self.write(r.label())?;
|
||||
self.write.extend_compound(&mut c, p)?;
|
||||
for f in r.fields() {
|
||||
let p = self.write(f)?;
|
||||
self.write.extend_compound(&mut c, p)?;
|
||||
}
|
||||
self.write.end_compound(c)
|
||||
}
|
||||
Value::Sequence(ref vs) => {
|
||||
let mut c = self.write.start_sequence(vs.len() as u64)?;
|
||||
for v in vs {
|
||||
let p = self.write(v)?;
|
||||
self.write.extend_compound(&mut c, p)?;
|
||||
}
|
||||
self.write.end_compound(c)
|
||||
}
|
||||
Value::Set(ref vs) => {
|
||||
let mut c = self.write.start_set(vs.len() as u64)?;
|
||||
for v in vs {
|
||||
let p = self.write(v)?;
|
||||
self.write.extend_compound(&mut c, p)?;
|
||||
}
|
||||
self.write.end_compound(c)
|
||||
}
|
||||
Value::Dictionary(ref vs) => {
|
||||
let mut d = self.write.start_dictionary(vs.len() as u64)?;
|
||||
for (k, v) in vs {
|
||||
let p = self.write(k)?;
|
||||
let kp = self.write.extend_dictionary_key(&mut d, p)?;
|
||||
let p = self.write(v)?;
|
||||
self.write.extend_dictionary_value(&mut d, kp, p)?;
|
||||
}
|
||||
self.write.end_dictionary(d)
|
||||
}
|
||||
Value::Domain(ref d) => self.write(&d.as_preserves()?)
|
||||
}
|
||||
}
|
||||
}
|
|
@ -1,6 +1,4 @@
|
|||
pub mod de;
|
||||
pub mod decoder;
|
||||
pub mod encoder;
|
||||
pub mod magic;
|
||||
pub mod packed;
|
||||
pub mod reader;
|
||||
|
@ -11,10 +9,9 @@ pub mod writer;
|
|||
|
||||
pub use de::Deserializer;
|
||||
pub use de::from_value;
|
||||
pub use decoder::Decoder;
|
||||
pub use encoder::Encoder;
|
||||
pub use packed::PackedReader;
|
||||
pub use packed::PackedWriter;
|
||||
pub use reader::ConfiguredReader;
|
||||
pub use reader::Reader;
|
||||
pub use ser::Serializer;
|
||||
pub use ser::to_value;
|
||||
|
|
|
@ -3,7 +3,6 @@ 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::super::signed_integer::SignedInteger;
|
||||
use super::super::value::{Value, NestedValue, IOValue, FALSE, TRUE, Map, Set, Record, Annotations};
|
||||
|
@ -14,6 +13,7 @@ use super::super::reader::{
|
|||
BytesBinarySource,
|
||||
CompoundBody,
|
||||
CompoundLimit,
|
||||
ConfiguredReader,
|
||||
IOBinarySource,
|
||||
IOResult,
|
||||
Reader,
|
||||
|
@ -47,13 +47,13 @@ fn out_of_range<I: Into<BigInt>>(i: I) -> error::Error {
|
|||
}
|
||||
|
||||
impl<'de> PackedReader<'de, BytesBinarySource<'de>> {
|
||||
pub fn from_bytes(bytes: &'de [u8]) -> Self {
|
||||
pub fn decode_bytes(bytes: &'de [u8]) -> Self {
|
||||
PackedReader::new(BytesBinarySource::new(bytes))
|
||||
}
|
||||
}
|
||||
|
||||
impl<'de, 'a, IOR: std::io::Read> PackedReader<'de, IOBinarySource<'a, IOR>> {
|
||||
pub fn from_read(read: &'a mut IOR) -> Self {
|
||||
pub fn decode_read(read: &'a mut IOR) -> Self {
|
||||
PackedReader::new(IOBinarySource::new(read))
|
||||
}
|
||||
}
|
||||
|
@ -308,11 +308,7 @@ impl<'de, S: BinarySource<'de>> Reader<'de> for PackedReader<'de, S> {
|
|||
Op::Atom(minor) =>
|
||||
decodebinary(minor, Cow::Owned(self.gather_chunks()?))?,
|
||||
Op::Compound(minor) => decodecompound(minor, DelimitedStream {
|
||||
reader: ConfiguredPackedReader {
|
||||
reader: self,
|
||||
read_annotations,
|
||||
phantom: PhantomData,
|
||||
},
|
||||
reader: self.configured(read_annotations),
|
||||
})?,
|
||||
_ => Err(io_syntax_error("Invalid format C start byte"))?,
|
||||
}
|
||||
|
@ -334,11 +330,7 @@ impl<'de, S: BinarySource<'de>> Reader<'de> for PackedReader<'de, S> {
|
|||
(Op::Compound(minor), arg) => {
|
||||
let count = self.wirelength(arg)?;
|
||||
decodecompound(minor, CountedStream {
|
||||
reader: ConfiguredPackedReader {
|
||||
reader: self,
|
||||
read_annotations,
|
||||
phantom: PhantomData,
|
||||
},
|
||||
reader: self.configured(read_annotations),
|
||||
count,
|
||||
})?
|
||||
}
|
||||
|
@ -473,18 +465,12 @@ impl<'de, S: BinarySource<'de>> Reader<'de> for PackedReader<'de, S> {
|
|||
}
|
||||
}
|
||||
|
||||
struct ConfiguredPackedReader<'de, 'a, S: BinarySource<'de>> {
|
||||
reader: &'a mut PackedReader<'de, S>,
|
||||
read_annotations: bool,
|
||||
phantom: PhantomData<&'de ()>,
|
||||
}
|
||||
|
||||
struct CountedStream<'de, 'a, S: BinarySource<'de>> {
|
||||
reader: ConfiguredPackedReader<'de, 'a, S>,
|
||||
struct CountedStream<'de, R: Reader<'de>> {
|
||||
reader: ConfiguredReader<'de, R>,
|
||||
count: usize,
|
||||
}
|
||||
|
||||
impl<'de, 'a, S: BinarySource<'de>> Iterator for CountedStream<'de, 'a, S>
|
||||
impl<'de, R: Reader<'de>> Iterator for CountedStream<'de, R>
|
||||
{
|
||||
type Item = IOResult<IOValue>;
|
||||
fn next(&mut self) -> Option<Self::Item> {
|
||||
|
@ -494,11 +480,11 @@ impl<'de, 'a, S: BinarySource<'de>> Iterator for CountedStream<'de, 'a, S>
|
|||
}
|
||||
}
|
||||
|
||||
struct DelimitedStream<'de, 'a, S: BinarySource<'de>> {
|
||||
reader: ConfiguredPackedReader<'de, 'a, S>,
|
||||
struct DelimitedStream<'a, 'de, S: BinarySource<'de>> {
|
||||
reader: ConfiguredReader<'de, &'a mut PackedReader<'de, S>>,
|
||||
}
|
||||
|
||||
impl<'de, 'a, S: BinarySource<'de>> Iterator for DelimitedStream<'de, 'a, S>
|
||||
impl<'a, 'de, S: BinarySource<'de>> Iterator for DelimitedStream<'a, 'de, S>
|
||||
{
|
||||
type Item = IOResult<IOValue>;
|
||||
fn next(&mut self) -> Option<Self::Item> {
|
||||
|
|
|
@ -3,7 +3,7 @@ use num::bigint::BigInt;
|
|||
use num::cast::ToPrimitive;
|
||||
use std::convert::TryInto;
|
||||
use super::constants::{Op, AtomMinor, CompoundMinor};
|
||||
use super::super::{Encoder, IOValue};
|
||||
use super::super::IOValue;
|
||||
|
||||
use super::super::writer::{Writer, Result, varint};
|
||||
|
||||
|
@ -40,6 +40,14 @@ impl<'w, W: std::io::Write> PackedWriter<'w, W> {
|
|||
}
|
||||
}
|
||||
|
||||
impl<'w> PackedWriter<'w, &'w mut Vec<u8>> {
|
||||
pub fn encode(v: &IOValue) -> std::io::Result<Vec<u8>> {
|
||||
let mut buf: Vec<u8> = Vec::new();
|
||||
PackedWriter(&mut buf).write(v)?;
|
||||
Ok(buf)
|
||||
}
|
||||
}
|
||||
|
||||
impl<'w, W: std::io::Write> Writer for PackedWriter<'w, W> {
|
||||
type Pointer = ();
|
||||
type Annotation = ();
|
||||
|
@ -58,7 +66,7 @@ impl<'w, W: std::io::Write> Writer for PackedWriter<'w, W> {
|
|||
|
||||
fn extend_annotation(&mut self, _a: &mut Self::Annotation, annotation: &IOValue) -> Result<()> {
|
||||
write_header(self, Op::Misc(0), 5)?;
|
||||
Encoder::new(self).write(annotation)
|
||||
self.write(annotation)
|
||||
}
|
||||
|
||||
fn end_annotation(&mut self, _a: Self::Annotation, _value_p: Self::Pointer) -> Result<Self::Pointer> {
|
||||
|
|
|
@ -1,5 +1,6 @@
|
|||
use std::borrow::Cow;
|
||||
use std::io::{Read, Error};
|
||||
use std::marker::PhantomData;
|
||||
use super::value::{NestedValue, IOValue};
|
||||
use crate::error::{self, ExpectedKind, Received, io_eof};
|
||||
|
||||
|
@ -89,6 +90,17 @@ pub trait Reader<'de> {
|
|||
Received::ReceivedRecordWithLabel(label.to_owned())))
|
||||
}
|
||||
}
|
||||
|
||||
fn configured(self, read_annotations: bool) -> ConfiguredReader<'de, Self>
|
||||
where
|
||||
Self: std::marker::Sized
|
||||
{
|
||||
ConfiguredReader {
|
||||
reader: self,
|
||||
read_annotations,
|
||||
phantom: PhantomData,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl<'r, 'de, R: Reader<'de>> Reader<'de> for &'r mut R {
|
||||
|
@ -321,3 +333,34 @@ impl<'de> BinarySource<'de> for BytesBinarySource<'de> {
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
pub struct ConfiguredReader<'de, R: Reader<'de>> {
|
||||
pub reader: R,
|
||||
pub read_annotations: bool,
|
||||
phantom: PhantomData<&'de ()>,
|
||||
}
|
||||
|
||||
impl<'de, R: Reader<'de>> ConfiguredReader<'de, R> {
|
||||
pub fn new(reader: R) -> Self {
|
||||
reader.configured(true)
|
||||
}
|
||||
|
||||
pub fn set_read_annotations(&mut self, read_annotations: bool) {
|
||||
self.read_annotations = read_annotations
|
||||
}
|
||||
|
||||
pub fn demand_next(&mut self) -> IOResult<IOValue> {
|
||||
self.reader.demand_next(self.read_annotations)
|
||||
}
|
||||
}
|
||||
|
||||
impl<'de, R: Reader<'de>> std::iter::Iterator for ConfiguredReader<'de, R> {
|
||||
type Item = IOResult<IOValue>;
|
||||
fn next(&mut self) -> Option<Self::Item> {
|
||||
match self.reader.next(self.read_annotations) {
|
||||
Err(e) => Some(Err(e)),
|
||||
Ok(None) => None,
|
||||
Ok(Some(v)) => Some(Ok(v)),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,7 +1,8 @@
|
|||
use num;
|
||||
use num::bigint::BigInt;
|
||||
use std::io::Error;
|
||||
use super::value::IOValue;
|
||||
use super::signed_integer::SignedIntegerRepr;
|
||||
use super::value::{Domain, Value, NestedValue, IOValue, UnwrappedIOValue, Float, Double};
|
||||
|
||||
pub type Result<T> = std::result::Result<T, Error>;
|
||||
|
||||
|
@ -62,6 +63,75 @@ pub trait Writer {
|
|||
fn extend_dictionary_key(&mut self, s: &mut Self::Dictionary, key_p: Self::Pointer) -> Result<Self::KeyPointer>;
|
||||
fn extend_dictionary_value(&mut self, s: &mut Self::Dictionary, key_p: Self::KeyPointer, value_p: Self::Pointer) -> Result<()>;
|
||||
fn end_dictionary(&mut self, s: Self::Dictionary) -> Result<Self::Pointer>;
|
||||
|
||||
//---------------------------------------------------------------------------
|
||||
|
||||
fn write(&mut self, v: &IOValue) -> Result<Self::Pointer> {
|
||||
match v.annotations().maybe_slice() {
|
||||
None => self.write_value(v.value()),
|
||||
Some(anns) => {
|
||||
let mut a = self.start_annotation()?;
|
||||
for ann in anns {
|
||||
self.extend_annotation(&mut a, ann)?;
|
||||
}
|
||||
let p = self.write_value(v.value())?;
|
||||
self.end_annotation(a, p)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fn write_value(&mut self, v: &UnwrappedIOValue) -> Result<Self::Pointer> {
|
||||
match v {
|
||||
Value::Boolean(b) => self.write_bool(*b),
|
||||
Value::Float(Float(f)) => self.write_f32(*f),
|
||||
Value::Double(Double(d)) => self.write_f64(*d),
|
||||
Value::SignedInteger(n) => match n.repr() {
|
||||
SignedIntegerRepr::I128(i) => self.write_i128(*i),
|
||||
SignedIntegerRepr::U128(u) => self.write_u128(*u),
|
||||
SignedIntegerRepr::Big(ref n) => self.write_int(n),
|
||||
}
|
||||
Value::String(ref s) => self.write_string(s),
|
||||
Value::ByteString(ref bs) => self.write_bytes(bs),
|
||||
Value::Symbol(ref s) => self.write_symbol(s),
|
||||
Value::Record(r) => {
|
||||
let mut c = self.start_record(r.arity() as u64)?;
|
||||
let p = self.write(r.label())?;
|
||||
self.extend_compound(&mut c, p)?;
|
||||
for f in r.fields() {
|
||||
let p = self.write(f)?;
|
||||
self.extend_compound(&mut c, p)?;
|
||||
}
|
||||
self.end_compound(c)
|
||||
}
|
||||
Value::Sequence(ref vs) => {
|
||||
let mut c = self.start_sequence(vs.len() as u64)?;
|
||||
for v in vs {
|
||||
let p = self.write(v)?;
|
||||
self.extend_compound(&mut c, p)?;
|
||||
}
|
||||
self.end_compound(c)
|
||||
}
|
||||
Value::Set(ref vs) => {
|
||||
let mut c = self.start_set(vs.len() as u64)?;
|
||||
for v in vs {
|
||||
let p = self.write(v)?;
|
||||
self.extend_compound(&mut c, p)?;
|
||||
}
|
||||
self.end_compound(c)
|
||||
}
|
||||
Value::Dictionary(ref vs) => {
|
||||
let mut d = self.start_dictionary(vs.len() as u64)?;
|
||||
for (k, v) in vs {
|
||||
let p = self.write(k)?;
|
||||
let kp = self.extend_dictionary_key(&mut d, p)?;
|
||||
let p = self.write(v)?;
|
||||
self.extend_dictionary_value(&mut d, kp, p)?;
|
||||
}
|
||||
self.end_dictionary(d)
|
||||
}
|
||||
Value::Domain(ref d) => self.write(&d.as_preserves()?)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
pub fn bigvarint<W: std::io::Write>(w: &mut W, mut v: u64) -> Result<()> {
|
||||
|
|
|
@ -1,22 +1,22 @@
|
|||
use preserves::error::{is_eof_io_error, is_syntax_io_error};
|
||||
use preserves::symbol::Symbol;
|
||||
use preserves::value::de::from_value as deserialize_from_value;
|
||||
use preserves::value::decoder;
|
||||
use preserves::value::encoder::encode_bytes;
|
||||
use preserves::value::IOValue;
|
||||
use preserves::value::PackedReader;
|
||||
use preserves::value::PackedWriter;
|
||||
use preserves::value::Reader;
|
||||
use preserves::value::de::from_value as deserialize_from_value;
|
||||
use std::iter::Iterator;
|
||||
|
||||
mod samples;
|
||||
use samples::*;
|
||||
|
||||
fn decode_all<'de>(bytes: &'de [u8]) -> Result<Vec<IOValue>, std::io::Error> {
|
||||
let d = decoder::from_bytes(bytes);
|
||||
d.collect()
|
||||
PackedReader::decode_bytes(bytes).configured(true).collect()
|
||||
}
|
||||
|
||||
#[test] fn run() -> std::io::Result<()> {
|
||||
let mut fh = std::fs::File::open("../../tests/samples.bin").unwrap();
|
||||
let mut d = decoder::from_read(&mut fh);
|
||||
let mut d = PackedReader::decode_read(&mut fh).configured(true);
|
||||
let tests: TestCases = deserialize_from_value(&d.next().unwrap().unwrap()).unwrap();
|
||||
// println!("{:#?}", tests);
|
||||
|
||||
|
@ -24,25 +24,25 @@ fn decode_all<'de>(bytes: &'de [u8]) -> Result<Vec<IOValue>, std::io::Error> {
|
|||
println!("{:?} ==> {:?}", name, case);
|
||||
match case {
|
||||
TestCase::Test(ref bin, ref val) => {
|
||||
assert_eq!(&decode_all(&encode_bytes(val)?[..])?, &[val.clone()]);
|
||||
assert_eq!(&decode_all(&PackedWriter::encode(val)?[..])?, &[val.clone()]);
|
||||
assert_eq!(&decode_all(&bin[..])?, &[val.clone()]);
|
||||
assert_eq!(&encode_bytes(val)?, bin);
|
||||
assert_eq!(&PackedWriter::encode(val)?, bin);
|
||||
}
|
||||
TestCase::NondeterministicTest(ref bin, ref val) => {
|
||||
// The test cases in samples.txt are carefully
|
||||
// written so that while strictly
|
||||
// "nondeterministic", the order of keys in
|
||||
// dictionaries follows Preserves order.
|
||||
assert_eq!(&decode_all(&encode_bytes(val)?[..])?, &[val.clone()]);
|
||||
assert_eq!(&decode_all(&PackedWriter::encode(val)?[..])?, &[val.clone()]);
|
||||
assert_eq!(&decode_all(&bin[..])?, &[val.clone()]);
|
||||
assert_eq!(&encode_bytes(val)?, bin);
|
||||
assert_eq!(&PackedWriter::encode(val)?, bin);
|
||||
}
|
||||
TestCase::StreamingTest(ref bin, ref val) => {
|
||||
assert_eq!(&decode_all(&encode_bytes(val)?[..])?, &[val.clone()]);
|
||||
assert_eq!(&decode_all(&PackedWriter::encode(val)?[..])?, &[val.clone()]);
|
||||
assert_eq!(&decode_all(&bin[..])?, &[val.clone()]);
|
||||
}
|
||||
TestCase::DecodeTest(ref bin, ref val) => {
|
||||
assert_eq!(&decode_all(&encode_bytes(val)?[..])?, &[val.clone()]);
|
||||
assert_eq!(&decode_all(&PackedWriter::encode(val)?[..])?, &[val.clone()]);
|
||||
assert_eq!(&decode_all(&bin[..])?, &[val.clone()]);
|
||||
}
|
||||
TestCase::ParseError(_) => (),
|
||||
|
@ -59,14 +59,14 @@ fn decode_all<'de>(bytes: &'de [u8]) -> Result<Vec<IOValue>, std::io::Error> {
|
|||
}
|
||||
}
|
||||
TestCase::DecodeShort(ref bin) => {
|
||||
assert!(if let Err(e) = decoder::from_bytes(bin).next().unwrap() {
|
||||
assert!(if let Err(e) = PackedReader::decode_bytes(bin).configured(true).next().unwrap() {
|
||||
is_eof_io_error(&e)
|
||||
} else {
|
||||
false
|
||||
})
|
||||
}
|
||||
TestCase::DecodeEOF(ref bin) => {
|
||||
assert!(decoder::from_bytes(bin).next().is_none());
|
||||
assert!(PackedReader::decode_bytes(bin).configured(true).next().is_none());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue