Blue Rust implementation (WIP)

This commit is contained in:
Tony Garnock-Jones 2022-07-10 13:25:35 +02:00
parent d22d0d7120
commit c2a48a9b78
28 changed files with 2036 additions and 2084 deletions

View File

@ -108,8 +108,9 @@ pub struct CompilerConfig {
pub fn load_schema_or_bundle(bundle: &mut Map<ModulePath, Schema>, i: &PathBuf) -> io::Result<()> {
let mut f = File::open(&i)?;
let mut src = IOBinarySource::new(&mut f);
let mut reader = src.packed_iovalues();
let blob = reader.demand_next(false)?;
let mut reader = src.packed().iovalues();
reader.set_read_annotations(false);
let blob = reader.demand_next()?;
let language = Language::default();
if let Ok(s) = language.parse(&blob) {
@ -139,8 +140,8 @@ impl CompilerConfig {
) -> Self {
CompilerConfig {
bundle: Map::new(),
output_dir: output_dir,
fully_qualified_module_prefix: fully_qualified_module_prefix,
output_dir,
fully_qualified_module_prefix,
support_crate: "preserves_schema".to_owned(),
external_modules: Map::new(),
plugins: vec![

File diff suppressed because it is too large Load Diff

View File

@ -42,8 +42,9 @@ mod tests {
let mut f = std::fs::File::open("../../../schema/schema.bin")?;
let mut src = IOBinarySource::new(&mut f);
let mut reader = src.packed_iovalues();
let schema = reader.demand_next(false)?;
let mut reader = src.packed().iovalues();
reader.set_read_annotations(false);
let schema = reader.demand_next()?;
let language = crate::gen::Language::default();
let parsed = Schema::parse(&language, &schema).expect("successful parse");
assert_eq!(schema, parsed.unparse(&language));

View File

@ -39,7 +39,7 @@ impl<'a, V: NestedValue> Context<'a, V> {
}
pub fn dynamic_unparse(&mut self, _module: &Vec<String>, _name: &str, _w: &V) -> Option<V> {
panic!("Not yet implemented");
todo!("Not yet implemented");
}
}

View File

@ -1,6 +1,9 @@
pub use lazy_static::lazy_static;
pub use preserves;
pub use preserves::value::ConfiguredReader;
pub use preserves::value::DomainDecode;
pub use preserves::value::Embeddable;
pub use preserves::value::Reader;
pub use preserves::value::boundary as B;
@ -59,15 +62,15 @@ impl<L, N: NestedValue> Codec<N> for L {
}
}
pub trait Deserialize<'de, N: NestedValue, R: Reader<'de, N>>
pub trait Deserialize<'de, _Value: NestedValue, _Dec: DomainDecode<_Value::Embedded>, _R: Reader<'de>>
where
Self: Sized
{
fn deserialize(r: &mut R) -> Result<Self, ParseError>;
fn deserialize(c: &mut ConfiguredReader<'de, _Value, _Dec, _R>) -> Result<Self, ParseError>;
}
pub fn decode_lit<N: NestedValue>(bs: &[u8]) -> io::Result<N> {
preserves::value::packed::from_bytes(bs, NoEmbeddedDomainCodec)
preserves::value::packed::from_bytes(bs, &mut NoEmbeddedDomainCodec)
}
pub fn decode_embedded<D: Domain>(
@ -100,7 +103,7 @@ pub enum ParseError {
impl From<preserves::error::Error> for ParseError {
fn from(v: preserves::error::Error) -> Self {
match v {
preserves::error::Error::Expected(_, _) =>
preserves::error::Error::Expected(_) =>
ParseError::ConformanceError("preserves::error::Error::Expected"),
_ =>
ParseError::Preserves(v),

View File

@ -33,7 +33,7 @@ enum Variety {
}
fn try_file(kind: &str, path: &str) -> io::Result<()> {
let fruits_value = IOBinarySource::new(&mut File::open(path)?).packed_iovalues().demand_next(true)?;
let fruits_value = IOBinarySource::new(&mut File::open(path)?).packed().iovalues().demand_next()?;
println!("{:?}", fruits_value);
let fruits1: Vec<Fruit> = value::de::from_value(&fruits_value)?;

View File

@ -6,14 +6,15 @@ use std::io;
use std::marker::PhantomData;
use super::value::boundary as B;
use super::value::{IOValue, IOValueDomainCodec, PackedReader, TextReader, ViaCodec};
use super::value::reader::{Reader, IOBinarySource, BytesBinarySource};
use super::value::{IOValueDomainCodec, PackedReader, TextReader};
use super::value::reader::Reader;
use super::value::source::{IOBinarySource, BytesBinarySource};
pub use super::error::Error;
pub use super::error::{Error, ExpectedKind};
pub type Result<T> = std::result::Result<T, Error>;
pub struct Deserializer<'de, 'r, R: Reader<'de, IOValue>> {
pub struct Deserializer<'de, 'r, R: Reader<'de>> {
pub read: &'r mut R,
phantom: PhantomData<&'de ()>,
}
@ -23,12 +24,11 @@ pub fn from_bytes<'de, T>(bytes: &'de [u8]) ->
where
T: Deserialize<'de>
{
from_reader(&mut PackedReader::new(&mut BytesBinarySource::new(bytes), IOValueDomainCodec))
from_reader(&mut PackedReader::new(&mut BytesBinarySource::new(bytes)))
}
pub fn from_text<'de, T>(text: &'de str) -> Result<T> where T: Deserialize<'de> {
from_reader(&mut TextReader::new(&mut BytesBinarySource::new(text.as_bytes()),
ViaCodec::new(IOValueDomainCodec)))
from_reader(&mut TextReader::new(&mut BytesBinarySource::new(text.as_bytes())))
}
pub fn from_read<'de, 'r, IOR: io::Read + io::Seek, T>(read: &'r mut IOR) ->
@ -36,10 +36,10 @@ pub fn from_read<'de, 'r, IOR: io::Read + io::Seek, T>(read: &'r mut IOR) ->
where
T: Deserialize<'de>
{
from_reader(&mut PackedReader::new(&mut IOBinarySource::new(read), IOValueDomainCodec))
from_reader(&mut PackedReader::new(&mut IOBinarySource::new(read)))
}
pub fn from_reader<'r, 'de, R: Reader<'de, IOValue>, T>(read: &'r mut R) ->
pub fn from_reader<'r, 'de, R: Reader<'de>, T>(read: &'r mut R) ->
Result<T>
where
T: Deserialize<'de>
@ -49,13 +49,29 @@ where
Ok(t)
}
impl<'r, 'de, R: Reader<'de, IOValue>> Deserializer<'de, 'r, R> {
impl<'r, 'de, R: Reader<'de>> Deserializer<'de, 'r, R> {
pub fn from_reader(read: &'r mut R) -> Self {
Deserializer { read, phantom: PhantomData }
}
fn new_record_boundary(&mut self) -> Result<B::Type> {
let b = B::start(B::Item::RecordLabel);
self.read.boundary(&b)?;
Ok(b)
}
fn open_simple_record(&mut self, label: &str) -> Result<B::Type> {
self.read.open_simple_record(label)?;
self.new_record_boundary()
}
fn open_record(&mut self) -> Result<B::Type> {
self.read.open_record()?;
self.new_record_boundary()
}
}
impl<'r, 'de, 'a, R: Reader<'de, IOValue>>
impl<'r, 'de, 'a, R: Reader<'de>>
serde::de::Deserializer<'de>
for &'a mut Deserializer<'de, 'r, R>
{
@ -155,19 +171,26 @@ impl<'r, 'de, 'a, R: Reader<'de, IOValue>>
fn deserialize_option<V>(self, visitor: V) -> Result<V::Value> where V: Visitor<'de>
{
if let Some(mut b) = self.read.open_option()? {
self.read.ensure_more_expected(&mut b, &B::Item::RecordField)?;
let result = visitor.visit_some(&mut *self)?;
self.read.ensure_complete(b, &B::Item::RecordField)?;
Ok(result)
} else {
Ok(visitor.visit_none::<Error>()?)
let mut b = self.open_record()?;
match self.read.next_symbol()?.as_ref() {
"None" => {
self.read.ensure_complete(b, &B::Item::RecordField)?;
visitor.visit_none::<Error>()
}
"Some" => {
self.read.ensure_more_expected(&mut b, &B::Item::RecordField)?;
let result = visitor.visit_some(&mut *self)?;
self.read.ensure_complete(b, &B::Item::RecordField)?;
Ok(result)
}
_ =>
Err(Error::Expected(ExpectedKind::Option)),
}
}
fn deserialize_unit<V>(self, visitor: V) -> Result<V::Value> where V: Visitor<'de>
{
let b = self.read.open_simple_record("tuple", Some(0))?;
let b = self.open_simple_record("tuple")?;
let result = visitor.visit_unit::<Error>()?;
self.read.ensure_complete(b, &B::Item::RecordField)?;
Ok(result)
@ -176,7 +199,7 @@ impl<'r, 'de, 'a, R: Reader<'de, IOValue>>
fn deserialize_unit_struct<V>(self, name: &'static str, visitor: V)
-> Result<V::Value> where V: Visitor<'de>
{
let b = self.read.open_simple_record(name, Some(0))?;
let b = self.open_simple_record(name)?;
let result = visitor.visit_unit::<Error>()?;
self.read.ensure_complete(b, &B::Item::RecordField)?;
Ok(result)
@ -186,11 +209,11 @@ impl<'r, 'de, 'a, R: Reader<'de, IOValue>>
-> Result<V::Value> where V: Visitor<'de>
{
match super::value::magic::transmit_input_value(
name, || Ok(self.read.demand_next(true)?))?
name, || Ok(self.read.demand_next(true, &mut IOValueDomainCodec)?))?
{
Some(v) => visitor.visit_u64(v),
None => {
let mut b = self.read.open_simple_record(name, Some(1))?;
let mut b = self.open_simple_record(name)?;
self.read.ensure_more_expected(&mut b, &B::Item::RecordField)?;
let result = visitor.visit_newtype_struct(&mut *self)?;
self.read.ensure_complete(b, &B::Item::RecordField)?;
@ -202,23 +225,31 @@ impl<'r, 'de, 'a, R: Reader<'de, IOValue>>
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 i = self.read.open_sequence_or_set()?;
visitor.visit_seq(Seq::new(self, B::Type::default(), i))
let mark = self.read.mark()?;
match self.read.open_sequence() {
Ok(()) => visitor.visit_seq(Seq::new(self, B::Type::default(), B::Item::SequenceValue)),
Err(Error::Expected(_)) => {
self.read.restore(&mark)?;
self.read.open_set()?;
visitor.visit_seq(Seq::new(self, B::Type::default(), B::Item::SetValue))
}
Err(e) => Err(e)?
}
}
fn deserialize_tuple<V>(self, len: usize, visitor: V) -> Result<V::Value> where V: Visitor<'de>
fn deserialize_tuple<V>(self, _len: usize, visitor: V) -> Result<V::Value> where V: Visitor<'de>
{
let b = self.read.open_simple_record("tuple", Some(len))?;
let b = self.open_simple_record("tuple")?;
let mut seq = Seq::new(self, b, B::Item::RecordField);
let result = visitor.visit_seq(&mut seq)?;
seq.skip_remainder()?;
Ok(result)
}
fn deserialize_tuple_struct<V>(self, name: &'static str, len: usize, visitor: V)
fn deserialize_tuple_struct<V>(self, name: &'static str, _len: usize, visitor: V)
-> Result<V::Value> where V: Visitor<'de>
{
let b = self.read.open_simple_record(name, Some(len))?;
let b = self.open_simple_record(name)?;
let mut seq = Seq::new(self, b, B::Item::RecordField);
let result = visitor.visit_seq(&mut seq)?;
seq.skip_remainder()?;
@ -234,11 +265,11 @@ impl<'r, 'de, 'a, R: Reader<'de, IOValue>>
fn deserialize_struct<V>(self,
name: &'static str,
fields: &'static [&'static str],
_fields: &'static [&'static str],
visitor: V)
-> Result<V::Value> where V: Visitor<'de>
{
let b = self.read.open_simple_record(name, Some(fields.len()))?;
let b = self.open_simple_record(name)?;
let mut seq = Seq::new(self, b, B::Item::RecordField);
let result = visitor.visit_seq(&mut seq)?;
seq.skip_remainder()?;
@ -268,13 +299,13 @@ impl<'r, 'de, 'a, R: Reader<'de, IOValue>>
}
}
pub struct Seq<'de, 'r, 'a, R: Reader<'de, IOValue>> {
pub struct Seq<'de, 'r, 'a, R: Reader<'de>> {
b: B::Type,
i: B::Item,
de: &'a mut Deserializer<'de, 'r, R>,
}
impl<'de, 'r, 'a, R: Reader<'de, IOValue>> Seq<'de, 'r, 'a, R> {
impl<'de, 'r, 'a, R: Reader<'de>> Seq<'de, 'r, 'a, R> {
fn new(de: &'a mut Deserializer<'de, 'r, R>, b: B::Type, i: B::Item) -> Self {
Seq { b, i, de }
}
@ -296,7 +327,7 @@ impl<'de, 'r, 'a, R: Reader<'de, IOValue>> Seq<'de, 'r, 'a, R> {
}
}
impl<'de, 'r, 'a, R: Reader<'de, IOValue>> SeqAccess<'de> for Seq<'de, 'r, 'a, R> {
impl<'de, 'r, 'a, R: Reader<'de>> SeqAccess<'de> for Seq<'de, 'r, 'a, R> {
type Error = Error;
fn next_element_seed<T>(&mut self, seed: T) ->
@ -306,7 +337,7 @@ impl<'de, 'r, 'a, R: Reader<'de, IOValue>> SeqAccess<'de> for Seq<'de, 'r, 'a, R
}
}
impl<'de, 'r, 'a, R: Reader<'de, IOValue>> MapAccess<'de> for Seq<'de, 'r, 'a, R> {
impl<'de, 'r, 'a, R: Reader<'de>> MapAccess<'de> for Seq<'de, 'r, 'a, R> {
type Error = Error;
fn next_key_seed<K>(&mut self, seed: K) ->
@ -327,20 +358,20 @@ impl<'de, 'r, 'a, R: Reader<'de, IOValue>> MapAccess<'de> for Seq<'de, 'r, 'a, R
}
}
impl<'de, 'r, 'a, R: Reader<'de, IOValue>> EnumAccess<'de> for &'a mut Deserializer<'de, 'r, R> {
impl<'de, 'r, 'a, R: Reader<'de>> EnumAccess<'de> for &'a mut Deserializer<'de, 'r, R> {
type Error = Error;
type Variant = Seq<'de, 'r, 'a, R>;
fn variant_seed<V>(self, seed: V)
-> Result<(V::Value, Self::Variant)> where V: DeserializeSeed<'de>
{
let b = self.read.open_record(None)?;
let b = self.open_record()?;
let variant = seed.deserialize(&mut *self)?;
Ok((variant, Seq::new(self, b, B::Item::RecordField)))
}
}
impl<'de, 'r, 'a, R: Reader<'de, IOValue>> VariantAccess<'de> for Seq<'de, 'r, 'a, R> {
impl<'de, 'r, 'a, R: Reader<'de>> VariantAccess<'de> for Seq<'de, 'r, 'a, R> {
type Error = Error;
fn unit_variant(mut self) -> Result<()> {

View File

@ -11,15 +11,7 @@ pub enum Error {
CannotDeserializeAny,
MissingCloseDelimiter,
MissingItem,
Expected(ExpectedKind, Received),
StreamingSerializationUnsupported,
}
#[derive(Debug)]
pub enum Received {
ReceivedSomethingElse,
ReceivedRecordWithLabel(String),
ReceivedOtherValue(String),
Expected(ExpectedKind),
}
#[derive(Debug, PartialEq)]
@ -35,16 +27,14 @@ pub enum ExpectedKind {
ByteString,
Symbol,
Record(Option<usize>),
SimpleRecord(String, Option<usize>),
Record,
SimpleRecord(String),
Sequence,
Set,
Dictionary,
Embedded,
SequenceOrSet, // Because of hacking up serde's data model: see open_sequence_or_set etc.
Option,
UnicodeScalar,
}

View File

@ -32,7 +32,10 @@ mod dom {
Value::from(2).wrap()])
.wrap();
assert_eq!(PackedWriter::encode_iovalue(&v.copy_via(&mut dom_as_preserves).unwrap()).unwrap(),
[0xb5, 0x91, 0xb2, 0x04, 255, 255, 255, 255, 0x92, 0x84]);
[0xa8,
0x82, 0xa3, 0x01,
0x85, 0xa5, 255, 255, 255, 255,
0x82, 0xa3, 0x02]);
}
#[test] fn test_two() {
@ -41,7 +44,10 @@ mod dom {
Value::from(2).wrap()])
.wrap();
assert_eq!(PackedWriter::encode_iovalue(&v.copy_via(&mut dom_as_preserves).unwrap()).unwrap(),
[0xb5, 0x91, 0xb3, 0x08, 68, 111, 109, 58, 58, 84, 119, 111, 0x92, 0x84]);
[0xa8,
0x82, 0xa3, 0x01,
0x89, 0xa6, 68, 111, 109, 58, 58, 84, 119, 111,
0x82, 0xa3, 0x02]);
}
}
@ -224,9 +230,15 @@ mod value_tests {
#[cfg(test)]
mod decoder_tests {
use crate::value::{Value, NestedValue, BinarySource, BytesBinarySource, ConfiguredReader};
use crate::de::from_bytes;
use crate::error::{Error, ExpectedKind, is_eof_io_error};
use crate::error::Error;
use crate::error::ExpectedKind;
use crate::error::is_eof_io_error;
use crate::value::BinarySource;
use crate::value::BytesBinarySource;
use crate::value::NestedValue;
use crate::value::Reader;
use crate::value::Value;
fn expect_number_out_of_range<T: core::fmt::Debug>(r: Result<T, Error>) {
match r {
@ -239,15 +251,15 @@ mod decoder_tests {
fn expect_expected<T: core::fmt::Debug>(k: ExpectedKind, r: Result<T, Error>) {
match r {
Ok(v) => panic!("Expected Expected({:?}), but got a parse of {:?}", k, v),
Err(Error::Expected(k1, _)) if k1 == k => (),
Err(Error::Expected(k1)) if k1 == k => (),
Err(e) => panic!("Expected Expected({:?}), but got an error of {:?}", k, e),
}
}
#[test] fn skip_annotations_noskip() {
let buf = &b"\x85\x92\x91"[..];
let buf = &b"\xbf\x82\xa3\x01\x82\xa3\x02"[..];
let mut src = BytesBinarySource::new(&buf);
let mut d = ConfiguredReader::new(src.packed_iovalues());
let mut d = src.packed().iovalues();
let v = d.demand_next().unwrap();
assert_eq!(v.annotations().slice().len(), 1);
assert_eq!(v.annotations().slice()[0], Value::from(2).wrap());
@ -255,9 +267,9 @@ mod decoder_tests {
}
#[test] fn skip_annotations_skip() {
let buf = &b"\x85\x92\x91"[..];
let buf = &b"\xbf\x82\xa3\x01\x82\xa3\x02"[..];
let mut src = BytesBinarySource::new(&buf);
let mut d = ConfiguredReader::new(src.packed_iovalues());
let mut d = src.packed().iovalues();
d.set_read_annotations(false);
let v = d.demand_next().unwrap();
assert_eq!(v.annotations().slice().len(), 0);
@ -265,37 +277,38 @@ mod decoder_tests {
}
#[test] fn multiple_values_buf_advanced() {
let buf = &b"\xb4\xb3\x04Ping\x84\xb4\xb3\x04Pong\x84"[..];
assert_eq!(buf.len(), 16);
let buf = &b"\xa8\x87\xa7\x85\xa6Ping\x87\xa7\x85\xa6Pong"[..];
assert_eq!(buf.len(), 17);
let mut src = BytesBinarySource::new(&buf);
let mut d = ConfiguredReader::new(src.packed_iovalues());
assert_eq!(d.reader.source.index, 0);
let mut d = src.packed().iovalues();
d.reader.open_sequence().unwrap();
assert_eq!(d.reader.source.source.index, 1);
assert_eq!(d.demand_next().unwrap().value(), &Value::simple_record0("Ping"));
assert_eq!(d.reader.source.index, 8);
assert_eq!(d.reader.source.source.index, 9);
assert_eq!(d.demand_next().unwrap().value(), &Value::simple_record0("Pong"));
assert_eq!(d.reader.source.index, 16);
assert_eq!(d.reader.source.source.index, 17);
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"\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_i8_format_a_positive() { assert_eq!(from_bytes::<i8>(b"\xa3\x01").unwrap(), 1) }
#[test] fn direct_i8_format_a_zero() { assert_eq!(from_bytes::<i8>(b"\xa3\x00").unwrap(), 0) }
#[test] fn direct_i8_format_a_negative() { assert_eq!(from_bytes::<i8>(b"\xa3\xff").unwrap(), -1) }
#[test] fn direct_i8_format_b() { assert_eq!(from_bytes::<i8>(b"\xa3\xfe").unwrap(), -2) }
#[test] fn direct_i8_format_b_too_long() { assert_eq!(from_bytes::<i8>(b"\xa3\xff\xff\xfe").unwrap(), -2) }
#[test] fn direct_i8_format_b_much_too_long() { assert_eq!(from_bytes::<i8>(b"\xa3\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"\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_a_positive() { assert_eq!(from_bytes::<u8>(b"\xa3\x01").unwrap(), 1) }
#[test] fn direct_u8_format_a_zero() { assert_eq!(from_bytes::<u8>(b"\xa3\x00").unwrap(), 0) }
#[test] fn direct_u8_format_b() { assert_eq!(from_bytes::<u8>(b"\xa31").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_u8_format_b_much_too_long() { assert_eq!(from_bytes::<u8>(b"\xa3\0\0\0\0\0\0\0\0\01").unwrap(), 49) }
#[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_i16_format_a() { assert_eq!(from_bytes::<i16>(b"\xa3\xfe").unwrap(), -2) }
#[test] fn direct_i16_format_b() { assert_eq!(from_bytes::<i16>(b"\xa3\xfe\xff").unwrap(), -257) }
#[test] fn direct_u8_wrong_format() {
expect_expected(ExpectedKind::SignedInteger, from_bytes::<u8>(b"\xb1\x05bogus"))
expect_expected(ExpectedKind::SignedInteger, from_bytes::<u8>(b"\xa6bogus"))
}
#[test] fn direct_u8_format_b_too_large() {
@ -303,15 +316,15 @@ mod decoder_tests {
}
#[test] fn direct_i8_format_b_too_large() {
expect_number_out_of_range(from_bytes::<i8>(b"\xa1\xfe\xff"))
expect_number_out_of_range(from_bytes::<i8>(b"\xa3\xfe\xff"))
}
#[test] fn direct_i16_format_b_too_large() {
expect_number_out_of_range(from_bytes::<i16>(b"\xa2\xfe\xff\xff"));
expect_number_out_of_range(from_bytes::<i16>(b"\xa3\xfe\xff\xff"));
}
#[test] fn direct_i32_format_b_ok() {
assert_eq!(from_bytes::<i32>(b"\xa2\xfe\xff\xff").unwrap(), -65537);
assert_eq!(from_bytes::<i32>(b"\xa3\xfe\xff\xff").unwrap(), -65537);
}
#[test] fn direct_i32_format_b_ok_2() {
@ -319,50 +332,50 @@ mod decoder_tests {
}
#[test] fn direct_i64_format_b() {
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);
assert_eq!(from_bytes::<i64>(b"\xa3\xff").unwrap(), -1);
assert_eq!(from_bytes::<i64>(b"\xa3\xff\xff\xff").unwrap(), -1);
assert_eq!(from_bytes::<i64>(b"\xa3\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff").unwrap(), -1);
assert_eq!(from_bytes::<i64>(b"\xa3\xfe").unwrap(), -2);
assert_eq!(from_bytes::<i64>(b"\xa3\xff\xfe\xff").unwrap(), -257);
assert_eq!(from_bytes::<i64>(b"\xa3\xfe\xff\xff").unwrap(), -65537);
assert_eq!(from_bytes::<i64>(b"\xa3\xff\xff\xff\xff\xff\xff\xfe\xff\xff\xff").unwrap(), -16777217);
assert_eq!(from_bytes::<i64>(b"\xa3\xff\xff\xfe\xff\xff\xff\xff\xff\xff\xff").unwrap(), -72057594037927937);
expect_number_out_of_range(from_bytes::<i64>(b"\xa3\xff\xff\x0e\xff\xff\xff\xff\xff\xff\xff"));
expect_number_out_of_range(from_bytes::<i64>(b"\xa3\xff\x0e\xff\xff\xff\xff\xff\xff\xff"));
expect_number_out_of_range(from_bytes::<i64>(b"\xa3\x80\x0e\xff\xff\xff\xff\xff\xff\xff"));
expect_number_out_of_range(from_bytes::<i64>(b"\xa3\xff\x00\x0e\xff\xff\xff\xff\xff\xff\xff"));
assert_eq!(from_bytes::<i64>(b"\xa3\xfe\xff\xff\xff\xff\xff\xff\xff").unwrap(), -72057594037927937);
assert_eq!(from_bytes::<i64>(b"\xa3\x0e\xff\xff\xff\xff\xff\xff\xff").unwrap(), 1080863910568919039);
assert_eq!(from_bytes::<i64>(b"\xa3\x80\0\0\0\0\0\0\0").unwrap(), -9223372036854775808);
assert_eq!(from_bytes::<i64>(b"\xa3\0\0\0\0\0\0\0\0").unwrap(), 0);
assert_eq!(from_bytes::<i64>(b"\xa3").unwrap(), 0);
assert_eq!(from_bytes::<i64>(b"\xa3\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"\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"));
expect_number_out_of_range(from_bytes::<u64>(b"\xa3\xff"));
assert_eq!(from_bytes::<u64>(b"\xa3\0\xff").unwrap(), 255);
expect_number_out_of_range(from_bytes::<u64>(b"\xa3\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);
expect_number_out_of_range(from_bytes::<u64>(b"\xa3\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff"));
assert_eq!(from_bytes::<u64>(b"\xa3\x02").unwrap(), 2);
assert_eq!(from_bytes::<u64>(b"\xa3\x00\x01\x00").unwrap(), 256);
assert_eq!(from_bytes::<u64>(b"\xa3\x01\x00\x00").unwrap(), 65536);
assert_eq!(from_bytes::<u64>(b"\xa3\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00").unwrap(), 16777216);
assert_eq!(from_bytes::<u64>(b"\xa3\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00").unwrap(), 72057594037927936);
assert_eq!(from_bytes::<u64>(b"\xa3\x00\x00\xf2\x00\x00\x00\x00\x00\x00\x00").unwrap(), 0xf200000000000000);
assert_eq!(from_bytes::<u64>(b"\xa3\x00\x00\x72\x00\x00\x00\x00\x00\x00\x00").unwrap(), 0x7200000000000000);
expect_number_out_of_range(from_bytes::<u64>(b"\xa3\x00\xf2\x00\x00\x00\x00\x00\x00\x00\x00"));
assert_eq!(from_bytes::<u64>(b"\xa3\x00\xf2\x00\x00\x00\x00\x00\x00\x00").unwrap(), 0xf200000000000000);
expect_number_out_of_range(from_bytes::<u64>(b"\xa3\x7f\xf2\x00\x00\x00\x00\x00\x00\x00"));
expect_number_out_of_range(from_bytes::<u64>(b"\xa3\x00\xff\xf2\x00\x00\x00\x00\x00\x00\x00"));
assert_eq!(from_bytes::<u64>(b"\xa3\x01\x00\x00\x00\x00\x00\x00\x00").unwrap(), 72057594037927936);
assert_eq!(from_bytes::<u64>(b"\xa3\x0e\xff\xff\xff\xff\xff\xff\xff").unwrap(), 1080863910568919039);
expect_number_out_of_range(from_bytes::<u64>(b"\xa3\x80\0\0\0\0\0\0\0"));
assert_eq!(from_bytes::<u64>(b"\xa3\0\x80\0\0\0\0\0\0\0").unwrap(), 9223372036854775808);
assert_eq!(from_bytes::<u64>(b"\xa3\0\0\0\0\0\0\0\0").unwrap(), 0);
assert_eq!(from_bytes::<u64>(b"\xa3").unwrap(), 0);
assert_eq!(from_bytes::<u64>(b"\xa3\x7f\xff\xff\xff\xff\xff\xff\xff").unwrap(), 9223372036854775807);
}
}
@ -371,7 +384,7 @@ mod serde_tests {
use crate::symbol::Symbol;
use crate::de::from_bytes as deserialize_from_bytes;
use crate::value::de::from_value as deserialize_from_value;
use crate::value::to_value;
use crate::value::{to_value, BinarySource, BytesBinarySource, Reader};
use crate::value::{Value, IOValue, Map, Set};
use crate::value::packed::PackedWriter;
@ -426,51 +439,51 @@ mod serde_tests {
assert_eq!(v, x);
let expected_bytes = vec![
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,
0xa7, // Record
0x8c, 0xa6, 0x53, 0x69, 0x6d, 0x70, 0x6c, 0x65, 0x56, 0x61, 0x6c, 0x75, 0x65, // SimpleValue
0x87, 0xa4, 0x68, 0x65, 0x6c, 0x6c, 0x6f, 0x00, // "hello"
0x85, 0xa6, 0x73, 0x79, 0x6d, 0x31, // sym1
0x85, 0xa6, 0x73, 0x79, 0x6d, 0x32, // sym2
0x85, 0xa6, 0x73, 0x79, 0x6d, 0x33, // sym3
0x85, 0xa6, 0x73, 0x79, 0x6d, 0x34, // sym4
0x87, 0xa4, 0x77, 0x6f, 0x72, 0x6c, 0x64, 0x00, // "world"
0x86, 0xa5, 0x73, 0x6c, 0x69, 0x63, 0x65, // #"slice"
0x84, 0xa5, 0x76, 0x65, 0x63, // #"vec"
0x89, 0xa8, // Sequence
0x81, 0xa0, // #f
0x81, 0xa1, // #t
0x81, 0xa0, // #f
0x81, 0xa1, // #t
0x95, 0xa9, // Set
0x85, 0xa4, 0x6f, 0x6e, 0x65, 0x00, // "one"
0x87, 0xa4, 0x74, 0x68, 0x72, 0x65, 0x65, 0x00, // "three"
0x85, 0xa4, 0x74, 0x77, 0x6f, 0x00, // "two"
0x83, 0xa3, 0x30, 0x39, // 12345
0x84, 0xa4, 0x68, 0x69, 0x00, // "hi"
0x82, 0x41, 0x45, 0x85, 0x1f, // 12.345,
0x83, 0x40, 0x28, 0xb0, 0xfc, 0xd3, 0x24, 0xd5, 0xa2, // 12.3456789
0x84,
0xcc, 0xaa, // Dictionary
0x86, 0xa4, 0x62, 0x6c, 0x75, 0x65, 0x00, // "blue"
0x91, 0xa7, 0x87, 0xa6, 0x43, 0x6f, 0x6c, 0x6f, 0x75, 0x72, 0x81, 0xa3, 0x81, 0xa3, 0x83, 0xa3, 0x00, 0xff,
0x87, 0xa4, 0x67, 0x72, 0x65, 0x65, 0x6e, 0x00, // "green"
0x91, 0xa7, 0x87, 0xa6, 0x43, 0x6f, 0x6c, 0x6f, 0x75, 0x72, 0x81, 0xa3, 0x83, 0xa3, 0x00, 0xff, 0x81, 0xa3,
0x85, 0xa4, 0x72, 0x65, 0x64, 0x00, // "red"
0x91, 0xa7, 0x87, 0xa6, 0x43, 0x6f, 0x6c, 0x6f, 0x75, 0x72, 0x83, 0xa3, 0x00, 0xff, 0x81, 0xa3, 0x81, 0xa3,
0x85, 0xa2, 0x41, 0x45, 0x85, 0x1f, // 12.345
0x89, 0xa2, 0x40, 0x28, 0xb0, 0xfc, 0xd3, 0x24, 0xd5, 0xa2 // 12.3456789
];
let y = deserialize_from_bytes(&expected_bytes).unwrap();
println!("== y: {:#?}", &y);
assert_eq!(v, y);
let v_bytes_1 = PackedWriter::encode_iovalue(&w).unwrap();
println!("== w bytes = {:?}", v_bytes_1);
assert_eq!(expected_bytes, v_bytes_1);
let z = BytesBinarySource::new(&v_bytes_1).packed().iovalues().demand_next().unwrap();
println!("== z: {:#?}", &z);
let y = deserialize_from_bytes(&expected_bytes).unwrap();
println!("== y: {:#?}", &y);
assert_eq!(v, y);
let mut v_bytes_2 = Vec::new();
v.serialize(&mut crate::ser::Serializer::new(&mut PackedWriter::new(&mut v_bytes_2))).unwrap();
println!("== v bytes = {:?}", v_bytes_2);

View File

@ -1,7 +1,7 @@
use serde::Serialize;
use super::value::IOValueDomainCodec;
use super::value::boundary as B;
use super::value::writer::{Writer, CompoundWriter};
use super::value::writer::Writer;
pub use super::error::Error;
type Result<T> = std::result::Result<T, Error>;
@ -17,22 +17,21 @@ impl<'w, W: Writer> Serializer<'w, W> {
}
}
enum SequenceVariant<W: Writer> {
Sequence(W::SeqWriter),
Record(W::RecWriter),
enum SequenceVariant {
Sequence,
Record,
}
pub struct SerializeCompound<'a, 'w, W: Writer> {
b: B::Type,
i: B::Item,
ser: &'a mut Serializer<'w, W>,
c: SequenceVariant<W>,
variant: SequenceVariant,
}
pub struct SerializeDictionary<'a, 'w, W: Writer> {
b: B::Type,
ser: &'a mut Serializer<'w, W>,
d: W::DictWriter,
}
impl<'a, 'w, W: Writer> serde::Serializer for &'a mut Serializer<'w, W> {
@ -91,13 +90,13 @@ impl<'a, 'w, W: Writer> serde::Serializer for &'a mut Serializer<'w, W> {
}
fn serialize_char(self, v: char) -> Result<Self::Ok> {
let mut c = self.write.start_record(Some(1))?;
c.boundary(&B::start(B::Item::RecordLabel))?;
c.write_symbol("UnicodeScalar")?;
c.boundary(&B::mid(B::Item::RecordLabel, B::Item::RecordField))?;
c.write_u32(v as u32)?;
c.boundary(&B::end(B::Item::RecordField))?;
Ok(self.write.end_record(c)?)
self.write.start_record()?;
self.write.boundary(&B::start(B::Item::RecordLabel))?;
self.write.write_symbol("UnicodeScalar")?;
self.write.boundary(&B::mid(B::Item::RecordLabel, B::Item::RecordField))?;
self.write.write_u32(v as u32)?;
self.write.boundary(&B::end(B::Item::RecordField))?;
Ok(self.write.end_record()?)
}
fn serialize_str(self, v: &str) -> Result<Self::Ok> {
@ -109,37 +108,37 @@ impl<'a, 'w, W: Writer> serde::Serializer for &'a mut Serializer<'w, W> {
}
fn serialize_none(self) -> Result<Self::Ok> {
let mut c = self.write.start_record(Some(0))?;
c.boundary(&B::start(B::Item::RecordLabel))?;
c.write_symbol("None")?;
c.boundary(&B::end(B::Item::RecordLabel))?;
Ok(self.write.end_record(c)?)
self.write.start_record()?;
self.write.boundary(&B::start(B::Item::RecordLabel))?;
self.write.write_symbol("None")?;
self.write.boundary(&B::end(B::Item::RecordLabel))?;
Ok(self.write.end_record()?)
}
fn serialize_some<T: ?Sized>(self, v: &T) -> Result<Self::Ok> where T: Serialize {
let mut c = self.write.start_record(Some(1))?;
c.boundary(&B::start(B::Item::RecordLabel))?;
c.write_symbol("Some")?;
c.boundary(&B::mid(B::Item::RecordLabel, B::Item::RecordField))?;
to_writer(&mut c, v)?;
c.boundary(&B::end(B::Item::RecordField))?;
Ok(self.write.end_record(c)?)
self.write.start_record()?;
self.write.boundary(&B::start(B::Item::RecordLabel))?;
self.write.write_symbol("Some")?;
self.write.boundary(&B::mid(B::Item::RecordLabel, B::Item::RecordField))?;
to_writer(self.write, v)?;
self.write.boundary(&B::end(B::Item::RecordField))?;
Ok(self.write.end_record()?)
}
fn serialize_unit(self) -> Result<Self::Ok> {
let mut c = self.write.start_record(Some(0))?;
c.boundary(&B::start(B::Item::RecordLabel))?;
c.write_symbol("tuple")?;
c.boundary(&B::end(B::Item::RecordLabel))?;
Ok(self.write.end_record(c)?)
self.write.start_record()?;
self.write.boundary(&B::start(B::Item::RecordLabel))?;
self.write.write_symbol("tuple")?;
self.write.boundary(&B::end(B::Item::RecordLabel))?;
Ok(self.write.end_record()?)
}
fn serialize_unit_struct(self, name: &'static str) -> Result<Self::Ok> {
let mut c = self.write.start_record(Some(0))?;
c.boundary(&B::start(B::Item::RecordLabel))?;
c.write_symbol(name)?;
c.boundary(&B::end(B::Item::RecordLabel))?;
Ok(self.write.end_record(c)?)
self.write.start_record()?;
self.write.boundary(&B::start(B::Item::RecordLabel))?;
self.write.write_symbol(name)?;
self.write.boundary(&B::end(B::Item::RecordLabel))?;
Ok(self.write.end_record()?)
}
fn serialize_unit_variant(self,
@ -148,11 +147,11 @@ impl<'a, 'w, W: Writer> serde::Serializer for &'a mut Serializer<'w, W> {
variant_name: &'static str) ->
Result<Self::Ok>
{
let mut c = self.write.start_record(Some(0))?;
c.boundary(&B::start(B::Item::RecordLabel))?;
c.write_symbol(variant_name)?;
c.boundary(&B::end(B::Item::RecordLabel))?;
Ok(self.write.end_record(c)?)
self.write.start_record()?;
self.write.boundary(&B::start(B::Item::RecordLabel))?;
self.write.write_symbol(variant_name)?;
self.write.boundary(&B::end(B::Item::RecordLabel))?;
Ok(self.write.end_record()?)
}
fn serialize_newtype_struct<T: ?Sized>(self, name: &'static str, value: &T) ->
@ -162,13 +161,13 @@ impl<'a, 'w, W: Writer> serde::Serializer for &'a mut Serializer<'w, W> {
Some(v) => Ok(self.write.write(&mut IOValueDomainCodec, &v)?),
None => {
// TODO: This is apparently discouraged, and we should apparently just serialize `value`?
let mut c = self.write.start_record(Some(1))?;
c.boundary(&B::start(B::Item::RecordLabel))?;
c.write_symbol(name)?;
c.boundary(&B::mid(B::Item::RecordLabel, B::Item::RecordField))?;
to_writer(&mut c, value)?;
c.boundary(&B::end(B::Item::RecordField))?;
Ok(self.write.end_record(c)?)
self.write.start_record()?;
self.write.boundary(&B::start(B::Item::RecordLabel))?;
self.write.write_symbol(name)?;
self.write.boundary(&B::mid(B::Item::RecordLabel, B::Item::RecordField))?;
to_writer(self.write, value)?;
self.write.boundary(&B::end(B::Item::RecordField))?;
Ok(self.write.end_record()?)
}
}
}
@ -180,72 +179,72 @@ impl<'a, 'w, W: Writer> serde::Serializer for &'a mut Serializer<'w, W> {
value: &T) ->
Result<Self::Ok> where T: Serialize
{
let mut c = self.write.start_record(Some(1))?;
c.boundary(&B::start(B::Item::RecordLabel))?;
c.write_symbol(variant_name)?;
c.boundary(&B::mid(B::Item::RecordLabel, B::Item::RecordField))?;
to_writer(&mut c, value)?;
c.boundary(&B::end(B::Item::RecordField))?;
Ok(self.write.end_record(c)?)
self.write.start_record()?;
self.write.boundary(&B::start(B::Item::RecordLabel))?;
self.write.write_symbol(variant_name)?;
self.write.boundary(&B::mid(B::Item::RecordLabel, B::Item::RecordField))?;
to_writer(self.write, value)?;
self.write.boundary(&B::end(B::Item::RecordField))?;
Ok(self.write.end_record()?)
}
fn serialize_seq(self, count: Option<usize>) -> Result<Self::SerializeSeq> {
let c = self.write.start_sequence(count)?;
Ok(SerializeCompound::seq(self, c))
fn serialize_seq(self, _count: Option<usize>) -> Result<Self::SerializeSeq> {
self.write.start_sequence()?;
Ok(SerializeCompound::seq(self))
}
fn serialize_tuple(self, count: usize) -> Result<Self::SerializeTuple> {
let mut c = self.write.start_record(Some(count))?;
c.boundary(&B::start(B::Item::RecordLabel))?;
c.write_symbol("tuple")?;
Ok(SerializeCompound::rec(self, c))
fn serialize_tuple(self, _count: usize) -> Result<Self::SerializeTuple> {
self.write.start_record()?;
self.write.boundary(&B::start(B::Item::RecordLabel))?;
self.write.write_symbol("tuple")?;
Ok(SerializeCompound::rec(self))
}
fn serialize_tuple_struct(self, name: &'static str, count: usize) ->
fn serialize_tuple_struct(self, name: &'static str, _count: usize) ->
Result<Self::SerializeTupleStruct>
{
let mut c = self.write.start_record(Some(count))?;
c.boundary(&B::start(B::Item::RecordLabel))?;
c.write_symbol(name)?;
Ok(SerializeCompound::rec(self, c))
self.write.start_record()?;
self.write.boundary(&B::start(B::Item::RecordLabel))?;
self.write.write_symbol(name)?;
Ok(SerializeCompound::rec(self))
}
fn serialize_tuple_variant(self,
_name: &'static str,
_variant: u32,
variant_name: &'static str,
count: usize) ->
_count: usize) ->
Result<Self::SerializeTupleVariant>
{
let mut c = self.write.start_record(Some(count))?;
c.boundary(&B::start(B::Item::RecordLabel))?;
c.write_symbol(variant_name)?;
Ok(SerializeCompound::rec(self, c))
self.write.start_record()?;
self.write.boundary(&B::start(B::Item::RecordLabel))?;
self.write.write_symbol(variant_name)?;
Ok(SerializeCompound::rec(self))
}
fn serialize_map(self, count: Option<usize>) -> Result<Self::SerializeMap> {
let d = self.write.start_dictionary(count)?;
Ok(SerializeDictionary { b: B::Type::default(), ser: self, d })
fn serialize_map(self, _count: Option<usize>) -> Result<Self::SerializeMap> {
self.write.start_dictionary()?;
Ok(SerializeDictionary { b: B::Type::default(), ser: self })
}
fn serialize_struct(self, name: &'static str, count: usize) -> Result<Self::SerializeStruct> {
let mut c = self.write.start_record(Some(count))?;
c.boundary(&B::start(B::Item::RecordLabel))?;
c.write_symbol(name)?;
Ok(SerializeCompound::rec(self, c))
fn serialize_struct(self, name: &'static str, _count: usize) -> Result<Self::SerializeStruct> {
self.write.start_record()?;
self.write.boundary(&B::start(B::Item::RecordLabel))?;
self.write.write_symbol(name)?;
Ok(SerializeCompound::rec(self))
}
fn serialize_struct_variant(self,
_name: &'static str,
_variant: u32,
variant_name: &'static str,
count: usize) ->
_count: usize) ->
Result<Self::SerializeStructVariant>
{
let mut c = self.write.start_record(Some(count))?;
c.boundary(&B::start(B::Item::RecordLabel))?;
c.write_symbol(variant_name)?;
Ok(SerializeCompound::rec(self, c))
self.write.start_record()?;
self.write.boundary(&B::start(B::Item::RecordLabel))?;
self.write.write_symbol(variant_name)?;
Ok(SerializeCompound::rec(self))
}
}
@ -255,42 +254,42 @@ impl<'a, 'w, W: Writer> serde::ser::SerializeMap for SerializeDictionary<'a, 'w,
fn serialize_key<T: ?Sized>(&mut self, key: &T) -> Result<()> where T: Serialize {
self.b.opening = Some(B::Item::DictionaryKey);
self.d.boundary(&self.b)?;
to_writer(&mut self.d, key)?;
self.ser.write.boundary(&self.b)?;
to_writer(self.ser.write, key)?;
self.b.shift(None);
Ok(())
}
fn serialize_value<T: ?Sized>(&mut self, value: &T) -> Result<()> where T: Serialize {
self.b.opening = Some(B::Item::DictionaryValue);
self.d.boundary(&self.b)?;
to_writer(&mut self.d, value)?;
self.ser.write.boundary(&self.b)?;
to_writer(self.ser.write, value)?;
self.b.shift(None);
Ok(())
}
fn end(mut self) -> Result<Self::Ok> {
self.d.boundary(&self.b)?;
Ok(self.ser.write.end_dictionary(self.d)?)
fn end(self) -> Result<Self::Ok> {
self.ser.write.boundary(&self.b)?;
Ok(self.ser.write.end_dictionary()?)
}
}
impl<'a, 'w, W: Writer> SerializeCompound<'a, 'w, W> {
fn seq(ser: &'a mut Serializer<'w, W>, c: W::SeqWriter) -> Self {
fn seq(ser: &'a mut Serializer<'w, W>) -> Self {
SerializeCompound {
b: B::Type::default(),
i: B::Item::SequenceValue,
ser,
c: SequenceVariant::Sequence(c),
variant: SequenceVariant::Sequence,
}
}
fn rec(ser: &'a mut Serializer<'w, W>, c: W::RecWriter) -> Self {
fn rec(ser: &'a mut Serializer<'w, W>) -> Self {
SerializeCompound {
b: B::end(B::Item::RecordLabel),
i: B::Item::RecordField,
ser,
c: SequenceVariant::Record(c),
variant: SequenceVariant::Record,
}
}
@ -298,23 +297,21 @@ impl<'a, 'w, W: Writer> SerializeCompound<'a, 'w, W> {
where T: Serialize
{
self.b.opening = Some(self.i.clone());
match &mut self.c {
SequenceVariant::Sequence(w) => { w.boundary(&self.b)?; to_writer(w, value)?; }
SequenceVariant::Record(w) => { w.boundary(&self.b)?; to_writer(w, value)?; }
}
self.ser.write.boundary(&self.b)?;
to_writer(self.ser.write, value)?;
self.b.shift(None);
Ok(())
}
fn complete(self) -> Result<()> {
match self.c {
SequenceVariant::Sequence(mut w) => {
w.boundary(&self.b)?;
Ok(self.ser.write.end_sequence(w)?)
match self.variant {
SequenceVariant::Sequence => {
self.ser.write.boundary(&self.b)?;
Ok(self.ser.write.end_sequence()?)
}
SequenceVariant::Record(mut w) => {
w.boundary(&self.b)?;
Ok(self.ser.write.end_record(w)?)
SequenceVariant::Record => {
self.ser.write.boundary(&self.b)?;
Ok(self.ser.write.end_record()?)
}
}
}

View File

@ -1,6 +1,6 @@
use crate::value::repr::{Float, Double};
use crate::value::{Value, NestedValue, IOValue, UnwrappedIOValue, Map};
use crate::error::{Error, ExpectedKind, Received};
use crate::value::{Value, NestedValue, IOValue, Map};
use crate::error::Error;
use serde::Deserialize;
use serde::de::{Visitor, SeqAccess, MapAccess, EnumAccess, VariantAccess, DeserializeSeed};
use std::iter::Iterator;
@ -11,7 +11,7 @@ pub struct Deserializer<'de> {
input: &'de IOValue,
}
pub fn from_value<'a, T>(v: &'a IOValue) -> Result<T> where T: Deserialize<'a>
pub fn from_value<'de, T>(v: &'de IOValue) -> Result<T> where T: Deserialize<'de>
{
let mut de = Deserializer::from_value(v);
let t = T::deserialize(&mut de)?;
@ -22,13 +22,6 @@ impl<'de> Deserializer<'de> {
pub fn from_value(v: &'de IOValue) -> Self {
Deserializer { input: v }
}
fn check<'a, T, F>(&'a mut self, f: F, k: ExpectedKind) -> Result<T>
where F: FnOnce(&'de UnwrappedIOValue) -> Option<T>
{
f(self.input.value()).ok_or_else(
|| Error::Expected(k, Received::ReceivedOtherValue(format!("{:?}", self.input))))
}
}
impl<'de, 'a> serde::de::Deserializer<'de> for &'a mut Deserializer<'de>
@ -42,7 +35,7 @@ impl<'de, 'a> serde::de::Deserializer<'de> for &'a mut Deserializer<'de>
Value::Boolean(b) => visitor.visit_bool(*b),
Value::Float(Float(f)) => visitor.visit_f32(*f),
Value::Double(Double(d)) => visitor.visit_f64(*d),
Value::String(ref s) => visitor.visit_str(&s),
Value::String(s) => visitor.visit_str(&s),
Value::ByteString(_) => self.deserialize_bytes(visitor),
Value::Record(_) =>
if v.is_simple_record("tuple", Some(0)) {
@ -139,8 +132,7 @@ impl<'de, 'a> serde::de::Deserializer<'de> for &'a mut Deserializer<'de>
fn deserialize_str<V>(self, visitor: V) -> Result<V::Value> where V: Visitor<'de>
{
let s: &'de str = &self.input.value().to_string()?;
visitor.visit_borrowed_str(s)
visitor.visit_borrowed_str(self.input.value().to_string()?)
}
fn deserialize_string<V>(self, visitor: V) -> Result<V::Value> where V: Visitor<'de>
@ -150,8 +142,7 @@ impl<'de, 'a> serde::de::Deserializer<'de> for &'a mut Deserializer<'de>
fn deserialize_bytes<V>(self, visitor: V) -> Result<V::Value> where V: Visitor<'de>
{
let bs: &'de [u8] = &self.input.value().to_bytestring()?;
visitor.visit_borrowed_bytes(bs)
visitor.visit_borrowed_bytes(self.input.value().to_bytestring()?)
}
fn deserialize_byte_buf<V>(self, visitor: V) -> Result<V::Value> where V: Visitor<'de>
@ -293,7 +284,7 @@ pub struct DictMap<'a, 'de: 'a> {
impl<'de, 'a> DictMap<'a, 'de> {
fn new(de: &'a mut Deserializer<'de>, d: &'de Map<IOValue, IOValue>) -> Self {
DictMap{ pending: None, iter: Box::new(d.iter()), de }
DictMap { pending: None, iter: Box::new(d.iter()), de }
}
}
@ -328,7 +319,7 @@ impl<'a, '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 r = self.check(|v| v.as_record(None), ExpectedKind::Record(None))?;
let r = self.input.value().to_record(None)?;
let v = self.input;
self.input = r.label();
let variant = seed.deserialize(&mut *self)?;
@ -345,7 +336,7 @@ impl<'a, 'de> VariantAccess<'de> for &'a mut Deserializer<'de> {
}
fn newtype_variant_seed<T>(self, seed: T) -> Result<T::Value> where T: DeserializeSeed<'de> {
let r = self.check(|v| v.as_record(Some(1)), ExpectedKind::Record(Some(1)))?;
let r = self.input.value().to_record(Some(1))?;
self.input = &r.fields()[0];
seed.deserialize(&mut *self)
}

View File

@ -1,24 +1,14 @@
use std::io;
use super::BinarySource;
use super::BytesBinarySource;
use super::Embeddable;
use super::IOValue;
use super::Reader;
use super::Writer;
use super::packed;
pub trait DomainParse<D: Embeddable> {
fn parse_embedded(
&mut self,
v: &IOValue,
) -> io::Result<D>;
}
pub trait DomainDecode<D: Embeddable> {
fn decode_embedded<'de, 'src, S: BinarySource<'de>>(
fn decode_embedded<'de, 'r, R: Reader<'de>>(
&mut self,
src: &'src mut S,
r: &'r mut R,
read_annotations: bool,
) -> io::Result<D>;
}
@ -31,34 +21,15 @@ pub trait DomainEncode<D: Embeddable> {
) -> io::Result<()>;
}
impl<'a, D: Embeddable, T: DomainParse<D>> DomainParse<D> for &'a mut T {
fn parse_embedded(
&mut self,
v: &IOValue,
) -> io::Result<D> {
(**self).parse_embedded(v)
}
}
impl<'a, D: Embeddable, T: DomainDecode<D>> DomainDecode<D> for &'a mut T {
fn decode_embedded<'de, 'src, S: BinarySource<'de>>(
&mut self,
src: &'src mut S,
read_annotations: bool,
) -> io::Result<D> {
(**self).decode_embedded(src, read_annotations)
}
}
pub struct IOValueDomainCodec;
impl DomainDecode<IOValue> for IOValueDomainCodec {
fn decode_embedded<'de, 'src, S: BinarySource<'de>>(
fn decode_embedded<'de, 'r, R: Reader<'de>>(
&mut self,
src: &'src mut S,
r: &'r mut R,
read_annotations: bool,
) -> io::Result<IOValue> {
packed::PackedReader::new(src, IOValueDomainCodec).demand_next(read_annotations)
r.demand_next(read_annotations, self)
}
}
@ -75,9 +46,9 @@ impl DomainEncode<IOValue> for IOValueDomainCodec {
pub struct NoEmbeddedDomainCodec;
impl<D: Embeddable> DomainDecode<D> for NoEmbeddedDomainCodec {
fn decode_embedded<'de, 'src, S: BinarySource<'de>>(
fn decode_embedded<'de, 'r, R: Reader<'de>>(
&mut self,
_src: &'src mut S,
_r: &'r mut R,
_read_annotations: bool,
) -> io::Result<D> {
Err(io::Error::new(io::ErrorKind::Unsupported, "Embedded values not supported here"))
@ -93,32 +64,3 @@ impl<D: Embeddable> DomainEncode<D> for NoEmbeddedDomainCodec {
Err(io::Error::new(io::ErrorKind::Unsupported, "Embedded values not supported here"))
}
}
pub struct ViaCodec<C>(C);
impl<C> ViaCodec<C> {
pub fn new(c: C) -> Self {
ViaCodec(c)
}
}
impl<D: Embeddable, C: DomainDecode<D>> DomainParse<D> for ViaCodec<C> {
fn parse_embedded(
&mut self,
v: &IOValue,
) -> io::Result<D> {
let bs = packed::PackedWriter::encode_iovalue(v)?;
self.0.decode_embedded(&mut BytesBinarySource::new(&bs), true)
}
}
impl<D: Embeddable, C: DomainParse<D>> DomainDecode<D> for ViaCodec<C> {
fn decode_embedded<'de, 'src, S: BinarySource<'de>>(
&mut self,
src: &'src mut S,
read_annotations: bool,
) -> io::Result<D> {
let v = src.packed(IOValueDomainCodec).demand_next(read_annotations)?;
self.0.parse_embedded(&v)
}
}

View File

@ -0,0 +1,85 @@
use std::borrow::Cow;
use std::cell::RefCell;
use std::io;
#[derive(Eq, Debug)]
pub struct IOList {
chunks: RefCell<Vec<Vec<u8>>>,
len: usize,
}
impl IOList {
pub fn new() -> Self {
IOList {
chunks: RefCell::new(Vec::new()),
len: 0,
}
}
fn rightmost_chunk(&mut self) -> &mut Vec<u8> {
let cs = self.chunks.get_mut();
if cs.is_empty() {
cs.push(Vec::new());
}
cs.last_mut().unwrap()
}
fn consolidate(&self) {
if self.chunks.borrow().len() != 1 {
let bs = self.chunks.replace(Vec::new()).concat();
self.chunks.borrow_mut().push(bs);
}
}
pub fn len(&mut self) -> usize {
self.len
}
pub fn write(&mut self, b: u8) {
self.rightmost_chunk().push(b);
self.len += 1;
}
#[inline(always)]
pub fn write_all(&mut self, cow: Cow<'_, [u8]>) {
self.len += cow.len();
match cow {
Cow::Borrowed(bs) => self.chunks.get_mut().push(bs.to_owned()),
Cow::Owned(bs) => self.chunks.get_mut().push(bs),
}
}
pub fn append(&mut self, mut iol: IOList) {
self.len += iol.len();
self.chunks.get_mut().append(&mut iol.chunks.take());
}
pub fn write_to<W: io::Write>(self, mut w: W) -> io::Result<()> {
for chunk in self.chunks.take() {
w.write_all(&chunk)?;
}
Ok(())
}
}
impl std::cmp::PartialEq for IOList {
fn eq(&self, other: &Self) -> bool {
self.consolidate();
other.consolidate();
self.chunks.borrow().last().unwrap() == other.chunks.borrow().last().unwrap()
}
}
impl std::cmp::Ord for IOList {
fn cmp(&self, other: &Self) -> std::cmp::Ordering {
self.consolidate();
other.consolidate();
self.chunks.borrow().last().unwrap().cmp(other.chunks.borrow().last().unwrap())
}
}
impl std::cmp::PartialOrd for IOList {
fn partial_cmp(&self, other: &Self) -> Option<std::cmp::Ordering> {
Some(self.cmp(other))
}
}

View File

@ -1,12 +1,14 @@
pub mod boundary;
pub mod de;
pub mod domain;
pub mod iolist;
pub mod magic;
pub mod packed;
pub mod reader;
pub mod repr;
pub mod ser;
pub mod signed_integer;
pub mod source;
pub mod suspendable;
pub mod text;
pub mod writer;
@ -16,17 +18,12 @@ pub use de::Deserializer;
pub use de::from_value;
pub use domain::DomainDecode;
pub use domain::DomainEncode;
pub use domain::DomainParse;
pub use domain::IOValueDomainCodec;
pub use domain::NoEmbeddedDomainCodec;
pub use domain::ViaCodec;
pub use merge::merge;
pub use packed::PackedReader;
pub use packed::PackedWriter;
pub use reader::BinarySource;
pub use reader::BytesBinarySource;
pub use reader::ConfiguredReader;
pub use reader::IOBinarySource;
pub use reader::Reader;
pub use reader::Token;
pub use repr::AnnotatedValue;
@ -50,6 +47,9 @@ pub use repr::Value;
pub use repr::ValueClass;
pub use ser::Serializer;
pub use ser::to_value;
pub use source::BinarySource;
pub use source::BytesBinarySource;
pub use source::IOBinarySource;
pub use text::TextReader;
pub use text::TextWriter;
pub use writer::Writer;

View File

@ -6,12 +6,6 @@ pub enum Tag {
False,
True,
Float,
Double,
End,
Annotation,
Embedded,
SmallInteger(i8),
MediumInteger(u8),
SignedInteger,
String,
ByteString,
@ -20,6 +14,8 @@ pub enum Tag {
Sequence,
Set,
Dictionary,
Embedded,
Annotation,
}
#[derive(Debug, PartialEq, Eq)]
@ -41,24 +37,19 @@ impl TryFrom<u8> for Tag {
type Error = InvalidTag;
fn try_from(v: u8) -> Result<Self, Self::Error> {
match v {
0x80 => Ok(Self::False),
0x81 => Ok(Self::True),
0x82 => Ok(Self::Float),
0x83 => Ok(Self::Double),
0x84 => Ok(Self::End),
0x85 => Ok(Self::Annotation),
0x86 => Ok(Self::Embedded),
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),
0xa0 => Ok(Self::False),
0xa1 => Ok(Self::True),
0xa2 => Ok(Self::Float),
0xa3 => Ok(Self::SignedInteger),
0xa4 => Ok(Self::String),
0xa5 => Ok(Self::ByteString),
0xa6 => Ok(Self::Symbol),
0xa7 => Ok(Self::Record),
0xa8 => Ok(Self::Sequence),
0xa9 => Ok(Self::Set),
0xaa => Ok(Self::Dictionary),
0xab => Ok(Self::Embedded),
0xbf => Ok(Self::Annotation),
_ => Err(InvalidTag(v))
}
}
@ -67,23 +58,19 @@ impl TryFrom<u8> for Tag {
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::Embedded => 0x86,
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,
Tag::False => 0xa0,
Tag::True => 0xa1,
Tag::Float => 0xa2,
Tag::SignedInteger => 0xa3,
Tag::String => 0xa4,
Tag::ByteString => 0xa5,
Tag::Symbol => 0xa6,
Tag::Record => 0xa7,
Tag::Sequence => 0xa8,
Tag::Set => 0xa9,
Tag::Dictionary => 0xaa,
Tag::Embedded => 0xab,
Tag::Annotation => 0xbf,
}
}
}

View File

@ -11,22 +11,22 @@ use super::{BinarySource, DomainDecode, IOValue, IOValueDomainCodec, NestedValue
pub fn from_bytes<N: NestedValue, Dec: DomainDecode<N::Embedded>>(
bs: &[u8],
decode_embedded: Dec,
decode_embedded: &mut Dec,
) -> io::Result<N> {
super::BytesBinarySource::new(bs).packed(decode_embedded).demand_next(false)
super::BytesBinarySource::new(bs).packed().demand_next(false, decode_embedded)
}
pub fn iovalue_from_bytes(bs: &[u8]) -> io::Result<IOValue> {
from_bytes(bs, IOValueDomainCodec)
from_bytes(bs, &mut IOValueDomainCodec)
}
pub fn annotated_from_bytes<N: NestedValue, Dec: DomainDecode<N::Embedded>>(
bs: &[u8],
decode_embedded: Dec,
decode_embedded: &mut Dec,
) -> io::Result<N> {
super::BytesBinarySource::new(bs).packed(decode_embedded).demand_next(true)
super::BytesBinarySource::new(bs).packed().demand_next(true, decode_embedded)
}
pub fn annotated_iovalue_from_bytes(bs: &[u8]) -> io::Result<IOValue> {
annotated_from_bytes(bs, IOValueDomainCodec)
annotated_from_bytes(bs, &mut IOValueDomainCodec)
}

View File

@ -1,4 +1,4 @@
use crate::error::{self, ExpectedKind, Received, is_eof_io_error, io_syntax_error};
use crate::error::{self, ExpectedKind, io_eof, io_syntax_error};
use num::bigint::BigInt;
use num::traits::cast::{FromPrimitive, ToPrimitive};
@ -6,6 +6,7 @@ use num::traits::cast::{FromPrimitive, ToPrimitive};
use std::borrow::Cow;
use std::convert::TryFrom;
use std::convert::TryInto;
use std::fmt::Debug;
use std::io;
use std::marker::PhantomData;
@ -15,6 +16,7 @@ use super::super::{
DomainDecode,
Map,
NestedValue,
NoEmbeddedDomainCodec,
Record,
Set,
Value,
@ -22,116 +24,294 @@ use super::super::{
boundary as B,
reader::{
Token,
BinarySource,
Reader,
ReaderResult,
},
repr::Annotations,
signed_integer::SignedInteger,
source::BinarySource,
};
pub struct PackedReader<'de, 'src, N: NestedValue, Dec: DomainDecode<N::Embedded>, S: BinarySource<'de>> {
pub source: &'src mut S,
pub decode_embedded: Dec,
phantom: PhantomData<&'de N>,
#[derive(Debug)]
enum Continuation {
Skip { count: Option<u64> },
Sequence { count: Option<u64> },
}
impl<'de, 'src, N: NestedValue, Dec: DomainDecode<N::Embedded>, S: BinarySource<'de>>
BinarySource<'de>
for PackedReader<'de, 'src, N, Dec, S>
{
type Mark = S::Mark;
pub struct PackedReaderSource<'de, 'src, S: BinarySource<'de>> {
pub source: &'src mut S,
stack: Vec<Continuation>,
count: Option<u64>,
expect_length: bool,
phantom: PhantomData<&'de ()>,
}
// TODO: inline PackedReaderSource.
pub struct PackedReader<'de, 'src, S: BinarySource<'de>> {
pub source: PackedReaderSource<'de, 'src, S>,
}
pub struct ReaderMark<SourceMark> {
source_mark: SourceMark,
stack_len: usize,
count: Option<u64>,
expect_length: bool,
}
impl<'de, 'src, S: BinarySource<'de>> PackedReaderSource<'de, 'src, S> {
fn advance(&mut self, delta: u64) -> bool {
if let Some(ref mut c) = self.count {
if *c < delta {
return false;
}
*c -= delta;
}
return true;
}
fn advance_or_eof(&mut self, delta: u64) -> io::Result<()> {
if self.advance(delta) { Ok(()) } else { Err(io_eof()) }
}
pub fn set_expected_count(&mut self, expected_count: u64) {
match self.count {
Some(n) =>
panic!("Attempt to set_expected_count to {} when count already {}",
expected_count,
n),
None =>
self.count = Some(expected_count),
}
}
#[inline(always)]
fn peek_noeof(&mut self) -> io::Result<u8> {
self.peek()?.ok_or_else(|| io_eof())
}
#[inline(always)]
fn read(&mut self) -> io::Result<u8> {
let v = self.peek_noeof()?;
self.skip()?;
Ok(v)
}
#[inline(always)]
fn varint(&mut self) -> io::Result<u64> {
let mut acc = self.read()? as u64;
if acc & 0x80 != 0 { return Ok(acc - 0x80) }
loop {
if acc & 0xfe0000000000000 != 0 {
return Err(io_syntax_error("Varint length marker overflow"));
}
acc <<= 7;
let v = self.read()? as u64;
if v & 0x80 != 0 { return Ok(acc + v - 0x80) }
acc += v;
}
}
fn narrow_to_len(&mut self) -> io::Result<Option<u64>> {
let item_len = self.varint()?;
if !self.advance(item_len) {
return Err(io_syntax_error("Bad item length"));
}
let remaining = self.count;
self.count = Some(item_len);
Ok(remaining)
}
fn narrow(&mut self) -> io::Result<()> {
if !self.expect_length {
self.expect_length = true; // after the first value, always true!
} else {
let count = self.narrow_to_len()?;
self.stack.push(Continuation::Sequence { count });
}
Ok(())
}
fn narrow_to_annotated_value(&mut self) -> io::Result<()> {
let count = self.narrow_to_len()?;
self.stack.push(Continuation::Skip { count });
Ok(())
}
fn widen<R: Debug>(&mut self, r: R) -> io::Result<R> {
loop {
match self.stack.pop() {
None => break,
Some(Continuation::Skip { count }) => match count {
Some(n) => self.source.discard(n)?,
None => { self.source.read_to_end()?; }
}
Some(Continuation::Sequence { count }) => {
self.count = count;
break;
}
}
}
Ok(r)
}
#[inline(always)]
fn read_signed_integer(&mut self) -> io::Result<SignedInteger> {
match self.count {
Some(0) => Ok(SignedInteger::from(0_i128)),
Some(1) => Ok(SignedInteger::from(self.read()? as i8)),
None | Some(_) => self.read_long_signed_integer()
}
}
fn read_long_signed_integer(&mut self) -> io::Result<SignedInteger> {
let bs = self.read_to_end()?;
let count = bs.len();
if count == 0 {
Ok(SignedInteger::from(0_i128))
} else if (bs[0] & 0x80) == 0 {
// Positive or zero.
let mut i = 0;
while i < count && bs[i] == 0 { i += 1; }
if count - i <= 16 {
let mut buf = [0; 16];
buf[16 - (count - i)..].copy_from_slice(&bs[i..]);
Ok(SignedInteger::from(u128::from_be_bytes(buf)))
} else {
Ok(SignedInteger::from(
Cow::Owned(BigInt::from_bytes_be(num::bigint::Sign::Plus, &bs[i..]))))
}
} else {
// Negative.
let mut i = 0;
while i < count && bs[i] == 0xff { i += 1; }
if count - i <= 16 {
let mut buf = [0xff; 16];
buf[16 - (count - i)..].copy_from_slice(&bs[i..]);
Ok(SignedInteger::from(i128::from_be_bytes(buf)))
} else {
Ok(SignedInteger::from(
Cow::Owned(BigInt::from_signed_bytes_be(&bs))))
}
}
}
}
impl<'de, 'src, S: BinarySource<'de>> BinarySource<'de> for PackedReaderSource<'de, 'src, S> {
type Mark = ReaderMark<S::Mark>;
#[inline(always)]
fn mark(&mut self) -> io::Result<Self::Mark> {
self.source.mark()
Ok(ReaderMark {
source_mark: self.source.mark()?,
stack_len: self.stack.len(),
count: self.count,
expect_length: self.expect_length,
})
}
#[inline(always)]
fn restore(&mut self, mark: &Self::Mark) -> io::Result<()> {
self.source.restore(mark)
let ReaderMark { source_mark, stack_len, count, expect_length } = mark;
if *stack_len > self.stack.len() {
panic!("Attempt to restore state to longer stack ({}) than exists ({})",
stack_len,
self.stack.len());
}
self.stack.truncate(*stack_len);
self.source.restore(source_mark)?;
self.count = *count;
self.expect_length = *expect_length;
Ok(())
}
#[inline(always)]
fn skip(&mut self) -> io::Result<()> {
self.advance_or_eof(1)?;
self.source.skip()
}
#[inline(always)]
fn peek(&mut self) -> io::Result<u8> {
self.source.peek()
fn peek(&mut self) -> io::Result<Option<u8>> {
match self.count {
Some(0) => Ok(None),
_ => self.source.peek(),
}
}
#[inline(always)]
fn readbytes(&mut self, count: usize) -> io::Result<Cow<'de, [u8]>> {
fn discard(&mut self, count: u64) -> io::Result<()> {
self.advance_or_eof(count)?;
self.source.discard(count)
}
#[inline(always)]
fn readbytes(&mut self, count: u64) -> io::Result<Cow<'de, [u8]>> {
self.advance_or_eof(count)?;
self.source.readbytes(count)
}
#[inline(always)]
fn readbytes_into(&mut self, bs: &mut [u8]) -> io::Result<()> {
self.advance_or_eof(bs.len() as u64)?;
self.source.readbytes_into(bs)
}
#[inline(always)]
fn read_to_end(&mut self) -> io::Result<Cow<'de, [u8]>> {
match self.count {
Some(n) => self.readbytes(n),
None => self.source.read_to_end(),
}
}
}
fn out_of_range<I: Into<BigInt>>(i: I) -> error::Error {
error::Error::NumberOutOfRange(i.into())
}
impl<'de, 'src, N: NestedValue, Dec: DomainDecode<N::Embedded>, S: BinarySource<'de>> PackedReader<'de, 'src, N, Dec, S> {
impl<'de, 'src, S: BinarySource<'de>> PackedReader<'de, 'src, S> {
#[inline(always)]
pub fn new(source: &'src mut S, decode_embedded: Dec) -> Self {
PackedReader { source, decode_embedded, phantom: PhantomData }
pub fn new(source: &'src mut S) -> Self {
PackedReader {
source: PackedReaderSource {
source,
stack: Vec::new(),
count: None,
expect_length: false,
phantom: PhantomData,
},
}
}
#[inline(always)]
fn read(&mut self) -> io::Result<u8> {
let v = self.peek()?;
self.skip()?;
Ok(v)
fn peek_tag(&mut self) -> io::Result<Tag> {
Ok(Tag::try_from(self.source.peek_noeof()?)?)
}
#[inline(always)]
fn read_tag(&mut self) -> io::Result<Tag> {
Ok(Tag::try_from(self.source.read()?)?)
}
fn expected(&mut self, k: ExpectedKind) -> error::Error {
match self.demand_next(true) {
Ok(v) => error::Error::Expected(k, Received::ReceivedOtherValue(format!("{:?}", v))),
Err(e) => e.into()
}
error::Error::Expected(k)
}
#[inline(always)]
fn varint(&mut self) -> io::Result<usize> {
let mut shift = 0;
let mut acc: usize = 0;
fn next_nonannotation_tag(&mut self) -> io::Result<Tag> {
self.source.narrow()?;
loop {
let v = self.read()?;
acc |= ((v & 0x7f) as usize) << shift;
shift += 7;
if v & 0x80 == 0 { return Ok(acc) }
}
}
#[inline(always)]
fn peekend(&mut self) -> io::Result<bool> {
if self.peek()? == Tag::End.into() {
self.skip()?;
Ok(true)
} else {
Ok(false)
}
}
#[inline(always)]
fn peek_next_nonannotation_tag(&mut self) -> ReaderResult<Tag> {
loop {
match Tag::try_from(self.peek()?)? {
Tag::Annotation => {
self.skip()?;
self.skip_value()?;
},
other => return Ok(other),
let tag = self.read_tag()?;
if tag == Tag::Annotation {
self.source.narrow_to_annotated_value()?;
} else {
return Ok(tag);
}
}
}
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)?)
if self.next_nonannotation_tag()? == expected_tag {
let bs = self.source.read_to_end()?;
Ok(self.source.widen(bs)?)
} else {
Err(self.expected(k))
}
@ -139,9 +319,7 @@ impl<'de, 'src, N: NestedValue, Dec: DomainDecode<N::Embedded>, S: BinarySource<
fn next_compound(&mut self, expected_tag: Tag, k: ExpectedKind) -> ReaderResult<()>
{
let actual_tag = self.peek_next_nonannotation_tag()?;
if actual_tag == expected_tag {
self.skip()?;
if self.next_nonannotation_tag()? == expected_tag {
Ok(())
} else {
Err(self.expected(k))
@ -149,246 +327,136 @@ impl<'de, 'src, N: NestedValue, Dec: DomainDecode<N::Embedded>, S: BinarySource<
}
#[inline(always)]
fn read_signed_integer(&mut self, count: usize) -> io::Result<SignedInteger> {
if count == 0 {
return Ok(SignedInteger::from(0_i128));
}
if count > 16 {
let bs = self.readbytes(count)?;
if (bs[0] & 0x80) == 0 {
// Positive or zero.
let mut i = 0;
while i < count && bs[i] == 0 { i += 1; }
if count - i <= 16 {
Ok(SignedInteger::from(u128::from_be_bytes(bs[bs.len() - 16..].try_into().unwrap())))
} else {
Ok(SignedInteger::from(Cow::Owned(BigInt::from_bytes_be(num::bigint::Sign::Plus, &bs[i..]))))
}
} else {
// Negative.
let mut i = 0;
while i < count && bs[i] == 0xff { i += 1; }
if count - i <= 16 {
Ok(SignedInteger::from(i128::from_be_bytes(bs[bs.len() - 16..].try_into().unwrap())))
} else {
Ok(SignedInteger::from(Cow::Owned(BigInt::from_signed_bytes_be(&bs))))
}
}
} else {
let first_byte = self.read()?;
let prefix_byte = if (first_byte & 0x80) == 0 { 0x00 } else { 0xff };
let mut bs = [prefix_byte; 16];
bs[16 - count] = first_byte;
self.readbytes_into(&mut bs[16 - (count - 1)..])?;
Ok(SignedInteger::from(i128::from_be_bytes(bs)))
}
}
#[inline(always)]
fn next_unsigned<T: FromPrimitive, F>(&mut self, f: F) -> ReaderResult<T>
fn next_unsigned<T: FromPrimitive + Debug, F>(&mut self, f: F) -> ReaderResult<T>
where
F: FnOnce(u128) -> Option<T>
{
let tag = self.peek_next_nonannotation_tag()?;
match tag {
Tag::SmallInteger(v) => {
self.skip()?;
if v < 0 {
Err(out_of_range(v))
} else {
f(v as u128).ok_or_else(|| out_of_range(v))
}
}
Tag::MediumInteger(count) => {
self.skip()?;
let n = &self.read_signed_integer(count.into())?;
let i = n.try_into().map_err(|_| out_of_range(n))?;
f(i).ok_or_else(|| out_of_range(i))
}
match self.next_nonannotation_tag()? {
Tag::SignedInteger => {
self.skip()?;
let count = self.varint()?;
let n = &self.read_signed_integer(count)?;
let n = &self.source.read_signed_integer()?;
let i = n.try_into().map_err(|_| out_of_range(n))?;
f(i).ok_or_else(|| out_of_range(i))
Ok(self.source.widen(f(i).ok_or_else(|| out_of_range(i))?)?)
}
_ => Err(self.expected(ExpectedKind::SignedInteger))
}
}
#[inline(always)]
fn next_signed<T: FromPrimitive, F>(&mut self, f: F) -> ReaderResult<T>
fn next_signed<T: FromPrimitive + Debug, F>(&mut self, f: F) -> ReaderResult<T>
where
F: FnOnce(i128) -> Option<T>
{
let tag = self.peek_next_nonannotation_tag()?;
match tag {
Tag::SmallInteger(v) => {
self.skip()?;
f(v.into()).ok_or_else(|| out_of_range(v))
}
Tag::MediumInteger(count) => {
self.skip()?;
let n = &self.read_signed_integer(count.into())?;
let i = n.try_into().map_err(|_| out_of_range(n))?;
f(i).ok_or_else(|| out_of_range(i))
}
match self.next_nonannotation_tag()? {
Tag::SignedInteger => {
self.skip()?;
let count = self.varint()?;
let n = &self.read_signed_integer(count)?;
let n = &self.source.read_signed_integer()?;
let i = n.try_into().map_err(|_| out_of_range(n))?;
f(i).ok_or_else(|| out_of_range(i))
Ok(self.source.widen(f(i).ok_or_else(|| out_of_range(i))?)?)
}
_ => Err(self.expected(ExpectedKind::SignedInteger))
}
}
fn gather_annotations(&mut self) -> io::Result<Vec<N>> {
let mut annotations = vec![self.demand_next(true)?];
while Tag::try_from(self.peek()?)? == Tag::Annotation {
self.skip()?;
annotations.push(self.demand_next(true)?);
}
Ok(annotations)
}
fn skip_annotations(&mut self) -> io::Result<()> {
self.skip_value()?;
while Tag::try_from(self.peek()?)? == Tag::Annotation {
self.skip()?;
self.skip_value()?;
}
Ok(())
}
fn next_upto_end(&mut self, read_annotations: bool) -> io::Result<Option<N>> {
match self.peekend()? {
true => Ok(None),
false => Ok(Some(self.demand_next(read_annotations)?)),
fn _next<N: NestedValue, Dec: DomainDecode<N::Embedded>>(
&mut self,
read_annotations: bool,
decode_embedded: &mut Dec,
) -> io::Result<N> {
loop {
return Ok(match self.read_tag()? {
Tag::False => N::new(false),
Tag::True => N::new(true),
Tag::Float => {
let bs = self.source.read_to_end()?;
match bs.len() {
4 => Value::from(f32::from_bits(u32::from_be_bytes((&bs[..]).try_into().unwrap()))).wrap(),
8 => Value::from(f64::from_bits(u64::from_be_bytes((&bs[..]).try_into().unwrap()))).wrap(),
_ => Err(io_syntax_error("Invalid floating-point width"))?,
}
}
Tag::SignedInteger => Value::SignedInteger(self.source.read_signed_integer()?).wrap(),
Tag::String => Value::String(decode_nul_str(self.source.read_to_end()?)?.into_owned()).wrap(),
Tag::ByteString => Value::ByteString(self.source.read_to_end()?.into_owned()).wrap(),
Tag::Symbol => Value::Symbol(decodestr(self.source.read_to_end()?)?.into_owned()).wrap(),
Tag::Record => {
let mut vs = Vec::new();
while let Some(v) = self.next(read_annotations, decode_embedded)? {
vs.push(v);
}
if vs.is_empty() {
return Err(io_syntax_error("Too few elements in encoded record"))
}
Value::Record(Record(vs)).wrap()
}
Tag::Sequence => {
let mut vs = Vec::new();
while let Some(v) = self.next(read_annotations, decode_embedded)? {
vs.push(v);
}
Value::Sequence(vs).wrap()
}
Tag::Set => {
let mut s = Set::new();
while let Some(v) = self.next(read_annotations, decode_embedded)? {
s.insert(v);
}
Value::Set(s).wrap()
}
Tag::Dictionary => {
let mut d = Map::new();
while let Some(k) = self.next(read_annotations, decode_embedded)? {
match self.next(read_annotations, decode_embedded)? {
Some(v) => { d.insert(k, v); }
None => return Err(io_syntax_error("Missing dictionary value")),
}
}
Value::Dictionary(d).wrap()
}
Tag::Embedded => Value::Embedded(
decode_embedded.decode_embedded(self, read_annotations)?).wrap(),
Tag::Annotation => {
if read_annotations {
let underlying: Option<N> = self.next(read_annotations, decode_embedded)?;
match underlying {
Some(v) => {
let mut vs = Vec::new();
while let Some(v) = self.next(read_annotations, decode_embedded)? {
vs.push(v);
}
let (mut existing_annotations, v) = v.pieces();
existing_annotations.modify(|ws| ws.extend_from_slice(&vs[..]));
N::wrap(existing_annotations, v)
}
None => return Err(io_syntax_error("Missing value in encoded annotation")),
}
} else {
self.source.narrow_to_annotated_value()?;
continue;
}
}
});
}
}
}
impl<'de, 'src, N: NestedValue, Dec: DomainDecode<N::Embedded>, S: BinarySource<'de>>
Reader<'de, N>
for PackedReader<'de, 'src, N, Dec, S>
{
fn next(&mut self, read_annotations: bool) -> io::Result<Option<N>> {
match self.peek() {
Err(e) if is_eof_io_error(&e) => return Ok(None),
Err(e) => return Err(e),
Ok(_) => (),
impl<'de, 'src, S: BinarySource<'de>> Reader<'de> for PackedReader<'de, 'src, S> {
fn next<N: NestedValue, Dec: DomainDecode<N::Embedded>>(
&mut self,
read_annotations: bool,
decode_embedded: &mut Dec,
) -> io::Result<Option<N>> {
match self.source.peek()? {
None => Ok(None),
Some(_) => {
self.source.narrow()?;
let v = self._next(read_annotations, decode_embedded)?;
self.source.widen(Some(v))
}
}
Ok(Some(match Tag::try_from(self.read()?)? {
Tag::False => N::new(false),
Tag::True => N::new(true),
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 = self.gather_annotations()?;
let (existing_annotations, v) = self.demand_next(read_annotations)?.pieces();
annotations.extend_from_slice(existing_annotations.slice());
N::wrap(Annotations::new(Some(annotations)), v)
} else {
self.skip_annotations()?;
self.demand_next(read_annotations)?
}
}
Tag::Embedded => {
Value::Embedded(self.decode_embedded.decode_embedded(self.source, read_annotations)?).wrap()
}
Tag::SmallInteger(v) => {
// TODO: prebuild these in value.rs
Value::from(v).wrap()
}
Tag::MediumInteger(count) => {
let n = self.read_signed_integer(count.into())?;
Value::SignedInteger(n).wrap()
}
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 mut vs = Vec::new();
while let Some(v) = self.next_upto_end(read_annotations)? { vs.push(v); }
if vs.is_empty() {
return Err(io_syntax_error("Too few elements in encoded record"))
}
Value::Record(Record(vs)).wrap()
}
Tag::Sequence => {
let mut vs = Vec::new();
while let Some(v) = self.next_upto_end(read_annotations)? { vs.push(v); }
Value::Sequence(vs).wrap()
}
Tag::Set => {
let mut s = Set::new();
while let Some(v) = self.next_upto_end(read_annotations)? { s.insert(v); }
Value::Set(s).wrap()
}
Tag::Dictionary => {
let mut d = Map::new();
while let Some(k) = self.next_upto_end(read_annotations)? {
match self.next_upto_end(read_annotations)? {
Some(v) => { 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)));
}
}))
}
#[inline(always)]
fn open_record(&mut self, arity: Option<usize>) -> ReaderResult<B::Type> {
self.next_compound(Tag::Record, ExpectedKind::Record(arity))?;
let mut b = B::Type::default();
self.ensure_more_expected(&mut b, &B::Item::RecordLabel)?;
Ok(b)
}
#[inline(always)]
fn open_sequence_or_set(&mut self) -> ReaderResult<B::Item> {
match self.peek_next_nonannotation_tag()? {
Tag::Sequence => {
self.skip()?;
Ok(B::Item::SequenceValue)
}
Tag::Set => {
self.skip()?;
Ok(B::Item::SetValue)
}
_ =>
Err(self.expected(ExpectedKind::SequenceOrSet)),
}
fn open_record(&mut self) -> ReaderResult<()> {
self.next_compound(Tag::Record, ExpectedKind::Record)
}
#[inline(always)]
@ -413,7 +481,11 @@ impl<'de, 'src, N: NestedValue, Dec: DomainDecode<N::Embedded>, S: BinarySource<
#[inline(always)]
fn close_compound(&mut self, _b: &mut B::Type, _i: &B::Item) -> ReaderResult<bool> {
Ok(self.peekend()?)
if self.source.peek()?.is_none() {
Ok(self.source.widen(true)?)
} else {
Ok(false)
}
}
#[inline(always)]
@ -423,95 +495,82 @@ impl<'de, 'src, N: NestedValue, Dec: DomainDecode<N::Embedded>, S: BinarySource<
#[inline(always)]
fn close_embedded(&mut self) -> ReaderResult<()> {
Ok(())
Ok(self.source.widen(())?)
}
type Mark = S::Mark;
type Mark = <PackedReaderSource<'de, 'src, S> as BinarySource<'de>>::Mark;
#[inline(always)]
fn mark(&mut self) -> io::Result<Self::Mark> {
self.source.mark()
BinarySource::mark(&mut self.source)
}
#[inline(always)]
fn restore(&mut self, mark: &Self::Mark) -> io::Result<()> {
self.source.restore(mark)
BinarySource::restore(&mut self.source, mark)
}
fn next_token(&mut self, read_embedded_annotations: bool) -> io::Result<Token<N>> {
loop {
return Ok(match Tag::try_from(self.peek()?)? {
Tag::Embedded => {
self.skip()?;
Token::Embedded(self.decode_embedded.decode_embedded(
self.source,
read_embedded_annotations)?)
fn next_token<N: NestedValue, Dec: DomainDecode<N::Embedded>>(
&mut self,
read_embedded_annotations: bool,
decode_embedded: &mut Dec,
) -> io::Result<Token<N>> {
match self.source.peek()? {
None => self.source.widen(Token::End),
Some(_) => {
self.source.narrow()?;
loop {
return match self.peek_tag()? {
Tag::False |
Tag::True |
Tag::Float |
Tag::SignedInteger |
Tag::String |
Tag::ByteString |
Tag::Symbol => {
let v = self._next(false, &mut NoEmbeddedDomainCodec)?;
self.source.widen(Token::Atom(v))
}
Tag::Record => { self.source.skip()?; Ok(Token::Compound(CompoundClass::Record)) }
Tag::Sequence => { self.source.skip()?; Ok(Token::Compound(CompoundClass::Sequence)) }
Tag::Set => { self.source.skip()?; Ok(Token::Compound(CompoundClass::Set)) }
Tag::Dictionary => { self.source.skip()?; Ok(Token::Compound(CompoundClass::Dictionary)) }
Tag::Embedded => {
self.source.skip()?;
let t = Token::Embedded(decode_embedded.decode_embedded(
self, read_embedded_annotations)?);
self.source.widen(t)
}
Tag::Annotation => {
self.source.skip()?;
self.source.narrow_to_annotated_value()?;
continue;
}
}
}
Tag::False |
Tag::True |
Tag::Float |
Tag::Double |
Tag::SmallInteger(_) |
Tag::MediumInteger(_) |
Tag::SignedInteger |
Tag::String |
Tag::ByteString |
Tag::Symbol =>
Token::Atom(self.demand_next(false)?),
Tag::Record => { self.skip()?; Token::Compound(CompoundClass::Record) }
Tag::Sequence => { self.skip()?; Token::Compound(CompoundClass::Sequence) }
Tag::Set => { self.skip()?; Token::Compound(CompoundClass::Set) }
Tag::Dictionary => { self.skip()?; Token::Compound(CompoundClass::Dictionary) }
Tag::End => { self.skip()?; Token::End }
Tag::Annotation => {
self.skip()?;
self.skip_annotations()?;
continue
}
})
}
}
fn next_annotations_and_token(&mut self) -> io::Result<(Vec<N>, Token<N>)> {
match Tag::try_from(self.peek()?)? {
Tag::Annotation => {
self.skip()?;
let annotations = self.gather_annotations()?;
Ok((annotations, self.next_token(true)?))
}
_ => Ok((Vec::new(), self.next_token(true)?)),
}
}
#[inline(always)]
fn next_boolean(&mut self) -> ReaderResult<bool> {
match self.peek_next_nonannotation_tag()? {
Tag::False => { self.skip()?; Ok(false) }
Tag::True => { self.skip()?; Ok(true) }
_ => Err(self.expected(ExpectedKind::Boolean)),
match self.next_nonannotation_tag()? {
Tag::False => { Ok(self.source.widen(false)?) }
Tag::True => { Ok(self.source.widen(true)?) }
_ => Err(self.expected(ExpectedKind::Boolean))?,
}
}
fn next_signedinteger(&mut self) -> ReaderResult<SignedInteger> {
let tag = self.peek_next_nonannotation_tag()?;
match tag {
Tag::SmallInteger(v) => {
self.skip()?;
Ok(SignedInteger::from(v as i32))
}
Tag::MediumInteger(count) => {
self.skip()?;
Ok(self.read_signed_integer(count.into())?)
}
match self.next_nonannotation_tag()? {
Tag::SignedInteger => {
self.skip()?;
let count = self.varint()?;
Ok(self.read_signed_integer(count)?)
}
_ => Err(self.expected(ExpectedKind::SignedInteger))
let i = self.source.read_signed_integer()?;
Ok(self.source.widen(i)?)
},
_ => Err(self.expected(ExpectedKind::SignedInteger))?
}
}
@ -528,47 +587,29 @@ impl<'de, 'src, N: NestedValue, Dec: DomainDecode<N::Embedded>, S: BinarySource<
fn next_u128(&mut self) -> ReaderResult<u128> { self.next_unsigned(|n| n.to_u128()) }
fn next_f32(&mut self) -> ReaderResult<f32> {
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)))
},
Tag::Double => {
self.skip()?;
let mut bs = [0; 8];
self.readbytes_into(&mut bs)?;
Ok(f64::from_bits(u64::from_be_bytes(bs)) as f32)
},
_ => Err(self.expected(ExpectedKind::Float)),
let bs = self.next_atomic(Tag::Float, ExpectedKind::Float)?;
match bs.len() {
4 => Ok(f32::from_bits(u32::from_be_bytes((&bs[..]).try_into().unwrap()))),
8 => Ok(f64::from_bits(u64::from_be_bytes((&bs[..]).try_into().unwrap())) as f32),
_ => Err(io_syntax_error("Invalid floating-point width"))?,
}
}
fn next_f64(&mut self) -> ReaderResult<f64> {
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)
},
Tag::Double => {
self.skip()?;
let mut bs = [0; 8];
self.readbytes_into(&mut bs)?;
Ok(f64::from_bits(u64::from_be_bytes(bs)))
},
_ => Err(self.expected(ExpectedKind::Double)),
let bs = self.next_atomic(Tag::Float, ExpectedKind::Double)?;
match bs.len() {
4 => Ok(f32::from_bits(u32::from_be_bytes((&bs[..]).try_into().unwrap())) as f64),
8 => Ok(f64::from_bits(u64::from_be_bytes((&bs[..]).try_into().unwrap()))),
_ => Err(io_syntax_error("Invalid floating-point width"))?,
}
}
fn next_str(&mut self) -> ReaderResult<Cow<'de, str>> {
Ok(decodestr(self.next_atomic(Tag::String, ExpectedKind::Symbol)?)?)
Ok(decode_nul_str(self.next_atomic(Tag::String, ExpectedKind::String)?)?)
}
fn next_bytestring(&mut self) -> ReaderResult<Cow<'de, [u8]>> {
self.next_atomic(Tag::ByteString, ExpectedKind::Symbol)
self.next_atomic(Tag::ByteString, ExpectedKind::ByteString)
}
fn next_symbol(&mut self) -> ReaderResult<Cow<'de, str>> {
@ -585,3 +626,24 @@ fn decodestr(cow: Cow<'_, [u8]>) -> io::Result<Cow<'_, str>> {
Ok(Cow::Owned(String::from_utf8(bs).map_err(|_| io_syntax_error("Invalid UTF-8"))?)),
}
}
fn check_nul(bs: &[u8]) -> io::Result<()> {
if bs.len() < 1 || bs[bs.len() - 1] != 0 {
return Err(io_syntax_error("Missing trailing NUL byte on string"));
}
Ok(())
}
fn decode_nul_str(cow: Cow<'_, [u8]>) -> io::Result<Cow<'_, str>> {
match cow {
Cow::Borrowed(bs) => {
check_nul(bs)?;
decodestr(Cow::Borrowed(&bs[0..bs.len()-1]))
}
Cow::Owned(mut bs) => {
check_nul(&bs)?;
bs.truncate(bs.len() - 1);
decodestr(Cow::Owned(bs))
}
}
}

View File

@ -1,19 +1,22 @@
use num::bigint::BigInt;
use num::cast::ToPrimitive;
use std::borrow::Cow;
use std::convert::TryInto;
use std::io;
use std::ops::DerefMut;
use super::constants::Tag;
use super::super::DomainEncode;
use super::super::IOValue;
use super::super::IOValueDomainCodec;
use super::super::NestedValue;
use super::super::boundary as B;
use super::super::suspendable::Suspendable;
use super::super::iolist::IOList;
use super::super::writer::Writer;
use super::super::writer::{Writer, CompoundWriter, varint};
pub struct PackedWriter<W: io::Write>(Suspendable<W>);
pub struct PackedWriter<W: io::Write> {
w: W,
buffer: IOList,
items: Vec<Vec<IOList>>,
}
impl PackedWriter<&mut Vec<u8>> {
#[inline(always)]
@ -32,246 +35,86 @@ impl PackedWriter<&mut Vec<u8>> {
}
}
pub fn varint(iol: &mut IOList, mut v: usize) {
loop {
if v < 128 {
iol.write((v + 0x80) as u8);
return;
} else {
iol.write((v & 0x7f) as u8);
v >>= 7;
}
}
}
impl<W: io::Write> PackedWriter<W> {
#[inline(always)]
pub fn new(write: W) -> Self {
PackedWriter(Suspendable::new(write))
PackedWriter {
w: write,
buffer: IOList::new(),
items: Vec::new(),
}
}
#[inline(always)]
pub fn w(&mut self) -> &mut W {
self.0.deref_mut()
pub fn write_byte(&mut self, b: u8) {
self.buffer.write(b)
}
#[inline(always)]
pub fn write_byte(&mut self, b: u8) -> io::Result<()> {
self.w().write_all(&[b])
pub fn write_all(&mut self, bs: &[u8]) {
self.buffer.write_all(Cow::Borrowed(bs))
}
#[inline(always)]
pub fn write_medium_integer(&mut self, bs: &[u8]) -> io::Result<()> {
let count: u8 = bs.len().try_into().unwrap();
if !(1..=16).contains(&count) { panic!("Invalid medium_integer count: {}", count) }
self.write_byte(Tag::MediumInteger(count).into())?;
self.w().write_all(bs)
pub fn write_integer(&mut self, bs: &[u8]) -> io::Result<()> {
self.write_atom(Tag::SignedInteger, bs)
}
#[inline(always)]
pub fn write_tag(&mut self, tag: Tag) {
self.write_byte(tag.into())
}
#[inline(always)]
pub fn write_atom(&mut self, tag: Tag, bs: &[u8]) -> io::Result<()> {
self.write_byte(tag.into())?;
varint(&mut self.w(), bs.len().try_into().unwrap())?;
self.w().write_all(bs)
self.write_tag(tag);
self.write_all(bs);
self.finish_item_if_toplevel()
}
#[inline(always)]
pub fn suspend(&mut self) -> Self {
PackedWriter(self.0.suspend())
}
#[inline(always)]
pub fn resume(&mut self, other: Self) {
self.0.resume(other.0)
}
}
pub struct BinaryOrderWriter(Vec<Vec<u8>>);
impl BinaryOrderWriter {
#[inline(always)]
fn new() -> Self {
BinaryOrderWriter(vec![vec![]])
}
#[inline(always)]
fn pop(&mut self) -> PackedWriter<Vec<u8>> {
PackedWriter::new(self.0.pop().unwrap())
}
#[inline(always)]
fn push(&mut self, w: PackedWriter<Vec<u8>>) {
self.0.push(w.0.take())
}
#[inline(always)]
fn items(&self) -> &Vec<Vec<u8>> {
&self.0
}
#[inline(always)]
fn items_mut(&mut self) -> &mut Vec<Vec<u8>> {
&mut self.0
}
#[inline(always)]
fn buffer(&mut self) -> &mut Vec<u8> {
self.0.last_mut().unwrap()
}
#[inline(always)]
fn finish<W: WriteWriter>(mut self, w: &mut W) -> io::Result<()> {
if !self.buffer().is_empty() { panic!("Missing final boundary()"); }
self.items_mut().pop();
self.items_mut().sort();
for bs in self.items() {
w.write_raw_bytes(&bs)?;
pub fn finish_item(&mut self) -> io::Result<()> {
let buffer = std::mem::replace(&mut self.buffer, IOList::new());
match self.items.last_mut() {
Some(iols) => Ok(iols.push(buffer)),
None => buffer.write_to(&mut self.w),
}
w.write_tag(Tag::End)?;
Ok(())
}
}
pub trait WriteWriter: Writer {
fn write_raw_bytes(&mut self, v: &[u8]) -> io::Result<()>;
#[inline(always)]
fn write_tag(&mut self, tag: Tag) -> io::Result<()> {
self.write_raw_bytes(&[tag.into()])
}
}
impl<W: io::Write> WriteWriter for PackedWriter<W> {
#[inline(always)]
fn write_raw_bytes(&mut self, v: &[u8]) -> io::Result<()> {
self.w().write_all(v)
}
}
impl WriteWriter for BinaryOrderWriter {
#[inline(always)]
fn write_raw_bytes(&mut self, v: &[u8]) -> io::Result<()> {
use io::Write;
self.buffer().write_all(v)
}
}
impl<W: io::Write> CompoundWriter for PackedWriter<W> {
#[inline(always)]
fn boundary(&mut self, b: &B::Type) -> io::Result<()> {
if let Some(B::Item::Annotation) = b.opening {
self.write_tag(Tag::Annotation)?;
pub fn finish_item_if_toplevel(&mut self) -> io::Result<()> {
if self.items.is_empty() {
self.finish_item()?;
}
Ok(())
}
}
impl CompoundWriter for BinaryOrderWriter {
#[inline(always)]
fn boundary(&mut self, b: &B::Type) -> io::Result<()> {
match b.closing {
Some(B::Item::DictionaryValue) |
Some(B::Item::RecordField) |
Some(B::Item::SequenceValue) |
Some(B::Item::SetValue) =>
self.items_mut().push(vec![]),
_ =>
()
pub fn start_seq(&mut self) -> io::Result<()> {
self.items.push(Vec::new());
Ok(())
}
pub fn finish_seq(&mut self, tag: Tag, sort: bool) -> io::Result<()> {
let mut items = self.items.pop().unwrap();
if sort {
items.sort();
}
Ok(())
}
}
macro_rules! binary_order_writer_method {
(mut $n:ident ($($argname:ident : $argty:ty),*) -> $retty:ty) =>
(#[inline(always)] fn $n (&mut self, $($argname : $argty),*) -> $retty {
(&mut PackedWriter::new(self.buffer())).$n($($argname),*)
});
}
impl Writer for BinaryOrderWriter {
type AnnWriter = PackedWriter<Vec<u8>>;
type RecWriter = PackedWriter<Vec<u8>>;
type SeqWriter = PackedWriter<Vec<u8>>;
type SetWriter = BinaryOrderWriter;
type DictWriter = BinaryOrderWriter;
type EmbeddedWriter = PackedWriter<Vec<u8>>;
#[inline(always)]
fn start_annotations(&mut self) -> io::Result<Self::AnnWriter> {
Ok(self.pop())
}
#[inline(always)]
fn end_annotations(&mut self, ann: Self::AnnWriter) -> io::Result<()> {
self.push(ann);
Ok(())
}
binary_order_writer_method!(mut write_bool(v: bool) -> io::Result<()>);
binary_order_writer_method!(mut write_f32(v: f32) -> io::Result<()>);
binary_order_writer_method!(mut write_f64(v: f64) -> io::Result<()>);
binary_order_writer_method!(mut write_i8(v: i8) -> io::Result<()>);
binary_order_writer_method!(mut write_u8(v: u8) -> io::Result<()>);
binary_order_writer_method!(mut write_i16(v: i16) -> io::Result<()>);
binary_order_writer_method!(mut write_u16(v: u16) -> io::Result<()>);
binary_order_writer_method!(mut write_i32(v: i32) -> io::Result<()>);
binary_order_writer_method!(mut write_u32(v: u32) -> io::Result<()>);
binary_order_writer_method!(mut write_i64(v: i64) -> io::Result<()>);
binary_order_writer_method!(mut write_u64(v: u64) -> io::Result<()>);
binary_order_writer_method!(mut write_i128(v: i128) -> io::Result<()>);
binary_order_writer_method!(mut write_u128(v: u128) -> io::Result<()>);
binary_order_writer_method!(mut write_int(v: &BigInt) -> io::Result<()>);
binary_order_writer_method!(mut write_string(v: &str) -> io::Result<()>);
binary_order_writer_method!(mut write_bytes(v: &[u8]) -> io::Result<()>);
binary_order_writer_method!(mut write_symbol(v: &str) -> io::Result<()>);
#[inline(always)]
fn start_record(&mut self, _field_count: Option<usize>) -> io::Result<Self::RecWriter> {
self.write_tag(Tag::Record)?;
Ok(self.pop())
}
#[inline(always)]
fn end_record(&mut self, rec: Self::RecWriter) -> io::Result<()> {
self.push(rec);
self.write_tag(Tag::End)
}
#[inline(always)]
fn start_sequence(&mut self, _item_count: Option<usize>) -> io::Result<Self::SeqWriter> {
self.write_tag(Tag::Sequence)?;
Ok(self.pop())
}
#[inline(always)]
fn end_sequence(&mut self, seq: Self::SeqWriter) -> io::Result<()> {
self.push(seq);
self.write_tag(Tag::End)
}
#[inline(always)]
fn start_set(&mut self, _item_count: Option<usize>) -> io::Result<Self::SetWriter> {
self.write_tag(Tag::Set)?;
Ok(BinaryOrderWriter::new())
}
#[inline(always)]
fn end_set(&mut self, set: Self::SetWriter) -> io::Result<()> {
set.finish(self)
}
#[inline(always)]
fn start_dictionary(&mut self, _entry_count: Option<usize>) -> io::Result<Self::DictWriter> {
self.write_tag(Tag::Dictionary)?;
Ok(BinaryOrderWriter::new())
}
#[inline(always)]
fn end_dictionary(&mut self, dict: Self::DictWriter) -> io::Result<()> {
dict.finish(self)
}
#[inline(always)]
fn start_embedded(&mut self) -> io::Result<Self::EmbeddedWriter> {
self.write_tag(Tag::Embedded)?;
Ok(self.pop())
}
#[inline(always)]
fn end_embedded(&mut self, ptr: Self::EmbeddedWriter) -> io::Result<()> {
self.push(ptr);
Ok(())
}
#[inline(always)]
fn flush(&mut self) -> io::Result<()> {
Ok(())
self.write_tag(tag);
for mut i in items {
varint(&mut self.buffer, i.len());
self.buffer.append(i);
}
self.finish_item_if_toplevel()
}
}
@ -284,162 +127,171 @@ macro_rules! fits_in_bytes {
impl<W: io::Write> Writer for PackedWriter<W>
{
type AnnWriter = Self;
type RecWriter = Self;
type SeqWriter = Self;
type SetWriter = BinaryOrderWriter;
type DictWriter = BinaryOrderWriter;
type EmbeddedWriter = Self;
#[inline(always)]
fn start_annotations(&mut self) -> io::Result<Self::AnnWriter> {
Ok(self.suspend())
fn boundary(&mut self, b: &B::Type) -> io::Result<()> {
match (b.closing.as_ref(), b.opening.as_ref()) {
(Some(_), _) =>
self.finish_item(),
(None, _) =>
Ok(()),
}
}
#[inline(always)]
fn end_annotations(&mut self, ann: Self::AnnWriter) -> io::Result<()> {
self.resume(ann);
Ok(())
fn start_annotations(&mut self) -> io::Result<()> {
self.start_seq()
}
#[inline(always)]
fn end_annotations(&mut self) -> io::Result<()> {
self.items.last_mut().unwrap().rotate_right(1);
self.finish_seq(Tag::Annotation, false)
}
#[inline(always)]
fn write_bool(&mut self, v: bool) -> io::Result<()> {
self.write_tag(if v { Tag::True } else { Tag::False })
self.write_tag(if v { Tag::True } else { Tag::False });
self.finish_item_if_toplevel()
}
#[inline(always)]
fn write_f32(&mut self, v: f32) -> io::Result<()> {
self.write_tag(Tag::Float)?;
self.write_raw_bytes(&u32::to_be_bytes(f32::to_bits(v)))
self.write_tag(Tag::Float);
self.write_all(&u32::to_be_bytes(f32::to_bits(v)));
self.finish_item_if_toplevel()
}
#[inline(always)]
fn write_f64(&mut self, v: f64) -> io::Result<()> {
self.write_tag(Tag::Double)?;
self.write_raw_bytes(&u64::to_be_bytes(f64::to_bits(v)))
self.write_tag(Tag::Float);
self.write_all(&u64::to_be_bytes(f64::to_bits(v)));
self.finish_item_if_toplevel()
}
#[inline(always)]
fn write_i8(&mut self, v: i8) -> io::Result<()> {
if v >= -3 && v <= 12 { return self.write_tag(Tag::SmallInteger(v)) }
self.write_medium_integer(&[v as u8])
if v == 0 {
self.write_integer(&[])
} else {
self.write_integer(&[v as u8])
}
}
#[inline(always)]
fn write_u8(&mut self, v: u8) -> io::Result<()> {
if let Ok(w) = v.try_into() { return self.write_i8(w) }
self.write_medium_integer(&[0, v])
self.write_integer(&[0, v])
}
#[inline(always)]
fn write_i16(&mut self, v: i16) -> io::Result<()> {
if let Ok(w) = v.try_into() { return self.write_i8(w) }
self.write_medium_integer(&[(v >> 8) as u8, (v & 255) as u8])
self.write_integer(&[(v >> 8) as u8, (v & 255) as u8])
}
#[inline(always)]
fn write_u16(&mut self, v: u16) -> io::Result<()> {
if let Ok(w) = v.try_into() { return self.write_i16(w) }
self.write_medium_integer(&[0, (v >> 8) as u8, (v & 255) as u8])
self.write_integer(&[0, (v >> 8) as u8, (v & 255) as u8])
}
#[inline(always)]
fn write_i32(&mut self, v: i32) -> io::Result<()> {
if let Ok(w) = v.try_into() { return self.write_i16(w) }
if fits_in_bytes!(v, 3) {
return self.write_medium_integer(&[(v >> 16) as u8,
(v >> 8) as u8,
(v & 255) as u8]);
return self.write_integer(&[(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])
self.write_integer(&[(v >> 24) as u8,
(v >> 16) as u8,
(v >> 8) as u8,
(v & 255) as u8])
}
#[inline(always)]
fn write_u32(&mut self, v: u32) -> io::Result<()> {
if let Ok(w) = v.try_into() { return self.write_i32(w) }
self.write_medium_integer(&[0,
(v >> 24) as u8,
(v >> 16) as u8,
(v >> 8) as u8,
(v & 255) as u8])
self.write_integer(&[0,
(v >> 24) as u8,
(v >> 16) as u8,
(v >> 8) as u8,
(v & 255) as u8])
}
#[inline(always)]
fn write_i64(&mut self, v: i64) -> io::Result<()> {
if let Ok(w) = v.try_into() { return self.write_i32(w) }
if fits_in_bytes!(v, 5) {
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]);
return self.write_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 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]);
return self.write_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 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 self.write_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]);
}
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])
self.write_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])
}
#[inline(always)]
fn write_u64(&mut self, v: u64) -> io::Result<()> {
if let Ok(w) = v.try_into() { return self.write_i64(w) }
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])
self.write_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])
}
#[inline(always)]
fn write_i128(&mut self, v: i128) -> io::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 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)
if fits_in_bytes!(v, 9) { return self.write_integer(&bs[7..]); }
if fits_in_bytes!(v, 10) { return self.write_integer(&bs[6..]); }
if fits_in_bytes!(v, 11) { return self.write_integer(&bs[5..]); }
if fits_in_bytes!(v, 12) { return self.write_integer(&bs[4..]); }
if fits_in_bytes!(v, 13) { return self.write_integer(&bs[3..]); }
if fits_in_bytes!(v, 14) { return self.write_integer(&bs[2..]); }
if fits_in_bytes!(v, 15) { return self.write_integer(&bs[1..]); }
self.write_integer(&bs)
}
#[inline(always)]
fn write_u128(&mut self, v: u128) -> io::Result<()> {
if let Ok(w) = v.try_into() { return self.write_i128(w) }
let bs: [u8; 16] = v.to_be_bytes();
self.write_tag(Tag::SignedInteger)?;
varint(&mut self.w(), 17)?;
self.write_byte(0)?;
self.write_raw_bytes(&bs)
self.write_tag(Tag::SignedInteger);
self.write_byte(0);
self.write_all(&bs);
Ok(())
}
#[inline(always)]
@ -457,7 +309,10 @@ impl<W: io::Write> Writer for PackedWriter<W>
#[inline(always)]
fn write_string(&mut self, v: &str) -> io::Result<()> {
self.write_atom(Tag::String, v.as_bytes())
self.write_tag(Tag::String);
self.write_all(v.as_bytes());
self.write_byte(0);
self.finish_item_if_toplevel()
}
#[inline(always)]
@ -471,65 +326,84 @@ impl<W: io::Write> Writer for PackedWriter<W>
}
#[inline(always)]
fn start_record(&mut self, _field_count: Option<usize>) -> io::Result<Self::RecWriter> {
self.write_tag(Tag::Record)?;
Ok(self.suspend())
fn start_record(&mut self) -> io::Result<()> {
self.start_seq()
}
#[inline(always)]
fn end_record(&mut self, rec: Self::RecWriter) -> io::Result<()> {
self.resume(rec);
self.write_tag(Tag::End)
fn end_record(&mut self) -> io::Result<()> {
self.finish_seq(Tag::Record, false)
}
#[inline(always)]
fn start_sequence(&mut self, _item_count: Option<usize>) -> io::Result<Self::SeqWriter> {
self.write_tag(Tag::Sequence)?;
Ok(self.suspend())
fn start_sequence(&mut self) -> io::Result<()> {
self.start_seq()
}
#[inline(always)]
fn end_sequence(&mut self, seq: Self::SeqWriter) -> io::Result<()> {
self.resume(seq);
self.write_tag(Tag::End)
fn end_sequence(&mut self) -> io::Result<()> {
self.finish_seq(Tag::Sequence, false)
}
#[inline(always)]
fn start_set(&mut self, _item_count: Option<usize>) -> io::Result<Self::SetWriter> {
self.write_tag(Tag::Set)?;
Ok(BinaryOrderWriter::new())
fn start_set(&mut self) -> io::Result<()> {
self.start_seq()
}
#[inline(always)]
fn end_set(&mut self, set: Self::SetWriter) -> io::Result<()> {
set.finish(self)
fn end_set(&mut self) -> io::Result<()> {
self.finish_seq(Tag::Set, true)
}
#[inline(always)]
fn start_dictionary(&mut self, _entry_count: Option<usize>) -> io::Result<Self::DictWriter> {
self.write_tag(Tag::Dictionary)?;
Ok(BinaryOrderWriter::new())
fn start_dictionary(&mut self) -> io::Result<()> {
self.start_seq()
}
#[inline(always)]
fn end_dictionary(&mut self, dict: Self::DictWriter) -> io::Result<()> {
dict.finish(self)
fn end_dictionary(&mut self) -> io::Result<()> {
let mut items_iter = self.items.pop().unwrap().into_iter();
let mut chunks = vec![];
while let Some(ki) = items_iter.next() {
match items_iter.next() {
Some(vi) => chunks.push((ki, vi)),
None => panic!("Missing dictionary value during serialization"),
}
}
chunks.sort();
self.write_tag(Tag::Dictionary);
for (mut ki, mut vi) in chunks {
varint(&mut self.buffer, ki.len());
self.buffer.append(ki);
varint(&mut self.buffer, vi.len());
self.buffer.append(vi);
}
Ok(())
}
#[inline(always)]
fn start_embedded(&mut self) -> io::Result<Self::EmbeddedWriter> {
self.write_tag(Tag::Embedded)?;
Ok(self.suspend())
fn start_embedded(&mut self) -> io::Result<()> {
self.write_tag(Tag::Embedded);
Ok(())
}
#[inline(always)]
fn end_embedded(&mut self, ann: Self::EmbeddedWriter) -> io::Result<()> {
self.resume(ann);
fn end_embedded(&mut self) -> io::Result<()> {
Ok(())
}
#[inline(always)]
fn flush(&mut self) -> io::Result<()> {
self.0.flush()
if self.buffer.len() != 0 { panic!("Attempt to flush with unfinished item in buffer"); }
self.w.flush()
}
fn write<N: NestedValue, Enc: DomainEncode<N::Embedded>>(
&mut self,
enc: &mut Enc,
v: &N,
) -> io::Result<()> {
self.inner_write(enc, v)?;
self.finish_item_if_toplevel()
}
}

View File

@ -1,4 +1,4 @@
use crate::error::{self, ExpectedKind, Received, io_eof};
use crate::error::{self, ExpectedKind, io_eof};
use std::borrow::Cow;
use std::io;
@ -6,18 +6,18 @@ use std::marker::PhantomData;
use super::CompoundClass;
use super::DomainDecode;
use super::DomainParse;
use super::Double;
use super::DummyValue;
use super::Float;
use super::IOValue;
use super::IOValueDomainCodec;
use super::NestedValue;
use super::ViaCodec;
use super::boundary as B;
use super::signed_integer::SignedInteger;
pub type ReaderResult<T> = std::result::Result<T, error::Error>;
#[derive(Debug)]
pub enum Token<N: NestedValue> {
Embedded(N::Embedded),
Atom(N),
@ -25,16 +25,21 @@ pub enum Token<N: NestedValue> {
End,
}
pub trait Reader<'de, N: NestedValue> {
fn next(&mut self, read_annotations: bool) -> io::Result<Option<N>>;
fn open_record(&mut self, arity: Option<usize>) -> ReaderResult<B::Type>;
fn open_sequence_or_set(&mut self) -> ReaderResult<B::Item>;
fn open_sequence(&mut self) -> ReaderResult<()>;
fn open_set(&mut self) -> ReaderResult<()>;
fn open_dictionary(&mut self) -> ReaderResult<()>;
pub trait Reader<'de> {
fn next<N: NestedValue, Dec: DomainDecode<N::Embedded>>(
&mut self,
read_annotations: bool,
decode_embedded: &mut Dec,
) -> io::Result<Option<N>>;
fn open_record(&mut self) -> ReaderResult<()>; // followed by label, then fields
fn open_sequence(&mut self) -> ReaderResult<()>; // followed by items
fn open_set(&mut self) -> ReaderResult<()>; // followed by items
fn open_dictionary(&mut self) -> ReaderResult<()>; // followed by key/value pairs
fn boundary(&mut self, b: &B::Type) -> ReaderResult<()>;
// close_compound implies a b.shift(...) and a self.boundary(b).
// Answers true for closed, false for more.
// Implies a b.shift of None if closed or of Some(i) if not closed, plus a .boundary.
fn close_compound(&mut self, b: &mut B::Type, i: &B::Item) -> ReaderResult<bool>;
fn open_embedded(&mut self) -> ReaderResult<()>;
@ -44,103 +49,107 @@ pub trait Reader<'de, N: NestedValue> {
fn mark(&mut self) -> io::Result<Self::Mark>;
fn restore(&mut self, mark: &Self::Mark) -> io::Result<()>;
fn next_token(&mut self, read_embedded_annotations: bool) -> io::Result<Token<N>>;
fn next_annotations_and_token(&mut self) -> io::Result<(Vec<N>, Token<N>)>;
fn next_token<N: NestedValue, Dec: DomainDecode<N::Embedded>>(
&mut self,
read_embedded_annotations: bool,
decode_embedded: &mut Dec,
) -> io::Result<Token<N>>;
//---------------------------------------------------------------------------
fn skip_value(&mut self) -> io::Result<()> {
// TODO efficient skipping in specific impls of this trait
let _ = self.demand_next(false)?;
let _: DummyValue<IOValue> = self.demand_next(false, &mut IOValueDomainCodec)?;
Ok(())
}
fn demand_next(&mut self, read_annotations: bool) -> io::Result<N> {
self.next(read_annotations)?.ok_or_else(io_eof)
fn next_iovalue(&mut self, read_annotations: bool) -> io::Result<IOValue> {
self.demand_next(read_annotations, &mut IOValueDomainCodec)
}
fn demand_next<N: NestedValue, Dec: DomainDecode<N::Embedded>>(
&mut self,
read_annotations: bool,
decode_embedded: &mut Dec,
) -> io::Result<N> {
self.next(read_annotations, decode_embedded)?.ok_or_else(io_eof)
}
fn next_boolean(&mut self) -> ReaderResult<bool> {
self.demand_next(false)?.value().to_boolean()
self.next_iovalue(false)?.value().to_boolean()
}
fn next_float(&mut self) -> ReaderResult<Float> {
Ok(self.demand_next(false)?.value().to_float()?.to_owned())
Ok(self.next_iovalue(false)?.value().to_float()?.to_owned())
}
fn next_double(&mut self) -> ReaderResult<Double> {
Ok(self.demand_next(false)?.value().to_double()?.to_owned())
Ok(self.next_iovalue(false)?.value().to_double()?.to_owned())
}
fn next_signedinteger(&mut self) -> ReaderResult<SignedInteger> {
Ok(self.demand_next(false)?.value().to_signedinteger()?.to_owned())
Ok(self.next_iovalue(false)?.value().to_signedinteger()?.to_owned())
}
fn next_i8(&mut self) -> ReaderResult<i8> { self.demand_next(false)?.value().to_i8() }
fn next_u8(&mut self) -> ReaderResult<u8> { self.demand_next(false)?.value().to_u8() }
fn next_i16(&mut self) -> ReaderResult<i16> { self.demand_next(false)?.value().to_i16() }
fn next_u16(&mut self) -> ReaderResult<u16> { self.demand_next(false)?.value().to_u16() }
fn next_i32(&mut self) -> ReaderResult<i32> { self.demand_next(false)?.value().to_i32() }
fn next_u32(&mut self) -> ReaderResult<u32> { self.demand_next(false)?.value().to_u32() }
fn next_i64(&mut self) -> ReaderResult<i64> { self.demand_next(false)?.value().to_i64() }
fn next_u64(&mut self) -> ReaderResult<u64> { self.demand_next(false)?.value().to_u64() }
fn next_i128(&mut self) -> ReaderResult<i128> { self.demand_next(false)?.value().to_i128() }
fn next_u128(&mut self) -> ReaderResult<u128> { self.demand_next(false)?.value().to_u128() }
fn next_f32(&mut self) -> ReaderResult<f32> { self.demand_next(false)?.value().to_f32() }
fn next_f64(&mut self) -> ReaderResult<f64> { self.demand_next(false)?.value().to_f64() }
fn next_char(&mut self) -> ReaderResult<char> { self.demand_next(false)?.value().to_char() }
fn next_i8(&mut self) -> ReaderResult<i8> { self.next_iovalue(false)?.value().to_i8() }
fn next_u8(&mut self) -> ReaderResult<u8> { self.next_iovalue(false)?.value().to_u8() }
fn next_i16(&mut self) -> ReaderResult<i16> { self.next_iovalue(false)?.value().to_i16() }
fn next_u16(&mut self) -> ReaderResult<u16> { self.next_iovalue(false)?.value().to_u16() }
fn next_i32(&mut self) -> ReaderResult<i32> { self.next_iovalue(false)?.value().to_i32() }
fn next_u32(&mut self) -> ReaderResult<u32> { self.next_iovalue(false)?.value().to_u32() }
fn next_i64(&mut self) -> ReaderResult<i64> { self.next_iovalue(false)?.value().to_i64() }
fn next_u64(&mut self) -> ReaderResult<u64> { self.next_iovalue(false)?.value().to_u64() }
fn next_i128(&mut self) -> ReaderResult<i128> { self.next_iovalue(false)?.value().to_i128() }
fn next_u128(&mut self) -> ReaderResult<u128> { self.next_iovalue(false)?.value().to_u128() }
fn next_f32(&mut self) -> ReaderResult<f32> { self.next_iovalue(false)?.value().to_f32() }
fn next_f64(&mut self) -> ReaderResult<f64> { self.next_iovalue(false)?.value().to_f64() }
fn next_char(&mut self) -> ReaderResult<char> { self.next_iovalue(false)?.value().to_char() }
fn next_str(&mut self) -> ReaderResult<Cow<'de, str>> {
Ok(Cow::Owned(self.demand_next(false)?.value().to_string()?.to_owned()))
Ok(Cow::Owned(self.next_iovalue(false)?.value().to_string()?.to_owned()))
}
fn next_bytestring(&mut self) -> ReaderResult<Cow<'de, [u8]>> {
Ok(Cow::Owned(self.demand_next(false)?.value().to_bytestring()?.to_owned()))
Ok(Cow::Owned(self.next_iovalue(false)?.value().to_bytestring()?.to_owned()))
}
fn next_symbol(&mut self) -> ReaderResult<Cow<'de, str>> {
Ok(Cow::Owned(self.demand_next(false)?.value().to_symbol()?.to_owned()))
Ok(Cow::Owned(self.next_iovalue(false)?.value().to_symbol()?.to_owned()))
}
fn open_option(&mut self) -> ReaderResult<Option<B::Type>>
fn open_simple_record(&mut self, name: &str) -> ReaderResult<()>
{
let b = self.open_record(None)?;
let label: &str = &self.next_symbol()?;
match label {
"None" => {
self.ensure_complete(b, &B::Item::RecordField)?;
Ok(None)
}
"Some" =>
Ok(Some(b)),
_ =>
Err(error::Error::Expected(ExpectedKind::Option,
Received::ReceivedRecordWithLabel(label.to_owned()))),
}
}
fn open_simple_record(&mut self, name: &str, arity: Option<usize>) -> ReaderResult<B::Type>
{
let b = self.open_record(arity)?;
let b = self.open_record()?;
let label: &str = &self.next_symbol()?;
if label == name {
Ok(b)
} else {
Err(error::Error::Expected(ExpectedKind::SimpleRecord(name.to_owned(), arity),
Received::ReceivedRecordWithLabel(label.to_owned())))
Err(error::Error::Expected(ExpectedKind::SimpleRecord(name.to_owned())))
}
}
fn configured(self, read_annotations: bool) -> ConfiguredReader<'de, N, Self>
fn configured<N: NestedValue, Dec: DomainDecode<N::Embedded>>(
self,
read_annotations: bool,
decode_embedded: Dec,
) -> ConfiguredReader<'de, N, Dec, Self>
where
Self: std::marker::Sized
{
ConfiguredReader {
reader: self,
read_annotations,
decode_embedded,
phantom: PhantomData,
}
}
fn iovalues(self) -> ConfiguredReader<'de, IOValue, IOValueDomainCodec, Self>
where Self: Sized
{
self.configured(true, IOValueDomainCodec)
}
fn ensure_more_expected(&mut self, b: &mut B::Type, i: &B::Item) -> ReaderResult<()> {
if !self.close_compound(b, i)? {
Ok(())
@ -158,17 +167,17 @@ pub trait Reader<'de, N: NestedValue> {
}
}
impl<'r, 'de, N: NestedValue, R: Reader<'de, N>> Reader<'de, N> for &'r mut R {
fn next(&mut self, read_annotations: bool) -> io::Result<Option<N>> {
(*self).next(read_annotations)
impl<'r, 'de, R: Reader<'de>> Reader<'de> for &'r mut R {
fn next<N: NestedValue, Dec: DomainDecode<N::Embedded>>(
&mut self,
read_annotations: bool,
decode_embedded: &mut Dec,
) -> io::Result<Option<N>> {
(*self).next(read_annotations, decode_embedded)
}
fn open_record(&mut self, arity: Option<usize>) -> ReaderResult<B::Type> {
(*self).open_record(arity)
}
fn open_sequence_or_set(&mut self) -> ReaderResult<B::Item> {
(*self).open_sequence_or_set()
fn open_record(&mut self) -> ReaderResult<()> {
(*self).open_record()
}
fn open_sequence(&mut self) -> ReaderResult<()> {
@ -209,210 +218,50 @@ impl<'r, 'de, N: NestedValue, R: Reader<'de, N>> Reader<'de, N> for &'r mut R {
(*self).restore(mark)
}
fn next_token(&mut self, read_embedded_annotations: bool) -> io::Result<Token<N>> {
(*self).next_token(read_embedded_annotations)
}
fn next_annotations_and_token(&mut self) -> io::Result<(Vec<N>, Token<N>)> {
(*self).next_annotations_and_token()
}
}
pub trait BinarySource<'de>: Sized {
type Mark;
fn mark(&mut self) -> io::Result<Self::Mark>;
fn restore(&mut self, mark: &Self::Mark) -> io::Result<()>;
fn skip(&mut self) -> io::Result<()>;
fn peek(&mut self) -> io::Result<u8>;
fn readbytes(&mut self, count: usize) -> io::Result<Cow<'de, [u8]>>;
fn readbytes_into(&mut self, bs: &mut [u8]) -> io::Result<()>;
fn packed<N: NestedValue, Dec: DomainDecode<N::Embedded>>(
fn next_token<N: NestedValue, Dec: DomainDecode<N::Embedded>>(
&mut self,
decode_embedded: Dec,
) -> super::PackedReader<'de, '_, N, Dec, Self> {
super::PackedReader::new(self, decode_embedded)
}
fn packed_iovalues(&mut self) ->
super::PackedReader<'de, '_, IOValue, IOValueDomainCodec, Self>
{
self.packed(IOValueDomainCodec)
}
fn text<N: NestedValue, Dec: DomainParse<N::Embedded>>(
&mut self,
decode_embedded: Dec,
) -> super::TextReader<'de, '_, N::Embedded, Dec, Self> {
super::TextReader::new(self, decode_embedded)
}
fn text_iovalues(&mut self) ->
super::TextReader<'de, '_, IOValue, ViaCodec<IOValueDomainCodec>, Self>
{
self.text::<IOValue, _>(ViaCodec::new(IOValueDomainCodec))
read_embedded_annotations: bool,
decode_embedded: &mut Dec,
) -> io::Result<Token<N>> {
(*self).next_token(read_embedded_annotations, decode_embedded)
}
}
pub struct IOBinarySource<R: io::Read + io::Seek> {
pub read: R,
pub buf: Option<u8>,
}
impl<R: io::Read + io::Seek> IOBinarySource<R> {
#[inline(always)]
pub fn new(read: R) -> Self {
IOBinarySource { read, buf: None }
}
}
impl<'de, R: io::Read + io::Seek> BinarySource<'de> for IOBinarySource<R> {
type Mark = u64;
#[inline(always)]
fn mark(&mut self) -> io::Result<Self::Mark> {
Ok(self.read.stream_position()? - (if self.buf.is_some() { 1 } else { 0 }))
}
#[inline(always)]
fn restore(&mut self, mark: &Self::Mark) -> io::Result<()> {
self.read.seek(io::SeekFrom::Start(*mark))?;
self.buf = None;
Ok(())
}
#[inline(always)]
fn skip(&mut self) -> io::Result<()> {
if self.buf.is_none() { unreachable!(); }
self.buf = None;
Ok(())
}
#[inline(always)]
fn peek(&mut self) -> io::Result<u8> {
match self.buf {
Some(b) => Ok(b),
None => {
let b = &mut [0];
match self.read.read(b)? {
0 => Err(io_eof()),
1 => {
self.buf = Some(b[0]);
Ok(b[0])
}
_ => unreachable!(),
}
}
}
}
#[inline(always)]
fn readbytes(&mut self, count: usize) -> io::Result<Cow<'de, [u8]>> {
if self.buf.is_some() { unreachable!(); }
let mut bs = vec![0; count];
self.read.read_exact(&mut bs)?;
Ok(Cow::Owned(bs))
}
#[inline(always)]
fn readbytes_into(&mut self, bs: &mut [u8]) -> io::Result<()> {
if self.buf.is_some() { unreachable!(); }
self.read.read_exact(bs)
}
}
pub struct BytesBinarySource<'de> {
pub bytes: &'de [u8],
pub index: usize,
}
impl<'de> BytesBinarySource<'de> {
#[inline(always)]
pub fn new(bytes: &'de [u8]) -> Self {
BytesBinarySource { bytes, index: 0 }
}
}
impl<'de> BinarySource<'de> for BytesBinarySource<'de> {
type Mark = usize;
#[inline(always)]
fn mark(&mut self) -> io::Result<Self::Mark> {
Ok(self.index)
}
#[inline(always)]
fn restore(&mut self, mark: &Self::Mark) -> io::Result<()> {
self.index = *mark;
Ok(())
}
#[inline(always)]
fn skip(&mut self) -> io::Result<()> {
if self.index >= self.bytes.len() { unreachable!(); }
self.index += 1;
Ok(())
}
#[inline(always)]
fn peek(&mut self) -> io::Result<u8> {
if self.index >= self.bytes.len() {
Err(io_eof())
} else {
Ok(self.bytes[self.index])
}
}
#[inline(always)]
fn readbytes(&mut self, count: usize) -> io::Result<Cow<'de, [u8]>> {
if self.index + count > self.bytes.len() {
Err(io_eof())
} else {
let bs = &self.bytes[self.index..self.index+count];
self.index += count;
Ok(Cow::Borrowed(bs))
}
}
#[inline(always)]
fn readbytes_into(&mut self, bs: &mut [u8]) -> io::Result<()> {
let count = bs.len();
if self.index + count > self.bytes.len() {
Err(io_eof())
} else {
bs.copy_from_slice(&self.bytes[self.index..self.index+count]);
self.index += count;
Ok(())
}
}
}
pub struct ConfiguredReader<'de, N: NestedValue, R: Reader<'de, N>> {
pub struct ConfiguredReader<'de, N: NestedValue, Dec: DomainDecode<N::Embedded>, R: Reader<'de>>
{
pub reader: R,
pub read_annotations: bool,
pub decode_embedded: Dec,
phantom: PhantomData<&'de N>,
}
impl<'de, N: NestedValue, R: Reader<'de, N>> ConfiguredReader<'de, N, R> {
pub fn new(reader: R) -> Self {
reader.configured(true)
impl<'de, N: NestedValue, Dec: DomainDecode<N::Embedded>, R: Reader<'de>>
ConfiguredReader<'de, N, Dec, R>
{
pub fn new(reader: R, decode_embedded: Dec) -> Self {
reader.configured(true, decode_embedded)
}
pub fn set_read_annotations(&mut self, read_annotations: bool) {
self.read_annotations = read_annotations
self.read_annotations = read_annotations;
}
pub fn demand_next(&mut self) -> io::Result<N> {
self.reader.demand_next(self.read_annotations)
self.reader.demand_next(self.read_annotations, &mut self.decode_embedded)
}
pub fn next_token(&mut self) -> io::Result<Token<N>> {
self.reader.next_token(self.read_annotations, &mut self.decode_embedded)
}
}
impl<'de, N: NestedValue, R: Reader<'de, N>> std::iter::Iterator for ConfiguredReader<'de, N, R> {
impl<'de, N: NestedValue, Dec: DomainDecode<N::Embedded>, R: Reader<'de>>
std::iter::Iterator
for ConfiguredReader<'de, N, Dec, R>
{
type Item = io::Result<N>;
fn next(&mut self) -> Option<Self::Item> {
match self.reader.next(self.read_annotations) {
match self.reader.next(self.read_annotations, &mut self.decode_embedded) {
Err(e) => Some(Err(e)),
Ok(None) => None,
Ok(Some(v)) => Some(Ok(v)),

View File

@ -17,7 +17,7 @@ pub use std::collections::BTreeSet as Set;
pub use std::collections::BTreeMap as Map;
use super::signed_integer::SignedInteger;
use crate::error::{Error, ExpectedKind, Received};
use crate::error::{Error, ExpectedKind};
pub trait Domain: Sized + Debug + Eq + Hash + Ord {}
pub trait Embeddable: Domain + Clone {}
@ -398,7 +398,7 @@ impl<N: NestedValue> Value<N> {
}
fn expected(&self, k: ExpectedKind) -> Error {
Error::Expected(k, Received::ReceivedOtherValue(format!("{:?}", self.clone().wrap())))
Error::Expected(k)
}
#[inline(always)]
@ -877,7 +877,7 @@ impl<N: NestedValue> Value<N> {
#[inline(always)]
pub fn to_record(&self, arity: Option<usize>) -> Result<&Record<N>, Error> {
self.as_record(arity).ok_or_else(|| self.expected(ExpectedKind::Record(arity)))
self.as_record(arity).ok_or_else(|| self.expected(ExpectedKind::Record))
}
#[inline(always)]
@ -917,7 +917,7 @@ impl<N: NestedValue> Value<N> {
Result<&[N], Error>
{
self.as_simple_record(label, arity)
.ok_or_else(|| self.expected(ExpectedKind::SimpleRecord(label.to_owned(), arity)))
.ok_or_else(|| self.expected(ExpectedKind::SimpleRecord(label.to_owned())))
}
#[inline(always)]
@ -1515,22 +1515,22 @@ impl<D: Embeddable> NestedValue for DummyValue<D> {
#[inline(always)]
fn annotations(&self) -> &Annotations<Self> {
&self.0.0
&(self.0).0
}
#[inline(always)]
fn value(&self) -> &Value<Self> {
&self.0.1
&(self.0).1
}
#[inline(always)]
fn pieces(self) -> (Annotations<Self>, Value<Self>) {
(self.0.0, self.0.1)
((self.0).0, (self.0).1)
}
#[inline(always)]
fn value_owned(self) -> Value<Self> {
self.0.1
(self.0).1
}
}

View File

@ -0,0 +1,193 @@
use crate::error::io_eof;
use std::borrow::Cow;
use std::io;
pub trait BinarySource<'de>: Sized {
type Mark;
fn mark(&mut self) -> io::Result<Self::Mark>;
fn restore(&mut self, mark: &Self::Mark) -> io::Result<()>;
fn skip(&mut self) -> io::Result<()>;
fn peek(&mut self) -> io::Result<Option<u8>>;
fn discard(&mut self, count: u64) -> io::Result<()>;
fn readbytes(&mut self, count: u64) -> io::Result<Cow<'de, [u8]>>;
fn readbytes_into(&mut self, bs: &mut [u8]) -> io::Result<()>;
fn read_to_end(&mut self) -> io::Result<Cow<'de, [u8]>>;
//---------------------------------------------------------------------------
fn packed(&mut self) -> super::PackedReader<'de, '_, Self> {
super::PackedReader::new(self)
}
fn text(&mut self) -> super::TextReader<'de, '_, Self> {
super::TextReader::new(self)
}
}
pub struct IOBinarySource<R: io::Read + io::Seek> {
pub read: R,
pub buf: Option<u8>,
}
impl<R: io::Read + io::Seek> IOBinarySource<R> {
#[inline(always)]
pub fn new(read: R) -> Self {
IOBinarySource { read, buf: None }
}
}
impl<'de, R: io::Read + io::Seek> BinarySource<'de> for IOBinarySource<R> {
type Mark = u64;
#[inline(always)]
fn mark(&mut self) -> io::Result<Self::Mark> {
Ok(self.read.stream_position()? - (if self.buf.is_some() { 1 } else { 0 }))
}
#[inline(always)]
fn restore(&mut self, mark: &Self::Mark) -> io::Result<()> {
self.read.seek(io::SeekFrom::Start(*mark))?;
self.buf = None;
Ok(())
}
#[inline(always)]
fn skip(&mut self) -> io::Result<()> {
if self.buf.is_none() { unreachable!(); }
self.buf = None;
Ok(())
}
#[inline(always)]
fn peek(&mut self) -> io::Result<Option<u8>> {
match self.buf {
Some(b) => Ok(Some(b)),
None => {
let b = &mut [0];
match self.read.read(b)? {
0 => Ok(None),
1 => {
self.buf = Some(b[0]);
Ok(Some(b[0]))
}
_ => unreachable!(),
}
}
}
}
fn discard(&mut self, mut count: u64) -> io::Result<()> {
if self.buf.is_some() { unreachable!(); }
while count > i64::MAX as u64 {
self.read.seek(io::SeekFrom::Current(i64::MAX))?;
count -= i64::MAX as u64;
}
self.read.seek(io::SeekFrom::Current(count as i64))?;
Ok(())
}
fn readbytes(&mut self, count: u64) -> io::Result<Cow<'de, [u8]>> {
let mut bs = vec![0; count as usize];
self.readbytes_into(&mut bs)?;
Ok(Cow::Owned(bs))
}
fn readbytes_into(&mut self, bs: &mut [u8]) -> io::Result<()> {
if self.buf.is_some() { unreachable!(); }
self.read.read_exact(bs)
}
fn read_to_end(&mut self) -> io::Result<Cow<'de, [u8]>> {
if self.buf.is_some() { unreachable!(); }
let mut bs = Vec::new();
self.read.read_to_end(&mut bs)?;
Ok(Cow::Owned(bs))
}
}
pub struct BytesBinarySource<'de> {
pub bytes: &'de [u8],
pub index: u64,
}
impl<'de> BytesBinarySource<'de> {
#[inline(always)]
pub fn new(bytes: &'de [u8]) -> Self {
BytesBinarySource { bytes, index: 0 }
}
}
impl<'de> BinarySource<'de> for BytesBinarySource<'de> {
type Mark = u64;
#[inline(always)]
fn mark(&mut self) -> io::Result<Self::Mark> {
Ok(self.index)
}
#[inline(always)]
fn restore(&mut self, mark: &Self::Mark) -> io::Result<()> {
self.index = *mark;
Ok(())
}
#[inline(always)]
fn skip(&mut self) -> io::Result<()> {
if self.index as usize >= self.bytes.len() { unreachable!(); }
self.index += 1;
Ok(())
}
#[inline(always)]
fn peek(&mut self) -> io::Result<Option<u8>> {
if self.index as usize >= self.bytes.len() {
Ok(None)
} else {
Ok(Some(self.bytes[self.index as usize]))
}
}
#[inline(always)]
fn discard(&mut self, count: u64) -> io::Result<()> {
if (self.index + count) as usize > self.bytes.len() {
Err(io_eof())
} else {
self.index += count;
Ok(())
}
}
#[inline(always)]
fn readbytes(&mut self, count: u64) -> io::Result<Cow<'de, [u8]>> {
let base = self.index as usize;
let limit = base + count as usize;
if limit > self.bytes.len() {
Err(io_eof())
} else {
let bs = &self.bytes[base..limit];
self.index += count;
Ok(Cow::Borrowed(bs))
}
}
#[inline(always)]
fn readbytes_into(&mut self, bs: &mut [u8]) -> io::Result<()> {
let base = self.index as usize;
let count = bs.len();
let limit = base + count;
if limit > self.bytes.len() {
Err(io_eof())
} else {
bs.copy_from_slice(&self.bytes[base..limit]);
self.index += count as u64;
Ok(())
}
}
#[inline(always)]
fn read_to_end(&mut self) -> io::Result<Cow<'de, [u8]>> {
self.readbytes(self.bytes.len() as u64 - self.index)
}
}

View File

@ -4,30 +4,30 @@ pub mod writer;
pub use reader::TextReader;
pub use writer::TextWriter;
use crate::value::reader::BytesBinarySource;
use crate::value::source::BytesBinarySource;
use std::io;
use super::{DomainParse, IOValue, IOValueDomainCodec, NestedValue, Reader, ViaCodec};
use super::{DomainDecode, IOValue, IOValueDomainCodec, NestedValue, Reader};
pub fn from_str<N: NestedValue, Dec: DomainParse<N::Embedded>>(
pub fn from_str<N: NestedValue, Dec: DomainDecode<N::Embedded>>(
s: &str,
decode_embedded: Dec,
decode_embedded: &mut Dec,
) -> io::Result<N> {
TextReader::new(&mut BytesBinarySource::new(s.as_bytes()), decode_embedded).demand_next(false)
TextReader::new(&mut BytesBinarySource::new(s.as_bytes())).demand_next(false, decode_embedded)
}
pub fn iovalue_from_str(s: &str) -> io::Result<IOValue> {
from_str(s, ViaCodec::new(IOValueDomainCodec))
from_str(s, &mut IOValueDomainCodec)
}
pub fn annotated_from_str<N: NestedValue, Dec: DomainParse<N::Embedded>>(
pub fn annotated_from_str<N: NestedValue, Dec: DomainDecode<N::Embedded>>(
s: &str,
decode_embedded: Dec,
decode_embedded: &mut Dec,
) -> io::Result<N> {
TextReader::new(&mut BytesBinarySource::new(s.as_bytes()), decode_embedded).demand_next(true)
TextReader::new(&mut BytesBinarySource::new(s.as_bytes())).demand_next(true, decode_embedded)
}
pub fn annotated_iovalue_from_str(s: &str) -> io::Result<IOValue> {
annotated_from_str(s, ViaCodec::new(IOValueDomainCodec))
annotated_from_str(s, &mut IOValueDomainCodec)
}

View File

@ -1,18 +1,12 @@
use crate::error::Error;
use crate::error::ExpectedKind;
use crate::error::Received;
use crate::error::io_eof;
use crate::error::io_syntax_error;
use crate::error::is_eof_io_error;
use crate::error::syntax_error;
use crate::hex;
use crate::value::CompoundClass;
use crate::value::DomainParse;
use crate::value::DummyValue;
use crate::value::Embeddable;
use crate::value::IOValue;
use crate::value::IOValueDomainCodec;
use crate::value::DomainDecode;
use crate::value::Map;
use crate::value::NestedValue;
use crate::value::Reader;
@ -20,11 +14,10 @@ use crate::value::Record;
use crate::value::Set;
use crate::value::Token;
use crate::value::Value;
use crate::value::ViaCodec;
use crate::value::boundary as B;
use crate::value::reader::BinarySource;
use crate::value::reader::ReaderResult;
use crate::value::repr::Annotations;
use crate::value::source::BinarySource;
use num::bigint::BigInt;
@ -32,10 +25,9 @@ use std::io;
use std::iter::FromIterator;
use std::marker::PhantomData;
pub struct TextReader<'de, 'src, D: Embeddable, Dec: DomainParse<D>, S: BinarySource<'de>> {
pub struct TextReader<'de, 'src, S: BinarySource<'de>> {
pub source: &'src mut S,
pub dec: Dec,
phantom: PhantomData<&'de D>,
phantom: PhantomData<&'de ()>,
}
fn decode_utf8(bs: Vec<u8>) -> io::Result<String> {
@ -50,34 +42,36 @@ fn append_codepoint(bs: &mut Vec<u8>, n: u32) -> io::Result<()> {
Ok(())
}
impl<'de, 'src, D: Embeddable, Dec: DomainParse<D>, S: BinarySource<'de>>
TextReader<'de, 'src, D, Dec, S>
{
pub fn new(source: &'src mut S, dec: Dec) -> Self {
impl<'de, 'src, S: BinarySource<'de>> TextReader<'de, 'src, S> {
pub fn new(source: &'src mut S) -> Self {
TextReader {
source,
dec,
phantom: PhantomData,
}
}
fn peek(&mut self) -> io::Result<u8> {
fn peek(&mut self) -> io::Result<Option<u8>> {
self.source.peek()
}
#[inline(always)]
fn peek_noeof(&mut self) -> io::Result<u8> {
self.source.peek()?.ok_or_else(|| io_eof())
}
fn skip(&mut self) -> io::Result<()> {
self.source.skip()
}
fn next_byte(&mut self) -> io::Result<u8> {
let b = self.source.peek()?;
let b = self.peek_noeof()?;
self.source.skip()?;
Ok(b)
}
fn skip_whitespace(&mut self) {
// Deliberately swallows errors.
while let Ok(c) = self.peek() {
while let Ok(Some(c)) = self.peek() {
match c {
b' ' | b'\t' | b'\r' | b'\n' | b',' => {
let _ = self.skip();
@ -88,21 +82,20 @@ impl<'de, 'src, D: Embeddable, Dec: DomainParse<D>, S: BinarySource<'de>>
}
}
// TODO: This is a duplicate of fn expected in PackedReader.
fn expected<N: NestedValue<Embedded = D>>(&mut self, k: ExpectedKind) -> Error {
match Reader::<N>::demand_next(self, true) {
Ok(v) => Error::Expected(k, Received::ReceivedOtherValue(format!("{:?}", v))),
Err(e) => e.into()
}
fn expected(&mut self, k: ExpectedKind) -> Error {
Error::Expected(k)
}
fn gather_annotations<N: NestedValue<Embedded = D>>(&mut self) -> ReaderResult<Vec<N>> {
fn gather_annotations<N: NestedValue, Dec: DomainDecode<N::Embedded>>(
&mut self,
decode_embedded: &mut Dec,
) -> ReaderResult<Vec<N>> {
let mut vs = Vec::new();
loop {
self.skip_whitespace();
match self.peek()? {
match self.peek_noeof()? {
b';' => { self.skip()?; vs.push(N::new(self.comment_line()?)) }
b'@' => { self.skip()?; vs.push(self.demand_next(true)?) }
b'@' => { self.skip()?; vs.push(self.demand_next(true, decode_embedded)?) }
_ => return Ok(vs),
}
}
@ -111,24 +104,18 @@ impl<'de, 'src, D: Embeddable, Dec: DomainParse<D>, S: BinarySource<'de>>
fn skip_annotations(&mut self) -> ReaderResult<()> {
loop {
self.skip_whitespace();
match self.peek()? {
match self.peek_noeof()? {
b';' => { self.skip()?; self.comment_line()?; },
b'@' => { self.skip()?; Reader::<DummyValue<D>>::skip_value(self)?; },
b'@' => { self.skip()?; self.skip_value()?; },
_ => return Ok(()),
}
}
}
pub fn next_iovalue(&mut self, read_annotations: bool) -> io::Result<IOValue> {
let mut r = TextReader::new(self.source, ViaCodec::new(IOValueDomainCodec));
let v = r.demand_next(read_annotations)?;
Ok(v)
}
fn comment_line(&mut self) -> io::Result<String> {
let mut bs = Vec::new();
loop {
let b = self.peek()?;
let b = self.peek_noeof()?;
self.skip()?;
match b {
b'\r' | b'\n' => return Ok(decode_utf8(bs)?),
@ -152,7 +139,7 @@ impl<'de, 'src, D: Embeddable, Dec: DomainParse<D>, S: BinarySource<'de>>
fn read_fracexp<N: NestedValue>(&mut self, mut bs: Vec<u8>) -> io::Result<N> {
let mut is_float = false;
match self.peek() {
match self.peek_noeof() {
Ok(b'.') => {
is_float = true;
bs.push(self.next_byte()?);
@ -161,7 +148,7 @@ impl<'de, 'src, D: Embeddable, Dec: DomainParse<D>, S: BinarySource<'de>>
}
_ => ()
}
match self.peek() {
match self.peek_noeof() {
Ok(b'e') | Ok(b'E') => {
bs.push(self.next_byte()?);
self.read_sign_and_exp(bs)
@ -171,7 +158,7 @@ impl<'de, 'src, D: Embeddable, Dec: DomainParse<D>, S: BinarySource<'de>>
}
fn read_sign_and_exp<N: NestedValue>(&mut self, mut bs: Vec<u8>) -> io::Result<N> {
match self.peek()? {
match self.peek_noeof()? {
b'+' | b'-' => bs.push(self.next_byte()?),
_ => (),
}
@ -183,7 +170,7 @@ impl<'de, 'src, D: Embeddable, Dec: DomainParse<D>, S: BinarySource<'de>>
fn finish_number<N: NestedValue>(&mut self, bs: Vec<u8>, is_float: bool) -> io::Result<N> {
let s = decode_utf8(bs)?;
if is_float {
match self.peek() {
match self.peek_noeof() {
Ok(b'f') | Ok(b'F') => {
self.skip()?;
Ok(N::new(s.parse::<f32>().map_err(
@ -208,7 +195,7 @@ impl<'de, 'src, D: Embeddable, Dec: DomainParse<D>, S: BinarySource<'de>>
return Err(io_syntax_error("Incomplete number"));
}
bs.push(c);
while let Ok(c) = self.peek() {
while let Ok(Some(c)) = self.peek() {
if !(c as char).is_digit(10) {
break;
}
@ -334,43 +321,51 @@ impl<'de, 'src, D: Embeddable, Dec: DomainParse<D>, S: BinarySource<'de>>
}
}
fn upto<N: NestedValue<Embedded = D>>(&mut self, delimiter: u8, read_annotations: bool) -> io::Result<Vec<N>> {
fn upto<N: NestedValue, Dec: DomainDecode<N::Embedded>>(
&mut self,
delimiter: u8,
read_annotations: bool,
decode_embedded: &mut Dec,
) -> io::Result<Vec<N>> {
let mut vs = Vec::new();
loop {
self.skip_whitespace();
if self.peek()? == delimiter {
if self.peek()? == Some(delimiter) {
self.skip()?;
return Ok(vs);
}
vs.push(Reader::<N>::demand_next(self, read_annotations)?);
vs.push(self.demand_next(read_annotations, decode_embedded)?);
}
}
fn read_dictionary<N: NestedValue<Embedded = D>>(&mut self, read_annotations: bool) -> io::Result<N> {
fn read_dictionary<N: NestedValue, Dec: DomainDecode<N::Embedded>>(
&mut self,
read_annotations: bool,
decode_embedded: &mut Dec,
) -> io::Result<N> {
let mut d = Map::new();
loop {
self.skip_whitespace();
if self.peek()? == b'}' {
if self.peek_noeof()? == b'}' {
self.skip()?;
return Ok(N::new(d));
}
let k = Reader::<N>::demand_next(self, read_annotations)?;
let k = self.demand_next(read_annotations, decode_embedded)?;
self.skip_whitespace();
if self.next_byte()? != b':' {
return Err(io_syntax_error("Missing expected key/value separator"));
}
let v = Reader::<N>::demand_next(self, read_annotations)?;
let v = self.demand_next(read_annotations, decode_embedded)?;
d.insert(k, v);
}
}
fn read_raw_symbol<N: NestedValue>(&mut self, mut bs: Vec<u8>) -> io::Result<N> {
loop {
let c = match self.peek() {
Err(e) if is_eof_io_error(&e) => b' ',
Err(e) => return Err(e)?,
Ok(c) if (c as char).is_whitespace() => b' ',
Ok(c) => c
let c = match self.peek()? {
None => b' ',
Some(c) if (c as char).is_whitespace() => b' ',
Some(c) => c
};
match c {
b'(' | b')' | b'{' | b'}' | b'[' | b']' | b'<' | b'>' |
@ -385,15 +380,16 @@ impl<'de, 'src, D: Embeddable, Dec: DomainParse<D>, S: BinarySource<'de>>
}
}
impl<'de, 'src, N: NestedValue, Dec: DomainParse<N::Embedded>, S: BinarySource<'de>>
Reader<'de, N> for TextReader<'de, 'src, N::Embedded, Dec, S>
{
fn next(&mut self, read_annotations: bool) -> io::Result<Option<N>> {
impl<'de, 'src, S: BinarySource<'de>> Reader<'de> for TextReader<'de, 'src, S> {
fn next<N: NestedValue, Dec: DomainDecode<N::Embedded>>(
&mut self,
read_annotations: bool,
decode_embedded: &mut Dec,
) -> io::Result<Option<N>> {
self.skip_whitespace();
let c = match self.peek() {
Ok(c) => c,
Err(e) if is_eof_io_error(&e) => return Ok(None),
Err(e) => return Err(e.into()),
let c = match self.peek()? {
None => return Ok(None),
Some(c) => c,
};
Ok(Some(match c {
b'-' => {
@ -415,14 +411,14 @@ impl<'de, 'src, N: NestedValue, Dec: DomainParse<N::Embedded>, S: BinarySource<'
}
b';' | b'@' => {
if read_annotations {
let mut annotations = self.gather_annotations()?;
let (existing_annotations, v) =
Reader::<N>::demand_next(self, read_annotations)?.pieces();
let mut annotations = self.gather_annotations(decode_embedded)?;
let av: N = self.demand_next(read_annotations, decode_embedded)?;
let (existing_annotations, v) = av.pieces();
annotations.extend_from_slice(existing_annotations.slice());
N::wrap(Annotations::new(Some(annotations)), v)
} else {
self.skip_annotations()?;
self.demand_next(read_annotations)?
self.demand_next(read_annotations, decode_embedded)?
}
}
b':' => {
@ -433,7 +429,8 @@ impl<'de, 'src, N: NestedValue, Dec: DomainParse<N::Embedded>, S: BinarySource<'
match self.next_byte()? {
b'f' => N::new(false),
b't' => N::new(true),
b'{' => N::new(Set::from_iter(self.upto(b'}', read_annotations)?.into_iter())),
b'{' => N::new(Set::from_iter(
self.upto(b'}', read_annotations, decode_embedded)?.into_iter())),
b'"' => self.read_literal_binary()?,
b'x' => if self.next_byte()? == b'"' {
self.read_hex_binary()?
@ -442,7 +439,7 @@ impl<'de, 'src, N: NestedValue, Dec: DomainParse<N::Embedded>, S: BinarySource<'
},
b'[' => self.read_base64_binary()?,
b'=' => {
let bs_val: N = self.demand_next(true)?;
let bs_val = self.next_iovalue(true)?;
if bs_val.annotations().slice().len() > 0 {
return Err(io_syntax_error("Annotations not permitted after #="));
}
@ -451,20 +448,18 @@ impl<'de, 'src, N: NestedValue, Dec: DomainParse<N::Embedded>, S: BinarySource<'
return Err(io_syntax_error("ByteString must follow #=")),
Some(bs) =>
crate::value::BytesBinarySource::new(bs)
.packed(ViaCodec::new(&mut self.dec))
.demand_next(read_annotations)?
.packed()
.demand_next(read_annotations, decode_embedded)?
}
}
b'!' => {
let v = self.next_iovalue(read_annotations)?;
Value::Embedded(self.dec.parse_embedded(&v)?).wrap()
}
b'!' => Value::Embedded(
decode_embedded.decode_embedded(self, read_annotations)?).wrap(),
other => return Err(io_syntax_error(&format!("Invalid # syntax: {:?}", other))),
}
}
b'<' => {
self.skip()?;
let vs = self.upto(b'>', read_annotations)?;
let vs = self.upto(b'>', read_annotations, decode_embedded)?;
if vs.is_empty() {
return Err(io_syntax_error("Missing record label"));
}
@ -472,11 +467,11 @@ impl<'de, 'src, N: NestedValue, Dec: DomainParse<N::Embedded>, S: BinarySource<'
}
b'[' => {
self.skip()?;
N::new(self.upto(b']', read_annotations)?)
N::new(self.upto(b']', read_annotations, decode_embedded)?)
}
b'{' => {
self.skip()?;
self.read_dictionary(read_annotations)?
self.read_dictionary(read_annotations, decode_embedded)?
}
b'>' => return Err(io_syntax_error("Unexpected >")),
b']' => return Err(io_syntax_error("Unexpected ]")),
@ -488,40 +483,23 @@ impl<'de, 'src, N: NestedValue, Dec: DomainParse<N::Embedded>, S: BinarySource<'
}))
}
fn open_record(&mut self, arity: Option<usize>) -> ReaderResult<B::Type> {
fn open_record(&mut self) -> ReaderResult<()> {
self.skip_annotations()?;
if self.peek()? != b'<' { return Err(self.expected::<N>(ExpectedKind::Record(arity))); }
if self.peek()? != Some(b'<') { return Err(self.expected(ExpectedKind::Record)); }
self.skip()?;
let mut b = B::Type::default();
Reader::<N>::ensure_more_expected(self, &mut b, &B::Item::RecordLabel)?;
Ok(b)
}
fn open_sequence_or_set(&mut self) -> ReaderResult<B::Item> {
self.skip_annotations()?;
let mark = Reader::<N>::mark(self)?;
match self.next_byte()? {
b'#' => match self.next_byte()? {
b'{' => return Ok(B::Item::SetValue),
_ => (),
},
b'[' => return Ok(B::Item::SequenceValue),
_ => (),
}
Reader::<N>::restore(self, &mark)?;
Err(self.expected::<N>(ExpectedKind::SequenceOrSet))
Ok(())
}
fn open_sequence(&mut self) -> ReaderResult<()> {
self.skip_annotations()?;
if self.peek()? != b'[' { return Err(self.expected::<N>(ExpectedKind::Sequence)); }
if self.peek()? != Some(b'[') { return Err(self.expected(ExpectedKind::Sequence)); }
self.skip()?;
Ok(())
}
fn open_set(&mut self) -> ReaderResult<()> {
self.skip_annotations()?;
let mark = Reader::<N>::mark(self)?;
let mark = self.mark()?;
match self.next_byte()? {
b'#' => match self.next_byte()? {
b'{' => return Ok(()),
@ -529,13 +507,13 @@ impl<'de, 'src, N: NestedValue, Dec: DomainParse<N::Embedded>, S: BinarySource<'
},
_ => (),
}
Reader::<N>::restore(self, &mark)?;
Err(self.expected::<N>(ExpectedKind::Set))
self.restore(&mark)?;
Err(self.expected(ExpectedKind::Set))
}
fn open_dictionary(&mut self) -> ReaderResult<()> {
self.skip_annotations()?;
if self.peek()? != b'{' { return Err(self.expected::<N>(ExpectedKind::Dictionary)); }
if self.peek()? != Some(b'{') { return Err(self.expected(ExpectedKind::Dictionary)); }
self.skip()?;
Ok(())
}
@ -549,7 +527,7 @@ impl<'de, 'src, N: NestedValue, Dec: DomainParse<N::Embedded>, S: BinarySource<'
} => {
self.skip_whitespace();
if self.next_byte()? != b':' {
return Err(syntax_error("Missing expected key/value separator"));
return Err(io_syntax_error("Missing expected key/value separator"))?;
}
},
_ => (),
@ -559,14 +537,14 @@ impl<'de, 'src, N: NestedValue, Dec: DomainParse<N::Embedded>, S: BinarySource<'
fn close_compound(&mut self, b: &mut B::Type, i: &B::Item) -> ReaderResult<bool> {
self.skip_whitespace();
match self.peek()? {
match self.peek_noeof()? {
b'>' | b']' | b'}' => {
self.skip()?;
Ok(true)
}
_ => {
b.shift(Some(i.clone()));
Reader::<N>::boundary(self, b)?;
self.boundary(b)?;
Ok(false)
}
}
@ -574,7 +552,7 @@ impl<'de, 'src, N: NestedValue, Dec: DomainParse<N::Embedded>, S: BinarySource<'
fn open_embedded(&mut self) -> ReaderResult<()> {
self.skip_annotations()?;
let mark = Reader::<N>::mark(self)?;
let mark = self.mark()?;
match self.next_byte()? {
b'#' => match self.next_byte()? {
b'!' => return Ok(()),
@ -582,8 +560,8 @@ impl<'de, 'src, N: NestedValue, Dec: DomainParse<N::Embedded>, S: BinarySource<'
},
_ => (),
}
Reader::<N>::restore(self, &mark)?;
Err(self.expected::<N>(ExpectedKind::Embedded))
self.restore(&mark)?;
Err(self.expected(ExpectedKind::Embedded))
}
fn close_embedded(&mut self) -> ReaderResult<()> {
@ -600,9 +578,13 @@ impl<'de, 'src, N: NestedValue, Dec: DomainParse<N::Embedded>, S: BinarySource<'
self.source.restore(mark)
}
fn next_token(&mut self, read_embedded_annotations: bool) -> io::Result<Token<N>> {
fn next_token<N: NestedValue, Dec: DomainDecode<N::Embedded>>(
&mut self,
read_embedded_annotations: bool,
decode_embedded: &mut Dec,
) -> io::Result<Token<N>> {
self.skip_annotations()?;
let mark = Reader::<N>::mark(self)?;
let mark = self.mark()?;
Ok(match self.next_byte()? {
b'<' => Token::Compound(CompoundClass::Record),
b'[' => Token::Compound(CompoundClass::Sequence),
@ -611,25 +593,18 @@ impl<'de, 'src, N: NestedValue, Dec: DomainParse<N::Embedded>, S: BinarySource<'
b']' => Token::End,
b'}' => Token::End,
b'#' => match self.next_byte()? {
b'!' => {
let v = self.next_iovalue(read_embedded_annotations)?;
Token::Embedded(self.dec.parse_embedded(&v)?)
}
b'!' => Token::Embedded(decode_embedded.decode_embedded(
self, read_embedded_annotations)?),
b'{' => Token::Compound(CompoundClass::Set),
_ => {
Reader::<N>::restore(self, &mark)?;
Token::Atom(self.demand_next(false)?)
self.restore(&mark)?;
Token::Atom(self.demand_next(false, decode_embedded)?)
}
},
_ => {
Reader::<N>::restore(self, &mark)?;
Token::Atom(self.demand_next(false)?)
self.restore(&mark)?;
Token::Atom(self.demand_next(false, decode_embedded)?)
}
})
}
fn next_annotations_and_token(&mut self) -> io::Result<(Vec<N>, Token<N>)> {
let annotations = self.gather_annotations()?;
Ok((annotations, self.next_token(true)?))
}
}

View File

@ -3,8 +3,6 @@ use crate::value::IOValue;
use crate::value::IOValueDomainCodec;
use crate::value::NestedValue;
use crate::value::Writer;
use crate::value::suspendable::Suspendable;
use crate::value::writer::CompoundWriter;
use num::bigint::BigInt;
@ -20,7 +18,7 @@ pub enum CommaStyle {
}
pub struct TextWriter<W: io::Write> {
w: Suspendable<W>,
w: W,
pub comma_style: CommaStyle,
pub indentation: usize,
pub escape_spaces: bool,
@ -51,7 +49,7 @@ impl TextWriter<&mut Vec<u8>> {
impl<W: io::Write> TextWriter<W> {
pub fn new(w: W) -> Self {
TextWriter {
w: Suspendable::new(w),
w,
comma_style: CommaStyle::default(),
indentation: 0,
escape_spaces: false,
@ -69,14 +67,6 @@ impl<W: io::Write> TextWriter<W> {
self
}
pub fn suspend(&mut self) -> Self {
TextWriter { w: self.w.suspend(), indent: self.indent.clone(), .. *self }
}
pub fn resume(&mut self, other: Self) {
self.w.resume(other.w)
}
pub fn write_stringlike_char_fallback<F>(
&mut self,
c: char,
@ -132,7 +122,14 @@ impl<W: io::Write> TextWriter<W> {
}
}
impl<W: io::Write> CompoundWriter for TextWriter<W> {
macro_rules! simple_writer_method {
($n:ident, $argty:ty) =>
(fn $n (&mut self, v: $argty) -> io::Result<()> {
write!(self.w, "{}", v)
});
}
impl<W: io::Write> Writer for TextWriter<W> {
#[inline]
fn boundary(&mut self, b: &B::Type) -> io::Result<()> {
match (b.closing.as_ref(), b.opening.as_ref()) {
@ -187,29 +184,12 @@ impl<W: io::Write> CompoundWriter for TextWriter<W> {
Ok(())
}
}
macro_rules! simple_writer_method {
($n:ident, $argty:ty) =>
(fn $n (&mut self, v: $argty) -> io::Result<()> {
write!(self.w, "{}", v)
});
}
impl<W: io::Write> Writer for TextWriter<W> {
type AnnWriter = Self;
type RecWriter = Self;
type SeqWriter = Self;
type SetWriter = Self;
type DictWriter = Self;
type EmbeddedWriter = Self;
fn start_annotations(&mut self) -> io::Result<Self::AnnWriter> {
Ok(self.suspend())
fn start_annotations(&mut self) -> io::Result<()> {
Ok(())
}
fn end_annotations(&mut self, ann: Self::AnnWriter) -> io::Result<()> {
self.resume(ann);
fn end_annotations(&mut self) -> io::Result<()> {
Ok(())
}
@ -218,12 +198,12 @@ impl<W: io::Write> Writer for TextWriter<W> {
}
fn write_f32(&mut self, v: f32) -> io::Result<()> {
dtoa::write(&mut *self.w, v)?;
dtoa::write(&mut self.w, v)?;
write!(self.w, "f")
}
fn write_f64(&mut self, v: f64) -> io::Result<()> {
dtoa::write(&mut *self.w, v)?;
dtoa::write(&mut self.w, v)?;
Ok(())
}
@ -273,53 +253,48 @@ impl<W: io::Write> Writer for TextWriter<W> {
}
}
fn start_record(&mut self, _field_count: Option<usize>) -> io::Result<Self::RecWriter> {
fn start_record(&mut self) -> io::Result<()> {
write!(self.w, "<")?;
Ok(self.suspend())
Ok(())
}
fn end_record(&mut self, rec: Self::RecWriter) -> io::Result<()> {
self.resume(rec);
fn end_record(&mut self) -> io::Result<()> {
write!(self.w, ">")
}
fn start_sequence(&mut self, _item_count: Option<usize>) -> io::Result<Self::SeqWriter> {
fn start_sequence(&mut self) -> io::Result<()> {
write!(self.w, "[")?;
Ok(self.suspend())
Ok(())
}
fn end_sequence(&mut self, seq: Self::SeqWriter) -> io::Result<()> {
self.resume(seq);
fn end_sequence(&mut self) -> io::Result<()> {
write!(self.w, "]")
}
fn start_set(&mut self, _item_count: Option<usize>) -> io::Result<Self::SetWriter> {
fn start_set(&mut self) -> io::Result<()> {
write!(self.w, "#{{")?;
Ok(self.suspend())
Ok(())
}
fn end_set(&mut self, set: Self::SetWriter) -> io::Result<()> {
self.resume(set);
fn end_set(&mut self) -> io::Result<()> {
write!(self.w, "}}")
}
fn start_dictionary(&mut self, _entry_count: Option<usize>) -> io::Result<Self::DictWriter> {
fn start_dictionary(&mut self) -> io::Result<()> {
write!(self.w, "{{")?;
Ok(self.suspend())
Ok(())
}
fn end_dictionary(&mut self, dict: Self::DictWriter) -> io::Result<()> {
self.resume(dict);
fn end_dictionary(&mut self) -> io::Result<()> {
write!(self.w, "}}")
}
fn start_embedded(&mut self) -> io::Result<Self::EmbeddedWriter> {
fn start_embedded(&mut self) -> io::Result<()> {
write!(self.w, "#!")?;
Ok(self.suspend())
Ok(())
}
fn end_embedded(&mut self, ptr: Self::EmbeddedWriter) -> io::Result<()> {
self.resume(ptr);
fn end_embedded(&mut self) -> io::Result<()> {
Ok(())
}

View File

@ -5,20 +5,9 @@ use super::boundary as B;
use super::signed_integer::SignedIntegerRepr;
use super::repr::{Value, NestedValue, Float, Double};
pub trait CompoundWriter: Writer {
fn boundary(&mut self, b: &B::Type) -> io::Result<()>;
}
pub trait Writer: Sized {
type AnnWriter: CompoundWriter;
type RecWriter: CompoundWriter;
type SeqWriter: CompoundWriter;
type SetWriter: CompoundWriter;
type DictWriter: CompoundWriter;
type EmbeddedWriter: Writer;
fn start_annotations(&mut self) -> io::Result<Self::AnnWriter>;
fn end_annotations(&mut self, ann: Self::AnnWriter) -> io::Result<()>;
fn start_annotations(&mut self) -> io::Result<()>;
fn end_annotations(&mut self) -> io::Result<()>;
fn write_bool(&mut self, v: bool) -> io::Result<()>;
@ -41,48 +30,59 @@ pub trait Writer: Sized {
fn write_bytes(&mut self, v: &[u8]) -> io::Result<()>;
fn write_symbol(&mut self, v: &str) -> io::Result<()>;
fn start_record(&mut self, field_count: Option<usize>) -> io::Result<Self::RecWriter>;
fn end_record(&mut self, rec: Self::RecWriter) -> io::Result<()>;
fn boundary(&mut self, b: &B::Type) -> io::Result<()>;
fn start_sequence(&mut self, item_count: Option<usize>) -> io::Result<Self::SeqWriter>;
fn end_sequence(&mut self, seq: Self::SeqWriter) -> io::Result<()>;
fn start_record(&mut self) -> io::Result<()>;
fn end_record(&mut self) -> io::Result<()>;
fn start_set(&mut self, item_count: Option<usize>) -> io::Result<Self::SetWriter>;
fn end_set(&mut self, set: Self::SetWriter) -> io::Result<()>;
fn start_sequence(&mut self) -> io::Result<()>;
fn end_sequence(&mut self) -> io::Result<()>;
fn start_dictionary(&mut self, entry_count: Option<usize>) -> io::Result<Self::DictWriter>;
fn end_dictionary(&mut self, dict: Self::DictWriter) -> io::Result<()>;
fn start_set(&mut self) -> io::Result<()>;
fn end_set(&mut self) -> io::Result<()>;
fn start_embedded(&mut self) -> io::Result<Self::EmbeddedWriter>;
fn end_embedded(&mut self, ptr: Self::EmbeddedWriter) -> io::Result<()>;
fn start_dictionary(&mut self) -> io::Result<()>;
fn end_dictionary(&mut self) -> io::Result<()>;
fn start_embedded(&mut self) -> io::Result<()>;
fn end_embedded(&mut self) -> io::Result<()>;
fn flush(&mut self) -> io::Result<()>;
//---------------------------------------------------------------------------
#[inline(always)]
fn write<N: NestedValue, Enc: DomainEncode<N::Embedded>>(
&mut self,
enc: &mut Enc,
v: &N,
) -> io::Result<()> {
self.inner_write(enc, v)
}
fn inner_write<N: NestedValue, Enc: DomainEncode<N::Embedded>>(
&mut self,
enc: &mut Enc,
v: &N,
) -> io::Result<()> {
match v.annotations().maybe_slice() {
None => {
self.write_value(enc, v.value())?;
}
Some(anns) => {
let mut a = self.start_annotations()?;
self.start_annotations()?;
let mut b = B::Type::default();
for ann in anns {
b.shift(Some(B::Item::Annotation));
a.boundary(&b)?;
a.write(enc, ann)?;
self.boundary(&b)?;
self.inner_write(enc, ann)?;
}
b.shift(Some(B::Item::AnnotatedValue));
a.boundary(&b)?;
a.write_value(enc, v.value())?;
self.boundary(&b)?;
self.write_value(enc, v.value())?;
b.shift(None);
a.boundary(&b)?;
self.end_annotations(a)?;
self.boundary(&b)?;
self.end_annotations()?;
}
}
Ok(())
@ -106,77 +106,63 @@ pub trait Writer: Sized {
Value::ByteString(bs) => self.write_bytes(bs),
Value::Symbol(s) => self.write_symbol(s),
Value::Record(r) => {
let mut c = self.start_record(Some(r.arity()))?;
self.start_record()?;
let mut b = B::start(B::Item::RecordLabel);
c.boundary(&b)?;
c.write(enc, r.label())?;
self.boundary(&b)?;
self.inner_write(enc, r.label())?;
for f in r.fields() {
b.shift(Some(B::Item::RecordField));
c.boundary(&b)?;
c.write(enc, f)?;
self.boundary(&b)?;
self.inner_write(enc, f)?;
}
b.shift(None);
c.boundary(&b)?;
self.end_record(c)
self.boundary(&b)?;
self.end_record()
}
Value::Sequence(vs) => {
let mut c = self.start_sequence(Some(vs.len()))?;
self.start_sequence()?;
let mut b = B::Type::default();
for v in vs {
b.shift(Some(B::Item::SequenceValue));
c.boundary(&b)?;
c.write(enc, v)?;
self.boundary(&b)?;
self.inner_write(enc, v)?;
}
b.shift(None);
c.boundary(&b)?;
self.end_sequence(c)
self.boundary(&b)?;
self.end_sequence()
}
Value::Set(vs) => {
let mut c = self.start_set(Some(vs.len()))?;
self.start_set()?;
let mut b = B::Type::default();
for v in vs {
b.shift(Some(B::Item::SetValue));
c.boundary(&b)?;
c.write(enc, v)?;
self.boundary(&b)?;
self.inner_write(enc, v)?;
}
b.shift(None);
c.boundary(&b)?;
self.end_set(c)
self.boundary(&b)?;
self.end_set()
}
Value::Dictionary(vs) => {
let mut c = self.start_dictionary(Some(vs.len()))?;
self.start_dictionary()?;
let mut b = B::Type::default();
for (k, v) in vs {
b.shift(Some(B::Item::DictionaryKey));
c.boundary(&b)?;
c.write(enc, k)?;
self.boundary(&b)?;
self.inner_write(enc, k)?;
b.shift(Some(B::Item::DictionaryValue));
c.boundary(&b)?;
c.write(enc, v)?;
self.boundary(&b)?;
self.inner_write(enc, v)?;
}
b.shift(None);
c.boundary(&b)?;
self.end_dictionary(c)
self.boundary(&b)?;
self.end_dictionary()
}
Value::Embedded(d) => {
let mut c = self.start_embedded()?;
enc.encode_embedded(&mut c, d)?;
self.end_embedded(c)
self.start_embedded()?;
enc.encode_embedded(self, d)?;
self.end_embedded()
}
}
}
}
pub fn varint<W: io::Write>(w: &mut W, mut v: u64) -> io::Result<usize> {
let mut byte_count = 0;
loop {
byte_count += 1;
if v < 128 {
w.write_all(&[v as u8])?;
return Ok(byte_count);
} else {
w.write_all(&[((v & 0x7f) + 128) as u8])?;
v >>= 7;
}
}
}

View File

@ -14,7 +14,7 @@ mod samples;
use samples::*;
fn decode_all(bytes: &'_ [u8]) -> io::Result<Vec<IOValue>> {
BytesBinarySource::new(bytes).packed_iovalues().configured(true).collect()
BytesBinarySource::new(bytes).packed().iovalues().collect()
}
#[test] fn compare_text_with_packed() -> io::Result<()> {
@ -23,14 +23,11 @@ fn decode_all(bytes: &'_ [u8]) -> io::Result<Vec<IOValue>> {
let mut fh = std::fs::File::open("../../../tests/samples.pr").unwrap();
let mut contents = String::new();
fh.read_to_string(&mut contents)?;
preserves::value::TextReader::new(
&mut BytesBinarySource::new(contents.as_bytes()),
preserves::value::ViaCodec::new(preserves::value::IOValueDomainCodec))
.next_iovalue(true)?
BytesBinarySource::new(contents.as_bytes()).text().next_iovalue(true)?
};
let from_packed = {
let mut fh = std::fs::File::open("../../../tests/samples.bin").unwrap();
IOBinarySource::new(&mut fh).packed_iovalues().demand_next(true)?
IOBinarySource::new(&mut fh).packed().next_iovalue(true)?
};
assert_eq!(from_text, from_packed);
Ok(())
@ -105,7 +102,7 @@ fn decode_all(bytes: &'_ [u8]) -> io::Result<Vec<IOValue>> {
#[test] fn run() -> io::Result<()> {
let mut fh = std::fs::File::open("../../../tests/samples.bin").unwrap();
let mut src = IOBinarySource::new(&mut fh);
let mut d = src.packed_iovalues().configured(true);
let mut d = src.packed().iovalues();
let tests: TestCases = deserialize_from_value(&d.next().unwrap().unwrap()).unwrap();
for (Symbol(ref name), ref case) in tests.tests {
@ -143,14 +140,14 @@ fn decode_all(bytes: &'_ [u8]) -> io::Result<Vec<IOValue>> {
}
}
TestCase::DecodeShort(ref bin) => {
assert!(if let Err(e) = BytesBinarySource::new(bin).packed_iovalues().configured(true).next().unwrap() {
assert!(if let Err(e) = BytesBinarySource::new(bin).packed().iovalues().next().unwrap() {
is_eof_io_error(&e)
} else {
false
})
}
TestCase::DecodeEOF(ref bin) => {
assert!(BytesBinarySource::new(bin).packed_iovalues().configured(true).next().is_none());
assert!(BytesBinarySource::new(bin).packed().iovalues().next().is_none());
}
}
}