Update Rust implementation

This commit is contained in:
Tony Garnock-Jones 2021-01-06 17:42:02 +01:00
parent ca2276d268
commit a1a604aee8
14 changed files with 1019 additions and 1045 deletions

View File

@ -1,6 +1,6 @@
[package] [package]
name = "preserves" name = "preserves"
version = "0.9.0" version = "0.10.0"
authors = ["Tony Garnock-Jones <tonyg@leastfixedpoint.com>"] authors = ["Tony Garnock-Jones <tonyg@leastfixedpoint.com>"]
edition = "2018" edition = "2018"
description = "Implementation of the Preserves serialization format via serde." description = "Implementation of the Preserves serialization format via serde."
@ -13,7 +13,6 @@ gitlab = { repository = "preserves/preserves" }
[dependencies] [dependencies]
num = "0.2" num = "0.2"
num_enum = "0.4.1"
serde = { version = "1.0", features = ["derive"] } serde = { version = "1.0", features = ["derive"] }
serde_bytes = "0.11" serde_bytes = "0.11"
lazy_static = "1.4.0" lazy_static = "1.4.0"

View File

@ -38,7 +38,7 @@ pub fn bench_encoder(c: &mut Criterion) {
let v = PackedReader::decode_read(&mut fh).demand_next(true).unwrap(); let v = PackedReader::decode_read(&mut fh).demand_next(true).unwrap();
c.bench_function("encode samples.bin", |b| b.iter_with_large_drop(|| { c.bench_function("encode samples.bin", |b| b.iter_with_large_drop(|| {
let mut bs = vec![]; let mut bs = vec![];
PackedWriter(&mut bs).write(&v).unwrap(); PackedWriter::new(&mut bs).write(&v).unwrap();
bs bs
})); }));
} }
@ -56,7 +56,7 @@ pub fn bench_ser(c: &mut Criterion) {
let v: TestCases = de::from_read(&mut fh).unwrap(); let v: TestCases = de::from_read(&mut fh).unwrap();
c.bench_function("serialize samples.bin", |b| b.iter_with_large_drop(|| { c.bench_function("serialize samples.bin", |b| b.iter_with_large_drop(|| {
let mut bs = vec![]; let mut bs = vec![];
ser::to_writer(&mut PackedWriter(&mut bs), &v).unwrap(); ser::to_writer(&mut PackedWriter::new(&mut bs), &v).unwrap();
bs bs
})); }));
} }
@ -74,7 +74,7 @@ pub fn bench_ser_encoder(c: &mut Criterion) {
let v: TestCases = de::from_read(&mut fh).unwrap(); let v: TestCases = de::from_read(&mut fh).unwrap();
c.bench_function("serialize-then-encode samples.bin", |b| b.iter_with_large_drop(|| { c.bench_function("serialize-then-encode samples.bin", |b| b.iter_with_large_drop(|| {
let mut bs = vec![]; let mut bs = vec![];
PackedWriter(&mut bs).write(&value::ser::to_value(&v)).unwrap(); PackedWriter::new(&mut bs).write(&value::ser::to_value(&v)).unwrap();
bs bs
})); }));
} }
@ -113,7 +113,7 @@ pub fn large_testdata_encoder(c: &mut Criterion) {
} }
b.iter_with_large_drop(|| { b.iter_with_large_drop(|| {
let mut bs = vec![]; let mut bs = vec![];
let mut w = PackedWriter(&mut bs); let mut w = PackedWriter::new(&mut bs);
for v in &vs { for v in &vs {
w.write(&v).unwrap(); w.write(&v).unwrap();
} }

View File

@ -3,7 +3,7 @@ use serde::de::{Visitor, SeqAccess, MapAccess, EnumAccess, VariantAccess, Deseri
use std::borrow::Cow; use std::borrow::Cow;
use std::marker::PhantomData; use std::marker::PhantomData;
use super::value::PackedReader; use super::value::PackedReader;
use super::value::reader::{Reader, IOBinarySource, BytesBinarySource, CompoundBody}; use super::value::reader::{Reader, IOBinarySource, BytesBinarySource};
pub use super::error::Error; pub use super::error::Error;
@ -144,31 +144,31 @@ impl<'r, 'de, 'a, R: Reader<'de>> serde::de::Deserializer<'de> for &'a mut Deser
fn deserialize_option<V>(self, visitor: V) -> Result<V::Value> where V: Visitor<'de> fn deserialize_option<V>(self, visitor: V) -> Result<V::Value> where V: Visitor<'de>
{ {
let (is_some, mut compound_body) = self.read.open_option()?; let is_some = self.read.open_option()?;
let result = if is_some { let result = if is_some {
compound_body.ensure_more_expected(self.read)?; self.read.ensure_more_expected()?;
visitor.visit_some(&mut *self)? visitor.visit_some(&mut *self)?
} else { } else {
visitor.visit_none::<Error>()? visitor.visit_none::<Error>()?
}; };
compound_body.ensure_complete(self.read)?; self.read.ensure_complete()?;
Ok(result) Ok(result)
} }
fn deserialize_unit<V>(self, visitor: V) -> Result<V::Value> where V: Visitor<'de> fn deserialize_unit<V>(self, visitor: V) -> Result<V::Value> where V: Visitor<'de>
{ {
let mut compound_body = self.read.open_simple_record("tuple", Some(0))?; self.read.open_simple_record("tuple", Some(0))?;
let result = visitor.visit_unit::<Error>()?; let result = visitor.visit_unit::<Error>()?;
compound_body.ensure_complete(self.read)?; self.read.ensure_complete()?;
Ok(result) Ok(result)
} }
fn deserialize_unit_struct<V>(self, name: &'static str, visitor: V) fn deserialize_unit_struct<V>(self, name: &'static str, visitor: V)
-> Result<V::Value> where V: Visitor<'de> -> Result<V::Value> where V: Visitor<'de>
{ {
let mut compound_body = self.read.open_simple_record(name, Some(0))?; self.read.open_simple_record(name, Some(0))?;
let result = visitor.visit_unit::<Error>()?; let result = visitor.visit_unit::<Error>()?;
compound_body.ensure_complete(self.read)?; self.read.ensure_complete()?;
Ok(result) Ok(result)
} }
@ -180,10 +180,10 @@ impl<'r, 'de, 'a, R: Reader<'de>> serde::de::Deserializer<'de> for &'a mut Deser
{ {
Some(v) => visitor.visit_u64(v), Some(v) => visitor.visit_u64(v),
None => { None => {
let mut compound_body = self.read.open_simple_record(name, Some(1))?; self.read.open_simple_record(name, Some(1))?;
compound_body.ensure_more_expected(self.read)?; self.read.ensure_more_expected()?;
let result = visitor.visit_newtype_struct(&mut *self)?; let result = visitor.visit_newtype_struct(&mut *self)?;
compound_body.ensure_complete(self.read)?; self.read.ensure_complete()?;
Ok(result) Ok(result)
} }
} }
@ -192,14 +192,14 @@ impl<'r, 'de, 'a, R: Reader<'de>> serde::de::Deserializer<'de> for &'a mut Deser
fn deserialize_seq<V>(self, visitor: V) -> Result<V::Value> where V: Visitor<'de> { fn deserialize_seq<V>(self, visitor: V) -> Result<V::Value> where V: Visitor<'de> {
// Hack around serde's model: Deserialize *sets* as sequences, // Hack around serde's model: Deserialize *sets* as sequences,
// too, and reconstruct them as Rust Sets on the visitor side. // too, and reconstruct them as Rust Sets on the visitor side.
let compound_body = self.read.open_sequence_or_set()?; self.read.open_sequence_or_set()?;
visitor.visit_seq(Seq::new(self, compound_body)) visitor.visit_seq(Seq::new(self))
} }
fn deserialize_tuple<V>(self, len: usize, visitor: V) -> Result<V::Value> where V: Visitor<'de> fn deserialize_tuple<V>(self, len: usize, visitor: V) -> Result<V::Value> where V: Visitor<'de>
{ {
let compound_body = self.read.open_simple_record("tuple", Some(len))?; self.read.open_simple_record("tuple", Some(len))?;
let mut seq = Seq::new(self, compound_body); let mut seq = Seq::new(self);
let result = visitor.visit_seq(&mut seq)?; let result = visitor.visit_seq(&mut seq)?;
seq.skip_remainder()?; seq.skip_remainder()?;
Ok(result) Ok(result)
@ -208,18 +208,17 @@ impl<'r, 'de, 'a, R: Reader<'de>> serde::de::Deserializer<'de> for &'a mut Deser
fn deserialize_tuple_struct<V>(self, name: &'static str, len: usize, visitor: V) fn deserialize_tuple_struct<V>(self, name: &'static str, len: usize, visitor: V)
-> Result<V::Value> where V: Visitor<'de> -> Result<V::Value> where V: Visitor<'de>
{ {
let compound_body = self.read.open_simple_record(name, Some(len))?; self.read.open_simple_record(name, Some(len))?;
let mut seq = Seq::new(self, compound_body); let mut seq = Seq::new(self);
let result = visitor.visit_seq(&mut seq)?; let result = visitor.visit_seq(&mut seq)?;
seq.skip_remainder()?; seq.skip_remainder()?;
Ok(result) Ok(result)
} }
fn deserialize_map<V>(self, visitor: V) -> Result<V::Value> where V: Visitor<'de> { fn deserialize_map<V>(self, visitor: V) -> Result<V::Value> where V: Visitor<'de> {
let compound_body = self.read.open_dictionary()?; self.read.open_dictionary()?;
let mut seq = Seq::new(self, compound_body); let mut seq = Seq::new(self);
let result = visitor.visit_map(&mut seq)?; let result = visitor.visit_map(&mut seq)?;
seq.skip_remainder()?;
Ok(result) Ok(result)
} }
@ -229,8 +228,8 @@ impl<'r, 'de, 'a, R: Reader<'de>> serde::de::Deserializer<'de> for &'a mut Deser
visitor: V) visitor: V)
-> Result<V::Value> where V: Visitor<'de> -> Result<V::Value> where V: Visitor<'de>
{ {
let compound_body = self.read.open_simple_record(name, Some(fields.len()))?; self.read.open_simple_record(name, Some(fields.len()))?;
let mut seq = Seq::new(self, compound_body); let mut seq = Seq::new(self);
let result = visitor.visit_seq(&mut seq)?; let result = visitor.visit_seq(&mut seq)?;
seq.skip_remainder()?; seq.skip_remainder()?;
Ok(result) Ok(result)
@ -261,24 +260,23 @@ impl<'r, 'de, 'a, R: Reader<'de>> serde::de::Deserializer<'de> for &'a mut Deser
pub struct Seq<'de, 'r, 'a, R: Reader<'de>> { pub struct Seq<'de, 'r, 'a, R: Reader<'de>> {
de: &'a mut Deserializer<'de, 'r, R>, de: &'a mut Deserializer<'de, 'r, R>,
compound_body: CompoundBody<R::CompoundInfo>,
} }
impl<'de, 'r, 'a, R: Reader<'de>> Seq<'de, 'r, 'a, R> { impl<'de, 'r, 'a, R: Reader<'de>> Seq<'de, 'r, 'a, R> {
fn new(de: &'a mut Deserializer<'de, 'r, R>, compound_body: CompoundBody<R::CompoundInfo>) -> Self { fn new(de: &'a mut Deserializer<'de, 'r, R>) -> Self {
Seq { de, compound_body } Seq { de }
} }
fn skip_remainder(&mut self) -> Result<()> { fn skip_remainder(&mut self) -> Result<()> {
self.compound_body.skip_remainder(self.de.read) self.de.read.skip_remainder()
} }
fn next_item<T>(&mut self, seed: T) -> fn next_item<T>(&mut self, seed: T) ->
Result<Option<T::Value>> where T: DeserializeSeed<'de> Result<Option<T::Value>> where T: DeserializeSeed<'de>
{ {
match self.compound_body.more_expected(self.de.read)? { match self.de.read.close_compound()? {
false => Ok(None), true => Ok(None),
true => Ok(Some(seed.deserialize(&mut *self.de)?)), false => Ok(Some(seed.deserialize(&mut *self.de)?)),
} }
} }
} }
@ -319,10 +317,9 @@ impl<'de, 'r, 'a, R: Reader<'de>> EnumAccess<'de> for &'a mut Deserializer<'de,
fn variant_seed<V>(self, seed: V) fn variant_seed<V>(self, seed: V)
-> Result<(V::Value, Self::Variant)> where V: DeserializeSeed<'de> -> Result<(V::Value, Self::Variant)> where V: DeserializeSeed<'de>
{ {
let mut compound_body = self.read.open_record(None)?; self.read.open_record(None)?;
compound_body.ensure_more_expected(self.read)?;
let variant = seed.deserialize(&mut *self)?; let variant = seed.deserialize(&mut *self)?;
Ok((variant, Seq::new(self, compound_body))) Ok((variant, Seq::new(self)))
} }
} }

View File

@ -24,7 +24,6 @@ mod dom {
impl Domain for Dom { impl Domain for Dom {
fn as_preserves(&self) -> Result<IOValue, std::io::Error> { fn as_preserves(&self) -> Result<IOValue, std::io::Error> {
Ok(match self { Ok(match self {
// TODO: How to nicely expose streaming values?
Dom::One => Value::ByteString(vec![255, 255, 255, 255]).wrap(), Dom::One => Value::ByteString(vec![255, 255, 255, 255]).wrap(),
Dom::Two => Value::symbol(&format!("Dom::{:?}", self)).wrap(), Dom::Two => Value::symbol(&format!("Dom::{:?}", self)).wrap(),
}) })
@ -37,7 +36,7 @@ mod dom {
Value::from(2).wrap()]) Value::from(2).wrap()])
.wrap(); .wrap();
assert_eq!(PackedWriter::encode(&v.to_io_value()).unwrap(), assert_eq!(PackedWriter::encode(&v.to_io_value()).unwrap(),
[147, 49, 100, 255, 255, 255, 255, 50]); [0xb5, 0x91, 0xb2, 0x04, 255, 255, 255, 255, 0x92, 0x84]);
} }
#[test] fn test_two() { #[test] fn test_two() {
@ -46,7 +45,7 @@ mod dom {
Value::from(2).wrap()]) Value::from(2).wrap()])
.wrap(); .wrap();
assert_eq!(PackedWriter::encode(&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]); [0xb5, 0x91, 0xb3, 0x08, 68, 111, 109, 58, 58, 84, 119, 111, 0x92, 0x84]);
} }
} }
@ -245,12 +244,12 @@ mod decoder_tests {
match r { match r {
Ok(v) => panic!("Expected Expected({:?}), but got a parse of {:?}", k, v), Ok(v) => panic!("Expected Expected({:?}), but got a parse of {:?}", k, v),
Err(Error::Expected(k1, _)) if k1 == k => (), Err(Error::Expected(k1, _)) if k1 == k => (),
Err(e) => panic!("Expected Expected({:?}, but got an error of {:?}", k, e), Err(e) => panic!("Expected Expected({:?}), but got an error of {:?}", k, e),
} }
} }
#[test] fn skip_annotations_noskip() { #[test] fn skip_annotations_noskip() {
let mut buf = &b"\x0521"[..]; let mut buf = &b"\x85\x92\x91"[..];
let mut d = ConfiguredReader::new(PackedReader::decode_bytes(&mut buf)); let mut d = ConfiguredReader::new(PackedReader::decode_bytes(&mut buf));
let v = d.demand_next().unwrap(); let v = d.demand_next().unwrap();
assert_eq!(v.annotations().slice().len(), 1); assert_eq!(v.annotations().slice().len(), 1);
@ -259,7 +258,7 @@ mod decoder_tests {
} }
#[test] fn skip_annotations_skip() { #[test] fn skip_annotations_skip() {
let mut buf = &b"\x0521"[..]; let mut buf = &b"\x85\x92\x91"[..];
let mut d = ConfiguredReader::new(PackedReader::decode_bytes(&mut buf)); let mut d = ConfiguredReader::new(PackedReader::decode_bytes(&mut buf));
d.set_read_annotations(false); d.set_read_annotations(false);
let v = d.demand_next().unwrap(); let v = d.demand_next().unwrap();
@ -268,117 +267,103 @@ mod decoder_tests {
} }
#[test] fn multiple_values_buf_advanced() { #[test] fn multiple_values_buf_advanced() {
let mut buf = &b"\x81tPing\x81tPong"[..]; let mut buf = &b"\xb4\xb3\x04Ping\x84\xb4\xb3\x04Pong\x84"[..];
assert_eq!(buf.len(), 12); assert_eq!(buf.len(), 16);
let mut d = ConfiguredReader::new(PackedReader::decode_bytes(&mut buf)); let mut d = ConfiguredReader::new(PackedReader::decode_bytes(&mut buf));
assert_eq!(d.reader.source.index, 0); assert_eq!(d.reader.source.index, 0);
assert_eq!(d.demand_next().unwrap().value(), &Value::simple_record0("Ping")); assert_eq!(d.demand_next().unwrap().value(), &Value::simple_record0("Ping"));
assert_eq!(d.reader.source.index, 6); assert_eq!(d.reader.source.index, 8);
assert_eq!(d.demand_next().unwrap().value(), &Value::simple_record0("Pong")); assert_eq!(d.demand_next().unwrap().value(), &Value::simple_record0("Pong"));
assert_eq!(d.reader.source.index, 12); assert_eq!(d.reader.source.index, 16);
assert!(d.next().is_none()); assert!(d.next().is_none());
assert!(if let Err(e) = d.demand_next() { is_eof_io_error(&e) } else { false }); assert!(if let Err(e) = d.demand_next() { is_eof_io_error(&e) } else { false });
} }
#[test] fn direct_i8_format_a_positive() { assert_eq!(from_bytes::<i8>(b"1").unwrap(), 1) } #[test] fn direct_i8_format_a_positive() { assert_eq!(from_bytes::<i8>(b"\x91").unwrap(), 1) }
#[test] fn direct_i8_format_a_zero() { assert_eq!(from_bytes::<i8>(b"0").unwrap(), 0) } #[test] fn direct_i8_format_a_zero() { assert_eq!(from_bytes::<i8>(b"\x90").unwrap(), 0) }
#[test] fn direct_i8_format_a_negative() { assert_eq!(from_bytes::<i8>(b"?").unwrap(), -1) } #[test] fn direct_i8_format_a_negative() { assert_eq!(from_bytes::<i8>(b"\x9f").unwrap(), -1) }
#[test] fn direct_i8_format_b() { assert_eq!(from_bytes::<i8>(b"A\xfe").unwrap(), -2) } #[test] fn direct_i8_format_b() { assert_eq!(from_bytes::<i8>(b"\xa0\xfe").unwrap(), -2) }
#[test] fn direct_i8_format_b_too_long() { assert_eq!(from_bytes::<i8>(b"C\xff\xff\xfe").unwrap(), -2) } #[test] fn direct_i8_format_b_too_long() { assert_eq!(from_bytes::<i8>(b"\xa2\xff\xff\xfe").unwrap(), -2) }
#[test] fn direct_i8_format_b_much_too_long() { assert_eq!(from_bytes::<i8>(b"J\xff\xff\xff\xff\xff\xff\xff\xff\xff\xfe").unwrap(), -2) } #[test] fn direct_i8_format_b_much_too_long() { assert_eq!(from_bytes::<i8>(b"\xa9\xff\xff\xff\xff\xff\xff\xff\xff\xff\xfe").unwrap(), -2) }
#[test] fn direct_i8_format_c() { assert_eq!(from_bytes::<i8>(b"$a\xfe\x04").unwrap(), -2) }
#[test] fn direct_i8_format_c_too_long() { assert_eq!(from_bytes::<i8>(b"$a\xffa\xfe\x04").unwrap(), -2) }
#[test] fn direct_i8_format_c_much_too_long() { assert_eq!(from_bytes::<i8>(b"$a\xffa\xffa\xffa\xffa\xffa\xffa\xffa\xffa\xffa\xffa\xffa\xfe\x04").unwrap(), -2) }
#[test] fn direct_u8_format_a_positive() { assert_eq!(from_bytes::<u8>(b"1").unwrap(), 1) } #[test] fn direct_u8_format_a_positive() { assert_eq!(from_bytes::<u8>(b"\x91").unwrap(), 1) }
#[test] fn direct_u8_format_a_zero() { assert_eq!(from_bytes::<u8>(b"0").unwrap(), 0) } #[test] fn direct_u8_format_a_zero() { assert_eq!(from_bytes::<u8>(b"\x90").unwrap(), 0) }
#[test] fn direct_u8_format_b() { assert_eq!(from_bytes::<u8>(b"A1").unwrap(), 49) } #[test] fn direct_u8_format_b() { assert_eq!(from_bytes::<u8>(b"\xa01").unwrap(), 49) }
#[test] fn direct_u8_format_b_too_long() { assert_eq!(from_bytes::<u8>(b"D\0\0\01").unwrap(), 49) } #[test] fn direct_u8_format_b_too_long() { assert_eq!(from_bytes::<u8>(b"\xa3\0\0\01").unwrap(), 49) }
#[test] fn direct_u8_format_b_much_too_long() { assert_eq!(from_bytes::<u8>(b"J\0\0\0\0\0\0\0\0\01").unwrap(), 49) } #[test] fn direct_u8_format_b_much_too_long() { assert_eq!(from_bytes::<u8>(b"\xa9\0\0\0\0\0\0\0\0\01").unwrap(), 49) }
#[test] fn direct_u8_format_c() { assert_eq!(from_bytes::<u8>(b"$a1\x04").unwrap(), 49) }
#[test] fn direct_u8_format_c_too_long() { assert_eq!(from_bytes::<u8>(b"$a\0a1\x04").unwrap(), 49) }
#[test] fn direct_u8_format_c_much_too_long() { assert_eq!(from_bytes::<u8>(b"$a\0a\0a\0a\0a\0a\0a\0a\0a\0a\0a\0a1\x04").unwrap(), 49) }
#[test] fn direct_i16_format_a() { assert_eq!(from_bytes::<i16>(b">").unwrap(), -2) } #[test] fn direct_i16_format_a() { assert_eq!(from_bytes::<i16>(b"\x9e").unwrap(), -2) }
#[test] fn direct_i16_format_b() { assert_eq!(from_bytes::<i16>(b"B\xfe\xff").unwrap(), -257) } #[test] fn direct_i16_format_b() { assert_eq!(from_bytes::<i16>(b"\xa1\xfe\xff").unwrap(), -257) }
#[test] fn direct_u8_wrong_format() { #[test] fn direct_u8_wrong_format() {
expect_expected(ExpectedKind::SignedInteger, from_bytes::<u8>(b"Ubogus")) expect_expected(ExpectedKind::SignedInteger, from_bytes::<u8>(b"\xb1\x05bogus"))
} }
#[test] fn direct_u8_format_b_too_large() { #[test] fn direct_u8_format_b_too_large() {
expect_number_out_of_range(from_bytes::<u8>(b"D\0\011")) expect_number_out_of_range(from_bytes::<u8>(b"\xa3\0\011"))
}
#[test] fn direct_u8_format_c_too_large() {
expect_number_out_of_range(from_bytes::<u8>(b"$a1a1\x04"))
} }
#[test] fn direct_i8_format_b_too_large() { #[test] fn direct_i8_format_b_too_large() {
expect_number_out_of_range(from_bytes::<i8>(b"B\xfe\xff")) expect_number_out_of_range(from_bytes::<i8>(b"\xa1\xfe\xff"))
}
#[test] fn direct_i8_format_c_too_large() {
expect_number_out_of_range(from_bytes::<u8>(b"$a\xfea\xff\x04"))
} }
#[test] fn direct_i16_format_b_too_large() { #[test] fn direct_i16_format_b_too_large() {
expect_number_out_of_range(from_bytes::<i16>(b"C\xfe\xff\xff")); expect_number_out_of_range(from_bytes::<i16>(b"\xa2\xfe\xff\xff"));
} }
#[test] fn direct_i32_format_b_ok() { #[test] fn direct_i32_format_b_ok() {
assert_eq!(from_bytes::<i32>(b"C\xfe\xff\xff").unwrap(), -65537); assert_eq!(from_bytes::<i32>(b"\xa2\xfe\xff\xff").unwrap(), -65537);
} }
#[test] fn direct_i32_format_b_ok_2() { #[test] fn direct_i32_format_b_ok_2() {
assert_eq!(from_bytes::<i32>(b"D\xfe\xff\xff\xff").unwrap(), -16777217); assert_eq!(from_bytes::<i32>(b"\xa3\xfe\xff\xff\xff").unwrap(), -16777217);
} }
#[test] fn direct_i64_format_b() { #[test] fn direct_i64_format_b() {
assert_eq!(from_bytes::<i64>(b"A\xff").unwrap(), -1); assert_eq!(from_bytes::<i64>(b"\xa0\xff").unwrap(), -1);
assert_eq!(from_bytes::<i64>(b"C\xff\xff\xff").unwrap(), -1); assert_eq!(from_bytes::<i64>(b"\xa2\xff\xff\xff").unwrap(), -1);
assert_eq!(from_bytes::<i64>(b"J\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff").unwrap(), -1); assert_eq!(from_bytes::<i64>(b"\xa9\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff").unwrap(), -1);
assert_eq!(from_bytes::<i64>(b"A\xfe").unwrap(), -2); assert_eq!(from_bytes::<i64>(b"\xa0\xfe").unwrap(), -2);
assert_eq!(from_bytes::<i64>(b"C\xff\xfe\xff").unwrap(), -257); assert_eq!(from_bytes::<i64>(b"\xa2\xff\xfe\xff").unwrap(), -257);
assert_eq!(from_bytes::<i64>(b"C\xfe\xff\xff").unwrap(), -65537); assert_eq!(from_bytes::<i64>(b"\xa2\xfe\xff\xff").unwrap(), -65537);
assert_eq!(from_bytes::<i64>(b"J\xff\xff\xff\xff\xff\xff\xfe\xff\xff\xff").unwrap(), -16777217); assert_eq!(from_bytes::<i64>(b"\xa9\xff\xff\xff\xff\xff\xff\xfe\xff\xff\xff").unwrap(), -16777217);
assert_eq!(from_bytes::<i64>(b"J\xff\xff\xfe\xff\xff\xff\xff\xff\xff\xff").unwrap(), -72057594037927937); assert_eq!(from_bytes::<i64>(b"\xa9\xff\xff\xfe\xff\xff\xff\xff\xff\xff\xff").unwrap(), -72057594037927937);
expect_number_out_of_range(from_bytes::<i64>(b"J\xff\xff\x0e\xff\xff\xff\xff\xff\xff\xff")); expect_number_out_of_range(from_bytes::<i64>(b"\xa9\xff\xff\x0e\xff\xff\xff\xff\xff\xff\xff"));
expect_number_out_of_range(from_bytes::<i64>(b"I\xff\x0e\xff\xff\xff\xff\xff\xff\xff")); expect_number_out_of_range(from_bytes::<i64>(b"\xa8\xff\x0e\xff\xff\xff\xff\xff\xff\xff"));
expect_number_out_of_range(from_bytes::<i64>(b"I\x80\x0e\xff\xff\xff\xff\xff\xff\xff")); expect_number_out_of_range(from_bytes::<i64>(b"\xa8\x80\x0e\xff\xff\xff\xff\xff\xff\xff"));
expect_number_out_of_range(from_bytes::<i64>(b"J\xff\x00\x0e\xff\xff\xff\xff\xff\xff\xff")); expect_number_out_of_range(from_bytes::<i64>(b"\xa9\xff\x00\x0e\xff\xff\xff\xff\xff\xff\xff"));
assert_eq!(from_bytes::<i64>(b"H\xfe\xff\xff\xff\xff\xff\xff\xff").unwrap(), -72057594037927937); assert_eq!(from_bytes::<i64>(b"\xa7\xfe\xff\xff\xff\xff\xff\xff\xff").unwrap(), -72057594037927937);
assert_eq!(from_bytes::<i64>(b"H\x0e\xff\xff\xff\xff\xff\xff\xff").unwrap(), 1080863910568919039); assert_eq!(from_bytes::<i64>(b"\xa7\x0e\xff\xff\xff\xff\xff\xff\xff").unwrap(), 1080863910568919039);
assert_eq!(from_bytes::<i64>(b"H\x80\0\0\0\0\0\0\0").unwrap(), -9223372036854775808); assert_eq!(from_bytes::<i64>(b"\xa7\x80\0\0\0\0\0\0\0").unwrap(), -9223372036854775808);
assert_eq!(from_bytes::<i64>(b"H\0\0\0\0\0\0\0\0").unwrap(), 0); assert_eq!(from_bytes::<i64>(b"\xa7\0\0\0\0\0\0\0\0").unwrap(), 0);
assert_eq!(from_bytes::<i64>(b"@").unwrap(), 0); assert_eq!(from_bytes::<i64>(b"\x90").unwrap(), 0);
assert_eq!(from_bytes::<i64>(b"H\x7f\xff\xff\xff\xff\xff\xff\xff").unwrap(), 9223372036854775807); assert_eq!(from_bytes::<i64>(b"\xa7\x7f\xff\xff\xff\xff\xff\xff\xff").unwrap(), 9223372036854775807);
} }
#[test] fn direct_u64_format_b() { #[test] fn direct_u64_format_b() {
expect_number_out_of_range(from_bytes::<u64>(b"A\xff")); expect_number_out_of_range(from_bytes::<u64>(b"\xa0\xff"));
assert_eq!(from_bytes::<u64>(b"B\0\xff").unwrap(), 255); assert_eq!(from_bytes::<u64>(b"\xa1\0\xff").unwrap(), 255);
expect_number_out_of_range(from_bytes::<u64>(b"C\xff\xff\xff")); expect_number_out_of_range(from_bytes::<u64>(b"\xa2\xff\xff\xff"));
assert_eq!(from_bytes::<u64>(b"D\0\xff\xff\xff").unwrap(), 0xffffff); assert_eq!(from_bytes::<u64>(b"\xa3\0\xff\xff\xff").unwrap(), 0xffffff);
expect_number_out_of_range(from_bytes::<u64>(b"J\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff")); expect_number_out_of_range(from_bytes::<u64>(b"\xa9\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff"));
assert_eq!(from_bytes::<u64>(b"A\x02").unwrap(), 2); assert_eq!(from_bytes::<u64>(b"\xa0\x02").unwrap(), 2);
assert_eq!(from_bytes::<u64>(b"C\x00\x01\x00").unwrap(), 256); assert_eq!(from_bytes::<u64>(b"\xa2\x00\x01\x00").unwrap(), 256);
assert_eq!(from_bytes::<u64>(b"C\x01\x00\x00").unwrap(), 65536); assert_eq!(from_bytes::<u64>(b"\xa2\x01\x00\x00").unwrap(), 65536);
assert_eq!(from_bytes::<u64>(b"J\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00").unwrap(), 16777216); assert_eq!(from_bytes::<u64>(b"\xa9\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00").unwrap(), 16777216);
assert_eq!(from_bytes::<u64>(b"J\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00").unwrap(), 72057594037927936); assert_eq!(from_bytes::<u64>(b"\xa9\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00").unwrap(), 72057594037927936);
assert_eq!(from_bytes::<u64>(b"J\x00\x00\xf2\x00\x00\x00\x00\x00\x00\x00").unwrap(), 0xf200000000000000); assert_eq!(from_bytes::<u64>(b"\xa9\x00\x00\xf2\x00\x00\x00\x00\x00\x00\x00").unwrap(), 0xf200000000000000);
assert_eq!(from_bytes::<u64>(b"J\x00\x00\x72\x00\x00\x00\x00\x00\x00\x00").unwrap(), 0x7200000000000000); assert_eq!(from_bytes::<u64>(b"\xa9\x00\x00\x72\x00\x00\x00\x00\x00\x00\x00").unwrap(), 0x7200000000000000);
expect_number_out_of_range(from_bytes::<u64>(b"J\x00\xf2\x00\x00\x00\x00\x00\x00\x00\x00")); expect_number_out_of_range(from_bytes::<u64>(b"\xa9\x00\xf2\x00\x00\x00\x00\x00\x00\x00\x00"));
assert_eq!(from_bytes::<u64>(b"I\x00\xf2\x00\x00\x00\x00\x00\x00\x00").unwrap(), 0xf200000000000000); assert_eq!(from_bytes::<u64>(b"\xa8\x00\xf2\x00\x00\x00\x00\x00\x00\x00").unwrap(), 0xf200000000000000);
expect_number_out_of_range(from_bytes::<u64>(b"I\x7f\xf2\x00\x00\x00\x00\x00\x00\x00")); expect_number_out_of_range(from_bytes::<u64>(b"\xa8\x7f\xf2\x00\x00\x00\x00\x00\x00\x00"));
expect_number_out_of_range(from_bytes::<u64>(b"J\x00\xff\xf2\x00\x00\x00\x00\x00\x00\x00")); expect_number_out_of_range(from_bytes::<u64>(b"\xa9\x00\xff\xf2\x00\x00\x00\x00\x00\x00\x00"));
assert_eq!(from_bytes::<u64>(b"H\x01\x00\x00\x00\x00\x00\x00\x00").unwrap(), 72057594037927936); assert_eq!(from_bytes::<u64>(b"\xa7\x01\x00\x00\x00\x00\x00\x00\x00").unwrap(), 72057594037927936);
assert_eq!(from_bytes::<u64>(b"H\x0e\xff\xff\xff\xff\xff\xff\xff").unwrap(), 1080863910568919039); assert_eq!(from_bytes::<u64>(b"\xa7\x0e\xff\xff\xff\xff\xff\xff\xff").unwrap(), 1080863910568919039);
expect_number_out_of_range(from_bytes::<u64>(b"H\x80\0\0\0\0\0\0\0")); expect_number_out_of_range(from_bytes::<u64>(b"\xa7\x80\0\0\0\0\0\0\0"));
assert_eq!(from_bytes::<u64>(b"I\0\x80\0\0\0\0\0\0\0").unwrap(), 9223372036854775808); assert_eq!(from_bytes::<u64>(b"\xa8\0\x80\0\0\0\0\0\0\0").unwrap(), 9223372036854775808);
assert_eq!(from_bytes::<u64>(b"H\0\0\0\0\0\0\0\0").unwrap(), 0); assert_eq!(from_bytes::<u64>(b"\xa7\0\0\0\0\0\0\0\0").unwrap(), 0);
assert_eq!(from_bytes::<u64>(b"@").unwrap(), 0); assert_eq!(from_bytes::<u64>(b"\x90").unwrap(), 0);
assert_eq!(from_bytes::<u64>(b"H\x7f\xff\xff\xff\xff\xff\xff\xff").unwrap(), 9223372036854775807); assert_eq!(from_bytes::<u64>(b"\xa7\x7f\xff\xff\xff\xff\xff\xff\xff").unwrap(), 9223372036854775807);
} }
} }
@ -442,50 +427,54 @@ mod serde_tests {
assert_eq!(v, x); assert_eq!(v, x);
let expected_bytes = vec![ let expected_bytes = vec![
0x8f, 0x10, // Struct, 15 members + 1 label 0xb4, // Struct
0x7b, 0x53, 0x69, 0x6d, 0x70, 0x6c, 0x65, 0x56, 0x61, 0x6c, 0x75, 0x65, // SimpleValue 0xb3, 0x0b, 0x53, 0x69, 0x6d, 0x70, 0x6c, 0x65, 0x56, 0x61, 0x6c, 0x75, 0x65, // SimpleValue
0x55, 0x68, 0x65, 0x6c, 0x6c, 0x6f, // "hello" 0xb1, 0x05, 0x68, 0x65, 0x6c, 0x6c, 0x6f, // "hello"
0x74, 0x73, 0x79, 0x6d, 0x31, // sym1 0xb3, 0x04, 0x73, 0x79, 0x6d, 0x31, // sym1
0x74, 0x73, 0x79, 0x6d, 0x32, // sym2 0xb3, 0x04, 0x73, 0x79, 0x6d, 0x32, // sym2
0x74, 0x73, 0x79, 0x6d, 0x33, // sym3 0xb3, 0x04, 0x73, 0x79, 0x6d, 0x33, // sym3
0x74, 0x73, 0x79, 0x6d, 0x34, // sym4 0xb3, 0x04, 0x73, 0x79, 0x6d, 0x34, // sym4
0x55, 0x77, 0x6f, 0x72, 0x6c, 0x64, // "world" 0xb1, 0x05, 0x77, 0x6f, 0x72, 0x6c, 0x64, // "world"
0x65, 0x73, 0x6c, 0x69, 0x63, 0x65, // #"slice" 0xb2, 0x05, 0x73, 0x6c, 0x69, 0x63, 0x65, // #"slice"
0x63, 0x76, 0x65, 0x63, // #"vec" 0xb2, 0x03, 0x76, 0x65, 0x63, // #"vec"
0x94, // Sequence, 4 items 0xb5, // Sequence
0x0, // false 0x80, // false
0x1, // true 0x81, // true
0x0, // false 0x80, // false
0x1, // true 0x81, // true
0xa3, // Set, 3 items 0x84,
0x53, 0x6f, 0x6e, 0x65, 0xb6, // Set
0x55, 0x74, 0x68, 0x72, 0x65, 0x65, 0xb1, 0x03, 0x6f, 0x6e, 0x65,
0x53, 0x74, 0x77, 0x6f, 0xb1, 0x03, 0x74, 0x77, 0x6f,
0x42, 0x30, 0x39, // 12345 0xb1, 0x05, 0x74, 0x68, 0x72, 0x65, 0x65,
0x52, 0x68, 0x69, // "hi" 0x84,
0xb6, // Dictionary, 6 items = 3 key/value pairs 0xa1, 0x30, 0x39, // 12345
0x54, 0x62, 0x6c, 0x75, 0x65, // "blue" 0xb1, 0x02, 0x68, 0x69, // "hi"
0x84, 0x76, 0x43, 0x6f, 0x6c, 0x6f, 0x75, 0x72, 0x30, 0x30, 0x42, 0x00, 0xff, 0xb7, // Dictionary
0x55, 0x67, 0x72, 0x65, 0x65, 0x6e, // "green" 0xb1, 0x03, 0x72, 0x65, 0x64, // "red"
0x84, 0x76, 0x43, 0x6f, 0x6c, 0x6f, 0x75, 0x72, 0x30, 0x42, 0x00, 0xff, 0x30, 0xb4, 0xb3, 0x06, 0x43, 0x6f, 0x6c, 0x6f, 0x75, 0x72, 0xa1, 0x00, 0xff, 0x90, 0x90, 0x84,
0x53, 0x72, 0x65, 0x64, // "red" 0xb1, 0x04, 0x62, 0x6c, 0x75, 0x65, // "blue"
0x84, 0x76, 0x43, 0x6f, 0x6c, 0x6f, 0x75, 0x72, 0x42, 0x00, 0xff, 0x30, 0x30, 0xb4, 0xb3, 0x06, 0x43, 0x6f, 0x6c, 0x6f, 0x75, 0x72, 0x90, 0x90, 0xa1, 0x00, 0xff, 0x84,
0xb1, 0x05, 0x67, 0x72, 0x65, 0x65, 0x6e, // "green"
0xb4, 0xb3, 0x06, 0x43, 0x6f, 0x6c, 0x6f, 0x75, 0x72, 0x90, 0xa1, 0x00, 0xff, 0x90, 0x84,
0x84,
0x2, 0x41, 0x45, 0x85, 0x1f, // 12.345, 0x82, 0x41, 0x45, 0x85, 0x1f, // 12.345,
0x3, 0x40, 0x28, 0xb0, 0xfc, 0xd3, 0x24, 0xd5, 0xa2, // 12.3456789 0x83, 0x40, 0x28, 0xb0, 0xfc, 0xd3, 0x24, 0xd5, 0xa2, // 12.3456789
0x84,
]; ];
let y = deserialize_from_bytes(&expected_bytes).unwrap();
println!("== y: {:#?}", &y);
assert_eq!(v, y);
let v_bytes_1 = PackedWriter::encode(&w).unwrap(); let v_bytes_1 = PackedWriter::encode(&w).unwrap();
println!("== w bytes = {:?}", v_bytes_1); println!("== w bytes = {:?}", v_bytes_1);
assert_eq!(expected_bytes, v_bytes_1); assert_eq!(expected_bytes, v_bytes_1);
let mut v_bytes_2 = Vec::new(); let mut v_bytes_2 = Vec::new();
v.serialize(&mut crate::ser::Serializer::new(&mut PackedWriter(&mut v_bytes_2))).unwrap(); v.serialize(&mut crate::ser::Serializer::new(&mut PackedWriter::new(&mut v_bytes_2))).unwrap();
println!("== v bytes = {:?}", v_bytes_2); println!("== v bytes = {:?}", v_bytes_2);
assert_eq!(v_bytes_1, v_bytes_2); assert_eq!(v_bytes_1, v_bytes_2);
let y = deserialize_from_bytes(&v_bytes_1).unwrap();
println!("== y: {:#?}", &y);
assert_eq!(v, y);
} }
} }

