diff --git a/src/elements/mod.rs b/src/elements/mod.rs index 37a8f9f..02c916f 100644 --- a/src/elements/mod.rs +++ b/src/elements/mod.rs @@ -85,4 +85,10 @@ pub fn deserialize_file>(p: P) -> Result(contents: Vec) -> Result { let mut reader = io::Cursor::new(contents); T::deserialize(&mut reader) +} + +pub fn serialize(val: T) -> Result, T::Error> { + let mut buf = Vec::new(); + val.serialize(&mut buf)?; + Ok(buf) } \ No newline at end of file diff --git a/src/elements/ops.rs b/src/elements/ops.rs index d6b0a90..7a0bf0e 100644 --- a/src/elements/ops.rs +++ b/src/elements/ops.rs @@ -32,6 +32,20 @@ impl Deserialize for Opcodes { pub struct InitExpr(Vec); +impl InitExpr { + pub fn new(code: Vec) -> Self { + InitExpr(code) + } + + pub fn empty() -> Self { + InitExpr(vec![Opcode::End]) + } + + pub fn code(&self) -> &[Opcode] { + &self.0 + } +} + // todo: check if kind of opcode sequence is valid as an expression impl Deserialize for InitExpr { type Error = Error; diff --git a/src/elements/section.rs b/src/elements/section.rs index 5c489ae..6588171 100644 --- a/src/elements/section.rs +++ b/src/elements/section.rs @@ -276,6 +276,10 @@ impl Deserialize for ElementSection { pub struct DataSection(Vec); impl DataSection { + pub fn new(segments: Vec) -> Self { + DataSection(segments) + } + pub fn entries(&self) -> &[DataSegment] { &self.0 } @@ -296,12 +300,14 @@ impl Serialize for DataSection { type Error = Error; fn serialize(self, writer: &mut W) -> Result<(), Self::Error> { + let mut counted_writer = CountedWriter::new(writer); let data = self.0; let counted_list = CountedListWriter::( data.len(), data.into_iter().map(Into::into), ); - counted_list.serialize(writer)?; + counted_list.serialize(&mut counted_writer)?; + counted_writer.done()?; Ok(()) } } @@ -309,8 +315,11 @@ impl Serialize for DataSection { #[cfg(test)] mod tests { - use super::super::{deserialize_buffer, deserialize_file, ValueType}; - use super::{Section, TypeSection, Type}; + use super::super::{ + deserialize_buffer, deserialize_file, ValueType, InitExpr, DataSegment, + serialize, + }; + use super::{Section, TypeSection, Type, DataSection}; #[test] fn import_section() { @@ -521,4 +530,52 @@ mod tests { } } } + + fn data_payload() -> Vec { + vec![ + 0x0bu8, // section id + 19, // 19 bytes overall + 0x01, // number of segments + 0x00, // index + 0x0b, // just `end` op + // 16x 0x00 + 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00 + ] + } + + #[test] + fn data_section_ser() { + let data_section = DataSection::new( + vec![DataSegment::new(0u32, InitExpr::empty(), vec![0u8; 16])] + ); + + let buf = serialize(data_section).expect("Data section to be serialized"); + + assert_eq!(buf, vec![ + 19u8, // 19 bytes overall + 0x01, // number of segments + 0x00, // index + 0x0b, // just `end` op + 0x00, 0x00, 0x00, 0x00, // 16x 0x00 as in initialization + 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00 + ]); + } + + #[test] + fn data_section_detect() { + let section: Section = + deserialize_buffer(data_payload()).expect("section to be deserialized"); + + match section { + Section::Data(_) => {}, + _ => { + panic!("Payload should be recognized as a data section") + } + } + } } \ No newline at end of file diff --git a/src/elements/segment.rs b/src/elements/segment.rs index 164cbb2..d7fde04 100644 --- a/src/elements/segment.rs +++ b/src/elements/segment.rs @@ -40,6 +40,14 @@ pub struct DataSegment { } impl DataSegment { + pub fn new(index: u32, offset: InitExpr, value: Vec) -> Self { + DataSegment { + index: index, + offset: offset, + value: value, + } + } + pub fn index(&self) -> u32 { self.index } pub fn offset(&self) -> &InitExpr { &self.offset } pub fn value(&self) -> &[u8] { &self.value }