/
xmllite.rs
141 lines (109 loc) · 5.73 KB
/
xmllite.rs
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
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
use windows::{core::*, Win32::Data::Xml::XmlLite::*, Win32::System::Com::StructuredStorage::*, Win32::System::Com::*};
#[test]
fn test() -> Result<()> {
unsafe {
let stream = CreateStreamOnHGlobal(0, true)?;
let mut writer: Option<IXmlWriter> = None;
CreateXmlWriter(&IXmlWriter::IID, &mut writer as *mut _ as _, None)?;
let writer = writer.unwrap();
writer.SetOutput(&stream)?;
writer.WriteStartDocument(XmlStandalone_Omit)?;
writer.WriteStartElement(None, w!("html"), None)?;
writer.WriteElementString(None, w!("head"), None, w!("The quick brown fox jumps over the lazy dog"))?;
writer.WriteStartElement(None, w!("body"), None)?;
writer.WriteChars(None)?;
writer.WriteChars(Some(&[0x52, 0x75, 0x73, 0x74]))?;
writer.WriteEndDocument()?;
writer.Flush()?;
let pos = stream.Seek(0, STREAM_SEEK_SET)?;
assert_eq!(pos, 0);
let mut reader: Option<IXmlReader> = None;
CreateXmlReader(&IXmlReader::IID, &mut reader as *mut _ as _, None)?;
let reader = reader.unwrap();
reader.SetInput(&stream)?;
let mut node_type = XmlNodeType_None;
reader.Read(Some(&mut node_type)).ok()?;
assert_eq!(node_type, XmlNodeType_XmlDeclaration);
let mut name = PWSTR::null();
let mut name_len = 0;
let mut node_type = XmlNodeType_None;
reader.Read(Some(&mut node_type)).ok()?;
assert_eq!(node_type, XmlNodeType_Element);
// TODO: workaround for https://github.com/microsoft/win32metadata/issues/1005
reader.GetLocalName(Some(&mut name), Some(&mut name_len))?;
assert_eq!(String::from_utf16_lossy(std::slice::from_raw_parts(name.0, name_len as _)), "html");
let mut node_type = XmlNodeType_None;
reader.Read(Some(&mut node_type)).ok()?;
assert_eq!(node_type, XmlNodeType_Element);
// TODO: workaround for https://github.com/microsoft/win32metadata/issues/1005
reader.GetLocalName(Some(&mut name), Some(&mut name_len))?;
assert_eq!(String::from_utf16_lossy(std::slice::from_raw_parts(name.0, name_len as _)), "head");
let mut node_type = XmlNodeType_None;
reader.Read(Some(&mut node_type)).ok()?;
assert_eq!(node_type, XmlNodeType_Text);
let mut message = Vec::new();
let mut chunk: [u16; 10] = std::mem::zeroed();
let mut chars_read = 0;
let mut read_count = 0;
while reader.ReadValueChunk(&mut chunk, &mut chars_read).is_ok() && chars_read > 0 {
message.extend_from_slice(&chunk[0..chars_read as _]);
read_count += 1;
}
assert_eq!(read_count, 5);
assert_eq!(String::from_utf16_lossy(std::slice::from_raw_parts(message.as_ptr(), message.len())), "The quick brown fox jumps over the lazy dog");
let mut node_type = XmlNodeType_None;
reader.Read(Some(&mut node_type)).ok()?;
assert_eq!(node_type, XmlNodeType_EndElement);
let mut node_type = XmlNodeType_None;
reader.Read(Some(&mut node_type)).ok()?;
assert_eq!(node_type, XmlNodeType_Element);
let mut node_type = XmlNodeType_None;
reader.Read(Some(&mut node_type)).ok()?;
assert_eq!(node_type, XmlNodeType_Text);
reader.ReadValueChunk(&mut chunk, &mut chars_read).ok()?;
assert_eq!(chars_read, 4);
assert_eq!(String::from_utf16_lossy(std::slice::from_raw_parts(chunk.as_ptr(), chars_read as _)), "Rust");
Ok(())
}
}
#[test]
fn lite() -> Result<()> {
unsafe {
let stream = CreateStreamOnHGlobal(0, true)?;
let mut writer: Option<IXmlWriterLite> = None;
CreateXmlWriter(&IXmlWriterLite::IID, &mut writer as *mut _ as _, None)?;
let writer = writer.unwrap();
writer.SetOutput(&stream)?;
writer.WriteStartElement(HSTRING::from("html").as_wide())?;
writer.WriteAttributeString(HSTRING::from("no-value").as_wide(), None)?;
writer.WriteAttributeString(HSTRING::from("with-value").as_wide(), Some(HSTRING::from("value").as_wide()))?;
writer.WriteEndElement(HSTRING::from("html").as_wide())?;
writer.Flush()?;
let pos = stream.Seek(0, STREAM_SEEK_SET)?;
assert_eq!(pos, 0);
let mut reader: Option<IXmlReader> = None;
CreateXmlReader(&IXmlReader::IID, &mut reader as *mut _ as _, None)?;
let reader = reader.unwrap();
reader.SetInput(&stream)?;
let mut name = PWSTR::null();
let mut name_len = 0;
let mut node_type = XmlNodeType_None;
reader.Read(Some(&mut node_type)).ok()?;
assert_eq!(node_type, XmlNodeType_Element);
// TODO: workaround for https://github.com/microsoft/win32metadata/issues/1005
reader.GetLocalName(Some(&mut name), Some(&mut name_len))?;
assert_eq!(String::from_utf16_lossy(std::slice::from_raw_parts(name.0, name_len as _)), "html");
assert_eq!(reader.GetAttributeCount()?, 2);
reader.MoveToFirstAttribute().ok()?;
reader.GetLocalName(Some(&mut name), Some(&mut name_len))?;
assert_eq!(String::from_utf16_lossy(std::slice::from_raw_parts(name.0, name_len as _)), "no-value");
reader.GetValue(Some(&mut name), Some(&mut name_len))?;
assert_eq!(String::from_utf16_lossy(std::slice::from_raw_parts(name.0, name_len as _)), "");
reader.MoveToNextAttribute().ok()?;
reader.GetLocalName(Some(&mut name), Some(&mut name_len))?;
assert_eq!(String::from_utf16_lossy(std::slice::from_raw_parts(name.0, name_len as _)), "with-value");
reader.GetValue(Some(&mut name), Some(&mut name_len))?;
assert_eq!(String::from_utf16_lossy(std::slice::from_raw_parts(name.0, name_len as _)), "value");
Ok(())
}
}