Back when I wrote C code for platform-dependent binary formats it was fairly common to perform stream I/O with structs and unions. This post looks at similar functionality in Rust.
use std::mem; #[allow(dead_code)] pub struct Ser { prop: u32 } pub fn to_bytes(ser: Ser) -> [u8; 4] { unsafe { mem::transmute_copy::<Ser, [u8; 4]>(&ser) } } #[cfg(test)] mod test { use super::*; #[test] fn test_to_bytes() { let instance = Ser { prop: 0x0A0B0C0D }; let bigend = Ser { prop: instance.prop.to_be() }; let actual = to_bytes(bigend); let expected: [u8; 4] = [0xA, 0xB, 0xC, 0xD]; assert_eq!(expected, actual); } }
In the above example a struct's byte representation is accessed directly and a copy is taken. This requires an unsafe block.
use std::mem; #[allow(dead_code)] pub struct DeSer { prop: u32 } pub fn from_bytes(arr: [u8; 4]) -> DeSer { unsafe { mem::transmute_copy::<[u8; 4], DeSer>(&arr) } } #[cfg(test)] mod test { use super::*; #[test] fn test_from_bytes() { let expected = DeSer { prop: 0x0A0B0C0D }; let instance: [u8; 4] = [0xA, 0xB, 0xC, 0xD]; let actual = from_bytes(instance); let sysend = u32::from_be(actual.prop); assert_eq!(expected.prop, sysend); } }
De-serialising a struct from bytes is very similar.
This post is just a code snippet written by someone getting started.
No promises are made about code quality.
Version: rustc 1.0.0-beta.4 (850151a75 2015-04-30) (built 2015-04-30)
No comments:
Post a Comment
All comments are moderated