mirror of
https://github.com/fluencelabs/parity-wasm
synced 2025-06-23 03:31:56 +00:00
128-bit packed serialization
This commit is contained in:
@ -16,7 +16,10 @@ pub use self::section::Section;
|
||||
pub use self::import_entry::{ImportEntry, MemoryType, TableType, GlobalType, External};
|
||||
pub use self::export_entry::{ExportEntry, Internal};
|
||||
pub use self::global_entry::GlobalEntry;
|
||||
pub use self::primitives::{VarUint32, VarUint7, VarUint1, VarInt7, Uint32, Uint64, VarUint64, CountedList};
|
||||
pub use self::primitives::{
|
||||
VarUint32, VarUint7, VarUint1, VarInt7, Uint32,
|
||||
Uint64, VarUint64, CountedList, CountedWriter,
|
||||
};
|
||||
pub use self::types::{ValueType, BlockType};
|
||||
pub use self::ops::{Opcode, Opcodes, InitExpr};
|
||||
pub use self::func::{Func, FuncBody, Local};
|
||||
@ -29,7 +32,7 @@ pub trait Deserialize : Sized {
|
||||
|
||||
pub trait Serialize {
|
||||
type Error;
|
||||
fn serialize<W: io::Write>(&self, writer: &mut W) -> Result<(), Self::Error>;
|
||||
fn serialize<W: io::Write>(self, writer: &mut W) -> Result<(), Self::Error>;
|
||||
}
|
||||
|
||||
#[derive(Debug)]
|
||||
|
@ -1,6 +1,6 @@
|
||||
use std::io;
|
||||
use byteorder::{LittleEndian, ByteOrder};
|
||||
use super::{Error, Deserialize};
|
||||
use super::{Error, Deserialize, Serialize};
|
||||
|
||||
#[derive(Copy, Clone)]
|
||||
pub struct VarUint32(u32);
|
||||
@ -17,6 +17,19 @@ impl From<VarUint32> for u32 {
|
||||
}
|
||||
}
|
||||
|
||||
impl From<u32> for VarUint32 {
|
||||
fn from(i: u32) -> VarUint32 {
|
||||
VarUint32(i)
|
||||
}
|
||||
}
|
||||
|
||||
impl From<usize> for VarUint32 {
|
||||
fn from(i: usize) -> VarUint32 {
|
||||
assert!(i <= ::std::u32::MAX as usize);
|
||||
VarUint32(i as u32)
|
||||
}
|
||||
}
|
||||
|
||||
impl Deserialize for VarUint32 {
|
||||
type Error = Error;
|
||||
|
||||
@ -37,6 +50,24 @@ impl Deserialize for VarUint32 {
|
||||
}
|
||||
}
|
||||
|
||||
impl Serialize for VarUint32 {
|
||||
type Error = Error;
|
||||
|
||||
fn serialize<W: io::Write>(self, writer: &mut W) -> Result<(), Self::Error> {
|
||||
let mut buf = [0u8; 1];
|
||||
let mut v = self.0;
|
||||
while v >= 0x80 {
|
||||
buf[0] = ((v & 0xff) as u8) | 0x80;
|
||||
writer.write_all(&buf[..])?;
|
||||
v >>= 7;
|
||||
}
|
||||
buf[0] = (v & 0xff) as u8;
|
||||
writer.write_all(&buf[..])?;
|
||||
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Copy, Clone)]
|
||||
pub struct VarUint64(u64);
|
||||
|
||||
@ -201,11 +232,83 @@ impl<T: Deserialize> Deserialize for CountedList<T> where T::Error : From<Error>
|
||||
}
|
||||
}
|
||||
|
||||
pub struct CountedWriter<'a, W: 'a + io::Write> {
|
||||
writer: &'a mut W,
|
||||
data: Vec<u8>,
|
||||
}
|
||||
|
||||
impl<'a, W: 'a + io::Write> CountedWriter<'a, W> {
|
||||
pub fn new(writer: &'a mut W) -> Self {
|
||||
CountedWriter {
|
||||
writer: writer,
|
||||
data: Vec::new(),
|
||||
}
|
||||
}
|
||||
|
||||
pub fn done(self) -> io::Result<()> {
|
||||
let writer = self.writer;
|
||||
let data = self.data;
|
||||
VarUint32::from(data.len())
|
||||
.serialize(writer)
|
||||
.map_err(
|
||||
|_| io::Error::new(
|
||||
io::ErrorKind::Other,
|
||||
"Length serialization error",
|
||||
)
|
||||
)?;
|
||||
writer.write_all(&data[..])?;
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
|
||||
impl<'a, W: 'a + io::Write> io::Write for CountedWriter<'a, W> {
|
||||
fn write(&mut self, buf: &[u8]) -> io::Result<usize> {
|
||||
self.data.extend(buf.to_vec());
|
||||
Ok(buf.len())
|
||||
}
|
||||
|
||||
fn flush(&mut self) -> io::Result<()> {
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
|
||||
use super::super::deserialize_buffer;
|
||||
use super::{CountedList, VarInt7};
|
||||
use super::super::{deserialize_buffer, Serialize};
|
||||
use super::{CountedList, VarInt7, VarUint32};
|
||||
|
||||
fn varuint32_ser_test(val: u32, expected: Vec<u8>) {
|
||||
let mut buf = Vec::new();
|
||||
let v1: VarUint32 = val.into();
|
||||
v1.serialize(&mut buf).expect("to be serialized ok");
|
||||
assert_eq!(expected, buf);
|
||||
}
|
||||
|
||||
fn varuint32_de_test(dt: Vec<u8>, expected: u32) {
|
||||
let val: VarUint32 = super::super::deserialize_buffer(dt).expect("buf to be serialized");
|
||||
assert_eq!(expected, val.into());
|
||||
}
|
||||
|
||||
fn varuint32_serde_test(dt: Vec<u8>, val: u32) {
|
||||
varuint32_de_test(dt.clone(), val);
|
||||
varuint32_ser_test(val, dt);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn varuint32_0() {
|
||||
varuint32_serde_test(vec![0u8; 1], 0);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn varuint32_1() {
|
||||
varuint32_serde_test(vec![1u8; 1], 1);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn varuint32_135() {
|
||||
varuint32_serde_test(vec![135u8, 0x01], 135);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn counted_list() {
|
||||
|
@ -1,5 +1,7 @@
|
||||
use std::io;
|
||||
use std::io::Write;
|
||||
use super::{
|
||||
Serialize,
|
||||
Deserialize,
|
||||
Unparsed,
|
||||
Error,
|
||||
@ -15,6 +17,7 @@ use super::{
|
||||
FuncBody,
|
||||
ElementSegment,
|
||||
DataSegment,
|
||||
CountedWriter,
|
||||
};
|
||||
|
||||
use super::types::Type;
|
||||
@ -279,7 +282,7 @@ impl DataSection {
|
||||
}
|
||||
|
||||
impl Deserialize for DataSection {
|
||||
type Error = Error;
|
||||
type Error = Error;
|
||||
|
||||
fn deserialize<R: io::Read>(reader: &mut R) -> Result<Self, Self::Error> {
|
||||
// todo: maybe use reader.take(section_length)
|
||||
@ -289,6 +292,18 @@ impl Deserialize for DataSection {
|
||||
}
|
||||
}
|
||||
|
||||
impl Serialize for DataSection {
|
||||
type Error = Error;
|
||||
|
||||
fn serialize<W: io::Write>(self, writer: &mut W) -> Result<(), Self::Error> {
|
||||
let mut counted_writer = CountedWriter::new(writer);
|
||||
let test = vec![0u8; 12];
|
||||
counted_writer.write(&test[..])?;
|
||||
counted_writer.done()?;
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
|
||||
|
Reference in New Issue
Block a user