#![allow(non_snake_case)]
use core::ffi::c_void;
use core::ptr;
use std::os::raw::{c_char, c_int, c_uint};
use crate::abi::allocator;
use crate::abi::callbacks::*;
use crate::abi::structs::*;
use crate::abi::types::xmlChar;
use crate::abi::types::xmlDocProperties::XML_DOC_WELLFORMED;
use crate::abi::types::xmlElementType::*;
use crate::xml::tree;
pub(crate) mod default_sax_handler {
use super::*;
unsafe fn ctxt_from_ctx(ctx: *mut c_void) -> *mut _xmlParserCtxt {
ctx as *mut _xmlParserCtxt
}
pub unsafe extern "C" fn startDocument(ctx: *mut c_void) {
let ctxt = unsafe { ctxt_from_ctx(ctx) };
if ctxt.is_null() {
return;
}
unsafe {
let c = &mut *ctxt;
let doc = tree::new_doc(ptr::null());
if doc.is_null() {
return;
}
c.myDoc = doc;
c.wellFormed = 1;
}
}
pub unsafe extern "C" fn endDocument(ctx: *mut c_void) {
let ctxt = unsafe { ctxt_from_ctx(ctx) };
if ctxt.is_null() {
return;
}
unsafe {
let c = &*ctxt;
if !c.myDoc.is_null() {
if !c.version.is_null() {
if (*c.myDoc).version.is_null() {
let dup = allocator::xmlMemStrdup(c.version as *const c_char);
(*c.myDoc).version = dup as *mut xmlChar;
}
}
if !c.encoding.is_null() {
if (*c.myDoc).encoding.is_null() {
let dup = allocator::xmlMemStrdup(c.encoding as *const c_char);
(*c.myDoc).encoding = dup as *mut xmlChar;
}
}
if c.wellFormed != 0 {
(*(c.myDoc)).properties |= XML_DOC_WELLFORMED as c_int;
}
}
}
}
#[allow(clippy::too_many_arguments)]
pub unsafe extern "C" fn startElementNs(
ctx: *mut c_void,
localname: *const xmlChar,
prefix: *const xmlChar,
URI: *const xmlChar,
nb_namespaces: c_int,
namespaces: *mut *const xmlChar,
nb_attributes: c_int,
nb_defaulted: c_int,
attributes: *mut *const xmlChar,
) {
let ctxt = unsafe { ctxt_from_ctx(ctx) };
if ctxt.is_null() || localname.is_null() {
return;
}
unsafe {
let c = &mut *ctxt;
let parent = if c.nodeNr > 0 && !c.nodeTab.is_null() {
let idx = (c.nodeNr - 1) as usize;
*c.nodeTab.add(idx)
} else {
ptr::null_mut()
};
let ns = if URI.is_null() && prefix.is_null() {
ptr::null_mut()
} else {
tree::search_ns(c.myDoc, parent, prefix)
};
let node = tree::new_node(ns, localname);
if node.is_null() {
return;
}
if !URI.is_null() && ns.is_null() {
let new_ns = tree::new_ns(node, URI, prefix);
(*node).ns = new_ns;
}
if nb_namespaces > 0 && !namespaces.is_null() {
let mut i: c_int = 0;
while i < nb_namespaces {
let ns_prefix = *namespaces.add((i * 2) as usize);
let ns_uri = *namespaces.add((i * 2 + 1) as usize);
tree::new_ns(node, ns_uri, ns_prefix);
i += 1;
}
}
if nb_attributes > 0 && !attributes.is_null() {
let mut i: c_int = 0;
while i < nb_attributes {
let attr_idx = (i * 5) as usize;
let attr_name = *attributes.add(attr_idx); let attr_prefix = *attributes.add(attr_idx + 1); let attr_uri = *attributes.add(attr_idx + 2); let attr_value_start = *attributes.add(attr_idx + 3); let attr_value_end = *attributes.add(attr_idx + 4);
if !attr_name.is_null() && !attr_value_start.is_null() {
let value_len = if attr_value_end.is_null() {
let mut len: isize = 0;
unsafe {
while *attr_value_start.offset(len) != 0 {
len += 1;
}
}
len
} else {
attr_value_end.offset_from(attr_value_start)
};
if value_len > 0 {
let value =
allocator::xmlMalloc((value_len + 1) as usize) as *mut xmlChar;
if !value.is_null() {
ptr::copy_nonoverlapping(
attr_value_start,
value,
value_len as usize,
);
*value.add(value_len as usize) = 0;
tree::set_prop(node, attr_name, value as *const xmlChar);
allocator::xmlFree(value as *mut c_void);
}
}
}
i += 1;
}
}
if !parent.is_null() {
tree::add_child(parent, node);
} else {
if !c.myDoc.is_null() {
tree::add_child(c.myDoc as *mut _xmlNode, node);
}
}
c.node = node;
if c.nodeNr >= c.nodeMax {
let new_max = if c.nodeMax == 0 { 8 } else { c.nodeMax * 2 };
let new_size = (new_max as usize) * size_of::<*mut _xmlNode>();
let new_tab =
allocator::xmlRealloc(c.nodeTab as *mut c_void, new_size) as *mut *mut _xmlNode;
if !new_tab.is_null() {
c.nodeTab = new_tab;
c.nodeMax = new_max;
}
}
if c.nodeNr < c.nodeMax && !c.nodeTab.is_null() {
*c.nodeTab.add(c.nodeNr as usize) = node;
c.nodeNr += 1;
}
}
}
pub unsafe extern "C" fn endElementNs(
ctx: *mut c_void,
localname: *const xmlChar,
prefix: *const xmlChar,
URI: *const xmlChar,
) {
let ctxt = unsafe { ctxt_from_ctx(ctx) };
if ctxt.is_null() {
return;
}
unsafe {
let c = &mut *ctxt;
if c.nodeNr > 0 {
c.nodeNr -= 1;
}
if c.nodeNr > 0 && !c.nodeTab.is_null() {
let idx = (c.nodeNr - 1) as usize;
c.node = *c.nodeTab.add(idx);
} else {
c.node = ptr::null_mut();
}
}
}
pub unsafe extern "C" fn characters(ctx: *mut c_void, ch: *const xmlChar, len: c_int) {
let ctxt = unsafe { ctxt_from_ctx(ctx) };
if ctxt.is_null() || ch.is_null() || len <= 0 {
return;
}
unsafe {
let c = &*ctxt;
let parent = if c.nodeNr > 0 && !c.nodeTab.is_null() {
let idx = (c.nodeNr - 1) as usize;
*c.nodeTab.add(idx)
} else {
c.myDoc as *mut _xmlNode
};
if parent.is_null() {
return;
}
let content = allocator::xmlMalloc((len + 1) as usize) as *mut xmlChar;
if content.is_null() {
return;
}
ptr::copy_nonoverlapping(ch, content, len as usize);
*content.add(len as usize) = 0;
let text = tree::new_text(content as *const xmlChar);
allocator::xmlFree(content as *mut c_void);
if !text.is_null() {
tree::add_child(parent, text);
}
}
}
pub unsafe extern "C" fn ignorableWhitespace(ctx: *mut c_void, ch: *const xmlChar, len: c_int) {
unsafe { characters(ctx, ch, len) };
}
pub unsafe extern "C" fn comment(ctx: *mut c_void, value: *const xmlChar) {
let ctxt = unsafe { ctxt_from_ctx(ctx) };
if ctxt.is_null() {
return;
}
unsafe {
let c = &*ctxt;
let parent = if c.nodeNr > 0 && !c.nodeTab.is_null() {
let idx = (c.nodeNr - 1) as usize;
*c.nodeTab.add(idx)
} else {
c.myDoc as *mut _xmlNode
};
if parent.is_null() {
return;
}
let comment_node = tree::new_comment(value);
if !comment_node.is_null() {
tree::add_child(parent, comment_node);
}
}
}
pub unsafe extern "C" fn processingInstruction(
ctx: *mut c_void,
target: *const xmlChar,
data: *const xmlChar,
) {
let ctxt = unsafe { ctxt_from_ctx(ctx) };
if ctxt.is_null() || target.is_null() {
return;
}
unsafe {
let c = &*ctxt;
let parent = if c.nodeNr > 0 && !c.nodeTab.is_null() {
let idx = (c.nodeNr - 1) as usize;
*c.nodeTab.add(idx)
} else {
c.myDoc as *mut _xmlNode
};
if parent.is_null() {
return;
}
let pi_node = tree::new_pi(target, data);
if !pi_node.is_null() {
tree::add_child(parent, pi_node);
}
}
}
pub unsafe extern "C" fn cdataBlock(ctx: *mut c_void, value: *const xmlChar, len: c_int) {
let ctxt = unsafe { ctxt_from_ctx(ctx) };
if ctxt.is_null() || value.is_null() || len <= 0 {
return;
}
unsafe {
let c = &*ctxt;
let parent = if c.nodeNr > 0 && !c.nodeTab.is_null() {
let idx = (c.nodeNr - 1) as usize;
*c.nodeTab.add(idx)
} else {
c.myDoc as *mut _xmlNode
};
if parent.is_null() {
return;
}
let cdata = tree::new_cdata_block(c.myDoc, value, len);
if !cdata.is_null() {
tree::add_child(parent, cdata);
}
}
}
pub unsafe extern "C" fn internalSubset(
ctx: *mut c_void,
name: *const xmlChar,
ext_id: *const xmlChar,
sys_id: *const xmlChar,
) {
let ctxt = unsafe { ctxt_from_ctx(ctx) };
if ctxt.is_null() || name.is_null() {
return;
}
unsafe {
let c = &mut *ctxt;
if c.myDoc.is_null() {
return;
}
let dtd = tree::new_dtd(c.myDoc, name, ext_id, sys_id);
if !dtd.is_null() {
}
}
}
pub unsafe extern "C" fn externalSubset(
ctx: *mut c_void,
name: *const xmlChar,
ext_id: *const xmlChar,
sys_id: *const xmlChar,
) {
let ctxt = unsafe { ctxt_from_ctx(ctx) };
if ctxt.is_null() || name.is_null() {
return;
}
unsafe {
let c = &mut *ctxt;
if c.myDoc.is_null() {
return;
}
if (*(c.myDoc)).intSubset.is_null() {
let dtd = tree::new_dtd(c.myDoc, name, ext_id, sys_id);
if !dtd.is_null() {
(*(c.myDoc)).extSubset = dtd;
}
} else {
let dtd = (*(c.myDoc)).intSubset;
if !ext_id.is_null() {
let ext_copy = tree::xml_strlen(ext_id);
if ext_copy > 0 {
(*(c.myDoc)).extSubset = dtd;
}
}
}
}
}
pub unsafe extern "C" fn entityDecl(
ctx: *mut c_void,
name: *const xmlChar,
type_: c_int,
pub_id: *const xmlChar,
sys_id: *const xmlChar,
content: *mut xmlChar,
) {
let ctxt = unsafe { ctxt_from_ctx(ctx) };
if ctxt.is_null() || name.is_null() {
return;
}
unsafe {
let c = &*ctxt;
if c.myDoc.is_null() {
return;
}
let _entity = tree::new_entity(
c.myDoc,
name,
type_,
pub_id,
sys_id,
content as *const xmlChar,
);
}
}
pub unsafe extern "C" fn attributeDecl(
ctx: *mut c_void,
elem: *const xmlChar,
fullname: *const xmlChar,
type_: c_int,
def: c_int,
default_value: *const xmlChar,
tree: *mut _xmlEnumeration,
) {
}
pub unsafe extern "C" fn elementDecl(
ctx: *mut c_void,
name: *const xmlChar,
type_: c_int,
content: *mut _xmlElementContent,
) {
}
pub unsafe extern "C" fn notationDecl(
ctx: *mut c_void,
name: *const xmlChar,
pub_id: *const xmlChar,
sys_id: *const xmlChar,
) {
}
pub unsafe extern "C" fn unparsedEntityDecl(
ctx: *mut c_void,
name: *const xmlChar,
pub_id: *const xmlChar,
sys_id: *const xmlChar,
notation: *const xmlChar,
) {
}
pub unsafe extern "C" fn resolveEntity(
ctx: *mut c_void,
pub_id: *const xmlChar,
sys_id: *const xmlChar,
) -> *mut _xmlParserInput {
ptr::null_mut()
}
pub unsafe extern "C" fn isStandalone(ctx: *mut c_void) -> c_int {
-1
}
pub unsafe extern "C" fn hasInternalSubset(ctx: *mut c_void) -> c_int {
let ctxt = unsafe { ctxt_from_ctx(ctx) };
if ctxt.is_null() {
return 0;
}
unsafe {
let c = &*ctxt;
if c.myDoc.is_null() {
return 0;
}
if (*(c.myDoc)).intSubset.is_null() {
0
} else {
1
}
}
}
pub unsafe extern "C" fn hasExternalSubset(ctx: *mut c_void) -> c_int {
let ctxt = unsafe { ctxt_from_ctx(ctx) };
if ctxt.is_null() {
return 0;
}
unsafe {
let c = &*ctxt;
if c.myDoc.is_null() {
return 0;
}
if (*(c.myDoc)).extSubset.is_null() {
0
} else {
1
}
}
}
pub unsafe extern "C" fn getEntity(ctx: *mut c_void, name: *const xmlChar) -> *mut _xmlEntity {
let ctxt = unsafe { ctxt_from_ctx(ctx) };
if ctxt.is_null() || name.is_null() {
return ptr::null_mut();
}
unsafe {
let c = &*ctxt;
if c.myDoc.is_null() {
return ptr::null_mut();
}
tree::get_doc_entity(c.myDoc, name)
}
}
pub unsafe extern "C" fn getParameterEntity(
ctx: *mut c_void,
name: *const xmlChar,
) -> *mut _xmlEntity {
let ctxt = unsafe { ctxt_from_ctx(ctx) };
if ctxt.is_null() || name.is_null() {
return ptr::null_mut();
}
unsafe {
let c = &*ctxt;
if c.myDoc.is_null() {
return ptr::null_mut();
}
tree::get_parameter_entity(c.myDoc, name)
}
}
pub unsafe extern "C" fn setDocumentLocator(ctx: *mut c_void, loc: *mut _xmlSAXLocator) {
}
pub unsafe extern "C" fn reference(ctx: *mut c_void, name: *const xmlChar) {
}
pub unsafe extern "C" fn warning(ctx: *mut c_void, msg: *const c_char) {
let ctxt = unsafe { ctxt_from_ctx(ctx) };
if ctxt.is_null() || msg.is_null() {
return;
}
unsafe {
let c = &mut *ctxt;
c.nbWarnings += 1;
}
}
pub unsafe extern "C" fn error(ctx: *mut c_void, msg: *const c_char) {
let ctxt = unsafe { ctxt_from_ctx(ctx) };
if ctxt.is_null() || msg.is_null() {
return;
}
unsafe {
let c = &mut *ctxt;
c.nbErrors += 1;
c.wellFormed = 0;
}
}
pub unsafe extern "C" fn fatalError(ctx: *mut c_void, msg: *const c_char) {
let ctxt = unsafe { ctxt_from_ctx(ctx) };
if ctxt.is_null() || msg.is_null() {
return;
}
unsafe {
let c = &mut *ctxt;
c.nbErrors += 1;
c.wellFormed = 0;
}
}
}