diff --git a/androscalpel_serializer/src/core.rs b/androscalpel_serializer/src/core.rs new file mode 100644 index 0000000..595cdc1 --- /dev/null +++ b/androscalpel_serializer/src/core.rs @@ -0,0 +1,849 @@ +/// The main core of the parser. +/// +/// TODO: split into more module (error, trait, base type) +use std::io::{Cursor, Read, Seek, SeekFrom, Write}; + +pub use androscalpel_serializer_derive::*; + +#[derive(Debug, PartialEq, Eq)] +pub enum Error { + InputTooSmall(String), // TODO: find a better name + SerializeationError(String), +} + +pub type Result = core::result::Result; + +pub trait ReadSeek: Read + Seek {} +impl ReadSeek for T {} + +impl std::fmt::Display for Error { + fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result { + match self { + Self::InputTooSmall(msg) => write!(f, "Error: {}", msg), + Self::SerializeationError(msg) => write!(f, "Error: {}", msg), + } + } +} + +impl std::error::Error for Error {} + +pub trait Serializable { + fn serialize(&self, output: &mut dyn Write) -> Result<()>; + fn deserialize(input: &mut dyn ReadSeek) -> Result + where + Self: Sized; + fn size(&self) -> usize; + + fn serialize_to_vec(&self) -> Result> { + let mut output = Cursor::new(Vec::::new()); + self.serialize(&mut output)?; + Ok(output.into_inner()) + } + + fn deserialize_from_slice(input: &[u8]) -> Result + where + Self: Sized, + { + let mut buffer = Cursor::new(input); + Self::deserialize(&mut buffer) + } +} + +pub trait SerializableUntil { + fn serialize(&self, output: &mut dyn Write, end_val: U) -> Result<()>; + fn deserialize(input: &mut dyn ReadSeek, end_val: U) -> Result + where + Self: Sized; + fn size(&self, end_val: U) -> usize; + fn serialize_to_vec(&self, end_val: U) -> Result> { + let mut output = Cursor::new(Vec::::new()); + self.serialize(&mut output, end_val)?; + Ok(output.into_inner()) + } + + fn deserialize_from_slice(input: &[u8], end_val: U) -> Result + where + Self: Sized, + { + let mut buffer = Cursor::new(input); + Self::deserialize(&mut buffer, end_val) + } +} + +impl SerializableUntil for Vec { + fn serialize(&self, output: &mut dyn Write, end_val: U) -> Result<()> { + for data in self { + data.serialize(output)?; + } + end_val.serialize(output) + } + + fn deserialize(input: &mut dyn ReadSeek, end_val: U) -> Result + where + Self: Sized, + { + let mut data = Self::new(); + loop { + let pos = input.stream_position().map_err(|err| { + Error::SerializeationError(format!("Failled to get position in steam: {err}")) + })?; + match U::deserialize(input) { + Ok(val) if val == end_val => break Ok(data), + Err(err) => break Err(err), + Ok(_) => input.seek(SeekFrom::Start(pos)).map_err(|err| { + Error::SerializeationError(format!( + "Failled to get to position in steam: {err}" + )) + })?, + }; + data.push(D::deserialize(input)?); + } + } + + fn size(&self, end_val: U) -> usize { + self.iter().map(|data| data.size()).sum::() + end_val.size() + } +} + +impl Serializable for u8 { + fn serialize(&self, output: &mut dyn Write) -> Result<()> { + output.write_all(&self.to_be_bytes()).map_err(|err| { + Error::SerializeationError(format!("Failed to write serialize u8 to output: {err}")) + })?; + Ok(()) + } + + fn deserialize(input: &mut dyn ReadSeek) -> Result { + let mut buffer = [0u8; 1]; + input.read_exact(&mut buffer).map_err(|_| { + Error::InputTooSmall("Failed to read all bytes for u8 from the input".into()) + })?; + Ok(Self::from_be_bytes(buffer)) + } + + fn size(&self) -> usize { + 1 + } +} + +impl Serializable for i8 { + fn serialize(&self, output: &mut dyn Write) -> Result<()> { + output.write_all(&self.to_be_bytes()).map_err(|err| { + Error::SerializeationError(format!("Failed to write serialize i8 to output: {err}")) + })?; + Ok(()) + } + + fn deserialize(input: &mut dyn ReadSeek) -> Result { + let mut buffer = [0u8; 1]; + input.read_exact(&mut buffer).map_err(|_| { + Error::InputTooSmall("Failed to read all bytes for i8 from the input".into()) + })?; + Ok(Self::from_be_bytes(buffer)) + } + + fn size(&self) -> usize { + 1 + } +} + +impl Serializable for u16 { + fn serialize(&self, output: &mut dyn Write) -> Result<()> { + output.write_all(&self.to_be_bytes()).map_err(|err| { + Error::SerializeationError(format!("Failed to write serialize u16 to output: {err}")) + })?; + Ok(()) + } + + fn deserialize(input: &mut dyn ReadSeek) -> Result { + let mut buffer = [0u8; 2]; + input.read_exact(&mut buffer).map_err(|_| { + Error::InputTooSmall("Failed to read all bytes for u16 from the input".into()) + })?; + Ok(Self::from_be_bytes(buffer)) + } + + fn size(&self) -> usize { + 2 + } +} + +impl Serializable for i16 { + fn serialize(&self, output: &mut dyn Write) -> Result<()> { + output.write_all(&self.to_be_bytes()).map_err(|err| { + Error::SerializeationError(format!("Failed to write serialize i16 to output: {err}")) + })?; + Ok(()) + } + + fn deserialize(input: &mut dyn ReadSeek) -> Result { + let mut buffer = [0u8; 2]; + input.read_exact(&mut buffer).map_err(|_| { + Error::InputTooSmall("Failed to read all bytes for i16 from the input".into()) + })?; + Ok(Self::from_be_bytes(buffer)) + } + + fn size(&self) -> usize { + 2 + } +} + +impl Serializable for u32 { + fn serialize(&self, output: &mut dyn Write) -> Result<()> { + output.write_all(&self.to_be_bytes()).map_err(|err| { + Error::SerializeationError(format!("Failed to write serialize u32 to output: {err}")) + })?; + Ok(()) + } + + fn deserialize(input: &mut dyn ReadSeek) -> Result { + let mut buffer = [0u8; 4]; + input.read_exact(&mut buffer).map_err(|_| { + Error::InputTooSmall("Failed to read all bytes for u32 from the input".into()) + })?; + Ok(Self::from_be_bytes(buffer)) + } + + fn size(&self) -> usize { + 4 + } +} + +impl Serializable for i32 { + fn serialize(&self, output: &mut dyn Write) -> Result<()> { + output.write_all(&self.to_be_bytes()).map_err(|err| { + Error::SerializeationError(format!("Failed to write serialize i32 to output: {err}")) + })?; + Ok(()) + } + + fn deserialize(input: &mut dyn ReadSeek) -> Result { + let mut buffer = [0u8; 4]; + input.read_exact(&mut buffer).map_err(|_| { + Error::InputTooSmall("Failed to read all bytes for i32 from the input".into()) + })?; + Ok(Self::from_be_bytes(buffer)) + } + + fn size(&self) -> usize { + 4 + } +} + +impl Serializable for u64 { + fn serialize(&self, output: &mut dyn Write) -> Result<()> { + output.write_all(&self.to_be_bytes()).map_err(|err| { + Error::SerializeationError(format!("Failed to write serialize u64 to output: {err}")) + })?; + Ok(()) + } + + fn deserialize(input: &mut dyn ReadSeek) -> Result { + let mut buffer = [0u8; 8]; + input.read_exact(&mut buffer).map_err(|_| { + Error::InputTooSmall("Failed to read all bytes for u64 from the input".into()) + })?; + Ok(Self::from_be_bytes(buffer)) + } + + fn size(&self) -> usize { + 8 + } +} + +impl Serializable for i64 { + fn serialize(&self, output: &mut dyn Write) -> Result<()> { + output.write_all(&self.to_be_bytes()).map_err(|err| { + Error::SerializeationError(format!("Failed to write serialize i64 to output: {err}")) + })?; + Ok(()) + } + + fn deserialize(input: &mut dyn ReadSeek) -> Result { + let mut buffer = [0u8; 8]; + input.read_exact(&mut buffer).map_err(|_| { + Error::InputTooSmall("Failed to read all bytes for i64 from the input".into()) + })?; + Ok(Self::from_be_bytes(buffer)) + } + + fn size(&self) -> usize { + 8 + } +} + +impl Serializable for u128 { + fn serialize(&self, output: &mut dyn Write) -> Result<()> { + output.write_all(&self.to_be_bytes()).map_err(|err| { + Error::SerializeationError(format!("Failed to write serialize u128 to output: {err}")) + })?; + Ok(()) + } + + fn deserialize(input: &mut dyn ReadSeek) -> Result { + let mut buffer = [0u8; 16]; + input.read_exact(&mut buffer).map_err(|_| { + Error::InputTooSmall("Failed to read all bytes for u128 from the input".into()) + })?; + Ok(Self::from_be_bytes(buffer)) + } + + fn size(&self) -> usize { + 16 + } +} + +impl Serializable for i128 { + fn serialize(&self, output: &mut dyn Write) -> Result<()> { + output.write_all(&self.to_be_bytes()).map_err(|err| { + Error::SerializeationError(format!("Failed to write serialize i128 to output: {err}")) + })?; + Ok(()) + } + + fn deserialize(input: &mut dyn ReadSeek) -> Result { + let mut buffer = [0u8; 16]; + input.read_exact(&mut buffer).map_err(|_| { + Error::InputTooSmall("Failed to read all bytes for i128 from the input".into()) + })?; + Ok(Self::from_be_bytes(buffer)) + } + + fn size(&self) -> usize { + 16 + } +} + +#[cfg(test)] +mod test { + use super::*; + // Hacky hack to refere to "crate" by its name + use crate as androscalpel_serializer; + + #[test] + fn serialize_u8() { + assert_eq!(42u8.serialize_to_vec().unwrap(), vec![42u8]); + } + + #[test] + fn deserialize_u8() { + assert_eq!(u8::deserialize_from_slice(&[42u8]).unwrap(), 42u8); + } + + #[test] + fn size_u8() { + assert_eq!(42u8.size(), 1); + } + + #[test] + fn serialize_u16() { + assert_eq!(0x1234u16.serialize_to_vec().unwrap(), vec![0x12u8, 0x34u8]); + } + + #[test] + fn deserialize_u16() { + assert_eq!( + u16::deserialize_from_slice(&[0x12u8, 0x34u8]).unwrap(), + 0x1234u16 + ); + } + + #[test] + fn size_u16() { + assert_eq!(0x1234u16.size(), 2); + } + + #[test] + fn serialize_u32() { + assert_eq!( + 0x12345678u32.serialize_to_vec().unwrap(), + vec![0x12u8, 0x34u8, 0x56u8, 0x78u8] + ); + } + + #[test] + fn deserialize_u32() { + assert_eq!( + u32::deserialize_from_slice(&[0x12u8, 0x34u8, 0x56u8, 0x78u8]).unwrap(), + 0x12345678u32 + ); + } + + #[test] + fn size_u32() { + assert_eq!(0x12345678u32.size(), 4); + } + + #[test] + fn serialize_u64() { + assert_eq!( + 0x123456789ABCDEF0u64.serialize_to_vec().unwrap(), + vec![0x12u8, 0x34u8, 0x56u8, 0x78u8, 0x9Au8, 0xBCu8, 0xDEu8, 0xF0u8] + ); + } + + #[test] + fn deserialize_u64() { + assert_eq!( + u64::deserialize_from_slice(&[ + 0x12u8, 0x34u8, 0x56u8, 0x78u8, 0x9Au8, 0xBCu8, 0xDEu8, 0xF0u8 + ]) + .unwrap(), + 0x123456789ABCDEF0u64 + ); + } + + #[test] + fn size_u64() { + assert_eq!(0x123456789ABCDEF0u64.size(), 8); + } + + #[test] + fn serialize_u128() { + assert_eq!( + 0x123456789ABCDEF0123456789ABCDEF0u128 + .serialize_to_vec() + .unwrap(), + vec![ + 0x12u8, 0x34u8, 0x56u8, 0x78u8, 0x9Au8, 0xBCu8, 0xDEu8, 0xF0u8, 0x12u8, 0x34u8, + 0x56u8, 0x78u8, 0x9Au8, 0xBCu8, 0xDEu8, 0xF0u8 + ] + ); + } + + #[test] + fn deserialize_u128() { + assert_eq!( + u128::deserialize_from_slice(&[ + 0x12u8, 0x34u8, 0x56u8, 0x78u8, 0x9Au8, 0xBCu8, 0xDEu8, 0xF0u8, 0x12u8, 0x34u8, + 0x56u8, 0x78u8, 0x9Au8, 0xBCu8, 0xDEu8, 0xF0u8 + ]) + .unwrap(), + 0x123456789ABCDEF0123456789ABCDEF0u128 + ); + } + + #[test] + fn size_u128() { + assert_eq!(0x123456789ABCDEF0123456789ABCDEF0u128.size(), 16); + } + + #[derive(Serializable, Debug, PartialEq, Eq)] + struct NamedComposedTest { + a: u8, + b: u16, + c: u32, + d: u64, + f: u128, + } + + #[derive(Serializable, Debug, PartialEq, Eq)] + struct UnamedComposedTest(u8, u16, u32, u64, u128); + + #[test] + fn serialize_unnamed_derived() { + let t = UnamedComposedTest( + 42u8, + 0x1234u16, + 0x12345678u32, + 0x123456789ABCDEF0u64, + 0x123456789ABCDEF0123456789ABCDEF0u128, + ); + assert_eq!( + t.serialize_to_vec().unwrap(), + vec![ + 42u8, 0x12u8, 0x34u8, 0x12u8, 0x34u8, 0x56u8, 0x78u8, 0x12u8, 0x34u8, 0x56u8, + 0x78u8, 0x9Au8, 0xBCu8, 0xDEu8, 0xF0u8, 0x12u8, 0x34u8, 0x56u8, 0x78u8, 0x9Au8, + 0xBCu8, 0xDEu8, 0xF0u8, 0x12u8, 0x34u8, 0x56u8, 0x78u8, 0x9Au8, 0xBCu8, 0xDEu8, + 0xF0u8 + ] + ); + } + + #[test] + fn deserialize_named_derived() { + let t = UnamedComposedTest( + 42u8, + 0x1234u16, + 0x12345678u32, + 0x123456789ABCDEF0u64, + 0x123456789ABCDEF0123456789ABCDEF0u128, + ); + let serialized = vec![ + 42u8, 0x12u8, 0x34u8, 0x12u8, 0x34u8, 0x56u8, 0x78u8, 0x12u8, 0x34u8, 0x56u8, 0x78u8, + 0x9Au8, 0xBCu8, 0xDEu8, 0xF0u8, 0x12u8, 0x34u8, 0x56u8, 0x78u8, 0x9Au8, 0xBCu8, 0xDEu8, + 0xF0u8, 0x12u8, 0x34u8, 0x56u8, 0x78u8, 0x9Au8, 0xBCu8, 0xDEu8, 0xF0u8, + ]; + assert_eq!( + UnamedComposedTest::deserialize_from_slice(&serialized).unwrap(), + t + ); + } + + #[test] + fn size_unnamed_derived() { + let t = UnamedComposedTest( + 42u8, + 0x1234u16, + 0x12345678u32, + 0x123456789ABCDEF0u64, + 0x123456789ABCDEF0123456789ABCDEF0u128, + ); + assert_eq!(t.size(), 1 + 2 + 4 + 8 + 16); + } + + #[derive(Serializable, Debug, PartialEq, Eq)] + struct NamedArrayComposedTest { + a: [u8; 1], + b: [u16; 2], + c: [u32; 3], + d: [u64; 4], + e: [u128; 5], + } + + #[derive(Serializable, Debug, PartialEq, Eq)] + struct UnamedArrayComposedTest([u8; 1], [u16; 2], [u32; 3], [u64; 4], [u128; 5]); + + #[test] + fn serialize_array_unamed_derived() { + let t = UnamedArrayComposedTest( + [42u8], + [0x1234u16, 0x1234u16], + [0x12345678u32, 0x12345678u32, 0x12345678u32], + [ + 0x123456789ABCDEF0u64, + 0x123456789ABCDEF0u64, + 0x123456789ABCDEF0u64, + 0x123456789ABCDEF0u64, + ], + [ + 0x123456789ABCDEF0123456789ABCDEF0u128, + 0x123456789ABCDEF0123456789ABCDEF0u128, + 0x123456789ABCDEF0123456789ABCDEF0u128, + 0x123456789ABCDEF0123456789ABCDEF0u128, + 0x123456789ABCDEF0123456789ABCDEF0u128, + ], + ); + assert_eq!( + t.serialize_to_vec().unwrap(), + vec![ + 42u8, 0x12u8, 0x34u8, 0x12u8, 0x34u8, 0x12u8, 0x34u8, 0x56u8, 0x78u8, 0x12u8, + 0x34u8, 0x56u8, 0x78u8, 0x12u8, 0x34u8, 0x56u8, 0x78u8, 0x12u8, 0x34u8, 0x56u8, + 0x78u8, 0x9Au8, 0xBCu8, 0xDEu8, 0xF0u8, 0x12u8, 0x34u8, 0x56u8, 0x78u8, 0x9Au8, + 0xBCu8, 0xDEu8, 0xF0u8, 0x12u8, 0x34u8, 0x56u8, 0x78u8, 0x9Au8, 0xBCu8, 0xDEu8, + 0xF0u8, 0x12u8, 0x34u8, 0x56u8, 0x78u8, 0x9Au8, 0xBCu8, 0xDEu8, 0xF0u8, 0x12u8, + 0x34u8, 0x56u8, 0x78u8, 0x9Au8, 0xBCu8, 0xDEu8, 0xF0u8, 0x12u8, 0x34u8, 0x56u8, + 0x78u8, 0x9Au8, 0xBCu8, 0xDEu8, 0xF0u8, 0x12u8, 0x34u8, 0x56u8, 0x78u8, 0x9Au8, + 0xBCu8, 0xDEu8, 0xF0u8, 0x12u8, 0x34u8, 0x56u8, 0x78u8, 0x9Au8, 0xBCu8, 0xDEu8, + 0xF0u8, 0x12u8, 0x34u8, 0x56u8, 0x78u8, 0x9Au8, 0xBCu8, 0xDEu8, 0xF0u8, 0x12u8, + 0x34u8, 0x56u8, 0x78u8, 0x9Au8, 0xBCu8, 0xDEu8, 0xF0u8, 0x12u8, 0x34u8, 0x56u8, + 0x78u8, 0x9Au8, 0xBCu8, 0xDEu8, 0xF0u8, 0x12u8, 0x34u8, 0x56u8, 0x78u8, 0x9Au8, + 0xBCu8, 0xDEu8, 0xF0u8, 0x12u8, 0x34u8, 0x56u8, 0x78u8, 0x9Au8, 0xBCu8, 0xDEu8, + 0xF0u8, 0x12u8, 0x34u8, 0x56u8, 0x78u8, 0x9Au8, 0xBCu8, 0xDEu8, 0xF0u8 + ] + ); + } + + #[test] + fn deserialize_array_unamed_derived() { + let t = UnamedArrayComposedTest( + [42u8], + [0x1234u16, 0x1234u16], + [0x12345678u32, 0x12345678u32, 0x12345678u32], + [ + 0x123456789ABCDEF0u64, + 0x123456789ABCDEF0u64, + 0x123456789ABCDEF0u64, + 0x123456789ABCDEF0u64, + ], + [ + 0x123456789ABCDEF0123456789ABCDEF0u128, + 0x123456789ABCDEF0123456789ABCDEF0u128, + 0x123456789ABCDEF0123456789ABCDEF0u128, + 0x123456789ABCDEF0123456789ABCDEF0u128, + 0x123456789ABCDEF0123456789ABCDEF0u128, + ], + ); + let serialized = vec![ + 42u8, 0x12u8, 0x34u8, 0x12u8, 0x34u8, 0x12u8, 0x34u8, 0x56u8, 0x78u8, 0x12u8, 0x34u8, + 0x56u8, 0x78u8, 0x12u8, 0x34u8, 0x56u8, 0x78u8, 0x12u8, 0x34u8, 0x56u8, 0x78u8, 0x9Au8, + 0xBCu8, 0xDEu8, 0xF0u8, 0x12u8, 0x34u8, 0x56u8, 0x78u8, 0x9Au8, 0xBCu8, 0xDEu8, 0xF0u8, + 0x12u8, 0x34u8, 0x56u8, 0x78u8, 0x9Au8, 0xBCu8, 0xDEu8, 0xF0u8, 0x12u8, 0x34u8, 0x56u8, + 0x78u8, 0x9Au8, 0xBCu8, 0xDEu8, 0xF0u8, 0x12u8, 0x34u8, 0x56u8, 0x78u8, 0x9Au8, 0xBCu8, + 0xDEu8, 0xF0u8, 0x12u8, 0x34u8, 0x56u8, 0x78u8, 0x9Au8, 0xBCu8, 0xDEu8, 0xF0u8, 0x12u8, + 0x34u8, 0x56u8, 0x78u8, 0x9Au8, 0xBCu8, 0xDEu8, 0xF0u8, 0x12u8, 0x34u8, 0x56u8, 0x78u8, + 0x9Au8, 0xBCu8, 0xDEu8, 0xF0u8, 0x12u8, 0x34u8, 0x56u8, 0x78u8, 0x9Au8, 0xBCu8, 0xDEu8, + 0xF0u8, 0x12u8, 0x34u8, 0x56u8, 0x78u8, 0x9Au8, 0xBCu8, 0xDEu8, 0xF0u8, 0x12u8, 0x34u8, + 0x56u8, 0x78u8, 0x9Au8, 0xBCu8, 0xDEu8, 0xF0u8, 0x12u8, 0x34u8, 0x56u8, 0x78u8, 0x9Au8, + 0xBCu8, 0xDEu8, 0xF0u8, 0x12u8, 0x34u8, 0x56u8, 0x78u8, 0x9Au8, 0xBCu8, 0xDEu8, 0xF0u8, + 0x12u8, 0x34u8, 0x56u8, 0x78u8, 0x9Au8, 0xBCu8, 0xDEu8, 0xF0u8, + ]; + assert_eq!( + UnamedArrayComposedTest::deserialize_from_slice(&serialized).unwrap(), + t + ); + } + + #[test] + fn size_array_unamed_derived() { + let t = UnamedArrayComposedTest( + [42u8], + [0x1234u16, 0x1234u16], + [0x12345678u32, 0x12345678u32, 0x12345678u32], + [ + 0x123456789ABCDEF0u64, + 0x123456789ABCDEF0u64, + 0x123456789ABCDEF0u64, + 0x123456789ABCDEF0u64, + ], + [ + 0x123456789ABCDEF0123456789ABCDEF0u128, + 0x123456789ABCDEF0123456789ABCDEF0u128, + 0x123456789ABCDEF0123456789ABCDEF0u128, + 0x123456789ABCDEF0123456789ABCDEF0u128, + 0x123456789ABCDEF0123456789ABCDEF0u128, + ], + ); + assert_eq!(t.size(), 1 + 2 * 2 + 4 * 3 + 8 * 4 + 16 * 5); + } + + #[test] + fn serialize_array_named_derived() { + let t = NamedArrayComposedTest { + a: [42u8], + b: [0x1234u16, 0x1234u16], + c: [0x12345678u32, 0x12345678u32, 0x12345678u32], + d: [ + 0x123456789ABCDEF0u64, + 0x123456789ABCDEF0u64, + 0x123456789ABCDEF0u64, + 0x123456789ABCDEF0u64, + ], + e: [ + 0x123456789ABCDEF0123456789ABCDEF0u128, + 0x123456789ABCDEF0123456789ABCDEF0u128, + 0x123456789ABCDEF0123456789ABCDEF0u128, + 0x123456789ABCDEF0123456789ABCDEF0u128, + 0x123456789ABCDEF0123456789ABCDEF0u128, + ], + }; + assert_eq!( + t.serialize_to_vec().unwrap(), + vec![ + 42u8, 0x12u8, 0x34u8, 0x12u8, 0x34u8, 0x12u8, 0x34u8, 0x56u8, 0x78u8, 0x12u8, + 0x34u8, 0x56u8, 0x78u8, 0x12u8, 0x34u8, 0x56u8, 0x78u8, 0x12u8, 0x34u8, 0x56u8, + 0x78u8, 0x9Au8, 0xBCu8, 0xDEu8, 0xF0u8, 0x12u8, 0x34u8, 0x56u8, 0x78u8, 0x9Au8, + 0xBCu8, 0xDEu8, 0xF0u8, 0x12u8, 0x34u8, 0x56u8, 0x78u8, 0x9Au8, 0xBCu8, 0xDEu8, + 0xF0u8, 0x12u8, 0x34u8, 0x56u8, 0x78u8, 0x9Au8, 0xBCu8, 0xDEu8, 0xF0u8, 0x12u8, + 0x34u8, 0x56u8, 0x78u8, 0x9Au8, 0xBCu8, 0xDEu8, 0xF0u8, 0x12u8, 0x34u8, 0x56u8, + 0x78u8, 0x9Au8, 0xBCu8, 0xDEu8, 0xF0u8, 0x12u8, 0x34u8, 0x56u8, 0x78u8, 0x9Au8, + 0xBCu8, 0xDEu8, 0xF0u8, 0x12u8, 0x34u8, 0x56u8, 0x78u8, 0x9Au8, 0xBCu8, 0xDEu8, + 0xF0u8, 0x12u8, 0x34u8, 0x56u8, 0x78u8, 0x9Au8, 0xBCu8, 0xDEu8, 0xF0u8, 0x12u8, + 0x34u8, 0x56u8, 0x78u8, 0x9Au8, 0xBCu8, 0xDEu8, 0xF0u8, 0x12u8, 0x34u8, 0x56u8, + 0x78u8, 0x9Au8, 0xBCu8, 0xDEu8, 0xF0u8, 0x12u8, 0x34u8, 0x56u8, 0x78u8, 0x9Au8, + 0xBCu8, 0xDEu8, 0xF0u8, 0x12u8, 0x34u8, 0x56u8, 0x78u8, 0x9Au8, 0xBCu8, 0xDEu8, + 0xF0u8, 0x12u8, 0x34u8, 0x56u8, 0x78u8, 0x9Au8, 0xBCu8, 0xDEu8, 0xF0u8 + ] + ); + } + + #[test] + fn deserialize_array_named_derived() { + let t = NamedArrayComposedTest { + a: [42u8], + b: [0x1234u16, 0x1234u16], + c: [0x12345678u32, 0x12345678u32, 0x12345678u32], + d: [ + 0x123456789ABCDEF0u64, + 0x123456789ABCDEF0u64, + 0x123456789ABCDEF0u64, + 0x123456789ABCDEF0u64, + ], + e: [ + 0x123456789ABCDEF0123456789ABCDEF0u128, + 0x123456789ABCDEF0123456789ABCDEF0u128, + 0x123456789ABCDEF0123456789ABCDEF0u128, + 0x123456789ABCDEF0123456789ABCDEF0u128, + 0x123456789ABCDEF0123456789ABCDEF0u128, + ], + }; + let serialized = vec![ + 42u8, 0x12u8, 0x34u8, 0x12u8, 0x34u8, 0x12u8, 0x34u8, 0x56u8, 0x78u8, 0x12u8, 0x34u8, + 0x56u8, 0x78u8, 0x12u8, 0x34u8, 0x56u8, 0x78u8, 0x12u8, 0x34u8, 0x56u8, 0x78u8, 0x9Au8, + 0xBCu8, 0xDEu8, 0xF0u8, 0x12u8, 0x34u8, 0x56u8, 0x78u8, 0x9Au8, 0xBCu8, 0xDEu8, 0xF0u8, + 0x12u8, 0x34u8, 0x56u8, 0x78u8, 0x9Au8, 0xBCu8, 0xDEu8, 0xF0u8, 0x12u8, 0x34u8, 0x56u8, + 0x78u8, 0x9Au8, 0xBCu8, 0xDEu8, 0xF0u8, 0x12u8, 0x34u8, 0x56u8, 0x78u8, 0x9Au8, 0xBCu8, + 0xDEu8, 0xF0u8, 0x12u8, 0x34u8, 0x56u8, 0x78u8, 0x9Au8, 0xBCu8, 0xDEu8, 0xF0u8, 0x12u8, + 0x34u8, 0x56u8, 0x78u8, 0x9Au8, 0xBCu8, 0xDEu8, 0xF0u8, 0x12u8, 0x34u8, 0x56u8, 0x78u8, + 0x9Au8, 0xBCu8, 0xDEu8, 0xF0u8, 0x12u8, 0x34u8, 0x56u8, 0x78u8, 0x9Au8, 0xBCu8, 0xDEu8, + 0xF0u8, 0x12u8, 0x34u8, 0x56u8, 0x78u8, 0x9Au8, 0xBCu8, 0xDEu8, 0xF0u8, 0x12u8, 0x34u8, + 0x56u8, 0x78u8, 0x9Au8, 0xBCu8, 0xDEu8, 0xF0u8, 0x12u8, 0x34u8, 0x56u8, 0x78u8, 0x9Au8, + 0xBCu8, 0xDEu8, 0xF0u8, 0x12u8, 0x34u8, 0x56u8, 0x78u8, 0x9Au8, 0xBCu8, 0xDEu8, 0xF0u8, + 0x12u8, 0x34u8, 0x56u8, 0x78u8, 0x9Au8, 0xBCu8, 0xDEu8, 0xF0u8, + ]; + assert_eq!( + NamedArrayComposedTest::deserialize_from_slice(&serialized).unwrap(), + t + ); + } + + #[test] + fn size_array_named_derived() { + let t = NamedArrayComposedTest { + a: [42u8], + b: [0x1234u16, 0x1234u16], + c: [0x12345678u32, 0x12345678u32, 0x12345678u32], + d: [ + 0x123456789ABCDEF0u64, + 0x123456789ABCDEF0u64, + 0x123456789ABCDEF0u64, + 0x123456789ABCDEF0u64, + ], + e: [ + 0x123456789ABCDEF0123456789ABCDEF0u128, + 0x123456789ABCDEF0123456789ABCDEF0u128, + 0x123456789ABCDEF0123456789ABCDEF0u128, + 0x123456789ABCDEF0123456789ABCDEF0u128, + 0x123456789ABCDEF0123456789ABCDEF0u128, + ], + }; + assert_eq!(t.size(), 1 + 2 * 2 + 4 * 3 + 8 * 4 + 16 * 5); + } + + #[test] + fn size_vec_serializable_until() { + #[derive(Serializable, PartialEq, Eq)] + struct UntilArray([u8; 3]); + let v = vec![0u8, 1u8, 2u8, 3u8]; + assert_eq!(v.size(UntilArray([0, 0, 0])), 7); + assert_eq!(v.size(0u8), 5); + } + + #[test] + fn serialize_vec_serializable_until() { + #[derive(Serializable, PartialEq, Eq)] + struct UntilArray([u8; 3]); + let v = vec![0u8, 1u8, 2u8, 3u8]; + assert_eq!( + v.serialize_to_vec(UntilArray([0, 0, 0])).unwrap(), + vec![0u8, 1u8, 2u8, 3u8, 0u8, 0u8, 0u8] + ); + assert_eq!( + v.serialize_to_vec(0u8).unwrap(), + vec![0u8, 1u8, 2u8, 3u8, 0u8] + ); + } + + #[test] + fn deserialize_vec_serializable_until() { + #[derive(Serializable, PartialEq, Eq)] + struct UntilArray([u8; 3]); + let v1 = vec![0u8, 1u8, 2u8, 3u8]; + let serialized_1 = &[0u8, 1u8, 2u8, 3u8, 0u8, 0u8, 0u8]; + let serialized_2 = &[0u8, 1u8, 2u8, 3u8, 0u8]; + assert_eq!( + v1, + Vec::::deserialize_from_slice(serialized_1, UntilArray([0, 0, 0])).unwrap() + ); + assert_eq!( + Vec::::new(), + Vec::::deserialize_from_slice(serialized_2, 0u8).unwrap() + ); + } + + #[derive(Serializable, PartialEq, Eq, Debug)] + struct UntilArray2([u8; 2]); + #[derive(Serializable, Debug, PartialEq, Eq)] + struct SerializableUntilNamed { + pr: u16, + #[until(u8, UntilArray2, UntilArray2([0u8, 0u8]))] + v: Vec, + ps: u32, + } + + #[test] + fn size_named_serializable_until() { + let v = SerializableUntilNamed { + pr: 0, + v: vec![1, 2, 3], + ps: 0, + }; + assert_eq!(v.size(), 2 + 3 + 2 + 4); + } + + #[test] + fn serialize_named_serializable_until() { + let v = SerializableUntilNamed { + pr: 0, + v: vec![1, 2, 3], + ps: 0x80000000, + }; + assert_eq!( + v.serialize_to_vec().unwrap(), + vec![0, 0, 1, 2, 3, 0, 0, 0x80, 0, 0, 0], + ); + } + + #[test] + fn deserialize_named_serializable_until() { + let v = SerializableUntilNamed { + pr: 0, + v: vec![1, 2, 3], + ps: 0x80000000, + }; + let s = &[0, 0, 1, 2, 3, 0, 0, 0x80, 0, 0, 0]; + assert_eq!( + v, + SerializableUntilNamed::deserialize_from_slice(s).unwrap() + ); + } + + #[derive(Serializable, PartialEq, Eq, Debug)] + #[prefix_type(u8)] + enum TestEnum { + #[prefix(0)] + Zero, + #[prefix(1)] + One(u32), + #[prefix(2)] + Two { a: u16, b: u32 }, + } + + #[test] + fn size_enum() { + assert_eq!(TestEnum::Zero.size(), 1); + assert_eq!(TestEnum::One(42).size(), 5); + assert_eq!(TestEnum::Two { a: 1, b: 2 }.size(), 7); + } + + #[test] + fn serialize_enum() { + assert_eq!(TestEnum::Zero.serialize_to_vec().unwrap(), vec![0u8]); + assert_eq!( + TestEnum::One(42).serialize_to_vec().unwrap(), + vec![1u8, 0u8, 0u8, 0u8, 42u8] + ); + assert_eq!( + TestEnum::Two { a: 1, b: 2 }.serialize_to_vec().unwrap(), + vec![2u8, 0u8, 1u8, 0u8, 0u8, 0u8, 2u8] + ); + } + + #[test] + fn deserialize_enum() { + assert_eq!( + TestEnum::deserialize_from_slice(&[0u8]).unwrap(), + TestEnum::Zero + ); + assert_eq!( + TestEnum::deserialize_from_slice(&[1u8, 0u8, 0u8, 0u8, 42u8]).unwrap(), + TestEnum::One(42) + ); + assert_eq!( + TestEnum::deserialize_from_slice(&[2u8, 0u8, 1u8, 0u8, 0u8, 0u8, 2u8]).unwrap(), + TestEnum::Two { a: 1, b: 2 } + ); + assert!(TestEnum::deserialize_from_slice(&[255u8]).is_err()); + } +} diff --git a/androscalpel_serializer/src/lib.rs b/androscalpel_serializer/src/lib.rs index bd474dd..ea2646e 100644 --- a/androscalpel_serializer/src/lib.rs +++ b/androscalpel_serializer/src/lib.rs @@ -1,846 +1,3 @@ -use std::io::{Cursor, Read, Seek, SeekFrom, Write}; +pub mod core; -pub use androscalpel_serializer_derive::*; - -#[derive(Debug, PartialEq, Eq)] -pub enum Error { - InputTooSmall(String), // TODO: find a better name - SerializeationError(String), -} - -pub type Result = core::result::Result; - -pub trait ReadSeek: Read + Seek {} -impl ReadSeek for T {} - -impl std::fmt::Display for Error { - fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result { - match self { - Self::InputTooSmall(msg) => write!(f, "Error: {}", msg), - Self::SerializeationError(msg) => write!(f, "Error: {}", msg), - } - } -} - -impl std::error::Error for Error {} - -pub trait Serializable { - fn serialize(&self, output: &mut dyn Write) -> Result<()>; - fn deserialize(input: &mut dyn ReadSeek) -> Result - where - Self: Sized; - fn size(&self) -> usize; - - fn serialize_to_vec(&self) -> Result> { - let mut output = Cursor::new(Vec::::new()); - self.serialize(&mut output)?; - Ok(output.into_inner()) - } - - fn deserialize_from_slice(input: &[u8]) -> Result - where - Self: Sized, - { - let mut buffer = Cursor::new(input); - Self::deserialize(&mut buffer) - } -} - -pub trait SerializableUntil { - fn serialize(&self, output: &mut dyn Write, end_val: U) -> Result<()>; - fn deserialize(input: &mut dyn ReadSeek, end_val: U) -> Result - where - Self: Sized; - fn size(&self, end_val: U) -> usize; - fn serialize_to_vec(&self, end_val: U) -> Result> { - let mut output = Cursor::new(Vec::::new()); - self.serialize(&mut output, end_val)?; - Ok(output.into_inner()) - } - - fn deserialize_from_slice(input: &[u8], end_val: U) -> Result - where - Self: Sized, - { - let mut buffer = Cursor::new(input); - Self::deserialize(&mut buffer, end_val) - } -} - -impl SerializableUntil for Vec { - fn serialize(&self, output: &mut dyn Write, end_val: U) -> Result<()> { - for data in self { - data.serialize(output)?; - } - end_val.serialize(output) - } - - fn deserialize(input: &mut dyn ReadSeek, end_val: U) -> Result - where - Self: Sized, - { - let mut data = Self::new(); - loop { - let pos = input.stream_position().map_err(|err| { - Error::SerializeationError(format!("Failled to get position in steam: {err}")) - })?; - match U::deserialize(input) { - Ok(val) if val == end_val => break Ok(data), - Err(err) => break Err(err), - Ok(_) => input.seek(SeekFrom::Start(pos)).map_err(|err| { - Error::SerializeationError(format!( - "Failled to get to position in steam: {err}" - )) - })?, - }; - data.push(D::deserialize(input)?); - } - } - - fn size(&self, end_val: U) -> usize { - self.iter().map(|data| data.size()).sum::() + end_val.size() - } -} - -impl Serializable for u8 { - fn serialize(&self, output: &mut dyn Write) -> Result<()> { - output.write_all(&self.to_be_bytes()).map_err(|err| { - Error::SerializeationError(format!("Failed to write serialize u8 to output: {err}")) - })?; - Ok(()) - } - - fn deserialize(input: &mut dyn ReadSeek) -> Result { - let mut buffer = [0u8; 1]; - input.read_exact(&mut buffer).map_err(|_| { - Error::InputTooSmall("Failed to read all bytes for u8 from the input".into()) - })?; - Ok(Self::from_be_bytes(buffer)) - } - - fn size(&self) -> usize { - 1 - } -} - -impl Serializable for i8 { - fn serialize(&self, output: &mut dyn Write) -> Result<()> { - output.write_all(&self.to_be_bytes()).map_err(|err| { - Error::SerializeationError(format!("Failed to write serialize i8 to output: {err}")) - })?; - Ok(()) - } - - fn deserialize(input: &mut dyn ReadSeek) -> Result { - let mut buffer = [0u8; 1]; - input.read_exact(&mut buffer).map_err(|_| { - Error::InputTooSmall("Failed to read all bytes for i8 from the input".into()) - })?; - Ok(Self::from_be_bytes(buffer)) - } - - fn size(&self) -> usize { - 1 - } -} - -impl Serializable for u16 { - fn serialize(&self, output: &mut dyn Write) -> Result<()> { - output.write_all(&self.to_be_bytes()).map_err(|err| { - Error::SerializeationError(format!("Failed to write serialize u16 to output: {err}")) - })?; - Ok(()) - } - - fn deserialize(input: &mut dyn ReadSeek) -> Result { - let mut buffer = [0u8; 2]; - input.read_exact(&mut buffer).map_err(|_| { - Error::InputTooSmall("Failed to read all bytes for u16 from the input".into()) - })?; - Ok(Self::from_be_bytes(buffer)) - } - - fn size(&self) -> usize { - 2 - } -} - -impl Serializable for i16 { - fn serialize(&self, output: &mut dyn Write) -> Result<()> { - output.write_all(&self.to_be_bytes()).map_err(|err| { - Error::SerializeationError(format!("Failed to write serialize i16 to output: {err}")) - })?; - Ok(()) - } - - fn deserialize(input: &mut dyn ReadSeek) -> Result { - let mut buffer = [0u8; 2]; - input.read_exact(&mut buffer).map_err(|_| { - Error::InputTooSmall("Failed to read all bytes for i16 from the input".into()) - })?; - Ok(Self::from_be_bytes(buffer)) - } - - fn size(&self) -> usize { - 2 - } -} - -impl Serializable for u32 { - fn serialize(&self, output: &mut dyn Write) -> Result<()> { - output.write_all(&self.to_be_bytes()).map_err(|err| { - Error::SerializeationError(format!("Failed to write serialize u32 to output: {err}")) - })?; - Ok(()) - } - - fn deserialize(input: &mut dyn ReadSeek) -> Result { - let mut buffer = [0u8; 4]; - input.read_exact(&mut buffer).map_err(|_| { - Error::InputTooSmall("Failed to read all bytes for u32 from the input".into()) - })?; - Ok(Self::from_be_bytes(buffer)) - } - - fn size(&self) -> usize { - 4 - } -} - -impl Serializable for i32 { - fn serialize(&self, output: &mut dyn Write) -> Result<()> { - output.write_all(&self.to_be_bytes()).map_err(|err| { - Error::SerializeationError(format!("Failed to write serialize i32 to output: {err}")) - })?; - Ok(()) - } - - fn deserialize(input: &mut dyn ReadSeek) -> Result { - let mut buffer = [0u8; 4]; - input.read_exact(&mut buffer).map_err(|_| { - Error::InputTooSmall("Failed to read all bytes for i32 from the input".into()) - })?; - Ok(Self::from_be_bytes(buffer)) - } - - fn size(&self) -> usize { - 4 - } -} - -impl Serializable for u64 { - fn serialize(&self, output: &mut dyn Write) -> Result<()> { - output.write_all(&self.to_be_bytes()).map_err(|err| { - Error::SerializeationError(format!("Failed to write serialize u64 to output: {err}")) - })?; - Ok(()) - } - - fn deserialize(input: &mut dyn ReadSeek) -> Result { - let mut buffer = [0u8; 8]; - input.read_exact(&mut buffer).map_err(|_| { - Error::InputTooSmall("Failed to read all bytes for u64 from the input".into()) - })?; - Ok(Self::from_be_bytes(buffer)) - } - - fn size(&self) -> usize { - 8 - } -} - -impl Serializable for i64 { - fn serialize(&self, output: &mut dyn Write) -> Result<()> { - output.write_all(&self.to_be_bytes()).map_err(|err| { - Error::SerializeationError(format!("Failed to write serialize i64 to output: {err}")) - })?; - Ok(()) - } - - fn deserialize(input: &mut dyn ReadSeek) -> Result { - let mut buffer = [0u8; 8]; - input.read_exact(&mut buffer).map_err(|_| { - Error::InputTooSmall("Failed to read all bytes for i64 from the input".into()) - })?; - Ok(Self::from_be_bytes(buffer)) - } - - fn size(&self) -> usize { - 8 - } -} - -impl Serializable for u128 { - fn serialize(&self, output: &mut dyn Write) -> Result<()> { - output.write_all(&self.to_be_bytes()).map_err(|err| { - Error::SerializeationError(format!("Failed to write serialize u128 to output: {err}")) - })?; - Ok(()) - } - - fn deserialize(input: &mut dyn ReadSeek) -> Result { - let mut buffer = [0u8; 16]; - input.read_exact(&mut buffer).map_err(|_| { - Error::InputTooSmall("Failed to read all bytes for u128 from the input".into()) - })?; - Ok(Self::from_be_bytes(buffer)) - } - - fn size(&self) -> usize { - 16 - } -} - -impl Serializable for i128 { - fn serialize(&self, output: &mut dyn Write) -> Result<()> { - output.write_all(&self.to_be_bytes()).map_err(|err| { - Error::SerializeationError(format!("Failed to write serialize i128 to output: {err}")) - })?; - Ok(()) - } - - fn deserialize(input: &mut dyn ReadSeek) -> Result { - let mut buffer = [0u8; 16]; - input.read_exact(&mut buffer).map_err(|_| { - Error::InputTooSmall("Failed to read all bytes for i128 from the input".into()) - })?; - Ok(Self::from_be_bytes(buffer)) - } - - fn size(&self) -> usize { - 16 - } -} - -#[cfg(test)] -mod test { - use super::*; - // Hacky hack to refere to "crate" by its name - use crate as androscalpel_serializer; - - #[test] - fn serialize_u8() { - assert_eq!(42u8.serialize_to_vec().unwrap(), vec![42u8]); - } - - #[test] - fn deserialize_u8() { - assert_eq!(u8::deserialize_from_slice(&[42u8]).unwrap(), 42u8); - } - - #[test] - fn size_u8() { - assert_eq!(42u8.size(), 1); - } - - #[test] - fn serialize_u16() { - assert_eq!(0x1234u16.serialize_to_vec().unwrap(), vec![0x12u8, 0x34u8]); - } - - #[test] - fn deserialize_u16() { - assert_eq!( - u16::deserialize_from_slice(&[0x12u8, 0x34u8]).unwrap(), - 0x1234u16 - ); - } - - #[test] - fn size_u16() { - assert_eq!(0x1234u16.size(), 2); - } - - #[test] - fn serialize_u32() { - assert_eq!( - 0x12345678u32.serialize_to_vec().unwrap(), - vec![0x12u8, 0x34u8, 0x56u8, 0x78u8] - ); - } - - #[test] - fn deserialize_u32() { - assert_eq!( - u32::deserialize_from_slice(&[0x12u8, 0x34u8, 0x56u8, 0x78u8]).unwrap(), - 0x12345678u32 - ); - } - - #[test] - fn size_u32() { - assert_eq!(0x12345678u32.size(), 4); - } - - #[test] - fn serialize_u64() { - assert_eq!( - 0x123456789ABCDEF0u64.serialize_to_vec().unwrap(), - vec![0x12u8, 0x34u8, 0x56u8, 0x78u8, 0x9Au8, 0xBCu8, 0xDEu8, 0xF0u8] - ); - } - - #[test] - fn deserialize_u64() { - assert_eq!( - u64::deserialize_from_slice(&[ - 0x12u8, 0x34u8, 0x56u8, 0x78u8, 0x9Au8, 0xBCu8, 0xDEu8, 0xF0u8 - ]) - .unwrap(), - 0x123456789ABCDEF0u64 - ); - } - - #[test] - fn size_u64() { - assert_eq!(0x123456789ABCDEF0u64.size(), 8); - } - - #[test] - fn serialize_u128() { - assert_eq!( - 0x123456789ABCDEF0123456789ABCDEF0u128 - .serialize_to_vec() - .unwrap(), - vec![ - 0x12u8, 0x34u8, 0x56u8, 0x78u8, 0x9Au8, 0xBCu8, 0xDEu8, 0xF0u8, 0x12u8, 0x34u8, - 0x56u8, 0x78u8, 0x9Au8, 0xBCu8, 0xDEu8, 0xF0u8 - ] - ); - } - - #[test] - fn deserialize_u128() { - assert_eq!( - u128::deserialize_from_slice(&[ - 0x12u8, 0x34u8, 0x56u8, 0x78u8, 0x9Au8, 0xBCu8, 0xDEu8, 0xF0u8, 0x12u8, 0x34u8, - 0x56u8, 0x78u8, 0x9Au8, 0xBCu8, 0xDEu8, 0xF0u8 - ]) - .unwrap(), - 0x123456789ABCDEF0123456789ABCDEF0u128 - ); - } - - #[test] - fn size_u128() { - assert_eq!(0x123456789ABCDEF0123456789ABCDEF0u128.size(), 16); - } - - #[derive(Serializable, Debug, PartialEq, Eq)] - struct NamedComposedTest { - a: u8, - b: u16, - c: u32, - d: u64, - f: u128, - } - - #[derive(Serializable, Debug, PartialEq, Eq)] - struct UnamedComposedTest(u8, u16, u32, u64, u128); - - #[test] - fn serialize_unnamed_derived() { - let t = UnamedComposedTest( - 42u8, - 0x1234u16, - 0x12345678u32, - 0x123456789ABCDEF0u64, - 0x123456789ABCDEF0123456789ABCDEF0u128, - ); - assert_eq!( - t.serialize_to_vec().unwrap(), - vec![ - 42u8, 0x12u8, 0x34u8, 0x12u8, 0x34u8, 0x56u8, 0x78u8, 0x12u8, 0x34u8, 0x56u8, - 0x78u8, 0x9Au8, 0xBCu8, 0xDEu8, 0xF0u8, 0x12u8, 0x34u8, 0x56u8, 0x78u8, 0x9Au8, - 0xBCu8, 0xDEu8, 0xF0u8, 0x12u8, 0x34u8, 0x56u8, 0x78u8, 0x9Au8, 0xBCu8, 0xDEu8, - 0xF0u8 - ] - ); - } - - #[test] - fn deserialize_named_derived() { - let t = UnamedComposedTest( - 42u8, - 0x1234u16, - 0x12345678u32, - 0x123456789ABCDEF0u64, - 0x123456789ABCDEF0123456789ABCDEF0u128, - ); - let serialized = vec![ - 42u8, 0x12u8, 0x34u8, 0x12u8, 0x34u8, 0x56u8, 0x78u8, 0x12u8, 0x34u8, 0x56u8, 0x78u8, - 0x9Au8, 0xBCu8, 0xDEu8, 0xF0u8, 0x12u8, 0x34u8, 0x56u8, 0x78u8, 0x9Au8, 0xBCu8, 0xDEu8, - 0xF0u8, 0x12u8, 0x34u8, 0x56u8, 0x78u8, 0x9Au8, 0xBCu8, 0xDEu8, 0xF0u8, - ]; - assert_eq!( - UnamedComposedTest::deserialize_from_slice(&serialized).unwrap(), - t - ); - } - - #[test] - fn size_unnamed_derived() { - let t = UnamedComposedTest( - 42u8, - 0x1234u16, - 0x12345678u32, - 0x123456789ABCDEF0u64, - 0x123456789ABCDEF0123456789ABCDEF0u128, - ); - assert_eq!(t.size(), 1 + 2 + 4 + 8 + 16); - } - - #[derive(Serializable, Debug, PartialEq, Eq)] - struct NamedArrayComposedTest { - a: [u8; 1], - b: [u16; 2], - c: [u32; 3], - d: [u64; 4], - e: [u128; 5], - } - - #[derive(Serializable, Debug, PartialEq, Eq)] - struct UnamedArrayComposedTest([u8; 1], [u16; 2], [u32; 3], [u64; 4], [u128; 5]); - - #[test] - fn serialize_array_unamed_derived() { - let t = UnamedArrayComposedTest( - [42u8], - [0x1234u16, 0x1234u16], - [0x12345678u32, 0x12345678u32, 0x12345678u32], - [ - 0x123456789ABCDEF0u64, - 0x123456789ABCDEF0u64, - 0x123456789ABCDEF0u64, - 0x123456789ABCDEF0u64, - ], - [ - 0x123456789ABCDEF0123456789ABCDEF0u128, - 0x123456789ABCDEF0123456789ABCDEF0u128, - 0x123456789ABCDEF0123456789ABCDEF0u128, - 0x123456789ABCDEF0123456789ABCDEF0u128, - 0x123456789ABCDEF0123456789ABCDEF0u128, - ], - ); - assert_eq!( - t.serialize_to_vec().unwrap(), - vec![ - 42u8, 0x12u8, 0x34u8, 0x12u8, 0x34u8, 0x12u8, 0x34u8, 0x56u8, 0x78u8, 0x12u8, - 0x34u8, 0x56u8, 0x78u8, 0x12u8, 0x34u8, 0x56u8, 0x78u8, 0x12u8, 0x34u8, 0x56u8, - 0x78u8, 0x9Au8, 0xBCu8, 0xDEu8, 0xF0u8, 0x12u8, 0x34u8, 0x56u8, 0x78u8, 0x9Au8, - 0xBCu8, 0xDEu8, 0xF0u8, 0x12u8, 0x34u8, 0x56u8, 0x78u8, 0x9Au8, 0xBCu8, 0xDEu8, - 0xF0u8, 0x12u8, 0x34u8, 0x56u8, 0x78u8, 0x9Au8, 0xBCu8, 0xDEu8, 0xF0u8, 0x12u8, - 0x34u8, 0x56u8, 0x78u8, 0x9Au8, 0xBCu8, 0xDEu8, 0xF0u8, 0x12u8, 0x34u8, 0x56u8, - 0x78u8, 0x9Au8, 0xBCu8, 0xDEu8, 0xF0u8, 0x12u8, 0x34u8, 0x56u8, 0x78u8, 0x9Au8, - 0xBCu8, 0xDEu8, 0xF0u8, 0x12u8, 0x34u8, 0x56u8, 0x78u8, 0x9Au8, 0xBCu8, 0xDEu8, - 0xF0u8, 0x12u8, 0x34u8, 0x56u8, 0x78u8, 0x9Au8, 0xBCu8, 0xDEu8, 0xF0u8, 0x12u8, - 0x34u8, 0x56u8, 0x78u8, 0x9Au8, 0xBCu8, 0xDEu8, 0xF0u8, 0x12u8, 0x34u8, 0x56u8, - 0x78u8, 0x9Au8, 0xBCu8, 0xDEu8, 0xF0u8, 0x12u8, 0x34u8, 0x56u8, 0x78u8, 0x9Au8, - 0xBCu8, 0xDEu8, 0xF0u8, 0x12u8, 0x34u8, 0x56u8, 0x78u8, 0x9Au8, 0xBCu8, 0xDEu8, - 0xF0u8, 0x12u8, 0x34u8, 0x56u8, 0x78u8, 0x9Au8, 0xBCu8, 0xDEu8, 0xF0u8 - ] - ); - } - - #[test] - fn deserialize_array_unamed_derived() { - let t = UnamedArrayComposedTest( - [42u8], - [0x1234u16, 0x1234u16], - [0x12345678u32, 0x12345678u32, 0x12345678u32], - [ - 0x123456789ABCDEF0u64, - 0x123456789ABCDEF0u64, - 0x123456789ABCDEF0u64, - 0x123456789ABCDEF0u64, - ], - [ - 0x123456789ABCDEF0123456789ABCDEF0u128, - 0x123456789ABCDEF0123456789ABCDEF0u128, - 0x123456789ABCDEF0123456789ABCDEF0u128, - 0x123456789ABCDEF0123456789ABCDEF0u128, - 0x123456789ABCDEF0123456789ABCDEF0u128, - ], - ); - let serialized = vec![ - 42u8, 0x12u8, 0x34u8, 0x12u8, 0x34u8, 0x12u8, 0x34u8, 0x56u8, 0x78u8, 0x12u8, 0x34u8, - 0x56u8, 0x78u8, 0x12u8, 0x34u8, 0x56u8, 0x78u8, 0x12u8, 0x34u8, 0x56u8, 0x78u8, 0x9Au8, - 0xBCu8, 0xDEu8, 0xF0u8, 0x12u8, 0x34u8, 0x56u8, 0x78u8, 0x9Au8, 0xBCu8, 0xDEu8, 0xF0u8, - 0x12u8, 0x34u8, 0x56u8, 0x78u8, 0x9Au8, 0xBCu8, 0xDEu8, 0xF0u8, 0x12u8, 0x34u8, 0x56u8, - 0x78u8, 0x9Au8, 0xBCu8, 0xDEu8, 0xF0u8, 0x12u8, 0x34u8, 0x56u8, 0x78u8, 0x9Au8, 0xBCu8, - 0xDEu8, 0xF0u8, 0x12u8, 0x34u8, 0x56u8, 0x78u8, 0x9Au8, 0xBCu8, 0xDEu8, 0xF0u8, 0x12u8, - 0x34u8, 0x56u8, 0x78u8, 0x9Au8, 0xBCu8, 0xDEu8, 0xF0u8, 0x12u8, 0x34u8, 0x56u8, 0x78u8, - 0x9Au8, 0xBCu8, 0xDEu8, 0xF0u8, 0x12u8, 0x34u8, 0x56u8, 0x78u8, 0x9Au8, 0xBCu8, 0xDEu8, - 0xF0u8, 0x12u8, 0x34u8, 0x56u8, 0x78u8, 0x9Au8, 0xBCu8, 0xDEu8, 0xF0u8, 0x12u8, 0x34u8, - 0x56u8, 0x78u8, 0x9Au8, 0xBCu8, 0xDEu8, 0xF0u8, 0x12u8, 0x34u8, 0x56u8, 0x78u8, 0x9Au8, - 0xBCu8, 0xDEu8, 0xF0u8, 0x12u8, 0x34u8, 0x56u8, 0x78u8, 0x9Au8, 0xBCu8, 0xDEu8, 0xF0u8, - 0x12u8, 0x34u8, 0x56u8, 0x78u8, 0x9Au8, 0xBCu8, 0xDEu8, 0xF0u8, - ]; - assert_eq!( - UnamedArrayComposedTest::deserialize_from_slice(&serialized).unwrap(), - t - ); - } - - #[test] - fn size_array_unamed_derived() { - let t = UnamedArrayComposedTest( - [42u8], - [0x1234u16, 0x1234u16], - [0x12345678u32, 0x12345678u32, 0x12345678u32], - [ - 0x123456789ABCDEF0u64, - 0x123456789ABCDEF0u64, - 0x123456789ABCDEF0u64, - 0x123456789ABCDEF0u64, - ], - [ - 0x123456789ABCDEF0123456789ABCDEF0u128, - 0x123456789ABCDEF0123456789ABCDEF0u128, - 0x123456789ABCDEF0123456789ABCDEF0u128, - 0x123456789ABCDEF0123456789ABCDEF0u128, - 0x123456789ABCDEF0123456789ABCDEF0u128, - ], - ); - assert_eq!(t.size(), 1 + 2 * 2 + 4 * 3 + 8 * 4 + 16 * 5); - } - - #[test] - fn serialize_array_named_derived() { - let t = NamedArrayComposedTest { - a: [42u8], - b: [0x1234u16, 0x1234u16], - c: [0x12345678u32, 0x12345678u32, 0x12345678u32], - d: [ - 0x123456789ABCDEF0u64, - 0x123456789ABCDEF0u64, - 0x123456789ABCDEF0u64, - 0x123456789ABCDEF0u64, - ], - e: [ - 0x123456789ABCDEF0123456789ABCDEF0u128, - 0x123456789ABCDEF0123456789ABCDEF0u128, - 0x123456789ABCDEF0123456789ABCDEF0u128, - 0x123456789ABCDEF0123456789ABCDEF0u128, - 0x123456789ABCDEF0123456789ABCDEF0u128, - ], - }; - assert_eq!( - t.serialize_to_vec().unwrap(), - vec![ - 42u8, 0x12u8, 0x34u8, 0x12u8, 0x34u8, 0x12u8, 0x34u8, 0x56u8, 0x78u8, 0x12u8, - 0x34u8, 0x56u8, 0x78u8, 0x12u8, 0x34u8, 0x56u8, 0x78u8, 0x12u8, 0x34u8, 0x56u8, - 0x78u8, 0x9Au8, 0xBCu8, 0xDEu8, 0xF0u8, 0x12u8, 0x34u8, 0x56u8, 0x78u8, 0x9Au8, - 0xBCu8, 0xDEu8, 0xF0u8, 0x12u8, 0x34u8, 0x56u8, 0x78u8, 0x9Au8, 0xBCu8, 0xDEu8, - 0xF0u8, 0x12u8, 0x34u8, 0x56u8, 0x78u8, 0x9Au8, 0xBCu8, 0xDEu8, 0xF0u8, 0x12u8, - 0x34u8, 0x56u8, 0x78u8, 0x9Au8, 0xBCu8, 0xDEu8, 0xF0u8, 0x12u8, 0x34u8, 0x56u8, - 0x78u8, 0x9Au8, 0xBCu8, 0xDEu8, 0xF0u8, 0x12u8, 0x34u8, 0x56u8, 0x78u8, 0x9Au8, - 0xBCu8, 0xDEu8, 0xF0u8, 0x12u8, 0x34u8, 0x56u8, 0x78u8, 0x9Au8, 0xBCu8, 0xDEu8, - 0xF0u8, 0x12u8, 0x34u8, 0x56u8, 0x78u8, 0x9Au8, 0xBCu8, 0xDEu8, 0xF0u8, 0x12u8, - 0x34u8, 0x56u8, 0x78u8, 0x9Au8, 0xBCu8, 0xDEu8, 0xF0u8, 0x12u8, 0x34u8, 0x56u8, - 0x78u8, 0x9Au8, 0xBCu8, 0xDEu8, 0xF0u8, 0x12u8, 0x34u8, 0x56u8, 0x78u8, 0x9Au8, - 0xBCu8, 0xDEu8, 0xF0u8, 0x12u8, 0x34u8, 0x56u8, 0x78u8, 0x9Au8, 0xBCu8, 0xDEu8, - 0xF0u8, 0x12u8, 0x34u8, 0x56u8, 0x78u8, 0x9Au8, 0xBCu8, 0xDEu8, 0xF0u8 - ] - ); - } - - #[test] - fn deserialize_array_named_derived() { - let t = NamedArrayComposedTest { - a: [42u8], - b: [0x1234u16, 0x1234u16], - c: [0x12345678u32, 0x12345678u32, 0x12345678u32], - d: [ - 0x123456789ABCDEF0u64, - 0x123456789ABCDEF0u64, - 0x123456789ABCDEF0u64, - 0x123456789ABCDEF0u64, - ], - e: [ - 0x123456789ABCDEF0123456789ABCDEF0u128, - 0x123456789ABCDEF0123456789ABCDEF0u128, - 0x123456789ABCDEF0123456789ABCDEF0u128, - 0x123456789ABCDEF0123456789ABCDEF0u128, - 0x123456789ABCDEF0123456789ABCDEF0u128, - ], - }; - let serialized = vec![ - 42u8, 0x12u8, 0x34u8, 0x12u8, 0x34u8, 0x12u8, 0x34u8, 0x56u8, 0x78u8, 0x12u8, 0x34u8, - 0x56u8, 0x78u8, 0x12u8, 0x34u8, 0x56u8, 0x78u8, 0x12u8, 0x34u8, 0x56u8, 0x78u8, 0x9Au8, - 0xBCu8, 0xDEu8, 0xF0u8, 0x12u8, 0x34u8, 0x56u8, 0x78u8, 0x9Au8, 0xBCu8, 0xDEu8, 0xF0u8, - 0x12u8, 0x34u8, 0x56u8, 0x78u8, 0x9Au8, 0xBCu8, 0xDEu8, 0xF0u8, 0x12u8, 0x34u8, 0x56u8, - 0x78u8, 0x9Au8, 0xBCu8, 0xDEu8, 0xF0u8, 0x12u8, 0x34u8, 0x56u8, 0x78u8, 0x9Au8, 0xBCu8, - 0xDEu8, 0xF0u8, 0x12u8, 0x34u8, 0x56u8, 0x78u8, 0x9Au8, 0xBCu8, 0xDEu8, 0xF0u8, 0x12u8, - 0x34u8, 0x56u8, 0x78u8, 0x9Au8, 0xBCu8, 0xDEu8, 0xF0u8, 0x12u8, 0x34u8, 0x56u8, 0x78u8, - 0x9Au8, 0xBCu8, 0xDEu8, 0xF0u8, 0x12u8, 0x34u8, 0x56u8, 0x78u8, 0x9Au8, 0xBCu8, 0xDEu8, - 0xF0u8, 0x12u8, 0x34u8, 0x56u8, 0x78u8, 0x9Au8, 0xBCu8, 0xDEu8, 0xF0u8, 0x12u8, 0x34u8, - 0x56u8, 0x78u8, 0x9Au8, 0xBCu8, 0xDEu8, 0xF0u8, 0x12u8, 0x34u8, 0x56u8, 0x78u8, 0x9Au8, - 0xBCu8, 0xDEu8, 0xF0u8, 0x12u8, 0x34u8, 0x56u8, 0x78u8, 0x9Au8, 0xBCu8, 0xDEu8, 0xF0u8, - 0x12u8, 0x34u8, 0x56u8, 0x78u8, 0x9Au8, 0xBCu8, 0xDEu8, 0xF0u8, - ]; - assert_eq!( - NamedArrayComposedTest::deserialize_from_slice(&serialized).unwrap(), - t - ); - } - - #[test] - fn size_array_named_derived() { - let t = NamedArrayComposedTest { - a: [42u8], - b: [0x1234u16, 0x1234u16], - c: [0x12345678u32, 0x12345678u32, 0x12345678u32], - d: [ - 0x123456789ABCDEF0u64, - 0x123456789ABCDEF0u64, - 0x123456789ABCDEF0u64, - 0x123456789ABCDEF0u64, - ], - e: [ - 0x123456789ABCDEF0123456789ABCDEF0u128, - 0x123456789ABCDEF0123456789ABCDEF0u128, - 0x123456789ABCDEF0123456789ABCDEF0u128, - 0x123456789ABCDEF0123456789ABCDEF0u128, - 0x123456789ABCDEF0123456789ABCDEF0u128, - ], - }; - assert_eq!(t.size(), 1 + 2 * 2 + 4 * 3 + 8 * 4 + 16 * 5); - } - - #[test] - fn size_vec_serializable_until() { - #[derive(Serializable, PartialEq, Eq)] - struct UntilArray([u8; 3]); - let v = vec![0u8, 1u8, 2u8, 3u8]; - assert_eq!(v.size(UntilArray([0, 0, 0])), 7); - assert_eq!(v.size(0u8), 5); - } - - #[test] - fn serialize_vec_serializable_until() { - #[derive(Serializable, PartialEq, Eq)] - struct UntilArray([u8; 3]); - let v = vec![0u8, 1u8, 2u8, 3u8]; - assert_eq!( - v.serialize_to_vec(UntilArray([0, 0, 0])).unwrap(), - vec![0u8, 1u8, 2u8, 3u8, 0u8, 0u8, 0u8] - ); - assert_eq!( - v.serialize_to_vec(0u8).unwrap(), - vec![0u8, 1u8, 2u8, 3u8, 0u8] - ); - } - - #[test] - fn deserialize_vec_serializable_until() { - #[derive(Serializable, PartialEq, Eq)] - struct UntilArray([u8; 3]); - let v1 = vec![0u8, 1u8, 2u8, 3u8]; - let serialized_1 = &[0u8, 1u8, 2u8, 3u8, 0u8, 0u8, 0u8]; - let serialized_2 = &[0u8, 1u8, 2u8, 3u8, 0u8]; - assert_eq!( - v1, - Vec::::deserialize_from_slice(serialized_1, UntilArray([0, 0, 0])).unwrap() - ); - assert_eq!( - Vec::::new(), - Vec::::deserialize_from_slice(serialized_2, 0u8).unwrap() - ); - } - - #[derive(Serializable, PartialEq, Eq, Debug)] - struct UntilArray2([u8; 2]); - #[derive(Serializable, Debug, PartialEq, Eq)] - struct SerializableUntilNamed { - pr: u16, - #[until(u8, UntilArray2, UntilArray2([0u8, 0u8]))] - v: Vec, - ps: u32, - } - - #[test] - fn size_named_serializable_until() { - let v = SerializableUntilNamed { - pr: 0, - v: vec![1, 2, 3], - ps: 0, - }; - assert_eq!(v.size(), 2 + 3 + 2 + 4); - } - - #[test] - fn serialize_named_serializable_until() { - let v = SerializableUntilNamed { - pr: 0, - v: vec![1, 2, 3], - ps: 0x80000000, - }; - assert_eq!( - v.serialize_to_vec().unwrap(), - vec![0, 0, 1, 2, 3, 0, 0, 0x80, 0, 0, 0], - ); - } - - #[test] - fn deserialize_named_serializable_until() { - let v = SerializableUntilNamed { - pr: 0, - v: vec![1, 2, 3], - ps: 0x80000000, - }; - let s = &[0, 0, 1, 2, 3, 0, 0, 0x80, 0, 0, 0]; - assert_eq!( - v, - SerializableUntilNamed::deserialize_from_slice(s).unwrap() - ); - } - - #[derive(Serializable, PartialEq, Eq, Debug)] - #[prefix_type(u8)] - enum TestEnum { - #[prefix(0)] - Zero, - #[prefix(1)] - One(u32), - #[prefix(2)] - Two { a: u16, b: u32 }, - } - - #[test] - fn size_enum() { - assert_eq!(TestEnum::Zero.size(), 1); - assert_eq!(TestEnum::One(42).size(), 5); - assert_eq!(TestEnum::Two { a: 1, b: 2 }.size(), 7); - } - - #[test] - fn serialize_enum() { - assert_eq!(TestEnum::Zero.serialize_to_vec().unwrap(), vec![0u8]); - assert_eq!( - TestEnum::One(42).serialize_to_vec().unwrap(), - vec![1u8, 0u8, 0u8, 0u8, 42u8] - ); - assert_eq!( - TestEnum::Two { a: 1, b: 2 }.serialize_to_vec().unwrap(), - vec![2u8, 0u8, 1u8, 0u8, 0u8, 0u8, 2u8] - ); - } - - #[test] - fn deserialize_enum() { - assert_eq!( - TestEnum::deserialize_from_slice(&[0u8]).unwrap(), - TestEnum::Zero - ); - assert_eq!( - TestEnum::deserialize_from_slice(&[1u8, 0u8, 0u8, 0u8, 42u8]).unwrap(), - TestEnum::One(42) - ); - assert_eq!( - TestEnum::deserialize_from_slice(&[2u8, 0u8, 1u8, 0u8, 0u8, 0u8, 2u8]).unwrap(), - TestEnum::Two { a: 1, b: 2 } - ); - assert!(TestEnum::deserialize_from_slice(&[255u8]).is_err()); - } -} +pub use crate::core::*;