summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authordefanor <defanor@uberspace.net>2023-09-09 13:54:01 +0300
committerdefanor <defanor@uberspace.net>2023-09-09 13:54:01 +0300
commiteb6f5e7f1127783c347e31d8de506d583cc69c59 (patch)
treee3585e106c6b1d6ffabd7bf1fdfa62c851ae0369 /src
parentaaae19eb8462c784daab0cf9afddc934fdbd1b75 (diff)
Use rxml for XML parsing when building with Rust
Diffstat (limited to 'src')
-rw-r--r--src/Cargo.toml1
-rw-r--r--src/Makefile.am8
-rw-r--r--src/rexmpp.c2
-rw-r--r--src/rexmpp_console.c1
-rw-r--r--src/rexmpp_dns.c1
-rw-r--r--src/rexmpp_http_upload.c1
-rw-r--r--src/rexmpp_roster.c1
-rw-r--r--src/rexmpp_rust.rs1
-rw-r--r--src/rexmpp_sasl.c1
-rw-r--r--src/rexmpp_tls.c1
-rw-r--r--src/rexmpp_xml.c14
-rw-r--r--src/rexmpp_xml.rs114
-rw-r--r--src/rexmpp_xml_parser.c7
-rw-r--r--src/rexmpp_xml_parser.h5
-rw-r--r--src/rexmpp_xml_parser.rs146
15 files changed, 232 insertions, 72 deletions
diff --git a/src/Cargo.toml b/src/Cargo.toml
index 6ce67b4..65a0ff4 100644
--- a/src/Cargo.toml
+++ b/src/Cargo.toml
@@ -14,3 +14,4 @@ path = "rexmpp_rust.rs"
[dependencies]
libc = "0.2"
errno = "0.3"
+rxml = "0.9"
diff --git a/src/Makefile.am b/src/Makefile.am
index eea4f8f..5bf0f1a 100644
--- a/src/Makefile.am
+++ b/src/Makefile.am
@@ -15,8 +15,7 @@ librexmpp_la_SOURCES = rexmpp_roster.h rexmpp_roster.c \
rexmpp_base64.h rexmpp_base64.c \
rexmpp_sasl.h rexmpp_sasl.c \
rexmpp_xml.h rexmpp_xml.c \
- rexmpp_utf8.h \
- rexmpp_xml_parser.h rexmpp_xml_parser.c
+ rexmpp_utf8.h
include_HEADERS = config.h rexmpp_roster.h rexmpp_tcp.h rexmpp_socks.h rexmpp.h \
rexmpp_dns.h rexmpp_tls.h rexmpp_jid.h rexmpp_openpgp.h rexmpp_console.h \
@@ -36,7 +35,7 @@ librexmpp_la_LDFLAGS = []
if USE_RUST
target_debug_librexmpp_rust_a_SOURCES = \
rexmpp_rust.rs rexmpp.rs rexmpp_jid.rs rexmpp_dns.rs rexmpp_tcp.rs \
- rexmpp_socks.rs rexmpp_xml.rs
+ rexmpp_socks.rs rexmpp_xml.rs rexmpp_xml_parser.rs
noinst_LIBRARIES = target/debug/librexmpp_rust.a
librexmpp_la_LIBADD += target/debug/librexmpp_rust.a
librexmpp_la_LDFLAGS += -L. -lpthread -ldl
@@ -46,5 +45,6 @@ target/debug/librexmpp_rust.a: $(target_debug_librexmpp_rust_a_SOURCES)
else
librexmpp_la_SOURCES += rexmpp_tcp.h rexmpp_tcp.c \
- rexmpp_socks.h rexmpp_socks.c
+ rexmpp_socks.h rexmpp_socks.c \
+ rexmpp_xml_parser.h rexmpp_xml_parser.c
endif
diff --git a/src/rexmpp.c b/src/rexmpp.c
index 886f091..7194d87 100644
--- a/src/rexmpp.c
+++ b/src/rexmpp.c
@@ -1225,7 +1225,7 @@ rexmpp_err_t rexmpp_recv (rexmpp_t *s) {
chunk = chunk_raw;
chunk_len = chunk_raw_len;
}
- rexmpp_xml_parser_feed(s->xml_parser, chunk, chunk_len);
+ rexmpp_xml_parser_feed(s->xml_parser, chunk, chunk_len, 0);
if (chunk != chunk_raw && chunk != NULL) {
free(chunk);
}
diff --git a/src/rexmpp_console.c b/src/rexmpp_console.c
index ce325aa..f1a5ca5 100644
--- a/src/rexmpp_console.c
+++ b/src/rexmpp_console.c
@@ -11,6 +11,7 @@
*/
#include <string.h>
+#include <stdlib.h>
#include "rexmpp.h"
#include "rexmpp_xml.h"
diff --git a/src/rexmpp_dns.c b/src/rexmpp_dns.c
index f793e88..d13472e 100644
--- a/src/rexmpp_dns.c
+++ b/src/rexmpp_dns.c
@@ -7,6 +7,7 @@
*/
#include <memory.h>
+#include <stdlib.h>
#include <syslog.h>
#include "config.h"
diff --git a/src/rexmpp_http_upload.c b/src/rexmpp_http_upload.c
index 2552771..4d8c631 100644
--- a/src/rexmpp_http_upload.c
+++ b/src/rexmpp_http_upload.c
@@ -10,6 +10,7 @@
#include <string.h>
#include <libgen.h>
#include <errno.h>
+#include <stdlib.h>
#include "config.h"
diff --git a/src/rexmpp_roster.c b/src/rexmpp_roster.c
index 0048848..c9d4532 100644
--- a/src/rexmpp_roster.c
+++ b/src/rexmpp_roster.c
@@ -10,6 +10,7 @@
#include "rexmpp_xml.h"
#include <syslog.h>
#include <string.h>
+#include <stdlib.h>
rexmpp_xml_t *
rexmpp_roster_find_item (rexmpp_t *s,
diff --git a/src/rexmpp_rust.rs b/src/rexmpp_rust.rs
index fd19bd4..04bbcca 100644
--- a/src/rexmpp_rust.rs
+++ b/src/rexmpp_rust.rs
@@ -1,5 +1,6 @@
mod rexmpp_jid;
mod rexmpp_xml;
+mod rexmpp_xml_parser;
mod rexmpp_dns;
mod rexmpp_tcp;
mod rexmpp_socks;
diff --git a/src/rexmpp_sasl.c b/src/rexmpp_sasl.c
index cf5d1fe..20c4ba0 100644
--- a/src/rexmpp_sasl.c
+++ b/src/rexmpp_sasl.c
@@ -8,6 +8,7 @@
*/
#include <syslog.h>
+#include <stdlib.h>
#include "config.h"
#include "rexmpp.h"
diff --git a/src/rexmpp_tls.c b/src/rexmpp_tls.c
index e1de5ea..9234e92 100644
--- a/src/rexmpp_tls.c
+++ b/src/rexmpp_tls.c
@@ -8,6 +8,7 @@
#include <syslog.h>
#include <string.h>
+#include <stdlib.h>
#include "config.h"
diff --git a/src/rexmpp_xml.c b/src/rexmpp_xml.c
index 4907d4e..a7572fc 100644
--- a/src/rexmpp_xml.c
+++ b/src/rexmpp_xml.c
@@ -8,6 +8,7 @@
#include <string.h>
#include <stdio.h>
+#include <stdlib.h>
#include "rexmpp.h"
#include "rexmpp_utf8.h"
#include "rexmpp_xml.h"
@@ -533,7 +534,7 @@ rexmpp_xml_t *rexmpp_xml_parse (const char *str, int str_len) {
struct rexmpp_xml_builder builder = { NULL, NULL };
rexmpp_xml_parser_ctx_t parser =
rexmpp_xml_parser_new(&builder_sax, &builder);
- rexmpp_xml_parser_feed(parser, str, str_len);
+ rexmpp_xml_parser_feed(parser, str, str_len, 1);
rexmpp_xml_parser_free(parser);
if (builder.current != NULL) {
/* The parsing is not complete. */
@@ -552,13 +553,14 @@ rexmpp_xml_t *rexmpp_xml_read_fd (FILE *fd) {
}
char *buf;
- size_t len = 0;
+ size_t init_len = 0;
+ ssize_t buf_len = 0;
do {
- len = getline(&buf, &len, fd);
- if (len > 0) {
- rexmpp_xml_parser_feed(parser, buf, len);
+ buf_len = getline(&buf, &init_len, fd);
+ if (buf_len > 0) {
+ rexmpp_xml_parser_feed(parser, buf, buf_len, 0);
}
- } while (len > 0 &&
+ } while (buf_len > 0 &&
! (builder.root != NULL && builder.current == NULL) );
rexmpp_xml_parser_free(parser);
diff --git a/src/rexmpp_xml.rs b/src/rexmpp_xml.rs
index 717501d..8938e57 100644
--- a/src/rexmpp_xml.rs
+++ b/src/rexmpp_xml.rs
@@ -15,8 +15,8 @@ use super::{rexmpp};
#[repr(C)]
pub struct RexmppXMLQName {
- name: *mut c_char,
- namespace: *mut c_char
+ pub name: *mut c_char,
+ pub namespace: *mut c_char
}
impl Copy for RexmppXMLQName { }
@@ -36,9 +36,9 @@ impl Clone for RexmppXMLQName {
#[repr(C)]
pub struct RexmppXMLAttribute {
- qname: RexmppXMLQName,
- value: *mut c_char,
- next: *mut RexmppXMLAttribute
+ pub qname: RexmppXMLQName,
+ pub value: *mut c_char,
+ pub next: *mut RexmppXMLAttribute
}
impl Copy for RexmppXMLAttribute { }
@@ -56,16 +56,16 @@ impl Clone for RexmppXMLAttribute {
#[derive(Copy, Clone)]
#[derive(PartialEq)]
#[repr(C)]
-enum NodeType {
+pub enum NodeType {
Element,
Text
}
#[repr(C)]
-struct RexmppXMLAltElem {
- qname: RexmppXMLQName,
- attributes: *mut RexmppXMLAttribute,
- children: *mut RexmppXML
+pub struct RexmppXMLAltElem {
+ pub qname: RexmppXMLQName,
+ pub attributes: *mut RexmppXMLAttribute,
+ pub children: *mut RexmppXML
}
impl Copy for RexmppXMLAltElem { }
@@ -99,16 +99,16 @@ impl Clone for RexmppXMLAltElem {
#[derive(Copy, Clone)]
#[repr(C)]
-union RexmppXMLAlt {
- elem: RexmppXMLAltElem,
- text: *mut c_char
+pub union RexmppXMLAlt {
+ pub elem: RexmppXMLAltElem,
+ pub text: *mut c_char
}
#[repr(C)]
pub struct RexmppXML {
- node_type: NodeType,
- alt: RexmppXMLAlt,
- next: *mut RexmppXML
+ pub node_type: NodeType,
+ pub alt: RexmppXMLAlt,
+ pub next: *mut RexmppXML
}
impl Copy for RexmppXML { }
@@ -129,7 +129,7 @@ impl Clone for RexmppXML {
}
#[no_mangle]
-extern "C"
+pub extern "C"
fn rexmpp_xml_qname_free (qname_ptr: *mut RexmppXMLQName) {
match unsafe { qname_ptr.as_mut() } {
None => return,
@@ -147,7 +147,7 @@ fn rexmpp_xml_qname_free (qname_ptr: *mut RexmppXMLQName) {
}
#[no_mangle]
-extern "C"
+pub extern "C"
fn rexmpp_xml_attribute_free (attr_ptr: *mut RexmppXMLAttribute) {
if attr_ptr == ptr::null_mut() {
return;
@@ -161,7 +161,7 @@ fn rexmpp_xml_attribute_free (attr_ptr: *mut RexmppXMLAttribute) {
}
#[no_mangle]
-extern "C"
+pub extern "C"
fn rexmpp_xml_attribute_free_list (mut attr_ptr: *mut RexmppXMLAttribute) {
let mut next;
while attr_ptr != ptr::null_mut() {
@@ -172,7 +172,7 @@ fn rexmpp_xml_attribute_free_list (mut attr_ptr: *mut RexmppXMLAttribute) {
}
#[no_mangle]
-extern "C"
+pub extern "C"
fn rexmpp_xml_free (node_ptr: *mut RexmppXML) {
if node_ptr == ptr::null_mut() {
return;
@@ -198,7 +198,7 @@ fn rexmpp_xml_free (node_ptr: *mut RexmppXML) {
}
#[no_mangle]
-extern "C"
+pub extern "C"
fn rexmpp_xml_free_list (mut node_ptr: *mut RexmppXML) {
let mut next;
while node_ptr != ptr::null_mut() {
@@ -209,7 +209,7 @@ fn rexmpp_xml_free_list (mut node_ptr: *mut RexmppXML) {
}
#[no_mangle]
-extern "C"
+pub extern "C"
fn rexmpp_xml_clone (node_ptr: *mut RexmppXML) -> *mut RexmppXML {
if node_ptr == ptr::null_mut() {
return ptr::null_mut();
@@ -218,7 +218,7 @@ fn rexmpp_xml_clone (node_ptr: *mut RexmppXML) -> *mut RexmppXML {
}
#[no_mangle]
-extern "C"
+pub extern "C"
fn rexmpp_xml_clone_list (mut node_ptr: *mut RexmppXML) -> *mut RexmppXML {
if node_ptr == ptr::null_mut() {
return ptr::null_mut();
@@ -236,7 +236,7 @@ fn rexmpp_xml_clone_list (mut node_ptr: *mut RexmppXML) -> *mut RexmppXML {
#[no_mangle]
-extern "C"
+pub extern "C"
fn rexmpp_xml_new_text (str: *const c_char) -> *mut RexmppXML {
let node = RexmppXML {
node_type: NodeType::Text,
@@ -248,7 +248,7 @@ fn rexmpp_xml_new_text (str: *const c_char) -> *mut RexmppXML {
}
#[no_mangle]
-extern "C"
+pub extern "C"
fn rexmpp_xml_new_text_len (str: *const c_char, len: usize) -> *mut RexmppXML {
let node = RexmppXML {
node_type: NodeType::Text,
@@ -260,7 +260,7 @@ fn rexmpp_xml_new_text_len (str: *const c_char, len: usize) -> *mut RexmppXML {
}
#[no_mangle]
-extern "C" fn rexmpp_xml_add_child (node: *mut RexmppXML,
+pub extern "C" fn rexmpp_xml_add_child (node: *mut RexmppXML,
child: *mut RexmppXML) -> () {
let mut last_ptr : &mut *mut RexmppXML =
unsafe { &mut ((*node).alt.elem.children) };
@@ -271,7 +271,7 @@ extern "C" fn rexmpp_xml_add_child (node: *mut RexmppXML,
}
#[no_mangle]
-extern "C" fn rexmpp_xml_add_text (node: *mut RexmppXML,
+pub extern "C" fn rexmpp_xml_add_text (node: *mut RexmppXML,
str: *const c_char) -> c_int {
let text_node : *mut RexmppXML = rexmpp_xml_new_text(str);
if text_node != ptr::null_mut() {
@@ -282,7 +282,7 @@ extern "C" fn rexmpp_xml_add_text (node: *mut RexmppXML,
}
#[no_mangle]
-extern "C" fn rexmpp_xml_add_text_len (node: *mut RexmppXML,
+pub extern "C" fn rexmpp_xml_add_text_len (node: *mut RexmppXML,
str: *const c_char,
len: usize) -> c_int {
let text_node : *mut RexmppXML = rexmpp_xml_new_text_len(str, len);
@@ -294,7 +294,7 @@ extern "C" fn rexmpp_xml_add_text_len (node: *mut RexmppXML,
}
#[no_mangle]
-extern "C"
+pub extern "C"
fn rexmpp_xml_new_elem (name: *const c_char,
namespace: *const c_char) -> *mut RexmppXML {
let node = RexmppXML {
@@ -320,7 +320,7 @@ fn rexmpp_xml_new_elem (name: *const c_char,
}
#[no_mangle]
-extern "C"
+pub extern "C"
fn rexmpp_xml_attr_new (name: *const c_char,
namespace: *const c_char,
value: *const c_char) -> *mut RexmppXMLAttribute {
@@ -340,7 +340,7 @@ fn rexmpp_xml_attr_new (name: *const c_char,
}
#[no_mangle]
-extern "C"
+pub extern "C"
fn rexmpp_xml_add_attr_ns (node: *mut RexmppXML,
name: *const c_char,
namespace: *const c_char,
@@ -358,7 +358,7 @@ fn rexmpp_xml_add_attr_ns (node: *mut RexmppXML,
}
#[no_mangle]
-extern "C"
+pub extern "C"
fn rexmpp_xml_remove_attr_ns (node: *mut RexmppXML,
name: *const c_char,
namespace: *const c_char) -> c_int {
@@ -382,7 +382,7 @@ fn rexmpp_xml_remove_attr_ns (node: *mut RexmppXML,
}
#[no_mangle]
-extern "C"
+pub extern "C"
fn rexmpp_xml_add_attr (node: *mut RexmppXML,
name: *const c_char,
value: *const c_char) -> c_int {
@@ -390,7 +390,7 @@ fn rexmpp_xml_add_attr (node: *mut RexmppXML,
}
#[no_mangle]
-extern "C"
+pub extern "C"
fn rexmpp_xml_remove_attr (node: *mut RexmppXML,
name: *const c_char) -> c_int {
rexmpp_xml_remove_attr_ns(node, name, ptr::null_mut())
@@ -571,7 +571,7 @@ fn rexmpp_xml_serialize_str (node_ptr: *const RexmppXML,
}
#[no_mangle]
-extern "C"
+pub extern "C"
fn rexmpp_xml_serialize (node_ptr: *const RexmppXML,
pretty: bool)
-> *mut c_char
@@ -584,7 +584,7 @@ fn rexmpp_xml_serialize (node_ptr: *const RexmppXML,
}
#[no_mangle]
-extern "C"
+pub extern "C"
fn rexmpp_xml_add_id (s: *mut rexmpp::Rexmpp, node: *mut RexmppXML)
-> *mut RexmppXML
{
@@ -603,7 +603,7 @@ fn rexmpp_xml_add_id (s: *mut rexmpp::Rexmpp, node: *mut RexmppXML)
}
#[no_mangle]
-extern "C"
+pub extern "C"
fn rexmpp_xml_write_file (path: *const c_char,
node: *const RexmppXML)
-> c_int
@@ -623,7 +623,7 @@ fn rexmpp_xml_write_file (path: *const c_char,
}
#[no_mangle]
-extern "C"
+pub extern "C"
fn rexmpp_xml_siblings_count (mut node: *const RexmppXML) -> c_uint {
let mut i : c_uint = 0;
while node != ptr::null() {
@@ -634,7 +634,7 @@ fn rexmpp_xml_siblings_count (mut node: *const RexmppXML) -> c_uint {
}
#[no_mangle]
-extern "C"
+pub extern "C"
fn rexmpp_xml_match (node_ptr: *const RexmppXML,
namespace: *const c_char,
name: *const c_char) -> c_int {
@@ -673,7 +673,7 @@ fn rexmpp_xml_match (node_ptr: *const RexmppXML,
}
#[no_mangle]
-extern "C"
+pub extern "C"
fn rexmpp_xml_attr_match (attr: *const RexmppXMLAttribute,
namespace: *const c_char,
name: *const c_char) -> c_int {
@@ -708,7 +708,7 @@ fn rexmpp_xml_attr_match (attr: *const RexmppXMLAttribute,
}
#[no_mangle]
-extern "C"
+pub extern "C"
fn rexmpp_xml_is_stanza (node: *const RexmppXML) -> c_int {
if rexmpp_xml_match(node,
CString::new("jabber:client").expect("CString::new failed").as_ptr(),
@@ -726,7 +726,7 @@ fn rexmpp_xml_is_stanza (node: *const RexmppXML) -> c_int {
}
#[no_mangle]
-extern "C"
+pub extern "C"
fn rexmpp_xml_error (error_type: *const c_char, condition: *const c_char)
-> *mut RexmppXML {
let error : *mut RexmppXML =
@@ -749,7 +749,7 @@ fn rexmpp_xml_error (error_type: *const c_char, condition: *const c_char)
}
#[no_mangle]
-extern "C"
+pub extern "C"
fn rexmpp_xml_find_attr (node_ptr: *mut RexmppXML,
name: *const c_char,
namespace: *const c_char)
@@ -773,7 +773,7 @@ fn rexmpp_xml_find_attr (node_ptr: *mut RexmppXML,
}
#[no_mangle]
-extern "C"
+pub extern "C"
fn rexmpp_xml_find_attr_val_ns (node: *mut RexmppXML,
name: *const c_char,
namespace: *const c_char)
@@ -787,7 +787,7 @@ fn rexmpp_xml_find_attr_val_ns (node: *mut RexmppXML,
}
#[no_mangle]
-extern "C"
+pub extern "C"
fn rexmpp_xml_find_attr_val (node: *mut RexmppXML,
name: *const c_char)
-> *const c_char {
@@ -795,7 +795,7 @@ fn rexmpp_xml_find_attr_val (node: *mut RexmppXML,
}
#[no_mangle]
-extern "C"
+pub extern "C"
fn rexmpp_xml_find_child (node_ptr: *mut RexmppXML,
namespace: *const c_char,
name: *const c_char)
@@ -819,7 +819,7 @@ fn rexmpp_xml_find_child (node_ptr: *mut RexmppXML,
#[no_mangle]
-extern "C"
+pub extern "C"
fn rexmpp_xml_eq (n1: *const RexmppXML, n2: *const RexmppXML) -> bool {
if n1 == n2 {
return true;
@@ -865,10 +865,10 @@ fn rexmpp_xml_eq (n1: *const RexmppXML, n2: *const RexmppXML) -> bool {
if strcmp(name1, name2) != 0
{ return false; }
// Compare namespaces
- if (namespace1 != namespace2 &&
+ if namespace1 != namespace2 &&
(namespace1 == ptr::null_mut() ||
namespace2 == ptr::null_mut() ||
- strcmp(namespace1, namespace2) != 0))
+ strcmp(namespace1, namespace2) != 0)
{ return false; }
// Compare attributes
let mut attr1 = attributes1;
@@ -914,7 +914,7 @@ fn rexmpp_xml_eq (n1: *const RexmppXML, n2: *const RexmppXML) -> bool {
}
#[no_mangle]
-extern "C"
+pub extern "C"
fn rexmpp_xml_children (node: *const RexmppXML)
-> *mut RexmppXML {
if node != ptr::null_mut()
@@ -925,7 +925,7 @@ fn rexmpp_xml_children (node: *const RexmppXML)
}
#[no_mangle]
-extern "C"
+pub extern "C"
fn rexmpp_xml_first_elem_child (node: *mut RexmppXML)
-> *mut RexmppXML {
let mut child: *mut RexmppXML = rexmpp_xml_children(node);
@@ -939,7 +939,7 @@ fn rexmpp_xml_first_elem_child (node: *mut RexmppXML)
}
#[no_mangle]
-extern "C"
+pub extern "C"
fn rexmpp_xml_next_elem_sibling (node: *mut RexmppXML)
-> *mut RexmppXML {
if node == ptr::null_mut() {
@@ -956,7 +956,7 @@ fn rexmpp_xml_next_elem_sibling (node: *mut RexmppXML)
}
#[no_mangle]
-extern "C"
+pub extern "C"
fn rexmpp_xml_text (node: *mut RexmppXML)
-> *mut c_char {
if node != ptr::null_mut()
@@ -967,14 +967,14 @@ fn rexmpp_xml_text (node: *mut RexmppXML)
}
#[no_mangle]
-extern "C"
+pub extern "C"
fn rexmpp_xml_text_child (node: *mut RexmppXML)
-> *mut c_char {
rexmpp_xml_text(rexmpp_xml_children(node))
}
#[no_mangle]
-extern "C"
+pub extern "C"
fn rexmpp_xml_reverse_list (mut node: *mut RexmppXML)
-> *mut RexmppXML {
let mut next;
@@ -991,7 +991,7 @@ fn rexmpp_xml_reverse_list (mut node: *mut RexmppXML)
}
#[no_mangle]
-extern "C"
+pub extern "C"
fn rexmpp_xml_reverse_children (node: *mut RexmppXML)
-> *mut RexmppXML {
unsafe {
@@ -999,7 +999,7 @@ fn rexmpp_xml_reverse_children (node: *mut RexmppXML)
return node;
}
(*node).alt.elem.children =
- rexmpp_xml_reverse_list((*node).alt.elem.children);;
+ rexmpp_xml_reverse_list((*node).alt.elem.children);
let mut cur = node;
while cur != ptr::null_mut() {
diff --git a/src/rexmpp_xml_parser.c b/src/rexmpp_xml_parser.c
index d30d630..b2eaf8b 100644
--- a/src/rexmpp_xml_parser.c
+++ b/src/rexmpp_xml_parser.c
@@ -308,11 +308,12 @@ rexmpp_xml_parser_ctx_t rexmpp_xml_parser_reset (rexmpp_xml_parser_ctx_t ctx) {
void
rexmpp_xml_parser_feed (rexmpp_xml_parser_ctx_t ctx,
const char *chunk,
- size_t len)
+ size_t len,
+ int final)
{
#if defined(USE_LIBXML2)
- xmlParseChunk(ctx->xml_parser, chunk, len, 0);
+ xmlParseChunk(ctx->xml_parser, chunk, len, final);
#elif defined(USE_EXPAT)
- XML_Parse(ctx->xml_parser, chunk, len, 0);
+ XML_Parse(ctx->xml_parser, chunk, len, final);
#endif
}
diff --git a/src/rexmpp_xml_parser.h b/src/rexmpp_xml_parser.h
index 07464a2..66627ab 100644
--- a/src/rexmpp_xml_parser.h
+++ b/src/rexmpp_xml_parser.h
@@ -42,6 +42,8 @@ struct rexmpp_xml_parser_ctx {
xmlParserCtxtPtr xml_parser;
#elif defined(USE_EXPAT)
XML_Parser xml_parser;
+#else
+ void *xml_parser;
#endif
rexmpp_xml_parser_handlers_t handlers;
void *user_data;
@@ -72,7 +74,8 @@ void rexmpp_xml_parser_free (rexmpp_xml_parser_ctx_t ctx);
void
rexmpp_xml_parser_feed (rexmpp_xml_parser_ctx_t ctx,
const char *chunk,
- size_t len);
+ size_t len,
+ int final);
/**
@brief Resets a parser context
diff --git a/src/rexmpp_xml_parser.rs b/src/rexmpp_xml_parser.rs
new file mode 100644
index 0000000..3c393de
--- /dev/null
+++ b/src/rexmpp_xml_parser.rs
@@ -0,0 +1,146 @@
+extern crate libc;
+extern crate rxml;
+use libc::{free, strndup};
+use std::ptr;
+use std::os::raw::{c_char, c_void};
+use std::ffi::{CStr, CString};
+use std::slice;
+use rxml::{FeedParser, Error, ResolvedEvent, XmlVersion, EventRead, CData};
+use std::io;
+use std::sync::Arc;
+use super::{rexmpp_xml};
+
+type RexmppXMLParserElementStart = unsafe extern "C"
+fn (data: *mut c_void,
+ name: *const c_char,
+ namespace: *const c_char,
+ attributes: *mut rexmpp_xml::RexmppXMLAttribute) -> ();
+
+type RexmppXMLParserElementEnd = unsafe extern "C"
+fn (data: *mut c_void) -> ();
+
+type RexmppXMLParserCharacters = unsafe extern "C"
+fn (data: *mut c_void,
+ ch: *const c_char,
+ len: usize) -> ();
+
+#[repr(C)]
+struct RexmppXMLParserHandlers {
+ elem_start: RexmppXMLParserElementStart,
+ elem_end: RexmppXMLParserElementEnd,
+ text: RexmppXMLParserCharacters
+}
+
+#[repr(C)]
+struct RexmppXMLParserCtx {
+ xml_parser: *mut FeedParser,
+ handlers: *mut RexmppXMLParserHandlers,
+ user_data: *mut c_void
+}
+
+#[no_mangle]
+extern "C"
+fn rexmpp_xml_parser_new (handlers: *mut RexmppXMLParserHandlers,
+ data: *mut c_void)
+ -> *mut RexmppXMLParserCtx
+{
+ let mut fp = FeedParser::default();
+ let ctx = RexmppXMLParserCtx {
+ xml_parser: Box::into_raw(Box::new(fp)),
+ handlers: handlers,
+ user_data: data
+ };
+ Box::into_raw(Box::new(ctx))
+}
+
+#[no_mangle]
+extern "C"
+fn rexmpp_xml_parser_free (ctx: *mut RexmppXMLParserCtx) {
+ unsafe { free(ctx as *mut c_void) };
+}
+
+#[no_mangle]
+extern "C"
+fn rexmpp_xml_parser_feed (ctx: *mut RexmppXMLParserCtx,
+ chunk: *const c_char,
+ len: usize,
+ is_final: bool)
+{
+ unsafe {
+ // todo: maybe duplicate the string, since apparently a
+ // mutable one is expected by the parser.
+ let mut buf : &[u8] = slice::from_raw_parts(chunk as *mut u8, len);
+ let user_data_ptr = (*ctx).user_data;
+ let handlers = (*ctx).handlers;
+ (*((*ctx).xml_parser)).parse_all(&mut buf, is_final, |ev| {
+ match ev {
+ ResolvedEvent::StartElement(_, (namespace, name), attrs) =>
+ {
+ let name_str = name.to_string();
+ let ns_opt_cstr : Option<CString> = match namespace {
+ None => None,
+ Some(ns_arc_name) => {
+ match CString::new(ns_arc_name.to_string()) {
+ Ok(cstr) => Some(cstr),
+ Err(_) => None
+ }
+ }
+ };
+ match CString::new(name_str) {
+ Ok(name_cstr) => {
+ let name_cstr_ptr = name_cstr.as_ptr();
+ let namespace_cstr_ptr =
+ match ns_opt_cstr {
+ None => ptr::null_mut(),
+ // "ref" is important to use here,
+ // otherwise the pointer will be
+ // wrong.
+ Some(ref ns_cstr) => ns_cstr.as_ptr()
+ };
+ let mut attributes = ptr::null_mut();
+ for ((_, attr_name), attr_val) in attrs.iter() {
+ match (CString::new(attr_name.to_string()),
+ CString::new(attr_val.to_string())) {
+ (Ok(attr_name_cstr), Ok(attr_val_cstr)) => {
+ let attr =
+ rexmpp_xml::rexmpp_xml_attr_new
+ (attr_name_cstr.as_ptr(),
+ ptr::null_mut(),
+ attr_val_cstr.as_ptr());
+ (*attr).next = attributes;
+ attributes = attr;
+ },
+ _ => ()
+ }
+ }
+ ((*handlers).elem_start)
+ (user_data_ptr,
+ name_cstr_ptr,
+ namespace_cstr_ptr,
+ attributes);
+ },
+ Err(_) => ()
+ }
+ },
+ ResolvedEvent::EndElement(_) =>
+ ((*handlers).elem_end)(user_data_ptr),
+ ResolvedEvent::Text(_, cd) =>
+ ((*handlers).text)(
+ user_data_ptr,
+ cd.as_ptr() as *const i8,
+ cd.len()
+ ),
+ _ => ()
+ }
+ });
+ }
+}
+
+#[no_mangle]
+extern "C"
+fn rexmpp_xml_parser_reset (ctx_raw: *mut RexmppXMLParserCtx)
+ -> *mut RexmppXMLParserCtx
+{
+ let ctx = unsafe { Box::from_raw(ctx_raw) };
+ rexmpp_xml_parser_new((*ctx).handlers, (*ctx).user_data)
+}