simple_xml_parser/
lib.rs

1pub use spdict::{spdict_add, spdict_del, SPDict};
2use std::ffi::{c_char, CStr, CString};
3use std::ptr::null_mut;
4
5#[no_mangle]
6pub extern "C" fn simple_xml_parse(xml: *const c_char) -> *mut SPDict {
7    unsafe {
8        let xml_cstr = CStr::from_ptr(xml);
9        let xml_str = match xml_cstr.to_str() {
10            Ok(s) => s.trim(),
11            Err(_) => return null_mut(),
12        };
13
14        // Remove XML declaration if it exists
15        let declaration = r#"<?xml version="1.0" encoding="UTF-8"?>"#;
16        let xml_str = if xml_str.starts_with(declaration) {
17            &xml_str[declaration.len()..]
18        } else {
19            xml_str
20        };
21
22        // Initialize the SPDict head
23        let mut head: *mut SPDict = null_mut();
24
25        // Parse the tag and value
26        if let Some(start_tag_pos) = xml_str.find('<') {
27            if let Some(end_tag_pos) = xml_str.find('>') {
28                let tag = &xml_str[start_tag_pos + 1..end_tag_pos]; // Extract tag name
29
30                // Find closing tag for the tag
31                let closing_tag = format!("</{}>", tag);
32                if let Some(closing_tag_pos) = xml_str.find(&closing_tag) {
33                    let value_start = end_tag_pos + 1;
34                    let value_end = closing_tag_pos;
35
36                    let value = xml_str[value_start..value_end].trim(); // Extract value between tags
37
38                    // Add to SPDict
39                    let tag_cstring = CString::new(tag).unwrap();
40                    let value_cstring = CString::new(value).unwrap();
41
42                    spdict_add(&mut head as *mut *mut SPDict, tag_cstring.as_ptr(), value_cstring.as_ptr());
43                    std::mem::forget(tag_cstring);
44                    std::mem::forget(value_cstring);
45                }
46            }
47        }
48
49        head
50    }
51}
52
53#[no_mangle]
54pub extern "C" fn delete_parsed_xml_Dict(head: *mut SPDict) {
55    unsafe {
56        let mut current = head;
57
58        // Traverse the linked list
59        while !current.is_null() {
60            // Save the next pointer before deallocating
61            let next = (*current).next;
62
63            // Safely deallocate `name` and `value` if not null
64            if !(*current).name.is_null() {
65                let _ = CString::from_raw((*current).name as *mut c_char);
66            }
67            if !(*current).value.is_null() {
68                let _ = CString::from_raw((*current).value as *mut c_char);
69            }
70
71            // Move to the next node
72            current = next;
73        }
74
75        // Call the external `spdict_del` to clean up the list
76        spdict_del(head);
77    }
78}
79