View File

@ -1,43 +1,42 @@
use serde::Serialize; use serde::Serialize;
use super::value::writer::Writer; use super::value::writer::{Writer, CompoundWriter};
pub use super::error::Error; pub use super::error::Error;
type Result<T> = std::result::Result<T, Error>; type Result<T> = std::result::Result<T, Error>;
#[derive(Debug)] #[derive(Debug)]
pub struct Serializer<'a, W: Writer> { pub struct Serializer<'w, W: Writer> {
pub write: &'a mut W, pub write: &'w mut W,
} }
impl<'a, W: Writer> Serializer<'a, W> { impl<'w, W: Writer> Serializer<'w, W> {
pub fn new(write: &'a mut W) -> Self { pub fn new(write: &'w mut W) -> Self {
Serializer { write } Serializer { write }
} }
} }
#[derive(Debug)] #[derive(Debug)]
pub struct SerializeCompound<'a, 'b, W: Writer> { pub struct SerializeCompound<'a, 'w, W: Writer> {
ser: &'a mut Serializer<'b, W>, ser: &'a mut Serializer<'w, W>,
c: W::Compound, c: W::SeqWriter,
} }
#[derive(Debug)] #[derive(Debug)]
pub struct SerializeDictionary<'a, 'b, W: Writer> { pub struct SerializeDictionary<'a, 'w, W: Writer> {
ser: &'a mut Serializer<'b, W>, ser: &'a mut Serializer<'w, W>,
d: W::Dictionary, d: W::SetWriter,
key_p: Option<W::KeyPointer>,
} }
impl<'a, 'b, W: Writer> serde::Serializer for &'a mut Serializer<'b, W> { impl<'a, 'w, W: Writer> serde::Serializer for &'a mut Serializer<'w, W> {
type Ok = W::Pointer; type Ok = ();
type Error = Error; type Error = Error;
type SerializeSeq = SerializeCompound<'a, 'b, W>; type SerializeSeq = SerializeCompound<'a, 'w, W>;
type SerializeTuple = SerializeCompound<'a, 'b, W>; type SerializeTuple = SerializeCompound<'a, 'w, W>;
type SerializeTupleStruct = SerializeCompound<'a, 'b, W>; type SerializeTupleStruct = SerializeCompound<'a, 'w, W>;
type SerializeTupleVariant = SerializeCompound<'a, 'b, W>; type SerializeTupleVariant = SerializeCompound<'a, 'w, W>;
type SerializeMap = SerializeDictionary<'a, 'b, W>; type SerializeMap = SerializeDictionary<'a, 'w, W>;
type SerializeStruct = SerializeCompound<'a, 'b, W>; type SerializeStruct = SerializeCompound<'a, 'w, W>;
type SerializeStructVariant = SerializeCompound<'a, 'b, W>; type SerializeStructVariant = SerializeCompound<'a, 'w, W>;
fn serialize_bool(self, v: bool) -> Result<Self::Ok> { fn serialize_bool(self, v: bool) -> Result<Self::Ok> {
Ok(self.write.write_bool(v)?) Ok(self.write.write_bool(v)?)
@ -84,12 +83,14 @@ impl<'a, 'b, W: Writer> serde::Serializer for &'a mut Serializer<'b, W> {
} }
fn serialize_char(self, v: char) -> Result<Self::Ok> { fn serialize_char(self, v: char) -> Result<Self::Ok> {
let mut c = self.write.start_record(1)?; let mut c = self.write.start_record(Some(1))?;
let p = self.write.write_symbol("UnicodeScalar")?; c.extend()?;
self.write.extend_compound(&mut c, p)?; c.write_symbol("UnicodeScalar")?;
let p = self.write.write_u32(v as u32)?; c.delimit()?;
self.write.extend_compound(&mut c, p)?; c.extend()?;
Ok(self.write.end_compound(c)?) c.write_u32(v as u32)?;
c.delimit()?;
Ok(self.write.end_seq(c)?)
} }
fn serialize_str(self, v: &str) -> Result<Self::Ok> { fn serialize_str(self, v: &str) -> Result<Self::Ok> {
@ -101,33 +102,38 @@ impl<'a, 'b, W: Writer> serde::Serializer for &'a mut Serializer<'b, W> {
} }
fn serialize_none(self) -> Result<Self::Ok> { fn serialize_none(self) -> Result<Self::Ok> {
let mut c = self.write.start_record(0)?; let mut c = self.write.start_record(Some(0))?;
let p = self.write.write_symbol("None")?; c.extend()?;
self.write.extend_compound(&mut c, p)?; c.write_symbol("None")?;
Ok(self.write.end_compound(c)?) c.delimit()?;
Ok(self.write.end_seq(c)?)
} }
fn serialize_some<T: ?Sized>(self, v: &T) -> Result<Self::Ok> where T: Serialize { fn serialize_some<T: ?Sized>(self, v: &T) -> Result<Self::Ok> where T: Serialize {
let mut c = self.write.start_record(1)?; let mut c = self.write.start_record(Some(1))?;
let p = self.write.write_symbol("Some")?; c.extend()?;
self.write.extend_compound(&mut c, p)?; c.write_symbol("Some")?;
let p = v.serialize(&mut *self)?; c.delimit()?;
self.write.extend_compound(&mut c, p)?; c.extend()?;
Ok(self.write.end_compound(c)?) to_writer(&mut c, v)?;
c.delimit()?;
Ok(self.write.end_seq(c)?)
} }
fn serialize_unit(self) -> Result<Self::Ok> { fn serialize_unit(self) -> Result<Self::Ok> {
let mut c = self.write.start_record(0)?; let mut c = self.write.start_record(Some(0))?;
let p = self.write.write_symbol("tuple")?; c.extend()?;
self.write.extend_compound(&mut c, p)?; c.write_symbol("tuple")?;
Ok(self.write.end_compound(c)?) c.delimit()?;
Ok(self.write.end_seq(c)?)
} }
fn serialize_unit_struct(self, name: &'static str) -> Result<Self::Ok> { fn serialize_unit_struct(self, name: &'static str) -> Result<Self::Ok> {
let mut c = self.write.start_record(0)?; let mut c = self.write.start_record(Some(0))?;
let p = self.write.write_symbol(name)?; c.extend()?;
self.write.extend_compound(&mut c, p)?; c.write_symbol(name)?;
Ok(self.write.end_compound(c)?) c.delimit()?;
Ok(self.write.end_seq(c)?)
} }
fn serialize_unit_variant(self, fn serialize_unit_variant(self,
@ -136,27 +142,28 @@ impl<'a, 'b, W: Writer> serde::Serializer for &'a mut Serializer<'b, W> {
variant_name: &'static str) -> variant_name: &'static str) ->
Result<Self::Ok> Result<Self::Ok>
{ {
let mut c = self.write.start_record(0)?; let mut c = self.write.start_record(Some(0))?;
let p = self.write.write_symbol(variant_name)?; c.extend()?;
self.write.extend_compound(&mut c, p)?; c.write_symbol(variant_name)?;
Ok(self.write.end_compound(c)?) c.delimit()?;
Ok(self.write.end_seq(c)?)
} }
fn serialize_newtype_struct<T: ?Sized>(self, name: &'static str, value: &T) -> fn serialize_newtype_struct<T: ?Sized>(self, name: &'static str, value: &T) ->
Result<Self::Ok> where T: Serialize Result<Self::Ok> where T: Serialize
{ {
match super::value::magic::receive_output_value(name, value) { match super::value::magic::receive_output_value(name, value) {
Some(v) => { Some(v) => Ok(self.write.write(&v)?),
Ok(self.write.write(&v)?)
}
None => { None => {
// TODO: This is apparently discouraged, and we should apparently just serialize `value`? // TODO: This is apparently discouraged, and we should apparently just serialize `value`?
let mut c = self.write.start_record(1)?; let mut c = self.write.start_record(Some(1))?;
let p = self.write.write_symbol(name)?; c.extend()?;
self.write.extend_compound(&mut c, p)?; c.write_symbol(name)?;
let p = value.serialize(&mut *self)?; c.delimit()?;
self.write.extend_compound(&mut c, p)?; c.extend()?;
Ok(self.write.end_compound(c)?) to_writer(&mut c, value)?;
c.delimit()?;
Ok(self.write.end_seq(c)?)
} }
} }
} }
@ -168,38 +175,36 @@ impl<'a, 'b, W: Writer> serde::Serializer for &'a mut Serializer<'b, W> {
value: &T) -> value: &T) ->
Result<Self::Ok> where T: Serialize Result<Self::Ok> where T: Serialize
{ {
let mut c = self.write.start_record(1)?; let mut c = self.write.start_record(Some(1))?;
let p = self.write.write_symbol(variant_name)?; c.extend()?;
self.write.extend_compound(&mut c, p)?; c.write_symbol(variant_name)?;
let p = value.serialize(&mut *self)?; c.delimit()?;
self.write.extend_compound(&mut c, p)?; c.extend()?;
Ok(self.write.end_compound(c)?) to_writer(&mut c, value)?;
c.delimit()?;
Ok(self.write.end_seq(c)?)
} }
fn serialize_seq(self, count: Option<usize>) -> Result<Self::SerializeSeq> { fn serialize_seq(self, count: Option<usize>) -> Result<Self::SerializeSeq> {
let c = match count { let c = self.write.start_sequence(count)?;
Some(n) => self.write.start_sequence(n)?,
None => match self.write.stream_sequence()? {
Some(c) => c,
None => return Err(Error::StreamingSerializationUnsupported),
}
};
Ok(SerializeCompound { ser: self, c }) Ok(SerializeCompound { ser: self, c })
} }
fn serialize_tuple(self, count: usize) -> Result<Self::SerializeTuple> { fn serialize_tuple(self, count: usize) -> Result<Self::SerializeTuple> {
let mut c = self.write.start_record(count)?; let mut c = self.write.start_record(Some(count))?;
let p = self.write.write_symbol("tuple")?; c.extend()?;
self.write.extend_compound(&mut c, p)?; c.write_symbol("tuple")?;
c.delimit()?;
Ok(SerializeCompound { ser: self, c }) Ok(SerializeCompound { ser: self, c })
} }
fn serialize_tuple_struct(self, name: &'static str, count: usize) -> fn serialize_tuple_struct(self, name: &'static str, count: usize) ->
Result<Self::SerializeTupleStruct> Result<Self::SerializeTupleStruct>
{ {
let mut c = self.write.start_record(count)?; let mut c = self.write.start_record(Some(count))?;
let p = self.write.write_symbol(name)?; c.extend()?;
self.write.extend_compound(&mut c, p)?; c.write_symbol(name)?;
c.delimit()?;
Ok(SerializeCompound { ser: self, c }) Ok(SerializeCompound { ser: self, c })
} }
@ -210,27 +215,23 @@ impl<'a, 'b, W: Writer> serde::Serializer for &'a mut Serializer<'b, W> {
count: usize) -> count: usize) ->
Result<Self::SerializeTupleVariant> Result<Self::SerializeTupleVariant>
{ {
let mut c = self.write.start_record(count)?; let mut c = self.write.start_record(Some(count))?;
let p = self.write.write_symbol(variant_name)?; c.extend()?;
self.write.extend_compound(&mut c, p)?; c.write_symbol(variant_name)?;
c.delimit()?;
Ok(SerializeCompound { ser: self, c }) Ok(SerializeCompound { ser: self, c })
} }
fn serialize_map(self, count: Option<usize>) -> Result<Self::SerializeMap> { fn serialize_map(self, count: Option<usize>) -> Result<Self::SerializeMap> {
let d = match count { let d = self.write.start_dictionary(count)?;
Some(n) => self.write.start_dictionary(n)?, Ok(SerializeDictionary { ser: self, d })
None => match self.write.stream_dictionary()? {
Some(d) => d,
None => return Err(Error::StreamingSerializationUnsupported),
}
};
Ok(SerializeDictionary { ser: self, d, key_p: None })
} }
fn serialize_struct(self, name: &'static str, count: usize) -> Result<Self::SerializeStruct> { fn serialize_struct(self, name: &'static str, count: usize) -> Result<Self::SerializeStruct> {
let mut c = self.write.start_record(count)?; let mut c = self.write.start_record(Some(count))?;
let p = self.write.write_symbol(name)?; c.extend()?;
self.write.extend_compound(&mut c, p)?; c.write_symbol(name)?;
c.delimit()?;
Ok(SerializeCompound { ser: self, c }) Ok(SerializeCompound { ser: self, c })
} }
@ -241,122 +242,130 @@ impl<'a, 'b, W: Writer> serde::Serializer for &'a mut Serializer<'b, W> {
count: usize) -> count: usize) ->
Result<Self::SerializeStructVariant> Result<Self::SerializeStructVariant>
{ {
let mut c = self.write.start_record(count)?; let mut c = self.write.start_record(Some(count))?;
let p = self.write.write_symbol(variant_name)?; c.extend()?;
self.write.extend_compound(&mut c, p)?; c.write_symbol(variant_name)?;
c.delimit()?;
Ok(SerializeCompound { ser: self, c }) Ok(SerializeCompound { ser: self, c })
} }
} }
impl<'a, 'b, W: Writer> serde::ser::SerializeMap for SerializeDictionary<'a, 'b, W> { impl<'a, 'w, W: Writer> serde::ser::SerializeMap for SerializeDictionary<'a, 'w, W> {
type Ok = W::Pointer; type Ok = ();
type Error = Error; type Error = Error;
fn serialize_key<T: ?Sized>(&mut self, key: &T) -> Result<()> where T: Serialize { fn serialize_key<T: ?Sized>(&mut self, key: &T) -> Result<()> where T: Serialize {
let kp1 = key.serialize(&mut *self.ser)?; self.d.extend()?;
self.key_p = Some(self.ser.write.extend_dictionary_key(&mut self.d, kp1)?); to_writer(&mut self.d, key)?;
Ok(()) Ok(())
} }
fn serialize_value<T: ?Sized>(&mut self, value: &T) -> Result<()> where T: Serialize { fn serialize_value<T: ?Sized>(&mut self, value: &T) -> Result<()> where T: Serialize {
let vp1 = value.serialize(&mut *self.ser)?; to_writer(&mut self.d, value)?;
Ok(self.ser.write.extend_dictionary_value(&mut self.d, self.key_p.take().unwrap(), vp1)?) Ok(self.d.delimit()?)
} }
fn end(self) -> Result<Self::Ok> { fn end(self) -> Result<Self::Ok> {
Ok(self.ser.write.end_dictionary(self.d)?) Ok(self.ser.write.end_set(self.d)?)
} }
} }
impl<'a, 'b, W: Writer> serde::ser::SerializeStruct for SerializeCompound<'a, 'b, W> { impl<'a, 'w, W: Writer> SerializeCompound<'a, 'w, W> {
type Ok = W::Pointer; fn extend<T: ?Sized>(&mut self, value: &T) -> Result<()>
where T: Serialize
{
self.c.extend()?;
to_writer(&mut self.c, value)?;
Ok(self.c.delimit()?)
}
fn complete(self) -> Result<()> {
Ok(self.ser.write.end_seq(self.c)?)
}
}
impl<'a, 'w, W: Writer> serde::ser::SerializeStruct for SerializeCompound<'a, 'w, W> {
type Ok = ();
type Error = Error; type Error = Error;
fn serialize_field<T: ?Sized>(&mut self, _name: &'static str, value: &T) -> Result<()> fn serialize_field<T: ?Sized>(&mut self, _name: &'static str, value: &T) -> Result<()>
where T: Serialize where T: Serialize
{ {
let p = value.serialize(&mut *self.ser)?; self.extend(value)
Ok(self.ser.write.extend_compound(&mut self.c, p)?)
} }
fn end(self) -> Result<Self::Ok> { fn end(self) -> Result<Self::Ok> {
Ok(self.ser.write.end_compound(self.c)?) self.complete()
} }
} }
impl<'a, 'b, W: Writer> serde::ser::SerializeStructVariant for SerializeCompound<'a, 'b, W> { impl<'a, 'w, W: Writer> serde::ser::SerializeStructVariant for SerializeCompound<'a, 'w, W> {
type Ok = W::Pointer; type Ok = ();
type Error = Error; type Error = Error;
fn serialize_field<T: ?Sized>(&mut self, _name: &'static str, value: &T) -> Result<()> fn serialize_field<T: ?Sized>(&mut self, _name: &'static str, value: &T) -> Result<()>
where T: Serialize where T: Serialize
{ {
let p = value.serialize(&mut *self.ser)?; self.extend(value)
Ok(self.ser.write.extend_compound(&mut self.c, p)?)
} }
fn end(self) -> Result<Self::Ok> { fn end(self) -> Result<Self::Ok> {
Ok(self.ser.write.end_compound(self.c)?) self.complete()
} }
} }
impl<'a, 'b, W: Writer> serde::ser::SerializeTuple for SerializeCompound<'a, 'b, W> { impl<'a, 'w, W: Writer> serde::ser::SerializeTuple for SerializeCompound<'a, 'w, W> {
type Ok = W::Pointer; type Ok = ();
type Error = Error; type Error = Error;
fn serialize_element<T: ?Sized>(&mut self, value: &T) -> Result<()> where T: Serialize { fn serialize_element<T: ?Sized>(&mut self, value: &T) -> Result<()> where T: Serialize {
let p = value.serialize(&mut *self.ser)?; self.extend(value)
Ok(self.ser.write.extend_compound(&mut self.c, p)?)
} }
fn end(self) -> Result<Self::Ok> { fn end(self) -> Result<Self::Ok> {
Ok(self.ser.write.end_compound(self.c)?) self.complete()
} }
} }
impl<'a, 'b, W: Writer> serde::ser::SerializeTupleStruct for SerializeCompound<'a, 'b, W> { impl<'a, 'w, W: Writer> serde::ser::SerializeTupleStruct for SerializeCompound<'a, 'w, W> {
type Ok = W::Pointer; type Ok = ();
type Error = Error; type Error = Error;
fn serialize_field<T: ?Sized>(&mut self, value: &T) -> Result<()> where T: Serialize { fn serialize_field<T: ?Sized>(&mut self, value: &T) -> Result<()> where T: Serialize {
let p = value.serialize(&mut *self.ser)?; self.extend(value)
Ok(self.ser.write.extend_compound(&mut self.c, p)?)
} }
fn end(self) -> Result<Self::Ok> { fn end(self) -> Result<Self::Ok> {
Ok(self.ser.write.end_compound(self.c)?) self.complete()
} }
} }
impl<'a, 'b, W: Writer> serde::ser::SerializeTupleVariant for SerializeCompound<'a, 'b, W> { impl<'a, 'w, W: Writer> serde::ser::SerializeTupleVariant for SerializeCompound<'a, 'w, W> {
type Ok = W::Pointer; type Ok = ();
type Error = Error; type Error = Error;
fn serialize_field<T: ?Sized>(&mut self, value: &T) -> Result<()> where T: Serialize { fn serialize_field<T: ?Sized>(&mut self, value: &T) -> Result<()> where T: Serialize {
let p = value.serialize(&mut *self.ser)?; self.extend(value)
Ok(self.ser.write.extend_compound(&mut self.c, p)?)
} }
fn end(self) -> Result<Self::Ok> { fn end(self) -> Result<Self::Ok> {
Ok(self.ser.write.end_compound(self.c)?) self.complete()
} }
} }
impl<'a, 'b, W: Writer> serde::ser::SerializeSeq for SerializeCompound<'a, 'b, W> { impl<'a, 'w, W: Writer> serde::ser::SerializeSeq for SerializeCompound<'a, 'w, W> {
type Ok = W::Pointer; type Ok = ();
type Error = Error; type Error = Error;
fn serialize_element<T: ?Sized>(&mut self, value: &T) -> Result<()> where T: Serialize { fn serialize_element<T: ?Sized>(&mut self, value: &T) -> Result<()> where T: Serialize {
let p = value.serialize(&mut *self.ser)?; self.extend(value)
Ok(self.ser.write.extend_compound(&mut self.c, p)?)
} }
fn end(self) -> Result<Self::Ok> { fn end(self) -> Result<Self::Ok> {
Ok(self.ser.write.end_compound(self.c)?) self.complete()
} }
} }
pub fn to_writer<W: Writer, T: Serialize>(write: &mut W, value: &T) -> Result<W::Pointer> { pub fn to_writer<W: Writer, T: Serialize + ?Sized>(write: &mut W, value: &T) -> Result<()> {
let mut ser: Serializer<'_, W> = Serializer::new(write); Ok(value.serialize(&mut Serializer::new(write))?)
value.serialize(&mut ser)
} }

