Created
May 29, 2015 03:01
-
-
Save richo/219fe5dad8c4d78aca71 to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| #![feature(convert)] | |
| /* Documentation for the various blocktypes | |
| 0x00000000 Reserved ??? | |
| 0x00000001 Interface Description Block | |
| 0x00000002 Packet Block | |
| 0x00000003 Simple Packet Block | |
| 0x00000004 Name Resolution Block | |
| 0x00000005 Interface Statistics Block | |
| 0x00000006 Enhanced Packet Block | |
| 0x00000007 IRIG Timestamp Block (requested by Gianluca Varenni <[email protected]>, CACE Technologies LLC) | |
| 0x00000008 Arinc 429 in AFDX Encapsulation Information Block (requested by Gianluca Varenni <[email protected]>, CACE Technologies LLC) | |
| 0x0A0D0D0A Section Header Block | |
| */ | |
| use std::io; | |
| use std::io::{Read,SeekFrom,Seek}; | |
| use std::mem; | |
| type Body = [u8]; | |
| pub type BlockType = u32; | |
| pub type BlockLength = u32; | |
| const BOM: u32 = 0x1A2B3C4D; | |
| pub struct SecHdr { | |
| ty: BlockType, | |
| total_length: u32, | |
| pub major_version: u16, | |
| pub minor_version: u16, | |
| pub section_length: u64, | |
| buf: Vec<u8>, | |
| } | |
| pub enum Block { | |
| SectionHeader(SecHdr), | |
| // InterfaceDescription(Box<Body>), | |
| // Packet(Box<Body>), | |
| // TODO other block types | |
| Debug(BlockType, BlockLength, Vec<u8>) | |
| } | |
| macro_rules! read_to { | |
| ($ty:ty, $len:expr, $reader:expr) => {{ | |
| let mut buf: [u8; $len] = [0; $len]; | |
| try!($reader.read(&mut buf)); | |
| let ret: $ty = unsafe { mem::transmute(buf) }; | |
| ret | |
| }} | |
| } | |
| const BLOCK_ALIGN: u32 = 4; // 32 bits | |
| impl Block { | |
| pub fn read_from_file<R>(reader: &mut R) -> Result<Block, io::Error> | |
| where R: Read + Seek { | |
| let ty = read_to!(u32, 4, reader); | |
| let block_len = read_to!(u32, 4, reader); | |
| let body_len = block_len - 12; // An empty block is 12 byte | |
| let mut body = vec![0; body_len as usize]; | |
| let read = try!(reader.read(&mut body)); | |
| assert!(read == body_len as usize, "Couldn't read the whole body into the vector"); | |
| // Advance the reader to u32 alignment | |
| let spill = BLOCK_ALIGN - (body_len % BLOCK_ALIGN); | |
| if spill != BLOCK_ALIGN { | |
| try!(reader.seek(SeekFrom::Current(spill as i64))); | |
| } | |
| let check_len = read_to!(u32, 4, reader); | |
| assert!(check_len == block_len, "Invalid block, len's don't match"); | |
| Ok(Block::block_from_type(ty, body)) | |
| } | |
| fn block_from_type(ty: u32, body: Vec<u8>) -> Block { | |
| match ty { | |
| 0x0A0D0D0A => { // Section Header Block | |
| // TODO maybe this wants to go into a SecHdr constructor | |
| // let bom: u32 = unsafe { mem::transmute(&body[8..12]) }; | |
| // assert!(bom == BOM, "Invalid bom in a section header"); | |
| // let minor: u16 = unsafe { mem::transmute(&body[12..14]) }; | |
| // let major: u16 = unsafe { mem::transmute(&body[14..16]) }; | |
| // let section_length: u64 = unsafe { mem::transmute(&body[16..24]) }; | |
| // Block::SectionHeader(SecHdr { | |
| // ty: ty, | |
| // total_length: body.len() as u32, | |
| // major_version: major, | |
| // minor_version: minor, | |
| // section_length: section_length, | |
| // buf: body, | |
| // } | |
| Block::Debug(ty, body.len() as u32, body) | |
| }, | |
| _ => panic!("Unknown block type: {:x}", ty), | |
| } | |
| } | |
| } |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment