Skip to content

Commit 5ca7704

Browse files
authored
Additional type system support (#388)
1 parent 5cad3b4 commit 5ca7704

File tree

7 files changed

+105
-14
lines changed

7 files changed

+105
-14
lines changed

crates/gen/src/constant.rs

Lines changed: 57 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -18,8 +18,64 @@ impl Constant {
1818
pub fn gen(&self) -> TokenStream {
1919
let name = format_ident(self.field.name());
2020

21+
let constant = self
22+
.field
23+
.constants()
24+
.next()
25+
.expect("Missing constant value");
26+
27+
let mut value = constant.value();
28+
29+
let value = match constant.value_type() {
30+
winmd::ElementType::I8 => ConstantValue::I8(value.read_i8()),
31+
winmd::ElementType::U8 => ConstantValue::U8(value.read_u8()),
32+
winmd::ElementType::I16 => ConstantValue::I16(value.read_i16()),
33+
winmd::ElementType::U16 => ConstantValue::U16(value.read_u16()),
34+
winmd::ElementType::I32 => ConstantValue::I32(value.read_i32()),
35+
winmd::ElementType::U32 => ConstantValue::U32(value.read_u32()),
36+
winmd::ElementType::F32 => ConstantValue::F32(value.read_f32()),
37+
winmd::ElementType::F64 => ConstantValue::F64(value.read_f64()),
38+
winmd::ElementType::String => ConstantValue::String(value.read_utf16()),
39+
value_type => panic!(
40+
"Unsupported constant: {} ({:?})",
41+
self.field.name(),
42+
value_type
43+
),
44+
};
45+
46+
let value = value.gen();
47+
2148
quote! {
22-
pub const #name: i32 = 0;
49+
pub const #name: #value;
50+
}
51+
}
52+
}
53+
54+
#[derive(Debug)]
55+
pub enum ConstantValue {
56+
U8(u8),
57+
I8(i8),
58+
U16(u16),
59+
I16(i16),
60+
U32(u32),
61+
I32(i32),
62+
F32(f32),
63+
F64(f64),
64+
String(String),
65+
}
66+
67+
impl ConstantValue {
68+
fn gen(&self) -> TokenStream {
69+
match self {
70+
Self::U8(value) => quote! { u8 = #value },
71+
Self::I8(value) => quote! { i8 = #value },
72+
Self::U16(value) => quote! { u16 = #value },
73+
Self::I16(value) => quote! { i16 = #value },
74+
Self::U32(value) => quote! { u32 = #value },
75+
Self::I32(value) => quote! { i32 = #value },
76+
Self::F32(value) => quote! { f32 = #value },
77+
Self::F64(value) => quote! { f64 = #value },
78+
Self::String(value) => quote! { &'static str = #value },
2379
}
2480
}
2581
}

crates/gen/src/type_namespaces.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@ impl TypeNamespaces {
2121
quote! {
2222
// TODO: remove this allowance when https://github.com/microsoft/winrt-rs/issues/212 is fixed
2323
#[allow(unused_variables)]
24+
#[allow(non_upper_case_globals)]
2425
pub mod #name {
2526
#(#tokens)*
2627
#foundation

crates/tests/build.rs

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -26,12 +26,14 @@ fn main() {
2626
// Test for https://github.com/microsoft/winrt-rs/issues/361
2727
windows::ui::xaml::{IApplicationOverrides, IApplicationOverrides2}
2828

29+
// Test for https://github.com/microsoft/winrt-rs/issues/386
2930
windows::ui::xaml::data::ICustomPropertyProvider
3031

3132
// Used to test Win32 support
3233
windows::win32::{
3334
ACCESS_MODE, CHOOSECOLORW, DXGI_ADAPTER_FLAG, DXGI_FORMAT, DXGI_MODE_DESC, DXGI_MODE_SCALING,
34-
DXGI_MODE_SCANLINE_ORDER, DXGI_RATIONAL, RECT, WM_KEYUP,
35+
DXGI_MODE_SCANLINE_ORDER, DXGI_RATIONAL, RECT, WM_KEYUP, ALLJOYN_BIG_ENDIAN, ALLJOYN_CRED_CERT_CHAIN,
36+
D3D12_DEFAULT_BLEND_FACTOR_ALPHA, UIA_ScrollPatternNoScroll, D3DCOMPILER_DLL
3537
}
3638
);
3739
}

crates/tests/tests/win32.rs

Lines changed: 10 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,8 @@
11
use tests::windows::win32::{
2-
ACCESS_MODE, CHOOSECOLORW, DXGI_ADAPTER_FLAG, DXGI_FORMAT, DXGI_MODE_DESC, DXGI_MODE_SCALING,
3-
DXGI_MODE_SCANLINE_ORDER, DXGI_RATIONAL, RECT, WM_KEYUP,
2+
UIA_ScrollPatternNoScroll, ACCESS_MODE, ALLJOYN_BIG_ENDIAN, ALLJOYN_CRED_CERT_CHAIN,
3+
CHOOSECOLORW, D3D12_DEFAULT_BLEND_FACTOR_ALPHA, D3DCOMPILER_DLL, DXGI_ADAPTER_FLAG,
4+
DXGI_FORMAT, DXGI_MODE_DESC, DXGI_MODE_SCALING, DXGI_MODE_SCANLINE_ORDER, DXGI_RATIONAL, RECT,
5+
WM_KEYUP,
46
};
57
use winrt::Abi;
68

@@ -87,5 +89,10 @@ fn size32() {
8789

8890
#[test]
8991
fn constant() {
90-
assert!(WM_KEYUP == 0);
92+
assert!(ALLJOYN_BIG_ENDIAN == 66u8);
93+
assert!(ALLJOYN_CRED_CERT_CHAIN == 4u16);
94+
assert!(WM_KEYUP == 257i32);
95+
assert!(D3D12_DEFAULT_BLEND_FACTOR_ALPHA == 1f32);
96+
assert!(UIA_ScrollPatternNoScroll == -1f64);
97+
assert!(D3DCOMPILER_DLL == "d3dcompiler_47.dll");
9198
}

crates/winmd/macros/src/lib.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -51,7 +51,7 @@ pub fn type_code(args: TokenStream, input: TokenStream) -> TokenStream {
5151
let encodes = TokenStream2::from_iter(encodes);
5252

5353
let output = quote!(
54-
#[derive(Copy, Clone, Debug)]// PartialEq, PartialOrd, Eq, Ord, Debug)]
54+
#[derive(Copy, Clone, Debug)] // TODO: PartialEq, PartialOrd, Eq, Ord, Debug)]
5555
pub enum #name {
5656
#variants
5757
}

crates/winmd/src/parsed/blob.rs

Lines changed: 29 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -6,11 +6,12 @@ pub struct Blob {
66
pub reader: &'static TypeReader,
77
pub file_index: u16,
88
pub offset: usize,
9+
pub size: usize,
910
}
1011

1112
impl Blob {
12-
fn bytes(&self) -> &[u8] {
13-
&self.file().bytes[self.offset..]
13+
fn bytes(&self) -> &'static [u8] {
14+
&self.reader.files[self.file_index as usize].bytes[self.offset..]
1415
}
1516

1617
pub fn peek_unsigned(&self) -> (u32, usize) {
@@ -67,10 +68,24 @@ impl Blob {
6768
mods
6869
}
6970

70-
pub fn read_str(&mut self) -> &str {
71+
pub fn read_str(&mut self) -> &'static str {
7172
let len = self.read_unsigned() as usize;
7273
self.offset += len;
73-
std::str::from_utf8(&self.file().bytes[self.offset - len..self.offset]).unwrap()
74+
std::str::from_utf8(
75+
&self.reader.files[self.file_index as usize].bytes[self.offset - len..self.offset],
76+
)
77+
.unwrap()
78+
}
79+
80+
pub fn read_utf16(&self) -> String {
81+
let bytes = self.reader.files[self.file_index as usize].bytes[self.offset..].as_ptr();
82+
unsafe {
83+
String::from_utf16(std::slice::from_raw_parts(
84+
bytes as *const u16,
85+
self.size / 2,
86+
))
87+
.unwrap()
88+
}
7489
}
7590

7691
pub fn read_i8(&mut self) -> i8 {
@@ -121,7 +136,15 @@ impl Blob {
121136
value
122137
}
123138

124-
fn file(&self) -> &File {
125-
&self.reader.files[self.file_index as usize]
139+
pub fn read_f32(&mut self) -> f32 {
140+
let value = f32::from_le_bytes(self.bytes()[..4].try_into().unwrap());
141+
self.offset += 4;
142+
value
143+
}
144+
145+
pub fn read_f64(&mut self) -> f64 {
146+
let value = f64::from_le_bytes(self.bytes()[..8].try_into().unwrap());
147+
self.offset += 8;
148+
value
126149
}
127150
}

crates/winmd/src/type_reader.rs

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -254,19 +254,21 @@ impl TypeReader {
254254
let file = &self.files[row.file_index as usize];
255255
let offset = (file.blobs + self.u32(row, column)) as usize;
256256
let initial_byte = file.bytes[offset];
257-
let (mut blob_size, blob_size_bytes) = match initial_byte >> 5 {
257+
let (blob_size, blob_size_bytes) = match initial_byte >> 5 {
258258
0..=3 => (initial_byte & 0x7f, 1),
259259
4..=5 => (initial_byte & 0x3f, 2),
260260
6 => (initial_byte & 0x1f, 4),
261261
_ => panic!("Invalid blob size"),
262262
};
263+
let mut blob_size = blob_size as usize;
263264
for byte in &file.bytes[offset + 1..offset + blob_size_bytes] {
264-
blob_size = blob_size.checked_shl(8).unwrap_or(0) + byte;
265+
blob_size = blob_size.checked_shl(8).unwrap_or(0) + (*byte as usize);
265266
}
266267
Blob {
267268
reader: self,
268269
file_index: row.file_index,
269270
offset: offset + blob_size_bytes,
271+
size: blob_size,
270272
}
271273
}
272274

0 commit comments

Comments
 (0)