View File

@ -1,68 +1,86 @@
use std::convert::{TryFrom, From}; use std::convert::{TryFrom, From};
use num_enum::TryFromPrimitive;
#[derive(Debug, PartialEq, Eq)] #[derive(Debug, PartialEq, Eq)]
pub enum Op { pub enum Tag {
Misc(u8), False,
Atom(AtomMinor), True,
Compound(CompoundMinor), Float,
Reserved(u8), Double,
End,
Annotation,
SmallInteger(i8),
MediumInteger(u8),
SignedInteger,
String,
ByteString,
Symbol,
Record,
Sequence,
Set,
Dictionary,
} }
#[derive(Debug, PartialEq, Eq)] #[derive(Debug, PartialEq, Eq)]
pub struct InvalidOp; pub struct InvalidTag(u8);
impl From<InvalidOp> for std::io::Error { impl From<InvalidTag> for std::io::Error {
fn from(_v: InvalidOp) -> Self { fn from(v: InvalidTag) -> Self {
std::io::Error::new(std::io::ErrorKind::InvalidData, std::io::Error::new(std::io::ErrorKind::InvalidData,
"Invalid Preserves lead byte major value") format!("Invalid Preserves tag {}", v.0).to_string())
} }
} }
impl From<InvalidOp> for crate::error::Error { impl From<InvalidTag> for crate::error::Error {
fn from(v: InvalidOp) -> Self { fn from(v: InvalidTag) -> Self {
crate::error::Error::Io(v.into()) crate::error::Error::Io(v.into())
} }
} }
impl TryFrom<u8> for Op { impl TryFrom<u8> for Tag {
type Error = InvalidOp; type Error = InvalidTag;
fn try_from(v: u8) -> Result<Self, Self::Error> { fn try_from(v: u8) -> Result<Self, Self::Error> {
match v >> 2 {
0 => Ok(Self::Misc(v & 3)),
1 => Ok(Self::Atom(AtomMinor::try_from(v & 3).unwrap())),
2 => Ok(Self::Compound(CompoundMinor::try_from(v & 3).unwrap())),
3 => Ok(Self::Reserved(v & 3)),
_ => Err(InvalidOp),
}
}
}
impl From<Op> for u8 {
fn from(v: Op) -> Self {
match v { match v {
Op::Misc(minor) => minor & 3, 0x80 => Ok(Self::False),
Op::Atom(minor) => (1 << 2) | ((minor as u8) & 3), 0x81 => Ok(Self::True),
Op::Compound(minor) => (2 << 2) | ((minor as u8) & 3), 0x82 => Ok(Self::Float),
Op::Reserved(minor) => (3 << 2) | (minor & 3), 0x83 => Ok(Self::Double),
0x84 => Ok(Self::End),
0x85 => Ok(Self::Annotation),
0x90..=0x9c => Ok(Self::SmallInteger((v - 0x90) as i8)),
0x9d..=0x9f => Ok(Self::SmallInteger((v - 0x90) as i8 - 16)),
0xa0..=0xaf => Ok(Self::MediumInteger(v - 0xa0 + 1)),
0xb0 => Ok(Self::SignedInteger),
0xb1 => Ok(Self::String),
0xb2 => Ok(Self::ByteString),
0xb3 => Ok(Self::Symbol),
0xb4 => Ok(Self::Record),
0xb5 => Ok(Self::Sequence),
0xb6 => Ok(Self::Set),
0xb7 => Ok(Self::Dictionary),
_ => Err(InvalidTag(v))
} }
} }
} }
#[derive(Debug, TryFromPrimitive, PartialEq, Eq, Clone, Copy)] impl From<Tag> for u8 {
#[repr(u8)] fn from(v: Tag) -> Self {
pub enum AtomMinor { match v {
SignedInteger = 0, Tag::False => 0x80,
String = 1, Tag::True => 0x81,
ByteString = 2, Tag::Float => 0x82,
Symbol = 3, Tag::Double => 0x83,
} Tag::End => 0x84,
Tag::Annotation => 0x85,
#[derive(Debug, TryFromPrimitive, PartialEq, Eq, Clone, Copy)] Tag::SmallInteger(v) => if v < 0 { (v + 16) as u8 + 0x90 } else { v as u8 + 0x90 },
#[repr(u8)] Tag::MediumInteger(count) => count - 1 + 0xa0,
pub enum CompoundMinor { Tag::SignedInteger => 0xb0,
Record = 0, Tag::String => 0xb1,
Sequence = 1, Tag::ByteString => 0xb2,
Set = 2, Tag::Symbol => 0xb3,
Dictionary = 3, Tag::Record => 0xb4,
Tag::Sequence => 0xb5,
Tag::Set => 0xb6,
Tag::Dictionary => 0xb7,
}
}
} }

