fn usage(args: &Vec) { println!("Usage: {} ", args[0]); } fn merge_u16(a: u8, b: u8) -> u16 { return ((a as u16) << 8) | (b as u16); } fn merge_u32(a: u8, b: u8, c: u8, d: u8) -> u32 { return ((a as u32) << 24) | ((b as u32) << 16) | ((c as u32) << 8) | (d as u32); } fn read_u16(content: &Vec, offset: usize) -> u16 { return merge_u16(content[offset], content[offset + 1]); } fn read_u32(content: &Vec, offset: usize) -> u32 { return merge_u32(content[offset], content[offset + 1], content[offset + 2], content[offset + 3]); } fn u32_to_str(a: u32) -> String { let mut s = String::new(); s.push((a >> 24) as u8 as char); s.push((a >> 16) as u8 as char); s.push((a >> 8) as u8 as char); s.push((a >> 0) as u8 as char); return s; } struct Table { tag: u32, checksum: u32, offset: u32, length: u32, } struct TTF { filetype: u32, content: Vec, table_count: u16, tables: Vec, } impl TTF { fn new(file: Vec) -> TTF { let mut ttf = TTF { filetype: u32::MAX, content: file, table_count: 0, tables: Vec::new() }; ttf.solve(); return ttf } } impl TTF { fn solve(&mut self) { let mut now = 0; let content = &self.content; self.filetype = read_u32(content, now); now += 4; self.table_count = read_u16(content, now); now += 2; now += 6; for _ in 0..self.table_count { let tag = read_u32(content, now); now += 4; let checksum = read_u32(content, now); now += 4; let offset = read_u32(content, now); now += 4; let length = read_u32(content, now); now += 4; self.tables.push(Table { tag, checksum, offset, length, }); } } fn print(self) { println!("{} bytes", self.content.len()); println!("filetype: {:0>8x}", self.filetype); println!("table_count: {}", self.table_count); for table in self.tables { println!("tag: 0x{:0>8x}({}), checksum: 0x{:0>8x}, offset: {:8}, length: {:8}", table.tag, u32_to_str(table.tag),table.checksum, table.offset, table.length); } } } fn main() { let args: Vec = std::env::args().collect(); if args.len() < 2 { usage(&args); return ; } let ttf = TTF::new( std::fs::read(&args[1]).unwrap() ); ttf.print(); }