summaryrefslogtreecommitdiffstats
path: root/vendor/windows-metadata/src/imp.rs
blob: 27a735a451db1c54e0d842e0dbbe940e7795b9f7 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
#[repr(C)]
#[derive(Default)]
pub struct METADATA_HEADER {
    pub signature: u32,
    pub major_version: u16,
    pub minor_version: u16,
    pub reserved: u32,
    pub length: u32,
    pub version: [u8; 20],
    pub flags: u16,
    pub streams: u16,
}

pub const METADATA_SIGNATURE: u32 = 0x424A_5342;

/// A coded index (see codes.rs) is a table index that may refer to different tables. The size of the column in memory
/// must therefore be large enough to hold an index for a row in the largest possible table. This function determines
/// this size for the given winmd file.
pub fn coded_index_size(tables: &[usize]) -> usize {
    fn small(row_count: usize, bits: u8) -> bool {
        (row_count as u64) < (1u64 << (16 - bits))
    }

    fn bits_needed(value: usize) -> u8 {
        let mut value = value - 1;
        let mut bits: u8 = 1;
        while {
            value >>= 1;
            value != 0
        } {
            bits += 1;
        }
        bits
    }

    let bits_needed = bits_needed(tables.len());

    if tables.iter().all(|table| small(*table, bits_needed)) {
        2
    } else {
        4
    }
}