View File

@ -7,12 +7,10 @@ use std::marker::PhantomData;
use super::super::signed_integer::SignedInteger; use super::super::signed_integer::SignedInteger;
use super::super::value::{Value, NestedValue, IOValue, FALSE, TRUE, Map, Set, Record, Annotations}; use super::super::value::{Value, NestedValue, IOValue, FALSE, TRUE, Map, Set, Record, Annotations};
use super::constants::{Op, InvalidOp, AtomMinor, CompoundMinor}; use super::constants::Tag;
use super::super::reader::{ use super::super::reader::{
BinarySource, BinarySource,
BytesBinarySource, BytesBinarySource,
CompoundBody,
CompoundLimit,
ConfiguredReader, ConfiguredReader,
IOBinarySource, IOBinarySource,
IOResult, IOResult,
@ -87,16 +85,8 @@ impl<'de, S: BinarySource<'de>> PackedReader<'de, S> {
} }
} }
fn wirelength(&mut self, arg: u8) -> IOResult<usize> {
if arg < 15 {
Ok(usize::from(arg))
} else {
self.varint()
}
}
fn peekend(&mut self) -> IOResult<bool> { fn peekend(&mut self) -> IOResult<bool> {
if self.peek()? == 4 { if self.peek()? == Tag::End.into() {
self.skip()?; self.skip()?;
Ok(true) Ok(true)
} else { } else {
@ -104,28 +94,10 @@ impl<'de, S: BinarySource<'de>> PackedReader<'de, S> {
} }
} }
fn gather_chunks(&mut self) -> IOResult<Vec<u8>> { fn peek_next_nonannotation_tag(&mut self) -> ReaderResult<Tag> {
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 { loop {
match decodeop(self.peek()?)? { match Tag::try_from(self.peek()?)? {
(Op::Misc(0), 5) => { Tag::Annotation => {
self.skip()?; self.skip()?;
self.skip_value()?; self.skip_value()?;
}, },
@ -134,44 +106,29 @@ impl<'de, S: BinarySource<'de>> PackedReader<'de, S> {
} }
} }
fn next_atomic(&mut self, minor: AtomMinor, k: ExpectedKind) -> ReaderResult<Cow<'de, [u8]>> { fn next_atomic(&mut self, expected_tag: Tag, k: ExpectedKind) -> ReaderResult<Cow<'de, [u8]>> {
match self.peek_next_nonannotation_op()? { let actual_tag = self.peek_next_nonannotation_tag()?;
(Op::Atom(actual_minor), arg) if actual_minor == minor => { if actual_tag == expected_tag {
self.skip()?; self.skip()?;
let count = self.wirelength(arg)?; let count = self.varint()?;
Ok(self.readbytes(count)?) Ok(self.readbytes(count)?)
} } else {
(Op::Misc(2), arg) => match Op::try_from(arg)? { Err(self.expected(k))
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) -> fn next_compound(&mut self, expected_tag: Tag, k: ExpectedKind) -> ReaderResult<()>
ReaderResult<CompoundBody<CompoundMinor>>
{ {
match self.peek_next_nonannotation_op()? { let actual_tag = self.peek_next_nonannotation_tag()?;
(Op::Compound(actual_minor), arg) if actual_minor == minor => { if actual_tag == expected_tag {
self.skip()?; self.skip()?;
Ok(CompoundBody::counted(minor, self.wirelength(arg)?)) Ok(())
} } else {
(Op::Misc(2), arg) => match Op::try_from(arg)? { Err(self.expected(k))
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<SignedInteger> { fn read_signed_integer(&mut self, count: usize) -> IOResult<SignedInteger> {
if count == 0 { if count == 0 {
return Ok(SignedInteger::from(0 as i128)); return Ok(SignedInteger::from(0 as i128));
} }
@ -211,28 +168,30 @@ impl<'de, S: BinarySource<'de>> PackedReader<'de, S> {
where where
F: FnOnce(u128) -> Option<T> F: FnOnce(u128) -> Option<T>
{ {
match self.peek_next_nonannotation_op()? { let tag = self.peek_next_nonannotation_tag()?;
(Op::Misc(3), arg) => { match tag {
Tag::SmallInteger(v) => {
self.skip()?; self.skip()?;
if arg > 12 { if v < 0 {
Err(out_of_range((arg as i8) - 16)) Err(out_of_range(v))
} else { } else {
f(arg as u128).ok_or_else(|| out_of_range(arg)) f(v as u128).ok_or_else(|| out_of_range(v))
} }
} }
(Op::Atom(AtomMinor::SignedInteger), arg) => { Tag::MediumInteger(count) => {
self.skip()?; self.skip()?;
let count = self.wirelength(arg)?; let n = &self.read_signed_integer(count.into())?;
let n = &self.read_number_format_b(count)?;
let i = n.try_into().or_else(|_| Err(out_of_range(n)))?; let i = n.try_into().or_else(|_| Err(out_of_range(n)))?;
f(i).ok_or_else(|| out_of_range(i)) f(i).ok_or_else(|| out_of_range(i))
} }
_ => { Tag::SignedInteger => {
let n_value = self.demand_next(false)?; self.skip()?;
let n = n_value.value().to_signedinteger()?; let count = self.varint()?;
let n = &self.read_signed_integer(count)?;
let i = n.try_into().or_else(|_| Err(out_of_range(n)))?; let i = n.try_into().or_else(|_| Err(out_of_range(n)))?;
f(i).ok_or_else(|| out_of_range(i)) f(i).ok_or_else(|| out_of_range(i))
} }
_ => Err(self.expected(ExpectedKind::SignedInteger))
} }
} }
@ -240,166 +199,169 @@ impl<'de, S: BinarySource<'de>> PackedReader<'de, S> {
where where
F: FnOnce(i128) -> Option<T> F: FnOnce(i128) -> Option<T>
{ {
match self.peek_next_nonannotation_op()? { let tag = self.peek_next_nonannotation_tag()?;
(Op::Misc(3), arg) => { match tag {
Tag::SmallInteger(v) => {
self.skip()?; self.skip()?;
let n = arg as i128; f(v.into()).ok_or_else(|| out_of_range(v))
let n = if n > 12 { n - 16 } else { n };
f(n).ok_or_else(|| out_of_range(n))
} }
(Op::Atom(AtomMinor::SignedInteger), arg) => { Tag::MediumInteger(count) => {
self.skip()?; self.skip()?;
let count = self.wirelength(arg)?; let n = &self.read_signed_integer(count.into())?;
let n = &self.read_number_format_b(count)?;
let i = n.try_into().or_else(|_| Err(out_of_range(n)))?; let i = n.try_into().or_else(|_| Err(out_of_range(n)))?;
f(i).ok_or_else(|| out_of_range(i)) f(i).ok_or_else(|| out_of_range(i))
} }
_ => { Tag::SignedInteger => {
let n_value = self.demand_next(false)?; self.skip()?;
let n = n_value.value().to_signedinteger()?; let count = self.varint()?;
let n = &self.read_signed_integer(count)?;
let i = n.try_into().or_else(|_| Err(out_of_range(n)))?; let i = n.try_into().or_else(|_| Err(out_of_range(n)))?;
f(i).ok_or_else(|| out_of_range(i)) f(i).ok_or_else(|| out_of_range(i))
} }
_ => Err(self.expected(ExpectedKind::SignedInteger))
} }
} }
} }
impl<'de, S: BinarySource<'de>> Reader<'de> for PackedReader<'de, S> { impl<'de, S: BinarySource<'de>> Reader<'de> for PackedReader<'de, S> {
type CompoundInfo = CompoundMinor;
fn next(&mut self, read_annotations: bool) -> IOResult<Option<IOValue>> { fn next(&mut self, read_annotations: bool) -> IOResult<Option<IOValue>> {
match self.peek() { match self.peek() {
Err(e) if is_eof_io_error(&e) => return Ok(None), Err(e) if is_eof_io_error(&e) => return Ok(None),
Err(e) => return Err(e), Err(e) => return Err(e),
Ok(_) => (), Ok(_) => (),
} }
loop { Ok(Some(match Tag::try_from(self.read()?)? {
return Ok(Some(match decodeop(self.read()?)? { Tag::False => FALSE.clone(),
(Op::Misc(0), 0) => FALSE.clone(), Tag::True => TRUE.clone(),
(Op::Misc(0), 1) => TRUE.clone(), Tag::Float => {
(Op::Misc(0), 2) => { let mut bs = [0; 4];
let mut bs = [0; 4]; self.readbytes_into(&mut bs)?;
self.readbytes_into(&mut bs)?; Value::from(f32::from_bits(u32::from_be_bytes(bs))).wrap()
Value::from(f32::from_bits(u32::from_be_bytes(bs))).wrap() }
} Tag::Double => {
(Op::Misc(0), 3) => { let mut bs = [0; 8];
let mut bs = [0; 8]; self.readbytes_into(&mut bs)?;
self.readbytes_into(&mut bs)?; Value::from(f64::from_bits(u64::from_be_bytes(bs))).wrap()
Value::from(f64::from_bits(u64::from_be_bytes(bs))).wrap() }
} Tag::Annotation => {
(Op::Misc(0), 5) => { if read_annotations {
if read_annotations { let mut annotations = vec![self.demand_next(read_annotations)?];
let mut annotations = vec![self.demand_next(read_annotations)?]; while Tag::try_from(self.peek()?)? == Tag::Annotation {
while decodeop(self.peek()?)? == (Op::Misc(0), 5) { self.skip()?;
self.skip()?; annotations.push(self.demand_next(read_annotations)?);
annotations.push(self.demand_next(read_annotations)?);
}
let (existing_annotations, v) = self.demand_next(read_annotations)?.pieces();
annotations.extend_from_slice(existing_annotations.slice());
IOValue::wrap(Annotations::new(Some(annotations)), v)
} else {
self.skip_value()?;
continue;
} }
} let (existing_annotations, v) = self.demand_next(read_annotations)?.pieces();
(Op::Misc(0), _) => Err(io_syntax_error("Invalid format A encoding"))?, annotations.extend_from_slice(existing_annotations.slice());
(Op::Misc(1), _) => Err(io_syntax_error("Invalid format A encoding"))?, IOValue::wrap(Annotations::new(Some(annotations)), v)
(Op::Misc(2), arg) => match Op::try_from(arg)? { } else {
Op::Atom(minor) => self.skip_value()?;
decodebinary(minor, Cow::Owned(self.gather_chunks()?))?, while Tag::try_from(self.peek()?)? == Tag::Annotation {
Op::Compound(minor) => decodecompound(minor, DelimitedStream { self.skip()?;
reader: self.configured(read_annotations), self.skip_value()?;
})?, }
_ => Err(io_syntax_error("Invalid format C start byte"))?, self.demand_next(read_annotations)?
}
(Op::Misc(3), arg) => {
let n = if arg > 12 { i32::from(arg) - 16 } else { i32::from(arg) };
// TODO: prebuild these in value.rs
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)?;
Value::SignedInteger(n).wrap()
}
(Op::Atom(minor), arg) => {
let count = self.wirelength(arg)?;
decodebinary(minor, self.readbytes(count)?)?
}
(Op::Compound(minor), arg) => {
let count = self.wirelength(arg)?;
decodecompound(minor, CountedStream {
reader: self.configured(read_annotations),
count,
})?
}
(Op::Reserved(3), 15) => continue,
(Op::Reserved(_), _) => return Err(InvalidOp.into()),
}))
}
}
fn open_record(&mut self, arity: Option<usize>) -> ReaderResult<CompoundBody<Self::CompoundInfo>> {
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) Tag::SmallInteger(v) => {
} else { // TODO: prebuild these in value.rs
self.next_compound(CompoundMinor::Record, ExpectedKind::Record(None)) Value::from(v).wrap()
} }
Tag::MediumInteger(count) => {
let n = self.read_signed_integer(count.into())?;
Value::SignedInteger(n).wrap()
}
Tag::SignedInteger => {
let count = self.varint()?;
let n = self.read_signed_integer(count)?;
Value::SignedInteger(n).wrap()
}
Tag::String => {
let count = self.varint()?;
Value::String(decodestr(self.readbytes(count)?)?.into_owned()).wrap()
}
Tag::ByteString => {
let count = self.varint()?;
Value::ByteString(self.readbytes(count)?.into_owned()).wrap()
}
Tag::Symbol => {
let count = self.varint()?;
Value::Symbol(decodestr(self.readbytes(count)?)?.into_owned()).wrap()
}
Tag::Record => {
let iter = DelimitedStream { reader: self.configured(read_annotations) };
let vs = iter.collect::<IOResult<Vec<IOValue>>>()?;
if vs.len() < 1 {
return Err(io_syntax_error("Too few elements in encoded record"))
}
Value::Record(Record(vs)).wrap()
}
Tag::Sequence => {
let iter = DelimitedStream { reader: self.configured(read_annotations) };
let vs = iter.collect::<IOResult<Vec<IOValue>>>()?;
Value::Sequence(vs).wrap()
}
Tag::Set => {
let iter = DelimitedStream { reader: self.configured(read_annotations) };
let mut s = Set::new();
for res in iter { s.insert(res?); }
Value::Set(s).wrap()
}
Tag::Dictionary => {
let mut iter = DelimitedStream { reader: self.configured(read_annotations) };
let mut d = Map::new();
while let Some(kres) = iter.next() {
let k = kres?;
match iter.next() {
Some(vres) => {
let v = vres?;
d.insert(k, v);
}
None => return Err(io_syntax_error("Missing dictionary value")),
}
}
Value::Dictionary(d).wrap()
}
tag @ Tag::End => {
return Err(io_syntax_error(&format!("Invalid tag: {:?}", tag)));
}
}))
} }
fn open_sequence_or_set(&mut self) -> ReaderResult<CompoundBody<Self::CompoundInfo>> { fn open_record(&mut self, arity: Option<usize>) -> ReaderResult<()> {
match self.peek_next_nonannotation_op()? { self.next_compound(Tag::Record, ExpectedKind::Record(arity))?;
(Op::Compound(minor), arg) self.ensure_more_expected()
if CompoundMinor::Sequence == minor || CompoundMinor::Set == minor => { }
self.skip()?;
Ok(CompoundBody::counted(minor, self.wirelength(arg)?)) fn open_sequence_or_set(&mut self) -> ReaderResult<()> {
} match self.peek_next_nonannotation_tag()? {
(Op::Misc(2), arg) => match Op::try_from(arg)? { Tag::Sequence | Tag::Set => {
Op::Compound(minor) self.skip()?;
if CompoundMinor::Sequence == minor || CompoundMinor::Set == minor => { Ok(())
self.skip()?;
Ok(CompoundBody::streaming(minor))
}
_ => Err(self.expected(ExpectedKind::SequenceOrSet)),
} }
_ => Err(self.expected(ExpectedKind::SequenceOrSet)), _ => Err(self.expected(ExpectedKind::SequenceOrSet)),
} }
} }
fn open_sequence(&mut self) -> ReaderResult<CompoundBody<Self::CompoundInfo>> { fn open_sequence(&mut self) -> ReaderResult<()> {
self.next_compound(CompoundMinor::Sequence, ExpectedKind::Sequence) self.next_compound(Tag::Sequence, ExpectedKind::Sequence)
} }
fn open_set(&mut self) -> ReaderResult<CompoundBody<Self::CompoundInfo>> { fn open_set(&mut self) -> ReaderResult<()> {
self.next_compound(CompoundMinor::Set, ExpectedKind::Set) self.next_compound(Tag::Set, ExpectedKind::Set)
} }
fn open_dictionary(&mut self) -> ReaderResult<CompoundBody<Self::CompoundInfo>> { fn open_dictionary(&mut self) -> ReaderResult<()> {
self.next_compound(CompoundMinor::Dictionary, ExpectedKind::Dictionary) self.next_compound(Tag::Dictionary, ExpectedKind::Dictionary)
} }
fn close_compound_counted(&mut self, _minor: Self::CompoundInfo) -> ReaderResult<()> { fn close_compound(&mut self) -> ReaderResult<bool> {
// Nothing to do -- no close delimiter to consume
Ok(())
}
fn close_compound_stream(&mut self, _minor: Self::CompoundInfo) -> ReaderResult<bool> {
Ok(self.peekend()?) Ok(self.peekend()?)
} }
fn next_boolean(&mut self) -> ReaderResult<bool> { fn next_boolean(&mut self) -> ReaderResult<bool> {
match self.peek_next_nonannotation_op()? { match self.peek_next_nonannotation_tag()? {
(Op::Misc(0), 0) => { self.skip()?; Ok(false) } Tag::False => { self.skip()?; Ok(false) }
(Op::Misc(0), 1) => { self.skip()?; Ok(true) } Tag::True => { self.skip()?; Ok(true) }
_ => Err(self.expected(ExpectedKind::Boolean)), _ => Err(self.expected(ExpectedKind::Boolean)),
} }
} }
@ -417,14 +379,14 @@ impl<'de, S: BinarySource<'de>> Reader<'de> for PackedReader<'de, S> {
fn next_u128(&mut self) -> ReaderResult<u128> { self.next_unsigned(|n| n.to_u128()) } fn next_u128(&mut self) -> ReaderResult<u128> { self.next_unsigned(|n| n.to_u128()) }
fn next_float(&mut self) -> ReaderResult<f32> { fn next_float(&mut self) -> ReaderResult<f32> {
match self.peek_next_nonannotation_op()? { match self.peek_next_nonannotation_tag()? {
(Op::Misc(0), 2) => { Tag::Float => {
self.skip()?; self.skip()?;
let mut bs = [0; 4]; let mut bs = [0; 4];
self.readbytes_into(&mut bs)?; self.readbytes_into(&mut bs)?;
Ok(f32::from_bits(u32::from_be_bytes(bs))) Ok(f32::from_bits(u32::from_be_bytes(bs)))
}, },
(Op::Misc(0), 3) => { Tag::Double => {
self.skip()?; self.skip()?;
let mut bs = [0; 8]; let mut bs = [0; 8];
self.readbytes_into(&mut bs)?; self.readbytes_into(&mut bs)?;
@ -435,14 +397,14 @@ impl<'de, S: BinarySource<'de>> Reader<'de> for PackedReader<'de, S> {
} }
fn next_double(&mut self) -> ReaderResult<f64> { fn next_double(&mut self) -> ReaderResult<f64> {
match self.peek_next_nonannotation_op()? { match self.peek_next_nonannotation_tag()? {
(Op::Misc(0), 2) => { Tag::Float => {
self.skip()?; self.skip()?;
let mut bs = [0; 4]; let mut bs = [0; 4];
self.readbytes_into(&mut bs)?; self.readbytes_into(&mut bs)?;
Ok(f32::from_bits(u32::from_be_bytes(bs)) as f64) Ok(f32::from_bits(u32::from_be_bytes(bs)) as f64)
}, },
(Op::Misc(0), 3) => { Tag::Double => {
self.skip()?; self.skip()?;
let mut bs = [0; 8]; let mut bs = [0; 8];
self.readbytes_into(&mut bs)?; self.readbytes_into(&mut bs)?;
@ -453,30 +415,15 @@ impl<'de, S: BinarySource<'de>> Reader<'de> for PackedReader<'de, S> {
} }
fn next_str(&mut self) -> ReaderResult<Cow<'de, str>> { fn next_str(&mut self) -> ReaderResult<Cow<'de, str>> {
Ok(decodestr(self.next_atomic(AtomMinor::String, ExpectedKind::Symbol)?)?) Ok(decodestr(self.next_atomic(Tag::String, ExpectedKind::Symbol)?)?)
} }
fn next_bytestring(&mut self) -> ReaderResult<Cow<'de, [u8]>> { fn next_bytestring(&mut self) -> ReaderResult<Cow<'de, [u8]>> {
self.next_atomic(AtomMinor::ByteString, ExpectedKind::Symbol) self.next_atomic(Tag::ByteString, ExpectedKind::Symbol)
} }
fn next_symbol(&mut self) -> ReaderResult<Cow<'de, str>> { fn next_symbol(&mut self) -> ReaderResult<Cow<'de, str>> {
Ok(decodestr(self.next_atomic(AtomMinor::Symbol, ExpectedKind::Symbol)?)?) Ok(decodestr(self.next_atomic(Tag::Symbol, ExpectedKind::Symbol)?)?)
}
}
struct CountedStream<'de, R: Reader<'de>> {
reader: ConfiguredReader<'de, R>,
count: usize,
}
impl<'de, R: Reader<'de>> Iterator for CountedStream<'de, R>
{
type Item = IOResult<IOValue>;
fn next(&mut self) -> Option<Self::Item> {
if self.count == 0 { return None }
self.count -= 1;
Some(self.reader.reader.demand_next(self.reader.read_annotations))
} }
} }
@ -496,11 +443,7 @@ impl<'a, 'de, S: BinarySource<'de>> Iterator for DelimitedStream<'a, 'de, S>
} }
} }
pub fn decodeop(b: u8) -> IOResult<(Op, u8)> { fn decodestr<'de>(cow: Cow<'de, [u8]>) -> IOResult<Cow<'de, str>> {
Ok((Op::try_from(b >> 4)?, b & 15))
}
pub fn decodestr<'de>(cow: Cow<'de, [u8]>) -> IOResult<Cow<'de, str>> {
match cow { match cow {
Cow::Borrowed(bs) => Cow::Borrowed(bs) =>
Ok(Cow::Borrowed(std::str::from_utf8(bs).map_err(|_| io_syntax_error("Invalid UTF-8"))?)), Ok(Cow::Borrowed(std::str::from_utf8(bs).map_err(|_| io_syntax_error("Invalid UTF-8"))?)),
@ -508,53 +451,3 @@ pub fn decodestr<'de>(cow: Cow<'de, [u8]>) -> IOResult<Cow<'de, str>> {
Ok(Cow::Owned(String::from_utf8(bs).map_err(|_| io_syntax_error("Invalid UTF-8"))?.to_owned())), Ok(Cow::Owned(String::from_utf8(bs).map_err(|_| io_syntax_error("Invalid UTF-8"))?.to_owned())),
} }
} }
pub fn decodebinary<'de>(minor: AtomMinor, bs: Cow<'de, [u8]>) -> IOResult<IOValue> {
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)?.into_owned()).wrap(),
})
}
pub fn decodecompound<'de, I: Iterator<Item = IOResult<IOValue>>>(
minor: CompoundMinor,
mut iter: I
) ->
IOResult<IOValue>
{
match minor {
CompoundMinor::Record => {
let vs = iter.collect::<IOResult<Vec<IOValue>>>()?;
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.collect::<IOResult<Vec<IOValue>>>()?;
Ok(Value::Sequence(vs).wrap())
}
CompoundMinor::Set => {
let mut s = Set::new();
for res in iter { s.insert(res?); }
Ok(Value::Set(s).wrap())
}
CompoundMinor::Dictionary => {
let mut d = Map::new();
while let Some(kres) = iter.next() {
let k = kres?;
match iter.next() {
Some(vres) => {
let v = vres?;
d.insert(k, v);
}
None => return Err(io_syntax_error("Missing dictionary value")),
}
}
Ok(Value::Dictionary(d).wrap())
}
}
}

View File

@ -2,30 +2,275 @@ use num;
use num::bigint::BigInt; use num::bigint::BigInt;
use num::cast::ToPrimitive; use num::cast::ToPrimitive;
use std::convert::TryInto; use std::convert::TryInto;
use super::constants::{Op, AtomMinor, CompoundMinor}; use std::mem;
use std::ops::{Deref, DerefMut};
use super::constants::Tag;
use super::super::IOValue; use super::super::IOValue;
use super::super::writer::{Writer, Result, varint}; use super::super::writer::{Writer, AnnotationWriter, CompoundWriter, Result, varint};
pub struct PackedWriter<'w, W: std::io::Write>(pub &'w mut W); pub enum Suspendable<T> {
Active(T),
pub fn write_op<W: std::io::Write>(w: &mut PackedWriter<W>, op: Op, arg: u8) -> Result<()> { Suspended,
w.0.write_all(&[(u8::from(op) << 4) | (arg & 15)])
} }
pub fn write_header<W: std::io::Write>(w: &mut PackedWriter<W>, op: Op, wirelength: usize) -> Result<()> { impl<T> Suspendable<T> {
if wirelength < 15 { pub fn new(t: T) -> Self {
write_op(w, op, wirelength as u8) Suspendable::Active(t)
} else { }
write_op(w, op, 15)?;
varint(w.0, wirelength as u64)?; pub fn suspend(&mut self) -> Self {
match self {
Suspendable::Active(_) => mem::replace(self, Suspendable::Suspended),
Suspendable::Suspended =>
panic!("Attempt to suspend suspended Suspendable"),
}
}
pub fn resume(&mut self, other: Self) {
match self {
Suspendable::Suspended =>
match other {
Suspendable::Active(_) => *self = other,
Suspendable::Suspended =>
panic!("Attempt to resume from suspended Suspendable"),
},
Suspendable::Active(_) =>
panic!("Attempt to resume non-suspended Suspendable"),
}
}
pub fn take(self) -> T {
match self {
Suspendable::Active(t) => t,
Suspendable::Suspended =>
panic!("Attempt to take from suspended Suspendable"),
}
}
}
impl<T> Deref for Suspendable<T> {
type Target = T;
fn deref(&self) -> &Self::Target {
match self {
Suspendable::Suspended => panic!("Suspended Suspendable at deref"),
Suspendable::Active(t) => t
}
}
}
impl<T> DerefMut for Suspendable<T> {
fn deref_mut(&mut self) -> &mut Self::Target {
match self {
Suspendable::Suspended => panic!("Empty Suspendable at deref_mut"),
Suspendable::Active(t) => t
}
}
}
pub struct PackedWriter<W: std::io::Write>(Suspendable<W>);
impl PackedWriter<Vec<u8>> {
pub fn encode(v: &IOValue) -> std::io::Result<Vec<u8>> {
let mut buf: Vec<u8> = Vec::new();
let w = &mut PackedWriter::new(&mut buf);
w.write(v)?;
Ok(buf)
}
}
impl<W: std::io::Write> PackedWriter<W> {
pub fn new(write: W) -> Self {
PackedWriter(Suspendable::new(write))
}
pub fn w(&mut self) -> &mut W {
self.0.deref_mut()
}
pub fn write_byte(&mut self, b: u8) -> Result<()> {
self.w().write_all(&[b])
}
pub fn write_medium_integer(&mut self, bs: &[u8]) -> Result<()> {
let count: u8 = bs.len().try_into().unwrap();
if count > 16 || count < 1 { panic!("Invalid medium_integer count: {}", count) }
self.write_byte(Tag::MediumInteger(count).into())?;
self.w().write_all(bs)
}
pub fn write_atom(&mut self, tag: Tag, bs: &[u8]) -> Result<()> {
self.write_byte(tag.into())?;
varint(&mut self.w(), bs.len().try_into().unwrap())?;
self.w().write_all(bs)
}
pub fn suspend(&mut self) -> Self {
PackedWriter(self.0.suspend())
}
pub fn resume(&mut self, other: Self) {
self.0.resume(other.0)
}
}
pub struct BinaryOrderWriter(Vec<Vec<u8>>);
impl BinaryOrderWriter {
fn new() -> Self {
BinaryOrderWriter(vec![vec![]])
}
fn pop(&mut self) -> PackedWriter<Vec<u8>> {
PackedWriter::new(self.0.pop().unwrap())
}
fn push(&mut self, w: PackedWriter<Vec<u8>>) {
self.0.push(w.0.take())
}
fn items(&self) -> &Vec<Vec<u8>> {
&self.0
}
fn items_mut(&mut self) -> &mut Vec<Vec<u8>> {
&mut self.0
}
fn buffer(&mut self) -> &mut Vec<u8> {
self.0.last_mut().unwrap()
}
fn finish<W: WriteWriter>(mut self, w: &mut W) -> Result<()> {
if self.buffer().len() != 0 { panic!("Missing final delimit()"); }
self.items_mut().pop();
self.items_mut().sort();
for bs in self.items() {
w.write_raw_bytes(&bs)?;
}
w.write_tag(Tag::End)?;
Ok(()) Ok(())
} }
} }
pub fn write_atom<W: std::io::Write>(w: &mut PackedWriter<W>, minor: AtomMinor, bs: &[u8]) -> Result<()> { pub trait WriteWriter: Writer {
write_header(w, Op::Atom(minor), bs.len())?; fn write_raw_bytes(&mut self, v: &[u8]) -> Result<()>;
w.0.write_all(bs) fn write_tag(&mut self, tag: Tag) -> Result<()> {
self.write_raw_bytes(&[tag.into()])
}
}
impl<W: std::io::Write> WriteWriter for PackedWriter<W> {
fn write_raw_bytes(&mut self, v: &[u8]) -> Result<()> {
self.w().write_all(v)
}
}
impl WriteWriter for BinaryOrderWriter {
fn write_raw_bytes(&mut self, v: &[u8]) -> Result<()> {
use std::io::Write;
self.buffer().write_all(v)
}
}
impl<T: WriteWriter> AnnotationWriter for T {
fn start_annotation(&mut self) -> Result<()> {
Ok(self.write_tag(Tag::Annotation)?)
}
fn start_value(&mut self) -> Result<()> {
Ok(())
}
}
impl<W: std::io::Write> CompoundWriter for PackedWriter<W> {
fn extend(&mut self) -> Result<()> {
Ok(())
}
fn delimit(&mut self) -> Result<()> {
Ok(())
}
}
impl CompoundWriter for BinaryOrderWriter {
fn extend(&mut self) -> Result<()> {
Ok(())
}
fn delimit(&mut self) -> Result<()> {
self.items_mut().push(vec![]);
Ok(())
}
}
macro_rules! binary_order_writer_method {
(mut $n:ident ($($argname:ident : $argty:ty),*) -> $retty:ty) =>
(fn $n (&mut self, $($argname : $argty),*) -> $retty {
(&mut PackedWriter::new(self.buffer())).$n($($argname),*)
});
}
impl Writer for BinaryOrderWriter {
type AnnWriter = PackedWriter<Vec<u8>>;
type SeqWriter = PackedWriter<Vec<u8>>;
type SetWriter = BinaryOrderWriter;
binary_order_writer_method!(mut align(natural_chunksize: u64) -> Result<()>);
fn start_annotations(&mut self) -> Result<Self::AnnWriter> {
Ok(self.pop())
}
fn end_annotations(&mut self, ann: Self::AnnWriter) -> Result<()> {
self.push(ann);
Ok(())
}
binary_order_writer_method!(mut write_bool(v: bool) -> Result<()>);
binary_order_writer_method!(mut write_f32(v: f32) -> Result<()>);
binary_order_writer_method!(mut write_f64(v: f64) -> Result<()>);
binary_order_writer_method!(mut write_i8(v: i8) -> Result<()>);
binary_order_writer_method!(mut write_u8(v: u8) -> Result<()>);
binary_order_writer_method!(mut write_i16(v: i16) -> Result<()>);
binary_order_writer_method!(mut write_u16(v: u16) -> Result<()>);
binary_order_writer_method!(mut write_i32(v: i32) -> Result<()>);
binary_order_writer_method!(mut write_u32(v: u32) -> Result<()>);
binary_order_writer_method!(mut write_i64(v: i64) -> Result<()>);
binary_order_writer_method!(mut write_u64(v: u64) -> Result<()>);
binary_order_writer_method!(mut write_i128(v: i128) -> Result<()>);
binary_order_writer_method!(mut write_u128(v: u128) -> Result<()>);
binary_order_writer_method!(mut write_int(v: &BigInt) -> Result<()>);
binary_order_writer_method!(mut write_string(v: &str) -> Result<()>);
binary_order_writer_method!(mut write_bytes(v: &[u8]) -> Result<()>);
binary_order_writer_method!(mut write_symbol(v: &str) -> Result<()>);
fn start_record(&mut self, _field_count: Option<usize>) -> Result<Self::SeqWriter> {
self.write_tag(Tag::Record)?;
Ok(self.pop())
}
fn start_sequence(&mut self, _item_count: Option<usize>) -> Result<Self::SeqWriter> {
self.write_tag(Tag::Sequence)?;
Ok(self.pop())
}
fn end_seq(&mut self, seq: Self::SeqWriter) -> Result<()> {
self.push(seq);
self.write_tag(Tag::End)
}
fn start_set(&mut self, _item_count: Option<usize>) -> Result<Self::SetWriter> {
self.write_tag(Tag::Set)?;
Ok(BinaryOrderWriter::new())
}
fn start_dictionary(&mut self, _entry_count: Option<usize>) -> Result<Self::SetWriter> {
self.write_tag(Tag::Dictionary)?;
Ok(BinaryOrderWriter::new())
}
fn end_set(&mut self, set: Self::SetWriter) -> Result<()> {
set.finish(self)
}
} }
macro_rules! fits_in_bytes { macro_rules! fits_in_bytes {
@ -35,38 +280,18 @@ macro_rules! fits_in_bytes {
}) })
} }
impl<'w, W: std::io::Write> PackedWriter<'w, W> { impl<W: std::io::Write> Writer for PackedWriter<W>
pub fn write_noop(&mut self) -> Result<()> { {
write_op(self, Op::Reserved(3), 15) type AnnWriter = Self;
} type SeqWriter = Self;
} type SetWriter = BinaryOrderWriter;
impl<'w> PackedWriter<'w, &'w mut Vec<u8>> { fn start_annotations(&mut self) -> Result<Self::AnnWriter> {
pub fn encode(v: &IOValue) -> std::io::Result<Vec<u8>> { Ok(self.suspend())
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 = ();
type Compound = bool;
type Dictionary = bool;
type StreamedAtom = ();
type KeyPointer = ();
fn start_annotation(&mut self) -> Result<Self::Annotation> {
Ok(())
} }
fn extend_annotation(&mut self, _a: &mut Self::Annotation, annotation: &IOValue) -> Result<()> { fn end_annotations(&mut self, ann: Self::AnnWriter) -> Result<()> {
write_header(self, Op::Misc(0), 5)?; self.resume(ann);
self.write(annotation)
}
fn end_annotation(&mut self, _a: Self::Annotation, _value_p: Self::Pointer) -> Result<Self::Pointer> {
Ok(()) Ok(())
} }
@ -75,235 +300,182 @@ impl<'w, W: std::io::Write> Writer for PackedWriter<'w, W> {
} }
fn write_bool(&mut self, v: bool) -> Result<()> { fn write_bool(&mut self, v: bool) -> Result<()> {
write_op(self, Op::Misc(0), if v { 1 } else { 0 }) self.write_tag(if v { Tag::True } else { Tag::False })
} }
fn write_f32(&mut self, v: f32) -> Result<()> { fn write_f32(&mut self, v: f32) -> Result<()> {
write_op(self, Op::Misc(0), 2)?; self.write_tag(Tag::Float)?;
self.0.write_all(&u32::to_be_bytes(f32::to_bits(v))) self.write_raw_bytes(&u32::to_be_bytes(f32::to_bits(v)))
} }
fn write_f64(&mut self, v: f64) -> Result<()> { fn write_f64(&mut self, v: f64) -> Result<()> {
write_op(self, Op::Misc(0), 3)?; self.write_tag(Tag::Double)?;
self.0.write_all(&u64::to_be_bytes(f64::to_bits(v))) self.write_raw_bytes(&u64::to_be_bytes(f64::to_bits(v)))
} }
fn write_i8(&mut self, v: i8) -> Result<()> { fn write_i8(&mut self, v: i8) -> Result<()> {
if v >= 0 && v <= 12 { return write_op(self, Op::Misc(3), v as u8) } if v >= -3 && v <= 12 { return self.write_tag(Tag::SmallInteger(v)) }
if v >= -3 && v < 0 { return write_op(self, Op::Misc(3), (v + 16) as u8) } self.write_medium_integer(&[v as u8])
write_atom(self, AtomMinor::SignedInteger, &[v as u8])
} }
fn write_u8(&mut self, v: u8) -> Result<()> { fn write_u8(&mut self, v: u8) -> Result<()> {
if let Ok(w) = v.try_into() { return self.write_i8(w) } if let Ok(w) = v.try_into() { return self.write_i8(w) }
write_atom(self, AtomMinor::SignedInteger, &[0, v]) self.write_medium_integer(&[0, v])
} }
fn write_i16(&mut self, v: i16) -> Result<()> { fn write_i16(&mut self, v: i16) -> Result<()> {
if let Ok(w) = v.try_into() { return self.write_i8(w) } if let Ok(w) = v.try_into() { return self.write_i8(w) }
write_atom(self, AtomMinor::SignedInteger, &[(v >> 8) as u8, (v & 255) as u8]) self.write_medium_integer(&[(v >> 8) as u8, (v & 255) as u8])
} }
fn write_u16(&mut self, v: u16) -> Result<()> { fn write_u16(&mut self, v: u16) -> Result<()> {
if let Ok(w) = v.try_into() { return self.write_i16(w) } if let Ok(w) = v.try_into() { return self.write_i16(w) }
write_atom(self, AtomMinor::SignedInteger, &[0, (v >> 8) as u8, (v & 255) as u8]) self.write_medium_integer(&[0, (v >> 8) as u8, (v & 255) as u8])
} }
fn write_i32(&mut self, v: i32) -> Result<()> { fn write_i32(&mut self, v: i32) -> Result<()> {
if let Ok(w) = v.try_into() { return self.write_i16(w) } if let Ok(w) = v.try_into() { return self.write_i16(w) }
if fits_in_bytes!(v, 3) { if fits_in_bytes!(v, 3) {
return write_atom(self, AtomMinor::SignedInteger, &[(v >> 16) as u8, return self.write_medium_integer(&[(v >> 16) as u8,
(v >> 8) as u8, (v >> 8) as u8,
(v & 255) as u8]); (v & 255) as u8]);
} }
return write_atom(self, AtomMinor::SignedInteger, &[(v >> 24) as u8, self.write_medium_integer(&[(v >> 24) as u8,
(v >> 16) as u8, (v >> 16) as u8,
(v >> 8) as u8, (v >> 8) as u8,
(v & 255) as u8]); (v & 255) as u8])
} }
fn write_u32(&mut self, v: u32) -> Result<()> { fn write_u32(&mut self, v: u32) -> Result<()> {
if let Ok(w) = v.try_into() { return self.write_i32(w) } if let Ok(w) = v.try_into() { return self.write_i32(w) }
return write_atom(self, AtomMinor::SignedInteger, &[0, self.write_medium_integer(&[0,
(v >> 24) as u8, (v >> 24) as u8,
(v >> 16) as u8, (v >> 16) as u8,
(v >> 8) as u8, (v >> 8) as u8,
(v & 255) as u8]); (v & 255) as u8])
} }
fn write_i64(&mut self, v: i64) -> Result<()> { fn write_i64(&mut self, v: i64) -> Result<()> {
if let Ok(w) = v.try_into() { return self.write_i32(w) } if let Ok(w) = v.try_into() { return self.write_i32(w) }
if fits_in_bytes!(v, 5) { if fits_in_bytes!(v, 5) {
return write_atom(self, AtomMinor::SignedInteger, &[(v >> 32) as u8, return self.write_medium_integer(&[(v >> 32) as u8,
(v >> 24) as u8, (v >> 24) as u8,
(v >> 16) as u8, (v >> 16) as u8,
(v >> 8) as u8, (v >> 8) as u8,
(v & 255) as u8]); (v & 255) as u8]);
} }
if fits_in_bytes!(v, 6) { if fits_in_bytes!(v, 6) {
return write_atom(self, AtomMinor::SignedInteger, &[(v >> 40) as u8, return self.write_medium_integer(&[(v >> 40) as u8,
(v >> 32) as u8, (v >> 32) as u8,
(v >> 24) as u8, (v >> 24) as u8,
(v >> 16) as u8, (v >> 16) as u8,
(v >> 8) as u8, (v >> 8) as u8,
(v & 255) as u8]); (v & 255) as u8]);
} }
if fits_in_bytes!(v, 7) { if fits_in_bytes!(v, 7) {
return write_atom(self, AtomMinor::SignedInteger, &[(v >> 48) as u8, return self.write_medium_integer(&[(v >> 48) as u8,
(v >> 40) as u8, (v >> 40) as u8,
(v >> 32) as u8, (v >> 32) as u8,
(v >> 24) as u8, (v >> 24) as u8,
(v >> 16) as u8, (v >> 16) as u8,
(v >> 8) as u8, (v >> 8) as u8,
(v & 255) as u8]); (v & 255) as u8]);
} }
return write_atom(self, AtomMinor::SignedInteger, &[(v >> 56) as u8, self.write_medium_integer(&[(v >> 56) as u8,
(v >> 48) as u8, (v >> 48) as u8,
(v >> 40) as u8, (v >> 40) as u8,
(v >> 32) as u8, (v >> 32) as u8,
(v >> 24) as u8, (v >> 24) as u8,
(v >> 16) as u8, (v >> 16) as u8,
(v >> 8) as u8, (v >> 8) as u8,
(v & 255) as u8]); (v & 255) as u8])
} }
fn write_u64(&mut self, v: u64) -> Result<()> { fn write_u64(&mut self, v: u64) -> Result<()> {
if let Ok(w) = v.try_into() { return self.write_i64(w) } if let Ok(w) = v.try_into() { return self.write_i64(w) }
return write_atom(self, AtomMinor::SignedInteger, &[0, self.write_medium_integer(&[0,
(v >> 56) as u8, (v >> 56) as u8,
(v >> 48) as u8, (v >> 48) as u8,
(v >> 40) as u8, (v >> 40) as u8,
(v >> 32) as u8, (v >> 32) as u8,
(v >> 24) as u8, (v >> 24) as u8,
(v >> 16) as u8, (v >> 16) as u8,
(v >> 8) as u8, (v >> 8) as u8,
(v & 255) as u8]); (v & 255) as u8])
} }
fn write_i128(&mut self, v: i128) -> Result<()> { fn write_i128(&mut self, v: i128) -> Result<()> {
if let Ok(w) = v.try_into() { return self.write_i64(w) } if let Ok(w) = v.try_into() { return self.write_i64(w) }
let bs: [u8; 16] = v.to_be_bytes(); let bs: [u8; 16] = v.to_be_bytes();
if fits_in_bytes!(v, 9) { return write_atom(self, AtomMinor::SignedInteger, &bs[7..]); } if fits_in_bytes!(v, 9) { return self.write_medium_integer(&bs[7..]); }
if fits_in_bytes!(v, 10) { return write_atom(self, AtomMinor::SignedInteger, &bs[6..]); } if fits_in_bytes!(v, 10) { return self.write_medium_integer(&bs[6..]); }
if fits_in_bytes!(v, 11) { return write_atom(self, AtomMinor::SignedInteger, &bs[5..]); } if fits_in_bytes!(v, 11) { return self.write_medium_integer(&bs[5..]); }
if fits_in_bytes!(v, 12) { return write_atom(self, AtomMinor::SignedInteger, &bs[4..]); } if fits_in_bytes!(v, 12) { return self.write_medium_integer(&bs[4..]); }
if fits_in_bytes!(v, 13) { return write_atom(self, AtomMinor::SignedInteger, &bs[3..]); } if fits_in_bytes!(v, 13) { return self.write_medium_integer(&bs[3..]); }
if fits_in_bytes!(v, 14) { return write_atom(self, AtomMinor::SignedInteger, &bs[2..]); } if fits_in_bytes!(v, 14) { return self.write_medium_integer(&bs[2..]); }
if fits_in_bytes!(v, 15) { return write_atom(self, AtomMinor::SignedInteger, &bs[1..]); } if fits_in_bytes!(v, 15) { return self.write_medium_integer(&bs[1..]); }
return write_atom(self, AtomMinor::SignedInteger, &bs); self.write_medium_integer(&bs)
} }
fn write_u128(&mut self, v: u128) -> Result<()> { fn write_u128(&mut self, v: u128) -> Result<()> {
if let Ok(w) = v.try_into() { return self.write_i128(w) } if let Ok(w) = v.try_into() { return self.write_i128(w) }
let bs: [u8; 16] = v.to_be_bytes(); let bs: [u8; 16] = v.to_be_bytes();
write_header(self, Op::Atom(AtomMinor::SignedInteger), bs.len() + 1)?; self.write_tag(Tag::SignedInteger)?;
self.0.write_all(&[0])?; varint(&mut self.w(), 17)?;
self.0.write_all(&bs) self.write_byte(0)?;
self.write_raw_bytes(&bs)
} }
fn write_int(&mut self, v: &BigInt) -> Result<()> { fn write_int(&mut self, v: &BigInt) -> Result<()> {
match v.to_i8() { match v.to_i8() {
Some(n) => self.write_i8(n), Some(n) => self.write_i8(n),
None => write_atom(self, AtomMinor::SignedInteger, &v.to_signed_bytes_be()), None => {
match v.to_i128() {
Some(n) => self.write_i128(n),
None => self.write_atom(Tag::SignedInteger, &v.to_signed_bytes_be()),
}
}
} }
} }
fn write_string(&mut self, v: &str) -> Result<()> { fn write_string(&mut self, v: &str) -> Result<()> {
write_atom(self, AtomMinor::String, v.as_bytes()) self.write_atom(Tag::String, v.as_bytes())
} }
fn write_bytes(&mut self, v: &[u8]) -> Result<()> { fn write_bytes(&mut self, v: &[u8]) -> Result<()> {
write_atom(self, AtomMinor::ByteString, v) self.write_atom(Tag::ByteString, v)
} }
fn write_symbol(&mut self, v: &str) -> Result<()> { fn write_symbol(&mut self, v: &str) -> Result<()> {
write_atom(self, AtomMinor::Symbol, v.as_bytes()) self.write_atom(Tag::Symbol, v.as_bytes())
} }
fn stream_string(&mut self) -> Result<Option<Self::StreamedAtom>> { fn start_record(&mut self, _field_count: Option<usize>) -> Result<Self::SeqWriter> {
write_op(self, Op::Misc(2), Op::Atom(AtomMinor::String).into())?; self.write_tag(Tag::Record)?;
Ok(Some(())) Ok(self.suspend())
} }
fn stream_bytes(&mut self) -> Result<Option<Self::StreamedAtom>> { fn start_sequence(&mut self, _item_count: Option<usize>) -> Result<Self::SeqWriter> {
write_op(self, Op::Misc(2), Op::Atom(AtomMinor::ByteString).into())?; self.write_tag(Tag::Sequence)?;
Ok(Some(())) Ok(self.suspend())
} }
fn stream_symbol(&mut self) -> Result<Option<Self::StreamedAtom>> { fn end_seq(&mut self, seq: Self::SeqWriter) -> Result<()> {
write_op(self, Op::Misc(2), Op::Atom(AtomMinor::Symbol).into())?; self.resume(seq);
Ok(Some(())) self.write_tag(Tag::End)
} }
fn extend_atom(&mut self, _s: &mut Self::StreamedAtom, bs: &[u8]) -> Result<()> { fn start_set(&mut self, _item_count: Option<usize>) -> Result<Self::SetWriter> {
self.write_bytes(bs) self.write_tag(Tag::Set)?;
Ok(BinaryOrderWriter::new())
} }
fn end_atom(&mut self, _s: Self::StreamedAtom) -> Result<()> { fn start_dictionary(&mut self, _entry_count: Option<usize>) -> Result<Self::SetWriter> {
write_op(self, Op::Misc(0), 4) self.write_tag(Tag::Dictionary)?;
Ok(BinaryOrderWriter::new())
} }
fn start_record(&mut self, field_count: usize) -> Result<Self::Compound> { fn end_set(&mut self, set: Self::SetWriter) -> Result<()> {
write_header(self, Op::Compound(CompoundMinor::Record), field_count + 1)?; set.finish(self)
Ok(false)
}
fn start_sequence(&mut self, item_count: usize) -> Result<Self::Compound> {
write_header(self, Op::Compound(CompoundMinor::Sequence), item_count)?;
Ok(false)
}
fn start_set(&mut self, item_count: usize) -> Result<Self::Compound> {
write_header(self, Op::Compound(CompoundMinor::Set), item_count)?;
Ok(false)
}
fn stream_record(&mut self) -> Result<Option<Self::Compound>> {
write_op(self, Op::Misc(2), Op::Compound(CompoundMinor::Record).into())?;
Ok(Some(true))
}
fn stream_sequence(&mut self) -> Result<Option<Self::Compound>> {
write_op(self, Op::Misc(2), Op::Compound(CompoundMinor::Sequence).into())?;
Ok(Some(true))
}
fn stream_set(&mut self) -> Result<Option<Self::Compound>> {
write_op(self, Op::Misc(2), Op::Compound(CompoundMinor::Set).into())?;
Ok(Some(true))
}
fn extend_compound(&mut self, _s: &mut Self::Compound, _value_p: Self::Pointer) -> Result<()> {
Ok(())
}
fn end_compound(&mut self, s: Self::Compound) -> Result<()> {
if s {
write_op(self, Op::Misc(0), 4)
} else {
Ok(())
}
}
fn start_dictionary(&mut self, entry_count: usize) -> Result<Self::Dictionary> {
write_header(self, Op::Compound(CompoundMinor::Dictionary), entry_count << 1)?;
Ok(false)
}
fn stream_dictionary(&mut self) -> Result<Option<Self::Dictionary>> {
write_op(self, Op::Misc(2), Op::Compound(CompoundMinor::Dictionary).into())?;
Ok(Some(true))
}
fn extend_dictionary_key(&mut self, _s: &mut Self::Dictionary, _key_p: Self::Pointer) -> Result<Self::KeyPointer> {
Ok(())
}
fn extend_dictionary_value(&mut self, _s: &mut Self::Dictionary, _key_p: Self::KeyPointer, _value_p: Self::Pointer) -> Result<()> {
Ok(())
}
fn end_dictionary(&mut self, s: Self::Dictionary) -> Result<()> {
self.end_compound(s)
} }
} }

