rust_rcs_client/connectivity/
reg_info_xml.rs

1// Copyright 2023 宋昊文
2//
3// Licensed under the Apache License, Version 2.0 (the "License");
4// you may not use this file except in compliance with the License.
5// You may obtain a copy of the License at
6//
7//     http://www.apache.org/licenses/LICENSE-2.0
8//
9// Unless required by applicable law or agreed to in writing, software
10// distributed under the License is distributed on an "AS IS" BASIS,
11// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12// See the License for the specific language governing permissions and
13// limitations under the License.
14
15extern 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}