rust_rcs_client/connectivity/
reg_info_xml.rs1extern crate quick_xml;
16
17use quick_xml::{
18 events::{BytesStart, Event},
19 Reader,
20};
21
22pub struct RegInfoXml {
23 pub version: String,
24 pub state: String,
25 pub registration_nodes: Vec<RegistrationNode>,
26}
27
28pub struct RegistrationNode {
29 pub aor: String,
30 pub id: String,
31 pub state: String,
32 pub contact_nodes: Vec<ContactNode>,
33}
34
35pub struct ContactNode {
36 pub state: String,
37 pub event: String,
38 pub duration_registered: Option<String>,
39 pub expires: Option<String>,
40 pub id: String,
41 pub uri: String,
42}
43
44pub fn parse_xml(data: &[u8]) -> Option<RegInfoXml> {
45 let mut xml_reader = Reader::from_reader(data);
46
47 let mut buf = Vec::new();
48 loop {
49 match xml_reader.read_event_into(&mut buf) {
50 Ok(Event::Start(ref e)) => {
51 if e.name().as_ref().eq_ignore_ascii_case(b"reginfo") {
52 let mut buf = Vec::new();
53 return parse_reg_info(&mut xml_reader, &mut buf, e, 1);
54 }
55 }
56
57 Ok(Event::Empty(ref e)) => {
58 if e.name().as_ref().eq_ignore_ascii_case(b"reginfo") {
59 let mut buf = Vec::new();
60 return parse_reg_info(&mut xml_reader, &mut buf, e, 0);
61 }
62 }
63
64 Ok(Event::Eof) | Err(_) => {
65 break;
66 }
67
68 _ => {}
69 }
70 }
71
72 None
73}
74
75pub fn parse_reg_info<R>(
76 xml_reader: &mut Reader<R>,
77 buf: &mut Vec<u8>,
78 e: &BytesStart,
79 level: i32,
80) -> Option<RegInfoXml>
81where
82 R: std::io::BufRead,
83{
84 let mut version: Option<String> = None;
85 let mut state: Option<String> = None;
86
87 for attribute in e.attributes() {
88 if let Ok(attribute) = attribute {
89 if attribute.key.as_ref() == b"version" {
90 if let Ok(attribute_value) = attribute.unescape_value() {
91 version.replace(attribute_value.into_owned());
92 }
93 } else if attribute.key.as_ref() == b"state" {
94 if let Ok(attribute_value) = attribute.unescape_value() {
95 state.replace(attribute_value.into_owned());
96 }
97 }
98 }
99 }
100
101 let mut registration_nodes = Vec::new();
102
103 let mut handle_element = |xml_reader: &mut Reader<R>, e: &BytesStart, level: i32| -> bool {
104 if e.name().as_ref().eq_ignore_ascii_case(b"registration") {
105 let mut buf = Vec::new();
106 if let Some(registration_node) = parse_registration_node(xml_reader, &mut buf, e, level)
107 {
108 registration_nodes.push(registration_node);
109 }
110 return true;
111 }
112 false
113 };
114
115 let mut level = level;
116
117 if level > 0 {
118 loop {
119 match xml_reader.read_event_into(buf) {
120 Ok(Event::Start(ref e)) => {
121 if !handle_element(xml_reader, e, 1) {
122 level += 1;
123 }
124 }
125
126 Ok(Event::Empty(ref e)) => {
127 handle_element(xml_reader, e, 0);
128 }
129
130 Ok(Event::End(_)) => {
131 level -= 1;
132 if level == 0 {
133 break;
134 }
135 }
136
137 Ok(Event::Eof) | Err(_) => {
138 break;
139 }
140
141 _ => {}
142 }
143 }
144 }
145
146 if let (Some(version), Some(state)) = (version, state) {
147 return Some(RegInfoXml {
148 version,
149 state,
150 registration_nodes,
151 });
152 }
153
154 None
155}
156
157pub fn parse_registration_node<R>(
158 xml_reader: &mut Reader<R>,
159 buf: &mut Vec<u8>,
160 e: &BytesStart,
161 level: i32,
162) -> Option<RegistrationNode>
163where
164 R: std::io::BufRead,
165{
166 let mut aor: Option<String> = None;
167 let mut id: Option<String> = None;
168 let mut state: Option<String> = None;
169
170 for attribute in e.attributes() {
171 if let Ok(attribute) = attribute {
172 if attribute.key.as_ref() == b"aor" {
173 if let Ok(attribute_value) = attribute.unescape_value() {
174 aor.replace(attribute_value.into_owned());
175 }
176 } else if attribute.key.as_ref() == b"id" {
177 if let Ok(attribute_value) = attribute.unescape_value() {
178 id.replace(attribute_value.into_owned());
179 }
180 } else if attribute.key.as_ref() == b"state" {
181 if let Ok(attribute_value) = attribute.unescape_value() {
182 state.replace(attribute_value.into_owned());
183 }
184 }
185 }
186 }
187
188 let mut contact_nodes = Vec::new();
189
190 let mut level = level;
191
192 let mut handle_element = |xml_reader: &mut Reader<R>, e: &BytesStart, level: i32| -> bool {
193 if e.name().as_ref().eq_ignore_ascii_case(b"contact") {
194 let mut buf = Vec::new();
195 if let Some(parameter) = parse_contact_node(xml_reader, &mut buf, e, level) {
196 contact_nodes.push(parameter);
197 }
198 return true;
199 }
200 false
201 };
202
203 if level > 0 {
204 loop {
205 match xml_reader.read_event_into(buf) {
206 Ok(Event::Start(ref e)) => {
207 if !handle_element(xml_reader, e, 1) {
208 level += 1;
209 }
210 }
211
212 Ok(Event::Empty(ref e)) => {
213 handle_element(xml_reader, e, 0);
214 }
215
216 Ok(Event::End(_)) => {
217 level -= 1;
218 if level == 0 {
219 break;
220 }
221 }
222
223 Ok(Event::Eof) | Err(_) => {
224 break;
225 }
226
227 _ => {}
228 }
229 }
230 }
231
232 if let (Some(aor), Some(id), Some(state)) = (aor, id, state) {
233 return Some(RegistrationNode {
234 aor,
235 id,
236 state,
237 contact_nodes,
238 });
239 }
240
241 None
242}
243
244pub fn parse_contact_node<R>(
245 xml_reader: &mut Reader<R>,
246 buf: &mut Vec<u8>,
247 e: &BytesStart,
248 level: i32,
249) -> Option<ContactNode>
250where
251 R: std::io::BufRead,
252{
253 let mut state: Option<String> = None;
254 let mut event: Option<String> = None;
255 let mut duration_registered: Option<String> = None;
256 let mut expires: Option<String> = None;
257 let mut id: Option<String> = None;
258
259 for attribute in e.attributes() {
260 if let Ok(attribute) = attribute {
261 if attribute.key.as_ref() == b"state" {
262 if let Ok(attribute_value) = attribute.unescape_value() {
263 state.replace(attribute_value.into_owned());
264 }
265 } else if attribute.key.as_ref() == b"event" {
266 if let Ok(attribute_value) = attribute.unescape_value() {
267 event.replace(attribute_value.into_owned());
268 }
269 } else if attribute.key.as_ref() == b"duration-registered" {
270 if let Ok(attribute_value) = attribute.unescape_value() {
271 duration_registered.replace(attribute_value.into_owned());
272 }
273 } else if attribute.key.as_ref() == b"expires" {
274 if let Ok(attribute_value) = attribute.unescape_value() {
275 expires.replace(attribute_value.into_owned());
276 }
277 } else if attribute.key.as_ref() == b"id" {
278 if let Ok(attribute_value) = attribute.unescape_value() {
279 id.replace(attribute_value.into_owned());
280 }
281 }
282 }
283 }
284
285 let mut uri: Option<String> = None;
286
287 let mut level = level;
288
289 if level > 0 {
290 loop {
291 match xml_reader.read_event_into(buf) {
292 Ok(Event::Start(ref e)) => {
293 if e.name().as_ref().eq_ignore_ascii_case(b"uri") {
294 let mut buf = Vec::new();
295 if let Some(contact_node_uri) = parse_contact_node_uri(xml_reader, &mut buf)
296 {
297 uri.replace(contact_node_uri);
298 }
299 } else {
300 level += 1;
301 }
302 }
303
304 Ok(Event::End(_)) => {
305 level -= 1;
306 if level == 0 {
307 break;
308 }
309 }
310
311 Ok(Event::Eof) | Err(_) => {
312 break;
313 }
314
315 _ => {}
316 }
317 }
318 }
319
320 if let (Some(state), Some(event), Some(id), Some(uri)) = (state, event, id, uri) {
321 return Some(ContactNode {
322 state,
323 event,
324 duration_registered,
325 expires,
326 id,
327 uri,
328 });
329 }
330
331 None
332}
333
334pub fn parse_contact_node_uri<R>(xml_reader: &mut Reader<R>, buf: &mut Vec<u8>) -> Option<String>
335where
336 R: std::io::BufRead,
337{
338 let mut uri: Option<String> = None;
339
340 let mut level = 1;
341
342 loop {
343 match xml_reader.read_event_into(buf) {
344 Ok(Event::Start(ref _e)) => {
345 level += 1;
346 }
347
348 Ok(Event::Text(ref e)) => {
349 if level == 1 {
350 if let Ok(t) = e.unescape() {
351 uri.replace(t.into_owned());
352 }
353 }
354 }
355
356 Ok(Event::End(_)) => {
357 level -= 1;
358 if level == 0 {
359 break;
360 }
361 }
362
363 Ok(Event::Eof) | Err(_) => {
364 break;
365 }
366
367 _ => {}
368 }
369 }
370
371 uri
372}