View File

@ -8,16 +8,13 @@ pub type IOResult<T> = std::result::Result<T, Error>;
pub type ReaderResult<T> = std::result::Result<T, error::Error>; pub type ReaderResult<T> = std::result::Result<T, error::Error>;
pub trait Reader<'de> { pub trait Reader<'de> {
type CompoundInfo: Copy;
fn next(&mut self, read_annotations: bool) -> IOResult<Option<IOValue>>; fn next(&mut self, read_annotations: bool) -> IOResult<Option<IOValue>>;
fn open_record(&mut self, arity: Option<usize>) -> ReaderResult<CompoundBody<Self::CompoundInfo>>; fn open_record(&mut self, arity: Option<usize>) -> ReaderResult<()>;
fn open_sequence_or_set(&mut self) -> ReaderResult<CompoundBody<Self::CompoundInfo>>; fn open_sequence_or_set(&mut self) -> ReaderResult<()>;
fn open_sequence(&mut self) -> ReaderResult<CompoundBody<Self::CompoundInfo>>; fn open_sequence(&mut self) -> ReaderResult<()>;
fn open_set(&mut self) -> ReaderResult<CompoundBody<Self::CompoundInfo>>; fn open_set(&mut self) -> ReaderResult<()>;
fn open_dictionary(&mut self) -> ReaderResult<CompoundBody<Self::CompoundInfo>>; fn open_dictionary(&mut self) -> ReaderResult<()>;
fn close_compound_counted(&mut self, info: Self::CompoundInfo) -> ReaderResult<()>; fn close_compound(&mut self) -> ReaderResult<bool>;
fn close_compound_stream(&mut self, info: Self::CompoundInfo) -> ReaderResult<bool>;
//--------------------------------------------------------------------------- //---------------------------------------------------------------------------
@ -28,10 +25,7 @@ pub trait Reader<'de> {
} }
fn demand_next(&mut self, read_annotations: bool) -> IOResult<IOValue> { fn demand_next(&mut self, read_annotations: bool) -> IOResult<IOValue> {
match self.next(read_annotations)? { self.next(read_annotations)?.ok_or_else(|| io_eof())
None => Err(io_eof()),
Some(v) => Ok(v)
}
} }
fn next_boolean(&mut self) -> ReaderResult<bool> { self.demand_next(false)?.value().to_boolean() } fn next_boolean(&mut self) -> ReaderResult<bool> { self.demand_next(false)?.value().to_boolean() }
@ -61,30 +55,24 @@ pub trait Reader<'de> {
Ok(Cow::Owned(self.demand_next(false)?.value().to_symbol()?.to_owned())) Ok(Cow::Owned(self.demand_next(false)?.value().to_symbol()?.to_owned()))
} }
fn open_option(&mut self) -> fn open_option(&mut self) -> ReaderResult<bool>
ReaderResult<(bool, CompoundBody<Self::CompoundInfo>)>
where
Self: Sized
{ {
let mut compound_body = self.open_record(None)?; self.open_record(None)?;
let label: &str = &compound_body.next_symbol(self)?.ok_or(error::Error::MissingItem)?; let label: &str = &self.next_symbol()?;
match label { match label {
"None" => Ok((false, compound_body)), "None" => Ok(false),
"Some" => Ok((true, compound_body)), "Some" => Ok(true),
_ => Err(error::Error::Expected(ExpectedKind::Option, _ => Err(error::Error::Expected(ExpectedKind::Option,
Received::ReceivedRecordWithLabel(label.to_owned()))), Received::ReceivedRecordWithLabel(label.to_owned()))),
} }
} }
fn open_simple_record(&mut self, name: &str, arity: Option<usize>) -> fn open_simple_record(&mut self, name: &str, arity: Option<usize>) -> ReaderResult<()>
ReaderResult<CompoundBody<Self::CompoundInfo>>
where
Self: Sized
{ {
let mut compound_body = self.open_record(arity)?; self.open_record(arity)?;
let label: &str = &compound_body.next_symbol(self)?.ok_or(error::Error::MissingItem)?; let label: &str = &self.next_symbol()?;
if label == name { if label == name {
Ok(compound_body) Ok(())
} else { } else {
Err(error::Error::Expected(ExpectedKind::SimpleRecord(name.to_owned(), arity), Err(error::Error::Expected(ExpectedKind::SimpleRecord(name.to_owned(), arity),
Received::ReceivedRecordWithLabel(label.to_owned()))) Received::ReceivedRecordWithLabel(label.to_owned())))
@ -101,129 +89,24 @@ pub trait Reader<'de> {
phantom: PhantomData, phantom: PhantomData,
} }
} }
}
impl<'r, 'de, R: Reader<'de>> Reader<'de> for &'r mut R { fn skip_remainder(&mut self) -> ReaderResult<()> {
type CompoundInfo = R::CompoundInfo; while !self.close_compound()? {
self.skip_value()?;
fn next(&mut self, read_annotations: bool) -> IOResult<Option<IOValue>> {
(*self).next(read_annotations)
}
fn open_record(&mut self, arity: Option<usize>) -> ReaderResult<CompoundBody<Self::CompoundInfo>> {
(*self).open_record(arity)
}
fn open_sequence_or_set(&mut self) -> ReaderResult<CompoundBody<Self::CompoundInfo>> {
(*self).open_sequence_or_set()
}
fn open_sequence(&mut self) -> ReaderResult<CompoundBody<Self::CompoundInfo>> {
(*self).open_sequence()
}
fn open_set(&mut self) -> ReaderResult<CompoundBody<Self::CompoundInfo>> {
(*self).open_set()
}
fn open_dictionary(&mut self) -> ReaderResult<CompoundBody<Self::CompoundInfo>> {
(*self).open_dictionary()
}
fn close_compound_counted(&mut self, info: Self::CompoundInfo) -> ReaderResult<()> {
(*self).close_compound_counted(info)
}
fn close_compound_stream(&mut self, info: Self::CompoundInfo) -> ReaderResult<bool> {
(*self).close_compound_stream(info)
}
}
#[derive(Debug)]
pub struct CompoundBody<I: Copy> {
pub info: I,
pub limit: CompoundLimit,
}
#[derive(Debug)]
pub enum CompoundLimit {
Counted(usize),
Streaming,
Finished,
}
impl<I: Copy> CompoundBody<I> {
pub fn counted(info: I, size: usize) -> Self {
CompoundBody { info, limit: CompoundLimit::Counted(size) }
}
pub fn streaming(info: I) -> Self {
CompoundBody { info, limit: CompoundLimit::Streaming }
}
pub fn more_expected<'de, R: Reader<'de, CompoundInfo = I>>(&mut self, read: &mut R) -> ReaderResult<bool> {
match self.limit {
CompoundLimit::Counted(ref mut n) =>
if *n == 0 {
read.close_compound_counted(self.info)?;
self.limit = CompoundLimit::Finished;
Ok(false)
} else {
*n = *n - 1;
Ok(true)
},
CompoundLimit::Streaming =>
Ok(!read.close_compound_stream(self.info)?),
CompoundLimit::Finished =>
Ok(false),
}
}
pub fn next_symbol<'de, R: Reader<'de, CompoundInfo = I>>(&mut self, read: &mut R) -> ReaderResult<Option<Cow<'de, str>>> {
match self.more_expected(read)? {
false => Ok(None),
true => Ok(Some(read.next_symbol()?)),
}
}
pub fn next_value<'de, R: Reader<'de, CompoundInfo = I>>(&mut self, read: &mut R, read_annotations: bool) ->
ReaderResult<Option<IOValue>>
{
match self.more_expected(read)? {
false => Ok(None),
true => Ok(Some(read.demand_next(read_annotations)?)),
}
}
pub fn remainder<'de, R: Reader<'de, CompoundInfo = I>>(&mut self, read: &mut R, read_annotations: bool) ->
ReaderResult<Vec<IOValue>>
{
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, CompoundInfo = I>>(&mut self, read: &mut R) ->
ReaderResult<()>
{
while let true = self.more_expected(read)? {
read.skip_value()?;
} }
Ok(()) Ok(())
} }
pub fn ensure_more_expected<'de, R: Reader<'de, CompoundInfo = I>>(&mut self, read: &mut R) -> ReaderResult<()> { fn ensure_more_expected(&mut self) -> ReaderResult<()> {
if self.more_expected(read)? { if !self.close_compound()? {
Ok(()) Ok(())
} else { } else {
Err(error::Error::MissingItem) Err(error::Error::MissingItem)
} }
} }
pub fn ensure_complete<'de, R: Reader<'de, CompoundInfo = I>>(&mut self, read: &mut R) -> ReaderResult<()> { fn ensure_complete(&mut self) -> ReaderResult<()> {
if self.more_expected(read)? { if !self.close_compound()? {
Err(error::Error::MissingCloseDelimiter) Err(error::Error::MissingCloseDelimiter)
} else { } else {
Ok(()) Ok(())
@ -231,6 +114,37 @@ impl<I: Copy> CompoundBody<I> {
} }
} }
impl<'r, 'de, R: Reader<'de>> Reader<'de> for &'r mut R {
fn next(&mut self, read_annotations: bool) -> IOResult<Option<IOValue>> {
(*self).next(read_annotations)
}
fn open_record(&mut self, arity: Option<usize>) -> 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(&mut self) -> ReaderResult<bool> {
(*self).close_compound()
}
}
pub trait BinarySource<'de> { pub trait BinarySource<'de> {
fn skip(&mut self) -> IOResult<()>; fn skip(&mut self) -> IOResult<()>;
fn peek(&mut self) -> IOResult<u8>; fn peek(&mut self) -> IOResult<u8>;

View File

@ -236,16 +236,16 @@ impl<N: NestedValue<D>, D: Domain> Debug for Value<N, D> {
// doesn't escape strings/symbols properly. // doesn't escape strings/symbols properly.
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
match self { match self {
Value::Boolean(false) => f.write_str("#false"), Value::Boolean(false) => f.write_str("#f"),
Value::Boolean(true) => f.write_str("#true"), Value::Boolean(true) => f.write_str("#t"),
Value::Float(Float(v)) => write!(f, "{:?}f", v), Value::Float(Float(v)) => write!(f, "{:?}f", v),
Value::Double(Double(v)) => write!(f, "{:?}", v), Value::Double(Double(v)) => write!(f, "{:?}", v),
Value::SignedInteger(v) => write!(f, "{}", v), Value::SignedInteger(v) => write!(f, "{}", v),
Value::String(ref v) => write!(f, "{:?}", v), // TODO: proper escaping! Value::String(ref v) => write!(f, "{:?}", v), // TODO: proper escaping!
Value::ByteString(ref v) => { Value::ByteString(ref v) => {
f.write_str("#hex{")?; f.write_str("#x\"")?;
for b in v { write!(f, "{:02x}", b)? } for b in v { write!(f, "{:02x}", b)? }
f.write_str("}") f.write_str("\"")
} }
Value::Symbol(ref v) => { Value::Symbol(ref v) => {
// TODO: proper escaping! // TODO: proper escaping!
@ -266,7 +266,7 @@ impl<N: NestedValue<D>, D: Domain> Debug for Value<N, D> {
} }
Value::Sequence(ref v) => v.fmt(f), Value::Sequence(ref v) => v.fmt(f),
Value::Set(ref v) => { Value::Set(ref v) => {
f.write_str("#set")?; f.write_str("#")?;
f.debug_set().entries(v.iter()).finish() f.debug_set().entries(v.iter()).finish()
} }
Value::Dictionary(ref v) => f.debug_map().entries(v.iter()).finish(), Value::Dictionary(ref v) => f.debug_map().entries(v.iter()).finish(),
@ -849,7 +849,7 @@ impl<N: NestedValue<D>, D: Domain> Annotations<N, D> {
} }
} }
/// An possibly-annotated Value, with annotations (themselves /// A possibly-annotated Value, with annotations (themselves
/// possibly-annotated) in order of appearance. /// possibly-annotated) in order of appearance.
#[derive(Clone)] #[derive(Clone)]
pub struct AnnotatedValue<N: NestedValue<D>, D: Domain>(pub Annotations<N, D>, pub Value<N, D>); pub struct AnnotatedValue<N: NestedValue<D>, D: Domain>(pub Annotations<N, D>, pub Value<N, D>);

View File

@ -6,79 +6,77 @@ use super::value::{Domain, Value, NestedValue, IOValue, UnwrappedIOValue, Float,
pub type Result<T> = std::result::Result<T, Error>; pub type Result<T> = std::result::Result<T, Error>;
pub trait Writer { pub trait AnnotationWriter: Writer {
type Pointer; fn start_annotation(&mut self) -> Result<()>;
type Annotation; fn start_value(&mut self) -> Result<()>;
type Compound; }
type Dictionary;
type StreamedAtom; pub trait CompoundWriter: Writer {
type KeyPointer; fn extend(&mut self) -> Result<()>;
fn delimit(&mut self) -> Result<()>;
}
pub trait Writer: Sized {
type AnnWriter: AnnotationWriter;
type SeqWriter: CompoundWriter;
type SetWriter: CompoundWriter;
fn align(&mut self, natural_chunksize: u64) -> Result<()>; fn align(&mut self, natural_chunksize: u64) -> Result<()>;
fn start_annotation(&mut self) -> Result<Self::Annotation>; fn start_annotations(&mut self) -> Result<Self::AnnWriter>;
fn extend_annotation(&mut self, a: &mut Self::Annotation, annotation: &IOValue) -> Result<()>; fn end_annotations(&mut self, ann: Self::AnnWriter) -> Result<()>;
fn end_annotation(&mut self, a: Self::Annotation, value_p: Self::Pointer) -> Result<Self::Pointer>;
fn write_bool(&mut self, v: bool) -> Result<Self::Pointer>; fn write_bool(&mut self, v: bool) -> Result<()>;
fn write_f32(&mut self, v: f32) -> Result<Self::Pointer>; fn write_f32(&mut self, v: f32) -> Result<()>;
fn write_f64(&mut self, v: f64) -> Result<Self::Pointer>; fn write_f64(&mut self, v: f64) -> Result<()>;
fn write_i8(&mut self, v: i8) -> Result<Self::Pointer>; fn write_i8(&mut self, v: i8) -> Result<()>;
fn write_u8(&mut self, v: u8) -> Result<Self::Pointer>; fn write_u8(&mut self, v: u8) -> Result<()>;
fn write_i16(&mut self, v: i16) -> Result<Self::Pointer>; fn write_i16(&mut self, v: i16) -> Result<()>;
fn write_u16(&mut self, v: u16) -> Result<Self::Pointer>; fn write_u16(&mut self, v: u16) -> Result<()>;
fn write_i32(&mut self, v: i32) -> Result<Self::Pointer>; fn write_i32(&mut self, v: i32) -> Result<()>;
fn write_u32(&mut self, v: u32) -> Result<Self::Pointer>; fn write_u32(&mut self, v: u32) -> Result<()>;
fn write_i64(&mut self, v: i64) -> Result<Self::Pointer>; fn write_i64(&mut self, v: i64) -> Result<()>;
fn write_u64(&mut self, v: u64) -> Result<Self::Pointer>; fn write_u64(&mut self, v: u64) -> Result<()>;
fn write_i128(&mut self, v: i128) -> Result<Self::Pointer>; fn write_i128(&mut self, v: i128) -> Result<()>;
fn write_u128(&mut self, v: u128) -> Result<Self::Pointer>; fn write_u128(&mut self, v: u128) -> Result<()>;
fn write_int(&mut self, v: &BigInt) -> Result<Self::Pointer>; fn write_int(&mut self, v: &BigInt) -> Result<()>;
fn write_string(&mut self, v: &str) -> Result<Self::Pointer>; fn write_string(&mut self, v: &str) -> Result<()>;
fn write_bytes(&mut self, v: &[u8]) -> Result<Self::Pointer>; fn write_bytes(&mut self, v: &[u8]) -> Result<()>;
fn write_symbol(&mut self, v: &str) -> Result<Self::Pointer>; fn write_symbol(&mut self, v: &str) -> Result<()>;
fn stream_string(&mut self) -> Result<Option<Self::StreamedAtom>>; fn start_record(&mut self, field_count: Option<usize>) -> Result<Self::SeqWriter>;
fn stream_bytes(&mut self) -> Result<Option<Self::StreamedAtom>>; fn start_sequence(&mut self, item_count: Option<usize>) -> Result<Self::SeqWriter>;
fn stream_symbol(&mut self) -> Result<Option<Self::StreamedAtom>>; fn end_seq(&mut self, seq: Self::SeqWriter) -> Result<()>;
fn extend_atom(&mut self, s: &mut Self::StreamedAtom, bs: &[u8]) -> Result<()>;
fn end_atom(&mut self, s: Self::StreamedAtom) -> Result<Self::Pointer>;
fn start_record(&mut self, field_count: usize) -> Result<Self::Compound>; fn start_set(&mut self, item_count: Option<usize>) -> Result<Self::SetWriter>;
fn start_sequence(&mut self, item_count: usize) -> Result<Self::Compound>; fn start_dictionary(&mut self, entry_count: Option<usize>) -> Result<Self::SetWriter>;
fn start_set(&mut self, item_count: usize) -> Result<Self::Compound>; fn end_set(&mut self, set: Self::SetWriter) -> Result<()>;
fn stream_record(&mut self) -> Result<Option<Self::Compound>>;
fn stream_sequence(&mut self) -> Result<Option<Self::Compound>>;
fn stream_set(&mut self) -> Result<Option<Self::Compound>>;
fn extend_compound(&mut self, s: &mut Self::Compound, value_p: Self::Pointer) -> Result<()>;
fn end_compound(&mut self, s: Self::Compound) -> Result<Self::Pointer>;
fn start_dictionary(&mut self, entry_count: usize) -> Result<Self::Dictionary>;
fn stream_dictionary(&mut self) -> Result<Option<Self::Dictionary>>;
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> { fn write(&mut self, v: &IOValue) -> Result<()> {
match v.annotations().maybe_slice() { match v.annotations().maybe_slice() {
None => self.write_value(v.value()), None => {
self.write_value(v.value())?;
}
Some(anns) => { Some(anns) => {
let mut a = self.start_annotation()?; let mut a = self.start_annotations()?;
for ann in anns { for ann in anns {
self.extend_annotation(&mut a, ann)?; a.start_annotation()?;
a.write(ann)?;
} }
let p = self.write_value(v.value())?; a.start_value()?;
self.end_annotation(a, p) a.write_value(v.value())?;
self.end_annotations(a)?;
} }
} }
Ok(())
} }
fn write_value(&mut self, v: &UnwrappedIOValue) -> Result<Self::Pointer> { fn write_value(&mut self, v: &UnwrappedIOValue) -> Result<()> {
match v { match v {
Value::Boolean(b) => self.write_bool(*b), Value::Boolean(b) => self.write_bool(*b),
Value::Float(Float(f)) => self.write_f32(*f), Value::Float(Float(f)) => self.write_f32(*f),
@ -92,60 +90,50 @@ pub trait Writer {
Value::ByteString(ref bs) => self.write_bytes(bs), Value::ByteString(ref bs) => self.write_bytes(bs),
Value::Symbol(ref s) => self.write_symbol(s), Value::Symbol(ref s) => self.write_symbol(s),
Value::Record(r) => { Value::Record(r) => {
let mut c = self.start_record(r.arity())?; let mut c = self.start_record(Some(r.arity()))?;
let p = self.write(r.label())?; c.extend()?;
self.extend_compound(&mut c, p)?; c.write(r.label())?;
c.delimit()?;
for f in r.fields() { for f in r.fields() {
let p = self.write(f)?; c.extend()?;
self.extend_compound(&mut c, p)?; c.write(f)?;
c.delimit()?;
} }
self.end_compound(c) self.end_seq(c)
} }
Value::Sequence(ref vs) => { Value::Sequence(ref vs) => {
let mut c = self.start_sequence(vs.len())?; let mut c = self.start_sequence(Some(vs.len()))?;
for v in vs { for v in vs {
let p = self.write(v)?; c.extend()?;
self.extend_compound(&mut c, p)?; c.write(v)?;
c.delimit()?;
} }
self.end_compound(c) self.end_seq(c)
} }
Value::Set(ref vs) => { Value::Set(ref vs) => {
let mut c = self.start_set(vs.len())?; let mut c = self.start_set(Some(vs.len()))?;
for v in vs { for v in vs {
let p = self.write(v)?; c.extend()?;
self.extend_compound(&mut c, p)?; c.write(v)?;
c.delimit()?;
} }
self.end_compound(c) self.end_set(c)
} }
Value::Dictionary(ref vs) => { Value::Dictionary(ref vs) => {
let mut d = self.start_dictionary(vs.len())?; let mut c = self.start_dictionary(Some(vs.len()))?;
for (k, v) in vs { for (k, v) in vs {
let p = self.write(k)?; c.extend()?;
let kp = self.extend_dictionary_key(&mut d, p)?; c.write(k)?;
let p = self.write(v)?; c.write(v)?;
self.extend_dictionary_value(&mut d, kp, p)?; c.delimit()?;
} }
self.end_dictionary(d) self.end_set(c)
} }
Value::Domain(ref d) => self.write(&d.as_preserves()?) Value::Domain(ref d) => self.write(&d.as_preserves()?)
} }
} }
} }
pub fn bigvarint<W: std::io::Write>(w: &mut W, mut v: u64) -> Result<usize> {
let mut byte_count = 0;
loop {
byte_count = byte_count + 4;
if v < (2 << 31) {
w.write_all(&(v as u32).to_le_bytes())?;
return Ok(byte_count);
} else {
w.write_all(&(((v & 0x7fffffff) + (2 << 31)) as u32).to_le_bytes())?;
v = v >> 31;
}
}
}
pub fn varint<W: std::io::Write>(w: &mut W, mut v: u64) -> Result<usize> { pub fn varint<W: std::io::Write>(w: &mut W, mut v: u64) -> Result<usize> {
let mut byte_count = 0; let mut byte_count = 0;
loop { loop {

View File

@ -10,7 +10,6 @@ pub struct TestCases {
pub enum TestCase { pub enum TestCase {
Test(#[serde(with = "serde_bytes")] Vec<u8>, IOValue), Test(#[serde(with = "serde_bytes")] Vec<u8>, IOValue),
NondeterministicTest(#[serde(with = "serde_bytes")] Vec<u8>, IOValue), NondeterministicTest(#[serde(with = "serde_bytes")] Vec<u8>, IOValue),
StreamingTest(#[serde(with = "serde_bytes")] Vec<u8>, IOValue),
DecodeTest(#[serde(with = "serde_bytes")] Vec<u8>, IOValue), DecodeTest(#[serde(with = "serde_bytes")] Vec<u8>, IOValue),
ParseError(String), ParseError(String),
ParseShort(String), ParseShort(String),

View File

@ -29,15 +29,11 @@ fn decode_all<'de>(bytes: &'de [u8]) -> Result<Vec<IOValue>, std::io::Error> {
assert_eq!(&PackedWriter::encode(val)?, bin); assert_eq!(&PackedWriter::encode(val)?, bin);
} }
TestCase::NondeterministicTest(ref bin, ref val) => { TestCase::NondeterministicTest(ref bin, ref val) => {
// The test cases in samples.txt are carefully // The test cases in samples.txt are carefully written
// written so that while strictly // so that while strictly "nondeterministic", the
// "nondeterministic", the order of keys in // order of keys in encoded dictionaries follows
// dictionaries follows Preserves order. // Preserves canonical order.
assert_eq!(&decode_all(&PackedWriter::encode(val)?[..])?, &[val.clone()]);
assert_eq!(&decode_all(&bin[..])?, &[val.clone()]);
assert_eq!(&PackedWriter::encode(val)?, bin); assert_eq!(&PackedWriter::encode(val)?, bin);
}
TestCase::StreamingTest(ref bin, ref val) => {
assert_eq!(&decode_all(&PackedWriter::encode(val)?[..])?, &[val.clone()]); assert_eq!(&decode_all(&PackedWriter::encode(val)?[..])?, &[val.clone()]);
assert_eq!(&decode_all(&bin[..])?, &[val.clone()]); assert_eq!(&decode_all(&bin[..])?, &[val.clone()]);
} }