windows_metadata/reader/tables/
method_param.rs1use super::*;
2
3#[derive(Copy, Clone, Debug, PartialEq, Eq)]
5pub enum ParamDirection {
6 Unspecified,
7 Input,
8 Output,
9 InputOutput,
10}
11
12#[derive(Copy, Clone, Debug, PartialEq, Eq)]
16pub enum BufferRelationship {
17 ElementsParam(i16),
18 BytesParam(i16),
19 ElementsConst(i32),
20}
21
22impl std::fmt::Debug for MethodParam<'_> {
23 fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
24 f.debug_tuple("MethodParam").field(&self.name()).finish()
25 }
26}
27
28impl MethodParam<'_> {
29 pub fn flags(&self) -> ParamAttributes {
30 ParamAttributes(self.usize(0).try_into().unwrap())
31 }
32
33 pub fn direction(&self) -> ParamDirection {
36 let flags = self.flags();
37 match (
38 flags.contains(ParamAttributes::In),
39 flags.contains(ParamAttributes::Out),
40 ) {
41 (false, false) => ParamDirection::Unspecified,
42 (true, false) => ParamDirection::Input,
43 (false, true) => ParamDirection::Output,
44 (true, true) => ParamDirection::InputOutput,
45 }
46 }
47
48 pub fn is_optional(&self) -> bool {
50 self.flags().contains(ParamAttributes::Optional)
51 }
52
53 pub fn is_reserved(&self) -> bool {
55 self.has_attribute("ReservedAttribute")
56 }
57
58 pub fn is_retval_attribute(&self) -> bool {
60 self.has_attribute("RetValAttribute")
61 }
62
63 pub fn buffer_relationship(&self) -> Option<BufferRelationship> {
68 let mut result = None;
69
70 for attribute in self.attributes() {
71 for (name, value) in attribute.value() {
72 let relationship = match (attribute.name(), name.as_str(), value) {
73 ("NativeArrayInfoAttribute", "CountParamIndex", Value::I16(value)) => {
74 BufferRelationship::ElementsParam(value)
75 }
76 ("NativeArrayInfoAttribute", "CountConst", Value::I32(value)) => {
77 BufferRelationship::ElementsConst(value)
78 }
79 ("MemorySizeAttribute", "BytesParamIndex", Value::I16(value)) => {
80 BufferRelationship::BytesParam(value)
81 }
82 ("NativeArrayInfoAttribute", "CountParamIndex" | "CountConst", _)
83 | ("MemorySizeAttribute", "BytesParamIndex", _) => return None,
84 _ => continue,
85 };
86
87 if result.replace(relationship).is_some() {
88 return None;
89 }
90 }
91 }
92
93 result
94 }
95
96 pub fn sequence(&self) -> u16 {
97 self.usize(1).try_into().unwrap()
98 }
99
100 pub fn name(&self) -> &str {
101 self.str(2)
102 }
103}