windows_metadata/
lib.rs

1/*!
2Learn more about Rust for Windows here: <https://github.com/microsoft/windows-rs>
3*/
4
5#![doc(hidden)]
6
7use std::cmp::Ordering;
8use std::collections::*;
9
10mod attributes;
11mod bindings;
12mod blob;
13mod codes;
14mod column;
15mod file;
16mod filter;
17mod reader;
18mod row;
19mod table;
20mod tables;
21mod r#type;
22mod type_name;
23
24pub use attributes::*;
25pub use bindings::*;
26pub use blob::*;
27pub use codes::*;
28use column::*;
29pub use file::*;
30use filter::*;
31pub use r#type::*;
32pub use reader::*;
33pub use row::*;
34use table::*;
35pub use tables::*;
36pub use type_name::*;
37
38#[repr(C)]
39#[derive(Default)]
40pub struct METADATA_HEADER {
41    pub signature: u32,
42    pub major_version: u16,
43    pub minor_version: u16,
44    pub reserved: u32,
45    pub length: u32,
46    pub version: [u8; 20],
47    pub flags: u16,
48    pub streams: u16,
49}
50
51pub const METADATA_SIGNATURE: u32 = 0x424A_5342;
52
53/// A coded index (see codes.rs) is a table index that may refer to different tables. The size of the column in memory
54/// must therefore be large enough to hold an index for a row in the largest possible table. This function determines
55/// this size for the given winmd file.
56pub fn coded_index_size(tables: &[usize]) -> usize {
57    fn small(row_count: usize, bits: u8) -> bool {
58        (row_count as u64) < (1u64 << (16 - bits))
59    }
60
61    fn bits_needed(value: usize) -> u8 {
62        let mut value = value - 1;
63        let mut bits: u8 = 1;
64        while {
65            value >>= 1;
66            value != 0
67        } {
68            bits += 1;
69        }
70        bits
71    }
72
73    let bits_needed = bits_needed(tables.len());
74
75    if tables.iter().all(|table| small(*table, bits_needed)) {
76        2
77    } else {
78        4
79    }
80}
81
82#[derive(Debug)]
83pub enum Value {
84    Bool(bool),
85    U8(u8),
86    I8(i8),
87    U16(u16),
88    I16(i16),
89    U32(u32),
90    I32(i32),
91    U64(u64),
92    I64(i64),
93    F32(f32),
94    F64(f64),
95    String(String),
96    TypeName(TypeName),
97    EnumDef(TypeDef, Box<Self>),
98}
99
100#[derive(Debug)]
101pub struct MethodDefSig {
102    pub call_flags: MethodCallAttributes,
103    pub return_type: Type,
104    pub params: Vec<Type>,
105}
106
107impl MethodDefSig {
108    pub fn size(&self) -> usize {
109        self.params
110            .iter()
111            .fold(0, |sum, param| sum + std::cmp::max(4, param.size()))
112    }
113}
114
115#[derive(Copy, Clone, PartialEq, Eq, Debug, PartialOrd, Ord)]
116pub enum TypeKind {
117    Interface,
118    Class,
119    Enum,
120    Struct,
121    Delegate,
122}