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]
name = "preserves"
version = "0.9.0"
version = "0.10.0"
authors = ["Tony Garnock-Jones <tonyg@leastfixedpoint.com>"]
edition = "2018"
description = "Implementation of the Preserves serialization format via serde."
@ -13,7 +13,6 @@ gitlab = { repository = "preserves/preserves" }
[dependencies]
num = "0.2"
num_enum = "0.4.1"
serde = { version = "1.0", features = ["derive"] }
serde_bytes = "0.11"
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();
c.bench_function("encode samples.bin", |b| b.iter_with_large_drop(|| {
let mut bs = vec![];
PackedWriter(&mut bs).write(&v).unwrap();
PackedWriter::new(&mut bs).write(&v).unwrap();
bs
}));
}
@ -56,7 +56,7 @@ pub fn bench_ser(c: &mut Criterion) {
let v: TestCases = de::from_read(&mut fh).unwrap();
c.bench_function("serialize samples.bin", |b| b.iter_with_large_drop(|| {
let mut bs = vec![];
ser::to_writer(&mut PackedWriter(&mut bs), &v).unwrap();
ser::to_writer(&mut PackedWriter::new(&mut bs), &v).unwrap();
bs
}));
}
@ -74,7 +74,7 @@ pub fn bench_ser_encoder(c: &mut Criterion) {
let v: TestCases = de::from_read(&mut fh).unwrap();
c.bench_function("serialize-then-encode samples.bin", |b| b.iter_with_large_drop(|| {
let mut bs = vec![];
PackedWriter(&mut bs).write(&value::ser::to_value(&v)).unwrap();
PackedWriter::new(&mut bs).write(&value::ser::to_value(&v)).unwrap();
bs
}));
}
@ -113,7 +113,7 @@ pub fn large_testdata_encoder(c: &mut Criterion) {
}
b.iter_with_large_drop(|| {
let mut bs = vec![];
let mut w = PackedWriter(&mut bs);
let mut w = PackedWriter::new(&mut bs);
for v in &vs {
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::marker::PhantomData;
use super::value::PackedReader;
use super::value::reader::{Reader, IOBinarySource, BytesBinarySource, CompoundBody};
use super::value::reader::{Reader, IOBinarySource, BytesBinarySource};
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>
{
let (is_some, mut compound_body) = self.read.open_option()?;
let is_some = self.read.open_option()?;
let result = if is_some {
compound_body.ensure_more_expected(self.read)?;
self.read.ensure_more_expected()?;
visitor.visit_some(&mut *self)?
} else {
visitor.visit_none::<Error>()?
};
compound_body.ensure_complete(self.read)?;
self.read.ensure_complete()?;
Ok(result)
}
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>()?;
compound_body.ensure_complete(self.read)?;
self.read.ensure_complete()?;
Ok(result)
}
fn deserialize_unit_struct<V>(self, name: &'static str, visitor: V)
-> 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>()?;
compound_body.ensure_complete(self.read)?;
self.read.ensure_complete()?;
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),
None => {
let mut compound_body = self.read.open_simple_record(name, Some(1))?;
compound_body.ensure_more_expected(self.read)?;
self.read.open_simple_record(name, Some(1))?;
self.read.ensure_more_expected()?;
let result = visitor.visit_newtype_struct(&mut *self)?;
compound_body.ensure_complete(self.read)?;
self.read.ensure_complete()?;
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> {
// Hack around serde's model: Deserialize *sets* as sequences,
// too, and reconstruct them as Rust Sets on the visitor side.
let compound_body = self.read.open_sequence_or_set()?;
visitor.visit_seq(Seq::new(self, compound_body))
self.read.open_sequence_or_set()?;
visitor.visit_seq(Seq::new(self))
}
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))?;
let mut seq = Seq::new(self, compound_body);
self.read.open_simple_record("tuple", Some(len))?;
let mut seq = Seq::new(self);
let result = visitor.visit_seq(&mut seq)?;
seq.skip_remainder()?;
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)
-> Result<V::Value> where V: Visitor<'de>
{
let compound_body = self.read.open_simple_record(name, Some(len))?;
let mut seq = Seq::new(self, compound_body);
self.read.open_simple_record(name, Some(len))?;
let mut seq = Seq::new(self);
let result = visitor.visit_seq(&mut seq)?;
seq.skip_remainder()?;
Ok(result)
}
fn deserialize_map<V>(self, visitor: V) -> Result<V::Value> where V: Visitor<'de> {
let compound_body = self.read.open_dictionary()?;
let mut seq = Seq::new(self, compound_body);
self.read.open_dictionary()?;
let mut seq = Seq::new(self);
let result = visitor.visit_map(&mut seq)?;
seq.skip_remainder()?;
Ok(result)
}
@ -229,8 +228,8 @@ impl<'r, 'de, 'a, R: Reader<'de>> serde::de::Deserializer<'de> for &'a mut Deser
visitor: V)
-> Result<V::Value> where V: Visitor<'de>
{
let compound_body = self.read.open_simple_record(name, Some(fields.len()))?;
let mut seq = Seq::new(self, compound_body);
self.read.open_simple_record(name, Some(fields.len()))?;
let mut seq = Seq::new(self);
let result = visitor.visit_seq(&mut seq)?;
seq.skip_remainder()?;
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>> {
de: &'a mut Deserializer<'de, 'r, R>,
compound_body: CompoundBody<R::CompoundInfo>,
}
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 {
Seq { de, compound_body }
fn new(de: &'a mut Deserializer<'de, 'r, R>) -> Self {
Seq { de }
}
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) ->
Result<Option<T::Value>> where T: DeserializeSeed<'de>
{
match self.compound_body.more_expected(self.de.read)? {
false => Ok(None),
true => Ok(Some(seed.deserialize(&mut *self.de)?)),
match self.de.read.close_compound()? {
true => Ok(None),
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)
-> Result<(V::Value, Self::Variant)> where V: DeserializeSeed<'de>
{
let mut compound_body = self.read.open_record(None)?;
compound_body.ensure_more_expected(self.read)?;
self.read.open_record(None)?;
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 {
fn as_preserves(&self) -> Result<IOValue, std::io::Error> {
Ok(match self {
// TODO: How to nicely expose streaming values?
Dom::One => Value::ByteString(vec![255, 255, 255, 255]).wrap(),
Dom::Two => Value::symbol(&format!("Dom::{:?}", self)).wrap(),
})
@ -37,7 +36,7 @@ mod dom {
Value::from(2).wrap()])
.wrap();
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() {
@ -46,7 +45,7 @@ mod dom {
Value::from(2).wrap()])
.wrap();
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 {
Ok(v) => panic!("Expected Expected({:?}), but got a parse of {:?}", k, v),
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() {
let mut buf = &b"\x0521"[..];
let mut buf = &b"\x85\x92\x91"[..];
let mut d = ConfiguredReader::new(PackedReader::decode_bytes(&mut buf));
let v = d.demand_next().unwrap();
assert_eq!(v.annotations().slice().len(), 1);
@ -259,7 +258,7 @@ mod decoder_tests {
}
#[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));
d.set_read_annotations(false);
let v = d.demand_next().unwrap();
@ -268,117 +267,103 @@ mod decoder_tests {
}
#[test] fn multiple_values_buf_advanced() {
let mut buf = &b"\x81tPing\x81tPong"[..];
assert_eq!(buf.len(), 12);
let mut buf = &b"\xb4\xb3\x04Ping\x84\xb4\xb3\x04Pong\x84"[..];
assert_eq!(buf.len(), 16);
let mut d = ConfiguredReader::new(PackedReader::decode_bytes(&mut buf));
assert_eq!(d.reader.source.index, 0);
assert_eq!(d.demand_next().unwrap().value(), &Value::simple_record0("Ping"));
assert_eq!(d.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.reader.source.index, 12);
assert_eq!(d.reader.source.index, 16);
assert!(d.next().is_none());
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_zero() { assert_eq!(from_bytes::<i8>(b"0").unwrap(), 0) }
#[test] fn direct_i8_format_a_negative() { assert_eq!(from_bytes::<i8>(b"?").unwrap(), -1) }
#[test] fn direct_i8_format_b() { assert_eq!(from_bytes::<i8>(b"A\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_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_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_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"\x90").unwrap(), 0) }
#[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"\xa0\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"\xa9\xff\xff\xff\xff\xff\xff\xff\xff\xff\xfe").unwrap(), -2) }
#[test] fn direct_u8_format_a_positive() { assert_eq!(from_bytes::<u8>(b"1").unwrap(), 1) }
#[test] fn direct_u8_format_a_zero() { assert_eq!(from_bytes::<u8>(b"0").unwrap(), 0) }
#[test] fn direct_u8_format_b() { assert_eq!(from_bytes::<u8>(b"A1").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_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_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_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"\x90").unwrap(), 0) }
#[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"\xa3\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_i16_format_a() { assert_eq!(from_bytes::<i16>(b">").unwrap(), -2) }
#[test] fn direct_i16_format_b() { assert_eq!(from_bytes::<i16>(b"B\xfe\xff").unwrap(), -257) }
#[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"\xa1\xfe\xff").unwrap(), -257) }
#[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() {
expect_number_out_of_range(from_bytes::<u8>(b"D\0\011"))
}
#[test] fn direct_u8_format_c_too_large() {
expect_number_out_of_range(from_bytes::<u8>(b"$a1a1\x04"))
expect_number_out_of_range(from_bytes::<u8>(b"\xa3\0\011"))
}
#[test] fn direct_i8_format_b_too_large() {
expect_number_out_of_range(from_bytes::<i8>(b"B\xfe\xff"))
}
#[test] fn direct_i8_format_c_too_large() {
expect_number_out_of_range(from_bytes::<u8>(b"$a\xfea\xff\x04"))
expect_number_out_of_range(from_bytes::<i8>(b"\xa1\xfe\xff"))
}
#[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() {
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() {
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() {
assert_eq!(from_bytes::<i64>(b"A\xff").unwrap(), -1);
assert_eq!(from_bytes::<i64>(b"C\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"A\xfe").unwrap(), -2);
assert_eq!(from_bytes::<i64>(b"C\xff\xfe\xff").unwrap(), -257);
assert_eq!(from_bytes::<i64>(b"C\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"J\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"I\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"J\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"H\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"H\0\0\0\0\0\0\0\0").unwrap(), 0);
assert_eq!(from_bytes::<i64>(b"@").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"\xa0\xff").unwrap(), -1);
assert_eq!(from_bytes::<i64>(b"\xa2\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"\xa0\xfe").unwrap(), -2);
assert_eq!(from_bytes::<i64>(b"\xa2\xff\xfe\xff").unwrap(), -257);
assert_eq!(from_bytes::<i64>(b"\xa2\xfe\xff\xff").unwrap(), -65537);
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"\xa9\xff\xff\xfe\xff\xff\xff\xff\xff\xff\xff").unwrap(), -72057594037927937);
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"\xa8\xff\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"\xa9\xff\x00\x0e\xff\xff\xff\xff\xff\xff\xff"));
assert_eq!(from_bytes::<i64>(b"\xa7\xfe\xff\xff\xff\xff\xff\xff\xff").unwrap(), -72057594037927937);
assert_eq!(from_bytes::<i64>(b"\xa7\x0e\xff\xff\xff\xff\xff\xff\xff").unwrap(), 1080863910568919039);
assert_eq!(from_bytes::<i64>(b"\xa7\x80\0\0\0\0\0\0\0").unwrap(), -9223372036854775808);
assert_eq!(from_bytes::<i64>(b"\xa7\0\0\0\0\0\0\0\0").unwrap(), 0);
assert_eq!(from_bytes::<i64>(b"\x90").unwrap(), 0);
assert_eq!(from_bytes::<i64>(b"\xa7\x7f\xff\xff\xff\xff\xff\xff\xff").unwrap(), 9223372036854775807);
}
#[test] fn direct_u64_format_b() {
expect_number_out_of_range(from_bytes::<u64>(b"A\xff"));
assert_eq!(from_bytes::<u64>(b"B\0\xff").unwrap(), 255);
expect_number_out_of_range(from_bytes::<u64>(b"C\xff\xff\xff"));
assert_eq!(from_bytes::<u64>(b"D\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"));
assert_eq!(from_bytes::<u64>(b"A\x02").unwrap(), 2);
assert_eq!(from_bytes::<u64>(b"C\x00\x01\x00").unwrap(), 256);
assert_eq!(from_bytes::<u64>(b"C\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"J\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"J\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"));
assert_eq!(from_bytes::<u64>(b"I\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"J\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"H\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"));
assert_eq!(from_bytes::<u64>(b"I\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"@").unwrap(), 0);
assert_eq!(from_bytes::<u64>(b"H\x7f\xff\xff\xff\xff\xff\xff\xff").unwrap(), 9223372036854775807);
expect_number_out_of_range(from_bytes::<u64>(b"\xa0\xff"));
assert_eq!(from_bytes::<u64>(b"\xa1\0\xff").unwrap(), 255);
expect_number_out_of_range(from_bytes::<u64>(b"\xa2\xff\xff\xff"));
assert_eq!(from_bytes::<u64>(b"\xa3\0\xff\xff\xff").unwrap(), 0xffffff);
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"\xa0\x02").unwrap(), 2);
assert_eq!(from_bytes::<u64>(b"\xa2\x00\x01\x00").unwrap(), 256);
assert_eq!(from_bytes::<u64>(b"\xa2\x01\x00\x00").unwrap(), 65536);
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"\xa9\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00").unwrap(), 72057594037927936);
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"\xa9\x00\x00\x72\x00\x00\x00\x00\x00\x00\x00").unwrap(), 0x7200000000000000);
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"\xa8\x00\xf2\x00\x00\x00\x00\x00\x00\x00").unwrap(), 0xf200000000000000);
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"\xa9\x00\xff\xf2\x00\x00\x00\x00\x00\x00\x00"));
assert_eq!(from_bytes::<u64>(b"\xa7\x01\x00\x00\x00\x00\x00\x00\x00").unwrap(), 72057594037927936);
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"\xa7\x80\0\0\0\0\0\0\0"));
assert_eq!(from_bytes::<u64>(b"\xa8\0\x80\0\0\0\0\0\0\0").unwrap(), 9223372036854775808);
assert_eq!(from_bytes::<u64>(b"\xa7\0\0\0\0\0\0\0\0").unwrap(), 0);
assert_eq!(from_bytes::<u64>(b"\x90").unwrap(), 0);
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);
let expected_bytes = vec![
0x8f, 0x10, // Struct, 15 members + 1 label
0x7b, 0x53, 0x69, 0x6d, 0x70, 0x6c, 0x65, 0x56, 0x61, 0x6c, 0x75, 0x65, // SimpleValue
0x55, 0x68, 0x65, 0x6c, 0x6c, 0x6f, // "hello"
0x74, 0x73, 0x79, 0x6d, 0x31, // sym1
0x74, 0x73, 0x79, 0x6d, 0x32, // sym2
0x74, 0x73, 0x79, 0x6d, 0x33, // sym3
0x74, 0x73, 0x79, 0x6d, 0x34, // sym4
0x55, 0x77, 0x6f, 0x72, 0x6c, 0x64, // "world"
0x65, 0x73, 0x6c, 0x69, 0x63, 0x65, // #"slice"
0x63, 0x76, 0x65, 0x63, // #"vec"
0x94, // Sequence, 4 items
0x0, // false
0x1, // true
0x0, // false
0x1, // true
0xa3, // Set, 3 items
0x53, 0x6f, 0x6e, 0x65,
0x55, 0x74, 0x68, 0x72, 0x65, 0x65,
0x53, 0x74, 0x77, 0x6f,
0x42, 0x30, 0x39, // 12345
0x52, 0x68, 0x69, // "hi"
0xb6, // Dictionary, 6 items = 3 key/value pairs
0x54, 0x62, 0x6c, 0x75, 0x65, // "blue"
0x84, 0x76, 0x43, 0x6f, 0x6c, 0x6f, 0x75, 0x72, 0x30, 0x30, 0x42, 0x00, 0xff,
0x55, 0x67, 0x72, 0x65, 0x65, 0x6e, // "green"
0x84, 0x76, 0x43, 0x6f, 0x6c, 0x6f, 0x75, 0x72, 0x30, 0x42, 0x00, 0xff, 0x30,
0x53, 0x72, 0x65, 0x64, // "red"
0x84, 0x76, 0x43, 0x6f, 0x6c, 0x6f, 0x75, 0x72, 0x42, 0x00, 0xff, 0x30, 0x30,
0xb4, // Struct
0xb3, 0x0b, 0x53, 0x69, 0x6d, 0x70, 0x6c, 0x65, 0x56, 0x61, 0x6c, 0x75, 0x65, // SimpleValue
0xb1, 0x05, 0x68, 0x65, 0x6c, 0x6c, 0x6f, // "hello"
0xb3, 0x04, 0x73, 0x79, 0x6d, 0x31, // sym1
0xb3, 0x04, 0x73, 0x79, 0x6d, 0x32, // sym2
0xb3, 0x04, 0x73, 0x79, 0x6d, 0x33, // sym3
0xb3, 0x04, 0x73, 0x79, 0x6d, 0x34, // sym4
0xb1, 0x05, 0x77, 0x6f, 0x72, 0x6c, 0x64, // "world"
0xb2, 0x05, 0x73, 0x6c, 0x69, 0x63, 0x65, // #"slice"
0xb2, 0x03, 0x76, 0x65, 0x63, // #"vec"
0xb5, // Sequence
0x80, // false
0x81, // true
0x80, // false
0x81, // true
0x84,
0xb6, // Set
0xb1, 0x03, 0x6f, 0x6e, 0x65,
0xb1, 0x03, 0x74, 0x77, 0x6f,
0xb1, 0x05, 0x74, 0x68, 0x72, 0x65, 0x65,
0x84,
0xa1, 0x30, 0x39, // 12345
0xb1, 0x02, 0x68, 0x69, // "hi"
0xb7, // Dictionary
0xb1, 0x03, 0x72, 0x65, 0x64, // "red"
0xb4, 0xb3, 0x06, 0x43, 0x6f, 0x6c, 0x6f, 0x75, 0x72, 0xa1, 0x00, 0xff, 0x90, 0x90, 0x84,
0xb1, 0x04, 0x62, 0x6c, 0x75, 0x65, // "blue"
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,
0x3, 0x40, 0x28, 0xb0, 0xfc, 0xd3, 0x24, 0xd5, 0xa2, // 12.3456789
0x82, 0x41, 0x45, 0x85, 0x1f, // 12.345,
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();
println!("== w bytes = {:?}", v_bytes_1);
assert_eq!(expected_bytes, v_bytes_1);
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);
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 super::value::writer::Writer;
use super::value::writer::{Writer, CompoundWriter};
pub use super::error::Error;
type Result<T> = std::result::Result<T, Error>;
#[derive(Debug)]
pub struct Serializer<'a, W: Writer> {
pub write: &'a mut W,
pub struct Serializer<'w, W: Writer> {
pub write: &'w mut W,
}
impl<'a, W: Writer> Serializer<'a, W> {
pub fn new(write: &'a mut W) -> Self {
impl<'w, W: Writer> Serializer<'w, W> {
pub fn new(write: &'w mut W) -> Self {
Serializer { write }
}
}
#[derive(Debug)]
pub struct SerializeCompound<'a, 'b, W: Writer> {
ser: &'a mut Serializer<'b, W>,
c: W::Compound,
pub struct SerializeCompound<'a, 'w, W: Writer> {
ser: &'a mut Serializer<'w, W>,
c: W::SeqWriter,
}
#[derive(Debug)]
pub struct SerializeDictionary<'a, 'b, W: Writer> {
ser: &'a mut Serializer<'b, W>,
d: W::Dictionary,
key_p: Option<W::KeyPointer>,
pub struct SerializeDictionary<'a, 'w, W: Writer> {
ser: &'a mut Serializer<'w, W>,
d: W::SetWriter,
}
impl<'a, 'b, W: Writer> serde::Serializer for &'a mut Serializer<'b, W> {
type Ok = W::Pointer;
impl<'a, 'w, W: Writer> serde::Serializer for &'a mut Serializer<'w, W> {
type Ok = ();
type Error = Error;
type SerializeSeq = SerializeCompound<'a, 'b, W>;
type SerializeTuple = SerializeCompound<'a, 'b, W>;
type SerializeTupleStruct = SerializeCompound<'a, 'b, W>;
type SerializeTupleVariant = SerializeCompound<'a, 'b, W>;
type SerializeMap = SerializeDictionary<'a, 'b, W>;
type SerializeStruct = SerializeCompound<'a, 'b, W>;
type SerializeStructVariant = SerializeCompound<'a, 'b, W>;
type SerializeSeq = SerializeCompound<'a, 'w, W>;
type SerializeTuple = SerializeCompound<'a, 'w, W>;
type SerializeTupleStruct = SerializeCompound<'a, 'w, W>;
type SerializeTupleVariant = SerializeCompound<'a, 'w, W>;
type SerializeMap = SerializeDictionary<'a, 'w, W>;
type SerializeStruct = SerializeCompound<'a, 'w, W>;
type SerializeStructVariant = SerializeCompound<'a, 'w, W>;
fn serialize_bool(self, v: bool) -> Result<Self::Ok> {
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> {
let mut c = self.write.start_record(1)?;
let p = self.write.write_symbol("UnicodeScalar")?;
self.write.extend_compound(&mut c, p)?;
let p = self.write.write_u32(v as u32)?;
self.write.extend_compound(&mut c, p)?;
Ok(self.write.end_compound(c)?)
let mut c = self.write.start_record(Some(1))?;
c.extend()?;
c.write_symbol("UnicodeScalar")?;
c.delimit()?;
c.extend()?;
c.write_u32(v as u32)?;
c.delimit()?;
Ok(self.write.end_seq(c)?)
}
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> {
let mut c = self.write.start_record(0)?;
let p = self.write.write_symbol("None")?;
self.write.extend_compound(&mut c, p)?;
Ok(self.write.end_compound(c)?)
let mut c = self.write.start_record(Some(0))?;
c.extend()?;
c.write_symbol("None")?;
c.delimit()?;
Ok(self.write.end_seq(c)?)
}
fn serialize_some<T: ?Sized>(self, v: &T) -> Result<Self::Ok> where T: Serialize {
let mut c = self.write.start_record(1)?;
let p = self.write.write_symbol("Some")?;
self.write.extend_compound(&mut c, p)?;
let p = v.serialize(&mut *self)?;
self.write.extend_compound(&mut c, p)?;
Ok(self.write.end_compound(c)?)
let mut c = self.write.start_record(Some(1))?;
c.extend()?;
c.write_symbol("Some")?;
c.delimit()?;
c.extend()?;
to_writer(&mut c, v)?;
c.delimit()?;
Ok(self.write.end_seq(c)?)
}
fn serialize_unit(self) -> Result<Self::Ok> {
let mut c = self.write.start_record(0)?;
let p = self.write.write_symbol("tuple")?;
self.write.extend_compound(&mut c, p)?;
Ok(self.write.end_compound(c)?)
let mut c = self.write.start_record(Some(0))?;
c.extend()?;
c.write_symbol("tuple")?;
c.delimit()?;
Ok(self.write.end_seq(c)?)
}
fn serialize_unit_struct(self, name: &'static str) -> Result<Self::Ok> {
let mut c = self.write.start_record(0)?;
let p = self.write.write_symbol(name)?;
self.write.extend_compound(&mut c, p)?;
Ok(self.write.end_compound(c)?)
let mut c = self.write.start_record(Some(0))?;
c.extend()?;
c.write_symbol(name)?;
c.delimit()?;
Ok(self.write.end_seq(c)?)
}
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) ->
Result<Self::Ok>
{
let mut c = self.write.start_record(0)?;
let p = self.write.write_symbol(variant_name)?;
self.write.extend_compound(&mut c, p)?;
Ok(self.write.end_compound(c)?)
let mut c = self.write.start_record(Some(0))?;
c.extend()?;
c.write_symbol(variant_name)?;
c.delimit()?;
Ok(self.write.end_seq(c)?)
}
fn serialize_newtype_struct<T: ?Sized>(self, name: &'static str, value: &T) ->
Result<Self::Ok> where T: Serialize
{
match super::value::magic::receive_output_value(name, value) {
Some(v) => {
Ok(self.write.write(&v)?)
}
Some(v) => Ok(self.write.write(&v)?),
None => {
// TODO: This is apparently discouraged, and we should apparently just serialize `value`?
let mut c = self.write.start_record(1)?;
let p = self.write.write_symbol(name)?;
self.write.extend_compound(&mut c, p)?;
let p = value.serialize(&mut *self)?;
self.write.extend_compound(&mut c, p)?;
Ok(self.write.end_compound(c)?)
let mut c = self.write.start_record(Some(1))?;
c.extend()?;
c.write_symbol(name)?;
c.delimit()?;
c.extend()?;
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) ->
Result<Self::Ok> where T: Serialize
{
let mut c = self.write.start_record(1)?;
let p = self.write.write_symbol(variant_name)?;
self.write.extend_compound(&mut c, p)?;
let p = value.serialize(&mut *self)?;
self.write.extend_compound(&mut c, p)?;
Ok(self.write.end_compound(c)?)
let mut c = self.write.start_record(Some(1))?;
c.extend()?;
c.write_symbol(variant_name)?;
c.delimit()?;
c.extend()?;
to_writer(&mut c, value)?;
c.delimit()?;
Ok(self.write.end_seq(c)?)
}
fn serialize_seq(self, count: Option<usize>) -> Result<Self::SerializeSeq> {
let c = match count {
Some(n) => self.write.start_sequence(n)?,
None => match self.write.stream_sequence()? {
Some(c) => c,
None => return Err(Error::StreamingSerializationUnsupported),
}
};
let c = self.write.start_sequence(count)?;
Ok(SerializeCompound { ser: self, c })
}
fn serialize_tuple(self, count: usize) -> Result<Self::SerializeTuple> {
let mut c = self.write.start_record(count)?;
let p = self.write.write_symbol("tuple")?;
self.write.extend_compound(&mut c, p)?;
let mut c = self.write.start_record(Some(count))?;
c.extend()?;
c.write_symbol("tuple")?;
c.delimit()?;
Ok(SerializeCompound { ser: self, c })
}
fn serialize_tuple_struct(self, name: &'static str, count: usize) ->
Result<Self::SerializeTupleStruct>
{
let mut c = self.write.start_record(count)?;
let p = self.write.write_symbol(name)?;
self.write.extend_compound(&mut c, p)?;
let mut c = self.write.start_record(Some(count))?;
c.extend()?;
c.write_symbol(name)?;
c.delimit()?;
Ok(SerializeCompound { ser: self, c })
}
@ -210,27 +215,23 @@ impl<'a, 'b, W: Writer> serde::Serializer for &'a mut Serializer<'b, W> {
count: usize) ->
Result<Self::SerializeTupleVariant>
{
let mut c = self.write.start_record(count)?;
let p = self.write.write_symbol(variant_name)?;
self.write.extend_compound(&mut c, p)?;
let mut c = self.write.start_record(Some(count))?;
c.extend()?;
c.write_symbol(variant_name)?;
c.delimit()?;
Ok(SerializeCompound { ser: self, c })
}
fn serialize_map(self, count: Option<usize>) -> Result<Self::SerializeMap> {
let d = match count {
Some(n) => self.write.start_dictionary(n)?,
None => match self.write.stream_dictionary()? {
Some(d) => d,
None => return Err(Error::StreamingSerializationUnsupported),
}
};
Ok(SerializeDictionary { ser: self, d, key_p: None })
let d = self.write.start_dictionary(count)?;
Ok(SerializeDictionary { ser: self, d })
}
fn serialize_struct(self, name: &'static str, count: usize) -> Result<Self::SerializeStruct> {
let mut c = self.write.start_record(count)?;
let p = self.write.write_symbol(name)?;
self.write.extend_compound(&mut c, p)?;
let mut c = self.write.start_record(Some(count))?;
c.extend()?;
c.write_symbol(name)?;
c.delimit()?;
Ok(SerializeCompound { ser: self, c })
}
@ -241,122 +242,130 @@ impl<'a, 'b, W: Writer> serde::Serializer for &'a mut Serializer<'b, W> {
count: usize) ->
Result<Self::SerializeStructVariant>
{
let mut c = self.write.start_record(count)?;
let p = self.write.write_symbol(variant_name)?;
self.write.extend_compound(&mut c, p)?;
let mut c = self.write.start_record(Some(count))?;
c.extend()?;
c.write_symbol(variant_name)?;
c.delimit()?;
Ok(SerializeCompound { ser: self, c })
}
}
impl<'a, 'b, W: Writer> serde::ser::SerializeMap for SerializeDictionary<'a, 'b, W> {
type Ok = W::Pointer;
impl<'a, 'w, W: Writer> serde::ser::SerializeMap for SerializeDictionary<'a, 'w, W> {
type Ok = ();
type Error = Error;
fn serialize_key<T: ?Sized>(&mut self, key: &T) -> Result<()> where T: Serialize {
let kp1 = key.serialize(&mut *self.ser)?;
self.key_p = Some(self.ser.write.extend_dictionary_key(&mut self.d, kp1)?);
self.d.extend()?;
to_writer(&mut self.d, key)?;
Ok(())
}
fn serialize_value<T: ?Sized>(&mut self, value: &T) -> Result<()> where T: Serialize {
let vp1 = value.serialize(&mut *self.ser)?;
Ok(self.ser.write.extend_dictionary_value(&mut self.d, self.key_p.take().unwrap(), vp1)?)
to_writer(&mut self.d, value)?;
Ok(self.d.delimit()?)
}
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> {
type Ok = W::Pointer;
impl<'a, 'w, W: Writer> SerializeCompound<'a, 'w, W> {
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;
fn serialize_field<T: ?Sized>(&mut self, _name: &'static str, value: &T) -> Result<()>
where T: Serialize
{
let p = value.serialize(&mut *self.ser)?;
Ok(self.ser.write.extend_compound(&mut self.c, p)?)
self.extend(value)
}
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> {
type Ok = W::Pointer;
impl<'a, 'w, W: Writer> serde::ser::SerializeStructVariant for SerializeCompound<'a, 'w, W> {
type Ok = ();
type Error = Error;
fn serialize_field<T: ?Sized>(&mut self, _name: &'static str, value: &T) -> Result<()>
where T: Serialize
{
let p = value.serialize(&mut *self.ser)?;
Ok(self.ser.write.extend_compound(&mut self.c, p)?)
self.extend(value)
}
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> {
type Ok = W::Pointer;
impl<'a, 'w, W: Writer> serde::ser::SerializeTuple for SerializeCompound<'a, 'w, W> {
type Ok = ();
type Error = Error;
fn serialize_element<T: ?Sized>(&mut self, value: &T) -> Result<()> where T: Serialize {
let p = value.serialize(&mut *self.ser)?;
Ok(self.ser.write.extend_compound(&mut self.c, p)?)
self.extend(value)
}
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> {
type Ok = W::Pointer;
impl<'a, 'w, W: Writer> serde::ser::SerializeTupleStruct for SerializeCompound<'a, 'w, W> {
type Ok = ();
type Error = Error;
fn serialize_field<T: ?Sized>(&mut self, value: &T) -> Result<()> where T: Serialize {
let p = value.serialize(&mut *self.ser)?;
Ok(self.ser.write.extend_compound(&mut self.c, p)?)
self.extend(value)
}
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> {
type Ok = W::Pointer;
impl<'a, 'w, W: Writer> serde::ser::SerializeTupleVariant for SerializeCompound<'a, 'w, W> {
type Ok = ();
type Error = Error;
fn serialize_field<T: ?Sized>(&mut self, value: &T) -> Result<()> where T: Serialize {
let p = value.serialize(&mut *self.ser)?;
Ok(self.ser.write.extend_compound(&mut self.c, p)?)
self.extend(value)
}
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> {
type Ok = W::Pointer;
impl<'a, 'w, W: Writer> serde::ser::SerializeSeq for SerializeCompound<'a, 'w, W> {
type Ok = ();
type Error = Error;
fn serialize_element<T: ?Sized>(&mut self, value: &T) -> Result<()> where T: Serialize {
let p = value.serialize(&mut *self.ser)?;
Ok(self.ser.write.extend_compound(&mut self.c, p)?)
self.extend(value)
}
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> {
let mut ser: Serializer<'_, W> = Serializer::new(write);
value.serialize(&mut ser)
pub fn to_writer<W: Writer, T: Serialize + ?Sized>(write: &mut W, value: &T) -> Result<()> {
Ok(value.serialize(&mut Serializer::new(write))?)
}

View File

@ -1,68 +1,86 @@
use std::convert::{TryFrom, From};
use num_enum::TryFromPrimitive;
#[derive(Debug, PartialEq, Eq)]
pub enum Op {
Misc(u8),
Atom(AtomMinor),
Compound(CompoundMinor),
Reserved(u8),
pub enum Tag {
False,
True,
Float,
Double,
End,
Annotation,
SmallInteger(i8),
MediumInteger(u8),
SignedInteger,
String,
ByteString,
Symbol,
Record,
Sequence,
Set,
Dictionary,
}
#[derive(Debug, PartialEq, Eq)]
pub struct InvalidOp;
pub struct InvalidTag(u8);
impl From<InvalidOp> for std::io::Error {
fn from(_v: InvalidOp) -> Self {
impl From<InvalidTag> for std::io::Error {
fn from(v: InvalidTag) -> Self {
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 {
fn from(v: InvalidOp) -> Self {
impl From<InvalidTag> for crate::error::Error {
fn from(v: InvalidTag) -> Self {
crate::error::Error::Io(v.into())
}
}
impl TryFrom<u8> for Op {
type Error = InvalidOp;
impl TryFrom<u8> for Tag {
type Error = InvalidTag;
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 {
Op::Misc(minor) => minor & 3,
Op::Atom(minor) => (1 << 2) | ((minor as u8) & 3),
Op::Compound(minor) => (2 << 2) | ((minor as u8) & 3),
Op::Reserved(minor) => (3 << 2) | (minor & 3),
0x80 => Ok(Self::False),
0x81 => Ok(Self::True),
0x82 => Ok(Self::Float),
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)]
#[repr(u8)]
pub enum AtomMinor {
SignedInteger = 0,
String = 1,
ByteString = 2,
Symbol = 3,
}
#[derive(Debug, TryFromPrimitive, PartialEq, Eq, Clone, Copy)]
#[repr(u8)]
pub enum CompoundMinor {
Record = 0,
Sequence = 1,
Set = 2,
Dictionary = 3,
impl From<Tag> for u8 {
fn from(v: Tag) -> Self {
match v {
Tag::False => 0x80,
Tag::True => 0x81,
Tag::Float => 0x82,
Tag::Double => 0x83,
Tag::End => 0x84,
Tag::Annotation => 0x85,
Tag::SmallInteger(v) => if v < 0 { (v + 16) as u8 + 0x90 } else { v as u8 + 0x90 },
Tag::MediumInteger(count) => count - 1 + 0xa0,
Tag::SignedInteger => 0xb0,
Tag::String => 0xb1,
Tag::ByteString => 0xb2,
Tag::Symbol => 0xb3,
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::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::{
BinarySource,
BytesBinarySource,
CompoundBody,
CompoundLimit,
ConfiguredReader,
IOBinarySource,
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> {
if self.peek()? == 4 {
if self.peek()? == Tag::End.into() {
self.skip()?;
Ok(true)
} else {
@ -104,28 +94,10 @@ impl<'de, S: BinarySource<'de>> PackedReader<'de, S> {
}
}
fn gather_chunks(&mut self) -> IOResult<Vec<u8>> {
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)> {
fn peek_next_nonannotation_tag(&mut self) -> ReaderResult<Tag> {
loop {
match decodeop(self.peek()?)? {
(Op::Misc(0), 5) => {
match Tag::try_from(self.peek()?)? {
Tag::Annotation => {
self.skip()?;
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]>> {
match self.peek_next_nonannotation_op()? {
(Op::Atom(actual_minor), arg) if actual_minor == minor => {
self.skip()?;
let count = self.wirelength(arg)?;
Ok(self.readbytes(count)?)
}
(Op::Misc(2), arg) => match Op::try_from(arg)? {
Op::Atom(actual_minor) if actual_minor == minor => {
self.skip()?;
Ok(Cow::Owned(self.gather_chunks()?))
}
_ => Err(self.expected(k)),
},
_ => Err(self.expected(k)),
fn next_atomic(&mut self, expected_tag: Tag, k: ExpectedKind) -> ReaderResult<Cow<'de, [u8]>> {
let actual_tag = self.peek_next_nonannotation_tag()?;
if actual_tag == expected_tag {
self.skip()?;
let count = self.varint()?;
Ok(self.readbytes(count)?)
} else {
Err(self.expected(k))
}
}
fn next_compound(&mut self, minor: CompoundMinor, k: ExpectedKind) ->
ReaderResult<CompoundBody<CompoundMinor>>
fn next_compound(&mut self, expected_tag: Tag, k: ExpectedKind) -> ReaderResult<()>
{
match self.peek_next_nonannotation_op()? {
(Op::Compound(actual_minor), arg) if actual_minor == minor => {
self.skip()?;
Ok(CompoundBody::counted(minor, self.wirelength(arg)?))
}
(Op::Misc(2), arg) => match Op::try_from(arg)? {
Op::Compound(actual_minor) if actual_minor == minor => {
self.skip()?;
Ok(CompoundBody::streaming(minor))
}
_ => Err(self.expected(k)),
},
_ => Err(self.expected(k)),
let actual_tag = self.peek_next_nonannotation_tag()?;
if actual_tag == expected_tag {
self.skip()?;
Ok(())
} else {
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 {
return Ok(SignedInteger::from(0 as i128));
}
@ -211,28 +168,30 @@ impl<'de, S: BinarySource<'de>> PackedReader<'de, S> {
where
F: FnOnce(u128) -> Option<T>
{
match self.peek_next_nonannotation_op()? {
(Op::Misc(3), arg) => {
let tag = self.peek_next_nonannotation_tag()?;
match tag {
Tag::SmallInteger(v) => {
self.skip()?;
if arg > 12 {
Err(out_of_range((arg as i8) - 16))
if v < 0 {
Err(out_of_range(v))
} 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()?;
let count = self.wirelength(arg)?;
let n = &self.read_number_format_b(count)?;
let n = &self.read_signed_integer(count.into())?;
let i = n.try_into().or_else(|_| Err(out_of_range(n)))?;
f(i).ok_or_else(|| out_of_range(i))
}
_ => {
let n_value = self.demand_next(false)?;
let n = n_value.value().to_signedinteger()?;
Tag::SignedInteger => {
self.skip()?;
let count = self.varint()?;
let n = &self.read_signed_integer(count)?;
let i = n.try_into().or_else(|_| Err(out_of_range(n)))?;
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
F: FnOnce(i128) -> Option<T>
{
match self.peek_next_nonannotation_op()? {
(Op::Misc(3), arg) => {
let tag = self.peek_next_nonannotation_tag()?;
match tag {
Tag::SmallInteger(v) => {
self.skip()?;
let n = arg as i128;
let n = if n > 12 { n - 16 } else { n };
f(n).ok_or_else(|| out_of_range(n))
f(v.into()).ok_or_else(|| out_of_range(v))
}
(Op::Atom(AtomMinor::SignedInteger), arg) => {
Tag::MediumInteger(count) => {
self.skip()?;
let count = self.wirelength(arg)?;
let n = &self.read_number_format_b(count)?;
let n = &self.read_signed_integer(count.into())?;
let i = n.try_into().or_else(|_| Err(out_of_range(n)))?;
f(i).ok_or_else(|| out_of_range(i))
}
_ => {
let n_value = self.demand_next(false)?;
let n = n_value.value().to_signedinteger()?;
Tag::SignedInteger => {
self.skip()?;
let count = self.varint()?;
let n = &self.read_signed_integer(count)?;
let i = n.try_into().or_else(|_| Err(out_of_range(n)))?;
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> {
type CompoundInfo = CompoundMinor;
fn next(&mut self, read_annotations: bool) -> IOResult<Option<IOValue>> {
match self.peek() {
Err(e) if is_eof_io_error(&e) => return Ok(None),
Err(e) => return Err(e),
Ok(_) => (),
}
loop {
return Ok(Some(match decodeop(self.read()?)? {
(Op::Misc(0), 0) => FALSE.clone(),
(Op::Misc(0), 1) => TRUE.clone(),
(Op::Misc(0), 2) => {
let mut bs = [0; 4];
self.readbytes_into(&mut bs)?;
Value::from(f32::from_bits(u32::from_be_bytes(bs))).wrap()
}
(Op::Misc(0), 3) => {
let mut bs = [0; 8];
self.readbytes_into(&mut bs)?;
Value::from(f64::from_bits(u64::from_be_bytes(bs))).wrap()
}
(Op::Misc(0), 5) => {
if read_annotations {
let mut annotations = vec![self.demand_next(read_annotations)?];
while decodeop(self.peek()?)? == (Op::Misc(0), 5) {
self.skip()?;
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;
Ok(Some(match Tag::try_from(self.read()?)? {
Tag::False => FALSE.clone(),
Tag::True => TRUE.clone(),
Tag::Float => {
let mut bs = [0; 4];
self.readbytes_into(&mut bs)?;
Value::from(f32::from_bits(u32::from_be_bytes(bs))).wrap()
}
Tag::Double => {
let mut bs = [0; 8];
self.readbytes_into(&mut bs)?;
Value::from(f64::from_bits(u64::from_be_bytes(bs))).wrap()
}
Tag::Annotation => {
if read_annotations {
let mut annotations = vec![self.demand_next(read_annotations)?];
while Tag::try_from(self.peek()?)? == Tag::Annotation {
self.skip()?;
annotations.push(self.demand_next(read_annotations)?);
}
}
(Op::Misc(0), _) => Err(io_syntax_error("Invalid format A encoding"))?,
(Op::Misc(1), _) => Err(io_syntax_error("Invalid format A encoding"))?,
(Op::Misc(2), arg) => match Op::try_from(arg)? {
Op::Atom(minor) =>
decodebinary(minor, Cow::Owned(self.gather_chunks()?))?,
Op::Compound(minor) => decodecompound(minor, DelimitedStream {
reader: self.configured(read_annotations),
})?,
_ => Err(io_syntax_error("Invalid format C start byte"))?,
}
(Op::Misc(3), arg) => {
let n = if arg > 12 { i32::from(arg) - 16 } else { i32::from(arg) };
// TODO: prebuild these in value.rs
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));
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()?;
while Tag::try_from(self.peek()?)? == Tag::Annotation {
self.skip()?;
self.skip_value()?;
}
self.demand_next(read_annotations)?
}
}
Ok(compound_format)
} else {
self.next_compound(CompoundMinor::Record, ExpectedKind::Record(None))
}
Tag::SmallInteger(v) => {
// TODO: prebuild these in value.rs
Value::from(v).wrap()
}
Tag::MediumInteger(count) => {
let n = self.read_signed_integer(count.into())?;
Value::SignedInteger(n).wrap()
}
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>> {
match self.peek_next_nonannotation_op()? {
(Op::Compound(minor), arg)
if CompoundMinor::Sequence == minor || CompoundMinor::Set == minor => {
self.skip()?;
Ok(CompoundBody::counted(minor, self.wirelength(arg)?))
}
(Op::Misc(2), arg) => match Op::try_from(arg)? {
Op::Compound(minor)
if CompoundMinor::Sequence == minor || CompoundMinor::Set == minor => {
self.skip()?;
Ok(CompoundBody::streaming(minor))
}
_ => Err(self.expected(ExpectedKind::SequenceOrSet)),
fn open_record(&mut self, arity: Option<usize>) -> ReaderResult<()> {
self.next_compound(Tag::Record, ExpectedKind::Record(arity))?;
self.ensure_more_expected()
}
fn open_sequence_or_set(&mut self) -> ReaderResult<()> {
match self.peek_next_nonannotation_tag()? {
Tag::Sequence | Tag::Set => {
self.skip()?;
Ok(())
}
_ => Err(self.expected(ExpectedKind::SequenceOrSet)),
}
}
fn open_sequence(&mut self) -> ReaderResult<CompoundBody<Self::CompoundInfo>> {
self.next_compound(CompoundMinor::Sequence, ExpectedKind::Sequence)
fn open_sequence(&mut self) -> ReaderResult<()> {
self.next_compound(Tag::Sequence, ExpectedKind::Sequence)
}
fn open_set(&mut self) -> ReaderResult<CompoundBody<Self::CompoundInfo>> {
self.next_compound(CompoundMinor::Set, ExpectedKind::Set)
fn open_set(&mut self) -> ReaderResult<()> {
self.next_compound(Tag::Set, ExpectedKind::Set)
}
fn open_dictionary(&mut self) -> ReaderResult<CompoundBody<Self::CompoundInfo>> {
self.next_compound(CompoundMinor::Dictionary, ExpectedKind::Dictionary)
fn open_dictionary(&mut self) -> ReaderResult<()> {
self.next_compound(Tag::Dictionary, ExpectedKind::Dictionary)
}
fn close_compound_counted(&mut self, _minor: Self::CompoundInfo) -> ReaderResult<()> {
// Nothing to do -- no close delimiter to consume
Ok(())
}
fn close_compound_stream(&mut self, _minor: Self::CompoundInfo) -> ReaderResult<bool> {
fn close_compound(&mut self) -> ReaderResult<bool> {
Ok(self.peekend()?)
}
fn next_boolean(&mut self) -> ReaderResult<bool> {
match self.peek_next_nonannotation_op()? {
(Op::Misc(0), 0) => { self.skip()?; Ok(false) }
(Op::Misc(0), 1) => { self.skip()?; Ok(true) }
match self.peek_next_nonannotation_tag()? {
Tag::False => { self.skip()?; Ok(false) }
Tag::True => { self.skip()?; Ok(true) }
_ => 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_float(&mut self) -> ReaderResult<f32> {
match self.peek_next_nonannotation_op()? {
(Op::Misc(0), 2) => {
match self.peek_next_nonannotation_tag()? {
Tag::Float => {
self.skip()?;
let mut bs = [0; 4];
self.readbytes_into(&mut bs)?;
Ok(f32::from_bits(u32::from_be_bytes(bs)))
},
(Op::Misc(0), 3) => {
Tag::Double => {
self.skip()?;
let mut bs = [0; 8];
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> {
match self.peek_next_nonannotation_op()? {
(Op::Misc(0), 2) => {
match self.peek_next_nonannotation_tag()? {
Tag::Float => {
self.skip()?;
let mut bs = [0; 4];
self.readbytes_into(&mut bs)?;
Ok(f32::from_bits(u32::from_be_bytes(bs)) as f64)
},
(Op::Misc(0), 3) => {
Tag::Double => {
self.skip()?;
let mut bs = [0; 8];
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>> {
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]>> {
self.next_atomic(AtomMinor::ByteString, ExpectedKind::Symbol)
self.next_atomic(Tag::ByteString, ExpectedKind::Symbol)
}
fn next_symbol(&mut self) -> ReaderResult<Cow<'de, str>> {
Ok(decodestr(self.next_atomic(AtomMinor::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))
Ok(decodestr(self.next_atomic(Tag::Symbol, ExpectedKind::Symbol)?)?)
}
}
@ -496,11 +443,7 @@ impl<'a, 'de, S: BinarySource<'de>> Iterator for DelimitedStream<'a, 'de, S>
}
}
pub fn decodeop(b: u8) -> IOResult<(Op, u8)> {
Ok((Op::try_from(b >> 4)?, b & 15))
}
pub fn decodestr<'de>(cow: Cow<'de, [u8]>) -> IOResult<Cow<'de, str>> {
fn decodestr<'de>(cow: Cow<'de, [u8]>) -> IOResult<Cow<'de, str>> {
match cow {
Cow::Borrowed(bs) =>
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())),
}
}
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::cast::ToPrimitive;
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::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 fn write_op<W: std::io::Write>(w: &mut PackedWriter<W>, op: Op, arg: u8) -> Result<()> {
w.0.write_all(&[(u8::from(op) << 4) | (arg & 15)])
pub enum Suspendable<T> {
Active(T),
Suspended,
}
pub fn write_header<W: std::io::Write>(w: &mut PackedWriter<W>, op: Op, wirelength: usize) -> Result<()> {
if wirelength < 15 {
write_op(w, op, wirelength as u8)
} else {
write_op(w, op, 15)?;
varint(w.0, wirelength as u64)?;
impl<T> Suspendable<T> {
pub fn new(t: T) -> Self {
Suspendable::Active(t)
}
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(())
}
}
pub fn write_atom<W: std::io::Write>(w: &mut PackedWriter<W>, minor: AtomMinor, bs: &[u8]) -> Result<()> {
write_header(w, Op::Atom(minor), bs.len())?;
w.0.write_all(bs)
pub trait WriteWriter: Writer {
fn write_raw_bytes(&mut self, v: &[u8]) -> Result<()>;
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 {
@ -35,38 +280,18 @@ macro_rules! fits_in_bytes {
})
}
impl<'w, W: std::io::Write> PackedWriter<'w, W> {
pub fn write_noop(&mut self) -> Result<()> {
write_op(self, Op::Reserved(3), 15)
}
}
impl<W: std::io::Write> Writer for PackedWriter<W>
{
type AnnWriter = Self;
type SeqWriter = Self;
type SetWriter = BinaryOrderWriter;
impl<'w> PackedWriter<'w, &'w mut Vec<u8>> {
pub fn encode(v: &IOValue) -> std::io::Result<Vec<u8>> {
let mut buf: Vec<u8> = Vec::new();
PackedWriter(&mut buf).write(v)?;
Ok(buf)
}
}
impl<'w, W: std::io::Write> Writer for PackedWriter<'w, W> {
type Pointer = ();
type Annotation = ();
type Compound = bool;
type Dictionary = bool;
type StreamedAtom = ();
type KeyPointer = ();
fn start_annotation(&mut self) -> Result<Self::Annotation> {
Ok(())
fn start_annotations(&mut self) -> Result<Self::AnnWriter> {
Ok(self.suspend())
}
fn extend_annotation(&mut self, _a: &mut Self::Annotation, annotation: &IOValue) -> Result<()> {
write_header(self, Op::Misc(0), 5)?;
self.write(annotation)
}
fn end_annotation(&mut self, _a: Self::Annotation, _value_p: Self::Pointer) -> Result<Self::Pointer> {
fn end_annotations(&mut self, ann: Self::AnnWriter) -> Result<()> {
self.resume(ann);
Ok(())
}
@ -75,235 +300,182 @@ impl<'w, W: std::io::Write> Writer for PackedWriter<'w, W> {
}
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<()> {
write_op(self, Op::Misc(0), 2)?;
self.0.write_all(&u32::to_be_bytes(f32::to_bits(v)))
self.write_tag(Tag::Float)?;
self.write_raw_bytes(&u32::to_be_bytes(f32::to_bits(v)))
}
fn write_f64(&mut self, v: f64) -> Result<()> {
write_op(self, Op::Misc(0), 3)?;
self.0.write_all(&u64::to_be_bytes(f64::to_bits(v)))
self.write_tag(Tag::Double)?;
self.write_raw_bytes(&u64::to_be_bytes(f64::to_bits(v)))
}
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 < 0 { return write_op(self, Op::Misc(3), (v + 16) as u8) }
write_atom(self, AtomMinor::SignedInteger, &[v as u8])
if v >= -3 && v <= 12 { return self.write_tag(Tag::SmallInteger(v)) }
self.write_medium_integer(&[v as u8])
}
fn write_u8(&mut self, v: u8) -> Result<()> {
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<()> {
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<()> {
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<()> {
if let Ok(w) = v.try_into() { return self.write_i16(w) }
if fits_in_bytes!(v, 3) {
return write_atom(self, AtomMinor::SignedInteger, &[(v >> 16) as u8,
(v >> 8) as u8,
(v & 255) as u8]);
return self.write_medium_integer(&[(v >> 16) as u8,
(v >> 8) as u8,
(v & 255) as u8]);
}
return write_atom(self, AtomMinor::SignedInteger, &[(v >> 24) as u8,
(v >> 16) as u8,
(v >> 8) as u8,
(v & 255) as u8]);
self.write_medium_integer(&[(v >> 24) as u8,
(v >> 16) as u8,
(v >> 8) as u8,
(v & 255) as u8])
}
fn write_u32(&mut self, v: u32) -> Result<()> {
if let Ok(w) = v.try_into() { return self.write_i32(w) }
return write_atom(self, AtomMinor::SignedInteger, &[0,
(v >> 24) as u8,
(v >> 16) as u8,
(v >> 8) as u8,
(v & 255) as u8]);
self.write_medium_integer(&[0,
(v >> 24) as u8,
(v >> 16) as u8,
(v >> 8) as u8,
(v & 255) as u8])
}
fn write_i64(&mut self, v: i64) -> Result<()> {
if let Ok(w) = v.try_into() { return self.write_i32(w) }
if fits_in_bytes!(v, 5) {
return write_atom(self, AtomMinor::SignedInteger, &[(v >> 32) as u8,
(v >> 24) as u8,
(v >> 16) as u8,
(v >> 8) as u8,
(v & 255) as u8]);
return self.write_medium_integer(&[(v >> 32) as u8,
(v >> 24) as u8,
(v >> 16) as u8,
(v >> 8) as u8,
(v & 255) as u8]);
}
if fits_in_bytes!(v, 6) {
return write_atom(self, AtomMinor::SignedInteger, &[(v >> 40) as u8,
(v >> 32) as u8,
(v >> 24) as u8,
(v >> 16) as u8,
(v >> 8) as u8,
(v & 255) as u8]);
return self.write_medium_integer(&[(v >> 40) as u8,
(v >> 32) as u8,
(v >> 24) as u8,
(v >> 16) as u8,
(v >> 8) as u8,
(v & 255) as u8]);
}
if fits_in_bytes!(v, 7) {
return write_atom(self, AtomMinor::SignedInteger, &[(v >> 48) as u8,
(v >> 40) as u8,
(v >> 32) as u8,
(v >> 24) as u8,
(v >> 16) as u8,
(v >> 8) as u8,
(v & 255) as u8]);
return self.write_medium_integer(&[(v >> 48) as u8,
(v >> 40) as u8,
(v >> 32) as u8,
(v >> 24) as u8,
(v >> 16) as u8,
(v >> 8) as u8,
(v & 255) as u8]);
}
return write_atom(self, AtomMinor::SignedInteger, &[(v >> 56) as u8,
(v >> 48) as u8,
(v >> 40) as u8,
(v >> 32) as u8,
(v >> 24) as u8,
(v >> 16) as u8,
(v >> 8) as u8,
(v & 255) as u8]);
self.write_medium_integer(&[(v >> 56) as u8,
(v >> 48) as u8,
(v >> 40) as u8,
(v >> 32) as u8,
(v >> 24) as u8,
(v >> 16) as u8,
(v >> 8) as u8,
(v & 255) as u8])
}
fn write_u64(&mut self, v: u64) -> Result<()> {
if let Ok(w) = v.try_into() { return self.write_i64(w) }
return write_atom(self, AtomMinor::SignedInteger, &[0,
(v >> 56) as u8,
(v >> 48) as u8,
(v >> 40) as u8,
(v >> 32) as u8,
(v >> 24) as u8,
(v >> 16) as u8,
(v >> 8) as u8,
(v & 255) as u8]);
self.write_medium_integer(&[0,
(v >> 56) as u8,
(v >> 48) as u8,
(v >> 40) as u8,
(v >> 32) as u8,
(v >> 24) as u8,
(v >> 16) as u8,
(v >> 8) as u8,
(v & 255) as u8])
}
fn write_i128(&mut self, v: i128) -> Result<()> {
if let Ok(w) = v.try_into() { return self.write_i64(w) }
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, 10) { return write_atom(self, AtomMinor::SignedInteger, &bs[6..]); }
if fits_in_bytes!(v, 11) { return write_atom(self, AtomMinor::SignedInteger, &bs[5..]); }
if fits_in_bytes!(v, 12) { return write_atom(self, AtomMinor::SignedInteger, &bs[4..]); }
if fits_in_bytes!(v, 13) { return write_atom(self, AtomMinor::SignedInteger, &bs[3..]); }
if fits_in_bytes!(v, 14) { return write_atom(self, AtomMinor::SignedInteger, &bs[2..]); }
if fits_in_bytes!(v, 15) { return write_atom(self, AtomMinor::SignedInteger, &bs[1..]); }
return write_atom(self, AtomMinor::SignedInteger, &bs);
if fits_in_bytes!(v, 9) { return self.write_medium_integer(&bs[7..]); }
if fits_in_bytes!(v, 10) { return self.write_medium_integer(&bs[6..]); }
if fits_in_bytes!(v, 11) { return self.write_medium_integer(&bs[5..]); }
if fits_in_bytes!(v, 12) { return self.write_medium_integer(&bs[4..]); }
if fits_in_bytes!(v, 13) { return self.write_medium_integer(&bs[3..]); }
if fits_in_bytes!(v, 14) { return self.write_medium_integer(&bs[2..]); }
if fits_in_bytes!(v, 15) { return self.write_medium_integer(&bs[1..]); }
self.write_medium_integer(&bs)
}
fn write_u128(&mut self, v: u128) -> Result<()> {
if let Ok(w) = v.try_into() { return self.write_i128(w) }
let bs: [u8; 16] = v.to_be_bytes();
write_header(self, Op::Atom(AtomMinor::SignedInteger), bs.len() + 1)?;
self.0.write_all(&[0])?;
self.0.write_all(&bs)
self.write_tag(Tag::SignedInteger)?;
varint(&mut self.w(), 17)?;
self.write_byte(0)?;
self.write_raw_bytes(&bs)
}
fn write_int(&mut self, v: &BigInt) -> Result<()> {
match v.to_i8() {
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<()> {
write_atom(self, AtomMinor::String, v.as_bytes())
self.write_atom(Tag::String, v.as_bytes())
}
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<()> {
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>> {
write_op(self, Op::Misc(2), Op::Atom(AtomMinor::String).into())?;
Ok(Some(()))
fn start_record(&mut self, _field_count: Option<usize>) -> Result<Self::SeqWriter> {
self.write_tag(Tag::Record)?;
Ok(self.suspend())
}
fn stream_bytes(&mut self) -> Result<Option<Self::StreamedAtom>> {
write_op(self, Op::Misc(2), Op::Atom(AtomMinor::ByteString).into())?;
Ok(Some(()))
fn start_sequence(&mut self, _item_count: Option<usize>) -> Result<Self::SeqWriter> {
self.write_tag(Tag::Sequence)?;
Ok(self.suspend())
}
fn stream_symbol(&mut self) -> Result<Option<Self::StreamedAtom>> {
write_op(self, Op::Misc(2), Op::Atom(AtomMinor::Symbol).into())?;
Ok(Some(()))
fn end_seq(&mut self, seq: Self::SeqWriter) -> Result<()> {
self.resume(seq);
self.write_tag(Tag::End)
}
fn extend_atom(&mut self, _s: &mut Self::StreamedAtom, bs: &[u8]) -> Result<()> {
self.write_bytes(bs)
fn start_set(&mut self, _item_count: Option<usize>) -> Result<Self::SetWriter> {
self.write_tag(Tag::Set)?;
Ok(BinaryOrderWriter::new())
}
fn end_atom(&mut self, _s: Self::StreamedAtom) -> Result<()> {
write_op(self, Op::Misc(0), 4)
fn start_dictionary(&mut self, _entry_count: Option<usize>) -> Result<Self::SetWriter> {
self.write_tag(Tag::Dictionary)?;
Ok(BinaryOrderWriter::new())
}
fn start_record(&mut self, field_count: usize) -> Result<Self::Compound> {
write_header(self, Op::Compound(CompoundMinor::Record), field_count + 1)?;
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)
fn end_set(&mut self, set: Self::SetWriter) -> Result<()> {
set.finish(self)
}
}

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 trait Reader<'de> {
type CompoundInfo: Copy;
fn next(&mut self, read_annotations: bool) -> IOResult<Option<IOValue>>;
fn open_record(&mut self, arity: Option<usize>) -> ReaderResult<CompoundBody<Self::CompoundInfo>>;
fn open_sequence_or_set(&mut self) -> ReaderResult<CompoundBody<Self::CompoundInfo>>;
fn open_sequence(&mut self) -> ReaderResult<CompoundBody<Self::CompoundInfo>>;
fn open_set(&mut self) -> ReaderResult<CompoundBody<Self::CompoundInfo>>;
fn open_dictionary(&mut self) -> ReaderResult<CompoundBody<Self::CompoundInfo>>;
fn close_compound_counted(&mut self, info: Self::CompoundInfo) -> ReaderResult<()>;
fn close_compound_stream(&mut self, info: Self::CompoundInfo) -> ReaderResult<bool>;
fn open_record(&mut self, arity: Option<usize>) -> ReaderResult<()>;
fn open_sequence_or_set(&mut self) -> ReaderResult<()>;
fn open_sequence(&mut self) -> ReaderResult<()>;
fn open_set(&mut self) -> ReaderResult<()>;
fn open_dictionary(&mut self) -> ReaderResult<()>;
fn close_compound(&mut self) -> ReaderResult<bool>;
//---------------------------------------------------------------------------
@ -28,10 +25,7 @@ pub trait Reader<'de> {
}
fn demand_next(&mut self, read_annotations: bool) -> IOResult<IOValue> {
match self.next(read_annotations)? {
None => Err(io_eof()),
Some(v) => Ok(v)
}
self.next(read_annotations)?.ok_or_else(|| io_eof())
}
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()))
}
fn open_option(&mut self) ->
ReaderResult<(bool, CompoundBody<Self::CompoundInfo>)>
where
Self: Sized
fn open_option(&mut self) -> ReaderResult<bool>
{
let mut compound_body = self.open_record(None)?;
let label: &str = &compound_body.next_symbol(self)?.ok_or(error::Error::MissingItem)?;
self.open_record(None)?;
let label: &str = &self.next_symbol()?;
match label {
"None" => Ok((false, compound_body)),
"Some" => Ok((true, compound_body)),
"None" => Ok(false),
"Some" => Ok(true),
_ => Err(error::Error::Expected(ExpectedKind::Option,
Received::ReceivedRecordWithLabel(label.to_owned()))),
}
}
fn open_simple_record(&mut self, name: &str, arity: Option<usize>) ->
ReaderResult<CompoundBody<Self::CompoundInfo>>
where
Self: Sized
fn open_simple_record(&mut self, name: &str, arity: Option<usize>) -> ReaderResult<()>
{
let mut compound_body = self.open_record(arity)?;
let label: &str = &compound_body.next_symbol(self)?.ok_or(error::Error::MissingItem)?;
self.open_record(arity)?;
let label: &str = &self.next_symbol()?;
if label == name {
Ok(compound_body)
Ok(())
} else {
Err(error::Error::Expected(ExpectedKind::SimpleRecord(name.to_owned(), arity),
Received::ReceivedRecordWithLabel(label.to_owned())))
@ -101,129 +89,24 @@ pub trait Reader<'de> {
phantom: PhantomData,
}
}
}
impl<'r, 'de, R: Reader<'de>> Reader<'de> for &'r mut R {
type CompoundInfo = R::CompoundInfo;
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()?;
fn skip_remainder(&mut self) -> ReaderResult<()> {
while !self.close_compound()? {
self.skip_value()?;
}
Ok(())
}
pub fn ensure_more_expected<'de, R: Reader<'de, CompoundInfo = I>>(&mut self, read: &mut R) -> ReaderResult<()> {
if self.more_expected(read)? {
fn ensure_more_expected(&mut self) -> ReaderResult<()> {
if !self.close_compound()? {
Ok(())
} else {
Err(error::Error::MissingItem)
}
}
pub fn ensure_complete<'de, R: Reader<'de, CompoundInfo = I>>(&mut self, read: &mut R) -> ReaderResult<()> {
if self.more_expected(read)? {
fn ensure_complete(&mut self) -> ReaderResult<()> {
if !self.close_compound()? {
Err(error::Error::MissingCloseDelimiter)
} else {
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> {
fn skip(&mut self) -> IOResult<()>;
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.
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
match self {
Value::Boolean(false) => f.write_str("#false"),
Value::Boolean(true) => f.write_str("#true"),
Value::Boolean(false) => f.write_str("#f"),
Value::Boolean(true) => f.write_str("#t"),
Value::Float(Float(v)) => write!(f, "{:?}f", v),
Value::Double(Double(v)) => write!(f, "{:?}", v),
Value::SignedInteger(v) => write!(f, "{}", v),
Value::String(ref v) => write!(f, "{:?}", v), // TODO: proper escaping!
Value::ByteString(ref v) => {
f.write_str("#hex{")?;
f.write_str("#x\"")?;
for b in v { write!(f, "{:02x}", b)? }
f.write_str("}")
f.write_str("\"")
}
Value::Symbol(ref v) => {
// 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::Set(ref v) => {
f.write_str("#set")?;
f.write_str("#")?;
f.debug_set().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.
#[derive(Clone)]
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 trait Writer {
type Pointer;
type Annotation;
type Compound;
type Dictionary;
type StreamedAtom;
type KeyPointer;
pub trait AnnotationWriter: Writer {
fn start_annotation(&mut self) -> Result<()>;
fn start_value(&mut self) -> Result<()>;
}
pub trait CompoundWriter: Writer {
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 start_annotation(&mut self) -> Result<Self::Annotation>;
fn extend_annotation(&mut self, a: &mut Self::Annotation, annotation: &IOValue) -> Result<()>;
fn end_annotation(&mut self, a: Self::Annotation, value_p: Self::Pointer) -> Result<Self::Pointer>;
fn start_annotations(&mut self) -> Result<Self::AnnWriter>;
fn end_annotations(&mut self, ann: Self::AnnWriter) -> Result<()>;
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_f64(&mut self, v: f64) -> Result<Self::Pointer>;
fn write_f32(&mut self, v: f32) -> Result<()>;
fn write_f64(&mut self, v: f64) -> Result<()>;
fn write_i8(&mut self, v: i8) -> Result<Self::Pointer>;
fn write_u8(&mut self, v: u8) -> Result<Self::Pointer>;
fn write_i16(&mut self, v: i16) -> Result<Self::Pointer>;
fn write_u16(&mut self, v: u16) -> Result<Self::Pointer>;
fn write_i32(&mut self, v: i32) -> Result<Self::Pointer>;
fn write_u32(&mut self, v: u32) -> Result<Self::Pointer>;
fn write_i64(&mut self, v: i64) -> Result<Self::Pointer>;
fn write_u64(&mut self, v: u64) -> Result<Self::Pointer>;
fn write_i128(&mut self, v: i128) -> Result<Self::Pointer>;
fn write_u128(&mut self, v: u128) -> Result<Self::Pointer>;
fn write_int(&mut self, v: &BigInt) -> Result<Self::Pointer>;
fn write_i8(&mut self, v: i8) -> Result<()>;
fn write_u8(&mut self, v: u8) -> Result<()>;
fn write_i16(&mut self, v: i16) -> Result<()>;
fn write_u16(&mut self, v: u16) -> Result<()>;
fn write_i32(&mut self, v: i32) -> Result<()>;
fn write_u32(&mut self, v: u32) -> Result<()>;
fn write_i64(&mut self, v: i64) -> Result<()>;
fn write_u64(&mut self, v: u64) -> Result<()>;
fn write_i128(&mut self, v: i128) -> Result<()>;
fn write_u128(&mut self, v: u128) -> Result<()>;
fn write_int(&mut self, v: &BigInt) -> Result<()>;
fn write_string(&mut self, v: &str) -> Result<Self::Pointer>;
fn write_bytes(&mut self, v: &[u8]) -> Result<Self::Pointer>;
fn write_symbol(&mut self, v: &str) -> Result<Self::Pointer>;
fn write_string(&mut self, v: &str) -> Result<()>;
fn write_bytes(&mut self, v: &[u8]) -> Result<()>;
fn write_symbol(&mut self, v: &str) -> Result<()>;
fn stream_string(&mut self) -> Result<Option<Self::StreamedAtom>>;
fn stream_bytes(&mut self) -> Result<Option<Self::StreamedAtom>>;
fn stream_symbol(&mut self) -> Result<Option<Self::StreamedAtom>>;
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: Option<usize>) -> Result<Self::SeqWriter>;
fn start_sequence(&mut self, item_count: Option<usize>) -> Result<Self::SeqWriter>;
fn end_seq(&mut self, seq: Self::SeqWriter) -> Result<()>;
fn start_record(&mut self, field_count: usize) -> Result<Self::Compound>;
fn start_sequence(&mut self, item_count: usize) -> Result<Self::Compound>;
fn start_set(&mut self, item_count: usize) -> Result<Self::Compound>;
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 start_set(&mut self, item_count: Option<usize>) -> Result<Self::SetWriter>;
fn start_dictionary(&mut self, entry_count: Option<usize>) -> Result<Self::SetWriter>;
fn end_set(&mut self, set: Self::SetWriter) -> Result<()>;
//---------------------------------------------------------------------------
fn write(&mut self, v: &IOValue) -> Result<Self::Pointer> {
fn write(&mut self, v: &IOValue) -> Result<()> {
match v.annotations().maybe_slice() {
None => self.write_value(v.value()),
None => {
self.write_value(v.value())?;
}
Some(anns) => {
let mut a = self.start_annotation()?;
let mut a = self.start_annotations()?;
for ann in anns {
self.extend_annotation(&mut a, ann)?;
a.start_annotation()?;
a.write(ann)?;
}
let p = self.write_value(v.value())?;
self.end_annotation(a, p)
a.start_value()?;
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 {
Value::Boolean(b) => self.write_bool(*b),
Value::Float(Float(f)) => self.write_f32(*f),
@ -92,60 +90,50 @@ pub trait Writer {
Value::ByteString(ref bs) => self.write_bytes(bs),
Value::Symbol(ref s) => self.write_symbol(s),
Value::Record(r) => {
let mut c = self.start_record(r.arity())?;
let p = self.write(r.label())?;
self.extend_compound(&mut c, p)?;
let mut c = self.start_record(Some(r.arity()))?;
c.extend()?;
c.write(r.label())?;
c.delimit()?;
for f in r.fields() {
let p = self.write(f)?;
self.extend_compound(&mut c, p)?;
c.extend()?;
c.write(f)?;
c.delimit()?;
}
self.end_compound(c)
self.end_seq(c)
}
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 {
let p = self.write(v)?;
self.extend_compound(&mut c, p)?;
c.extend()?;
c.write(v)?;
c.delimit()?;
}
self.end_compound(c)
self.end_seq(c)
}
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 {
let p = self.write(v)?;
self.extend_compound(&mut c, p)?;
c.extend()?;
c.write(v)?;
c.delimit()?;
}
self.end_compound(c)
self.end_set(c)
}
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 {
let p = self.write(k)?;
let kp = self.extend_dictionary_key(&mut d, p)?;
let p = self.write(v)?;
self.extend_dictionary_value(&mut d, kp, p)?;
c.extend()?;
c.write(k)?;
c.write(v)?;
c.delimit()?;
}
self.end_dictionary(d)
self.end_set(c)
}
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> {
let mut byte_count = 0;
loop {

View File

@ -10,7 +10,6 @@ pub struct TestCases {
pub enum TestCase {
Test(#[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),
ParseError(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);
}
TestCase::NondeterministicTest(ref bin, ref val) => {
// The test cases in samples.txt are carefully
// written so that while strictly
// "nondeterministic", the order of keys in
// dictionaries follows Preserves order.
assert_eq!(&decode_all(&PackedWriter::encode(val)?[..])?, &[val.clone()]);
assert_eq!(&decode_all(&bin[..])?, &[val.clone()]);
// The test cases in samples.txt are carefully written
// so that while strictly "nondeterministic", the
// order of keys in encoded dictionaries follows
// Preserves canonical order.
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(&bin[..])?, &[val.clone()]);
}