1use common::*;
9
10#[derive(Debug,Copy,Clone,Eq,PartialEq)]
12pub struct Slice {
13 pub offset: i32, pub size: u32,
15}
16
17#[derive(Debug,Copy,Clone,Eq,PartialEq)]
20pub struct Header {
21 pub version: u32,
22 pub header_size: u32,
23 pub minimum_type_index: TypeIndex,
24 pub maximum_type_index: TypeIndex,
25 pub gprec_size: u32,
26 pub tpi_hash_stream: u16,
27 pub tpi_hash_pad_stream: u16,
28 pub hash_key_size: u32,
29 pub hash_bucket_size: u32,
30 pub hash_values: Slice,
31 pub ti_off: Slice,
32 pub hash_adj: Slice, }
34
35impl Header {
36 pub fn parse(buf: &mut ParseBuffer) -> Result<Header> {
37 assert!(buf.pos() == 0);
38
39 let h = Header{
40 version: buf.parse_u32()?,
41 header_size: buf.parse_u32()?,
42 minimum_type_index: buf.parse_u32()?,
43 maximum_type_index: buf.parse_u32()?,
44 gprec_size: buf.parse_u32()?,
45 tpi_hash_stream: buf.parse_u16()?,
46 tpi_hash_pad_stream: buf.parse_u16()?,
47 hash_key_size: buf.parse_u32()?,
48 hash_bucket_size: buf.parse_u32()?,
49 hash_values: Slice{
50 offset: buf.parse_i32()?,
51 size: buf.parse_u32()?,
52 },
53 ti_off: Slice{
54 offset: buf.parse_i32()?,
55 size: buf.parse_u32()?,
56 },
57 hash_adj: Slice{
58 offset: buf.parse_i32()?,
59 size: buf.parse_u32()?,
60 },
61 };
62
63 let bytes_read = buf.pos() as u32;
66 if h.header_size < bytes_read {
67 return Err(Error::InvalidTypeInformationHeader("header size is impossibly small"));
68 } else if h.header_size > 1024 {
69 return Err(Error::InvalidTypeInformationHeader("header size is unreasonably large"));
70 }
71
72 buf.take((h.header_size - bytes_read) as usize)?;
74
75 if h.minimum_type_index < 4096 {
77 return Err(Error::InvalidTypeInformationHeader("minimum type index is < 4096"));
78 }
79 if h.maximum_type_index < h.minimum_type_index {
80 return Err(Error::InvalidTypeInformationHeader("maximum type index is < minimum type index"));
81 }
82
83 Ok(h)
85 }
86}