#![allow(non_snake_case)]
#![allow(unused_variables)]
#![allow(clippy::missing_safety_doc)]
#![allow(clippy::not_unsafe_ptr_arg_deref)]
use core::ffi::c_void;
use core::ptr;
use once_cell::sync::Lazy;
use parking_lot::Mutex;
use std::collections::HashMap;
use std::ffi::{CStr, CString};
use std::mem::size_of;
use std::os::raw::{c_char, c_int, c_long, c_uint, c_ulong};
use crate::xml::xpath::ast::CompiledExpr;
use crate::xml::xpath::context::{BoxedXPathFunction, XPathContext};
use crate::xml::xpath::types::{NodeSet, XPathValue};
use crate::abi::allocator::*;
use crate::abi::callbacks::*;
use crate::abi::structs::*;
use crate::abi::types::*;
#[no_mangle]
pub unsafe extern "C" fn xmlInitParser() {
crate::internal::globals::init_parser();
}
#[no_mangle]
pub const unsafe extern "C" fn xmlInitGlobals() {
}
#[no_mangle]
pub const unsafe extern "C" fn xmlInitializeGlobalState(_gs: *mut c_void) {
}
#[no_mangle]
pub const extern "C" fn xmlInitializeDict() -> c_int {
0
}
#[no_mangle]
pub const extern "C" fn xmlInitializePredefinedEntities() {
}
#[no_mangle]
pub const extern "C" fn xmlCleanupPredefinedEntities() {
}
#[no_mangle]
pub const extern "C" fn xmlDefaultSAXHandlerInit() {
}
static SAX2_DEFAULT_VERSION: core::sync::atomic::AtomicI32 = core::sync::atomic::AtomicI32::new(2);
#[no_mangle]
pub extern "C" fn xmlSAXDefaultVersion(version: c_int) -> c_int {
use core::sync::atomic::Ordering;
let ret = SAX2_DEFAULT_VERSION.load(Ordering::Relaxed);
if version != 1 && version != 2 {
return -1;
}
SAX2_DEFAULT_VERSION.store(version, Ordering::Relaxed);
ret
}
#[no_mangle]
pub unsafe extern "C" fn xmlSAXVersion(
hdlr: *mut crate::abi::structs::_xmlSAXHandler,
version: c_int,
) -> c_int {
if hdlr.is_null() {
return -1;
}
if version != 1 && version != 2 {
return -1;
}
unsafe {
crate::xml::sax::dispatch::xmlSAX2InitDefaultSAXHandler(hdlr);
let h = &mut *hdlr;
if version == 2 {
h.initialized = crate::abi::constants::XML_SAX2_MAGIC as c_uint;
} else {
h.initialized = 1;
}
}
0
}
#[no_mangle]
pub extern "C" fn xmlHasFeature(feature: c_int) -> c_int {
if (1..=24).contains(&feature) {
1
} else {
0
}
}
#[no_mangle]
pub const unsafe extern "C" fn xmlCleanupGlobals() {
}
#[no_mangle]
pub unsafe extern "C" fn xmlCleanupParser() {
crate::internal::globals::cleanup_parser();
}
#[no_mangle]
pub extern "C" fn xmlNewMutex() -> *mut c_void {
crate::xml::threads::new_mutex()
}
#[no_mangle]
pub unsafe extern "C" fn xmlFreeMutex(tok: *mut c_void) {
crate::xml::threads::free_mutex(tok);
}
#[no_mangle]
pub unsafe extern "C" fn xmlMutexLock(tok: *mut c_void) {
crate::xml::threads::mutex_lock(tok);
}
#[no_mangle]
pub unsafe extern "C" fn xmlMutexUnlock(tok: *mut c_void) {
crate::xml::threads::mutex_unlock(tok);
}
#[no_mangle]
pub extern "C" fn xmlNewRMutex() -> *mut c_void {
crate::xml::threads::new_rmutex()
}
#[no_mangle]
pub unsafe extern "C" fn xmlFreeRMutex(tok: *mut c_void) {
crate::xml::threads::free_rmutex(tok);
}
#[no_mangle]
pub unsafe extern "C" fn xmlRMutexLock(tok: *mut c_void) {
crate::xml::threads::rmutex_lock(tok);
}
#[no_mangle]
pub unsafe extern "C" fn xmlRMutexUnlock(tok: *mut c_void) {
crate::xml::threads::rmutex_unlock(tok);
}
#[no_mangle]
pub const extern "C" fn xmlCheckThreadLocalStorage() -> c_int {
0
}
#[no_mangle]
pub unsafe extern "C" fn xmlInitThreads() {
let _ = unsafe { crate::internal::globals::init_threads() };
}
#[no_mangle]
pub unsafe extern "C" fn xmlCleanupThreads() {
crate::xml::threads::cleanup_threads();
}
#[no_mangle]
pub extern "C" fn xmlIsInitialized() -> c_int {
if crate::abi::versioning::is_initialized() {
1
} else {
0
}
}
#[no_mangle]
pub const unsafe extern "C" fn xmlLockLibrary() {
crate::xml::threads::lock_library();
}
#[no_mangle]
pub const unsafe extern "C" fn xmlUnlockLibrary() {
crate::xml::threads::unlock_library();
}
#[no_mangle]
pub unsafe extern "C" fn xmlSetGenericErrorFunc(
ctx: *mut c_void,
handler: Option<crate::abi::callbacks::xmlGenericErrorFunc>,
) {
unsafe { crate::xml::errors::set_generic_error_func(ctx, handler) };
}
#[no_mangle]
pub unsafe extern "C" fn xmlSetStructuredErrorFunc(
ctx: *mut c_void,
handler: Option<xmlStructuredErrorFunc>,
) {
unsafe { crate::xml::errors::set_structured_error_func(ctx, handler) };
}
#[no_mangle]
pub extern "C" fn xmlGetLastError() -> *mut _xmlError {
crate::xml::errors::get_last_error()
}
#[no_mangle]
pub unsafe extern "C" fn xmlCopyError(from: *const _xmlError, to: *mut _xmlError) -> c_int {
unsafe { crate::xml::errors::copy_error(from, to) }
}
#[no_mangle]
pub const unsafe extern "C" fn xmlResetError(err: *mut _xmlError) {
unsafe { crate::xml::errors::reset_error(err) };
}
#[no_mangle]
pub unsafe extern "C" fn xmlRaiseError(
ctxt: *mut c_void,
ctxt2: *mut c_void,
ctxt3: *mut c_void,
ctxt4: *mut c_void,
ctxt5: *mut c_void,
domain: c_int,
code: c_int,
level: c_int,
file: *const c_char,
line: c_int,
str1: *const c_char,
str2: *const c_char,
str3: *const c_char,
int1: c_int,
int2: c_int,
msg: *const c_char,
) {
unsafe {
crate::xml::errors::raise_error(
ctxt, ctxt2, ctxt3, ctxt4, ctxt5, domain, code, level, file, line, str1, str2, str3,
int1, int2, msg,
);
}
}
#[no_mangle]
pub extern "C" fn xmlResetLastError() {
crate::xml::errors::reset_last_error();
}
#[no_mangle]
pub unsafe extern "C" fn xmlStrdup(cur: *const xmlChar) -> *mut xmlChar {
if cur.is_null() {
return ptr::null_mut();
}
let len = unsafe { xmlStrlen(cur) };
let size = len + 1;
let new_ptr = unsafe { xmlMallocImpl(size as usize) };
if new_ptr.is_null() {
return ptr::null_mut();
}
unsafe {
ptr::copy_nonoverlapping(cur, new_ptr as *mut u8, size as usize);
}
new_ptr as *mut xmlChar
}
#[no_mangle]
pub unsafe extern "C" fn xmlStrndup(cur: *const xmlChar, len: c_int) -> *mut xmlChar {
if cur.is_null() || len < 0 {
return ptr::null_mut();
}
let size = len as usize + 1;
let new_ptr = unsafe { xmlMallocImpl(size) };
if new_ptr.is_null() {
return ptr::null_mut();
}
unsafe {
ptr::copy_nonoverlapping(cur, new_ptr as *mut u8, len as usize);
*(new_ptr.add(len as usize) as *mut u8) = 0;
}
new_ptr as *mut xmlChar
}
#[no_mangle]
pub unsafe extern "C" fn xmlStrlen(str: *const xmlChar) -> c_int {
if str.is_null() {
return 0;
}
unsafe { libc::strlen(str as *const c_char) as c_int }
}
#[no_mangle]
pub const unsafe extern "C" fn xmlStrchr(str: *const xmlChar, val: xmlChar) -> *const xmlChar {
if str.is_null() {
return ptr::null();
}
unsafe {
let mut cur = str;
while *cur != 0 {
if *cur == val {
return cur;
}
cur = cur.add(1);
}
ptr::null()
}
}
#[no_mangle]
pub unsafe extern "C" fn xmlStrcmp(str1: *const xmlChar, str2: *const xmlChar) -> c_int {
if str1.is_null() && str2.is_null() {
return 0;
}
if str1.is_null() {
return -1;
}
if str2.is_null() {
return 1;
}
unsafe { libc::strcmp(str1 as *const c_char, str2 as *const c_char) as c_int }
}
#[no_mangle]
pub unsafe extern "C" fn xmlStrncmp(
str1: *const xmlChar,
str2: *const xmlChar,
len: c_int,
) -> c_int {
if len <= 0 {
return 0;
}
if str1.is_null() && str2.is_null() {
return 0;
}
if str1.is_null() {
return -1;
}
if str2.is_null() {
return 1;
}
unsafe { libc::strncmp(str1 as *const c_char, str2 as *const c_char, len as usize) as c_int }
}
#[no_mangle]
pub unsafe extern "C" fn xmlStrcasecmp(str1: *const xmlChar, str2: *const xmlChar) -> c_int {
if str1.is_null() && str2.is_null() {
return 0;
}
if str1.is_null() {
return -1;
}
if str2.is_null() {
return 1;
}
unsafe { libc::strcasecmp(str1 as *const c_char, str2 as *const c_char) as c_int }
}
#[no_mangle]
pub unsafe extern "C" fn xmlStrncasecmp(
str1: *const xmlChar,
str2: *const xmlChar,
len: c_int,
) -> c_int {
if len <= 0 {
return 0;
}
if str1.is_null() && str2.is_null() {
return 0;
}
if str1.is_null() {
return -1;
}
if str2.is_null() {
return 1;
}
unsafe {
libc::strncasecmp(str1 as *const c_char, str2 as *const c_char, len as usize) as c_int
}
}
#[no_mangle]
pub unsafe extern "C" fn xmlStrEqual(str1: *const xmlChar, str2: *const xmlChar) -> c_int {
if str1.is_null() && str2.is_null() {
return 1;
}
if str1.is_null() || str2.is_null() {
return 0;
}
unsafe { (libc::strcmp(str1 as *const c_char, str2 as *const c_char) == 0) as c_int }
}
#[no_mangle]
pub unsafe extern "C" fn xmlBuildQName(
ncname: *const xmlChar,
prefix: *const xmlChar,
memory: *mut xmlChar,
len: c_int,
) -> *mut xmlChar {
crate::xml::string::build_qname(ncname, prefix, memory, len)
}
#[no_mangle]
pub unsafe extern "C" fn xmlSplitQName2(
name: *const xmlChar,
prefix: *mut *mut xmlChar,
) -> *mut xmlChar {
crate::xml::string::split_qname2(name, prefix)
}
#[no_mangle]
pub unsafe extern "C" fn xmlSplitQName3(name: *const xmlChar, len: *mut c_int) -> *mut xmlChar {
crate::xml::string::split_qname3(name, len)
}
#[no_mangle]
pub unsafe extern "C" fn xmlSplitQName(
_ctxt: *mut _xmlParserCtxt,
name: *const xmlChar,
prefix: *mut *mut xmlChar,
) -> *mut xmlChar {
crate::xml::string::split_qname2(name, prefix)
}
#[no_mangle]
pub const unsafe extern "C" fn xmlUTF8Strlen(utf: *const xmlChar) -> c_int {
crate::xml::string::utf8_strlen(utf)
}
#[no_mangle]
pub const unsafe extern "C" fn xmlUTF8Size(utf: *const xmlChar) -> c_int {
crate::xml::string::utf8_size(utf)
}
#[no_mangle]
pub const unsafe extern "C" fn xmlCheckUTF8(utf: *const xmlChar) -> c_int {
crate::xml::string::check_utf8(utf)
}
#[no_mangle]
pub unsafe extern "C" fn xmlStrQEqual(
pref: *const xmlChar,
name: *const xmlChar,
str: *const xmlChar,
) -> c_int {
if name.is_null() || str.is_null() {
return 0;
}
if pref.is_null() {
return unsafe { xmlStrEqual(name, str) };
}
let pref_len = unsafe { xmlStrlen(pref) };
let name_len = unsafe { xmlStrlen(name) };
let total_len = pref_len + 1 + name_len;
let str_len = unsafe { xmlStrlen(str) };
if total_len != str_len {
return 0;
}
if unsafe {
libc::strncmp(
pref as *const c_char,
str as *const c_char,
pref_len as usize,
)
} != 0
{
return 0;
}
if unsafe { *str.add(pref_len as usize) } != b':' as xmlChar {
return 0;
}
(unsafe {
libc::strncmp(
name as *const c_char,
str.add((pref_len + 1) as usize) as *const c_char,
name_len as usize,
) == 0
}) as c_int
}
#[no_mangle]
pub unsafe extern "C" fn xmlStrcat(cur: *mut xmlChar, add: *const xmlChar) -> *mut xmlChar {
if add.is_null() {
return cur;
}
if cur.is_null() {
return unsafe { xmlStrdup(add) };
}
let cur_len = unsafe { xmlStrlen(cur) } as usize;
let add_len = unsafe { xmlStrlen(add) } as usize;
let new_size = cur_len + add_len + 1;
let new_ptr = unsafe { xmlReallocImpl(cur as *mut c_void, new_size) };
if new_ptr.is_null() {
unsafe { xmlFreeImpl(cur as *mut c_void) };
return ptr::null_mut();
}
unsafe {
ptr::copy_nonoverlapping(add, (new_ptr as *mut u8).add(cur_len), add_len);
*((new_ptr as *mut u8).add(cur_len + add_len)) = 0;
}
new_ptr as *mut xmlChar
}
#[no_mangle]
pub unsafe extern "C" fn xmlStrncat(
cur: *mut xmlChar,
add: *const xmlChar,
len: c_int,
) -> *mut xmlChar {
if add.is_null() || len <= 0 {
return cur;
}
let len = len as usize;
if cur.is_null() {
return unsafe { xmlStrndup(add, len as c_int) };
}
let cur_len = unsafe { xmlStrlen(cur) } as usize;
let new_size = cur_len + len + 1;
let new_ptr = unsafe { xmlReallocImpl(cur as *mut c_void, new_size) };
if new_ptr.is_null() {
unsafe { xmlFreeImpl(cur as *mut c_void) };
return ptr::null_mut();
}
unsafe {
ptr::copy_nonoverlapping(add, (new_ptr as *mut u8).add(cur_len), len);
*((new_ptr as *mut u8).add(cur_len + len)) = 0;
}
new_ptr as *mut xmlChar
}
#[no_mangle]
pub unsafe extern "C" fn xmlStrncatNew(
str1: *const xmlChar,
str2: *const xmlChar,
len: c_int,
) -> *mut xmlChar {
let mut result: *mut xmlChar = ptr::null_mut();
if !str1.is_null() {
result = unsafe { xmlStrdup(str1) };
}
if !str2.is_null() && len > 0 {
result = unsafe { xmlStrncat(result, str2, len) };
}
result
}
#[no_mangle]
pub unsafe extern "C" fn xmlStrcpy(dst: *mut xmlChar, src: *const xmlChar) -> *mut xmlChar {
if dst.is_null() || src.is_null() {
return dst;
}
let len = unsafe { xmlStrlen(src) } as usize + 1;
unsafe {
ptr::copy_nonoverlapping(src, dst, len);
}
dst
}
#[no_mangle]
pub unsafe extern "C" fn xmlStrncpy(
dst: *mut xmlChar,
src: *const xmlChar,
len: c_int,
) -> *mut xmlChar {
if dst.is_null() || src.is_null() || len <= 0 {
return dst;
}
let len = len as usize;
let src_len = unsafe { xmlStrlen(src) } as usize;
let copy_len = if src_len < len { src_len } else { len - 1 };
unsafe {
ptr::copy_nonoverlapping(src, dst, copy_len);
*dst.add(copy_len) = 0;
}
dst
}
#[no_mangle]
pub unsafe extern "C" fn xmlStrsub(str: *const xmlChar, start: c_int, len: c_int) -> *mut xmlChar {
if str.is_null() || start < 0 || len < 0 {
return ptr::null_mut();
}
let str_len = unsafe { xmlStrlen(str) };
if start >= str_len {
return unsafe { xmlStrdup(b"\0" as *const u8 as *const xmlChar) };
}
let actual_len = if start + len > str_len {
str_len - start
} else {
len
};
unsafe { xmlStrndup(str.add(start as usize), actual_len) }
}
#[no_mangle]
pub unsafe extern "C" fn xmlNewDoc(version: *const xmlChar) -> *mut _xmlDoc {
crate::xml::tree::new_doc(version)
}
#[no_mangle]
pub unsafe extern "C" fn xmlFreeDoc(doc: *mut _xmlDoc) {
crate::xml::tree::free_doc(doc);
}
#[no_mangle]
pub unsafe extern "C" fn xmlGetDocCompressMode(doc: *mut _xmlDoc) -> c_int {
crate::xml::tree::xmlGetDocCompressMode(doc)
}
#[no_mangle]
pub unsafe extern "C" fn xmlSetDocCompressMode(doc: *mut _xmlDoc, mode: c_int) {
crate::xml::tree::xmlSetDocCompressMode(doc, mode);
}
#[no_mangle]
pub unsafe extern "C" fn xmlNewNode(ns: *mut _xmlNs, name: *const xmlChar) -> *mut _xmlNode {
crate::xml::tree::new_node(ns, name)
}
#[no_mangle]
pub unsafe extern "C" fn xmlFreeNode(node: *mut _xmlNode) {
crate::xml::tree::free_node(node);
}
#[no_mangle]
pub unsafe extern "C" fn xmlFreeNodeList(node: *mut _xmlNode) {
crate::xml::tree::free_node_list(node);
}
#[no_mangle]
pub unsafe extern "C" fn xmlUnlinkNode(node: *mut _xmlNode) {
crate::xml::tree::unlink_node(node);
}
#[no_mangle]
pub unsafe extern "C" fn xmlSAX2InitDefaultSAXHandler(
handler: *mut crate::abi::structs::_xmlSAXHandler,
_warning: c_int,
) {
crate::xml::sax::dispatch::xmlSAX2InitDefaultSAXHandler(handler);
}
#[no_mangle]
pub unsafe extern "C" fn xmlSAX2InitHtmlDefaultSAXHandler(
handler: *mut crate::abi::structs::_xmlSAXHandler,
) {
if handler.is_null() {
return;
}
unsafe {
if (*handler).initialized != 0 {
return;
}
crate::xml::sax::dispatch::xmlSAX2InitDefaultSAXHandler(handler);
let h = &mut *handler;
h.resolveEntity = None;
h.getParameterEntity = None;
h.entityDecl = None;
h.attributeDecl = None;
h.elementDecl = None;
h.notationDecl = None;
h.unparsedEntityDecl = None;
h.reference = None;
h.externalSubset = None;
h.initialized = 1;
}
}
#[no_mangle]
pub unsafe extern "C" fn xmlAddChild(parent: *mut _xmlNode, cur: *mut _xmlNode) -> *mut _xmlNode {
crate::xml::tree::add_child(parent, cur)
}
#[no_mangle]
pub unsafe extern "C" fn xmlAddSibling(
cur: *mut _xmlNode,
sibling: *mut _xmlNode,
) -> *mut _xmlNode {
crate::xml::tree::add_sibling(cur, sibling)
}
#[no_mangle]
pub unsafe extern "C" fn xmlNewChild(
parent: *mut _xmlNode,
ns: *mut _xmlNs,
name: *const xmlChar,
content: *const xmlChar,
) -> *mut _xmlNode {
if parent.is_null() || name.is_null() {
return ptr::null_mut();
}
let ptype = unsafe { (*parent).type_ };
use crate::abi::types::xmlElementType::*;
if ptype != XML_DOCUMENT_NODE as c_int
&& ptype != XML_HTML_DOCUMENT_NODE as c_int
&& ptype != XML_DOCUMENT_FRAG_NODE as c_int
&& ptype != XML_ELEMENT_NODE as c_int
{
return ptr::null_mut();
}
let mut ns = ns;
if ptype == XML_ELEMENT_NODE as c_int && ns.is_null() {
ns = unsafe { (*parent).ns };
}
let node = crate::abi::exports_tree::xmlNewDocNode(unsafe { (*parent).doc }, ns, name, content);
if node.is_null() {
return ptr::null_mut();
}
unsafe {
(*node).parent = parent;
if (*parent).children.is_null() {
(*parent).children = node;
(*parent).last = node;
} else {
let prev = (*parent).last;
(*prev).next = node;
(*node).prev = prev;
(*parent).last = node;
}
}
node
}
#[no_mangle]
pub unsafe extern "C" fn xmlDocSetRootElement(
doc: *mut _xmlDoc,
root: *mut _xmlNode,
) -> *mut _xmlNode {
crate::xml::tree::doc_set_root_element(doc, root)
}
#[no_mangle]
pub extern "C" fn xmlDocGetRootElement(doc: *const _xmlDoc) -> *mut _xmlNode {
crate::xml::tree::doc_get_root_element(doc as *mut _xmlDoc)
}
#[no_mangle]
pub unsafe extern "C" fn xmlCopyNode(node: *const _xmlNode, extended: c_int) -> *mut _xmlNode {
crate::xml::tree::copy_node(node, extended)
}
#[no_mangle]
pub unsafe extern "C" fn xmlCopyDoc(doc: *const _xmlDoc, recursive: c_int) -> *mut _xmlDoc {
crate::xml::tree::copy_doc(doc, recursive)
}
#[no_mangle]
pub unsafe extern "C" fn xmlNewText(content: *const xmlChar) -> *mut _xmlNode {
crate::xml::tree::new_text(content)
}
#[no_mangle]
pub unsafe extern "C" fn xmlNewComment(content: *const xmlChar) -> *mut _xmlNode {
crate::xml::tree::new_comment(content)
}
#[no_mangle]
pub unsafe extern "C" fn xmlNewPI(name: *const xmlChar, content: *const xmlChar) -> *mut _xmlNode {
crate::xml::tree::new_pi(name, content)
}
#[no_mangle]
pub unsafe extern "C" fn xmlNewCDataBlock(
doc: *mut _xmlDoc,
content: *const xmlChar,
len: c_int,
) -> *mut _xmlNode {
crate::xml::tree::new_cdata_block(doc, content, len)
}
#[no_mangle]
pub unsafe extern "C" fn xmlNewNs(
node: *mut _xmlNode,
href: *const xmlChar,
prefix: *const xmlChar,
) -> *mut _xmlNs {
crate::xml::tree::new_ns(node, href, prefix)
}
#[no_mangle]
pub unsafe extern "C" fn xmlSetNs(node: *mut _xmlNode, ns: *mut _xmlNs) {
crate::xml::tree::set_ns(node, ns);
}
#[no_mangle]
pub unsafe extern "C" fn xmlGetNsList(
doc: *mut _xmlDoc,
node: *const _xmlNode,
) -> *mut *mut _xmlNs {
crate::xml::tree::get_ns_list(doc, node as *mut _xmlNode)
}
#[no_mangle]
pub unsafe extern "C" fn xmlSearchNs(
doc: *mut _xmlDoc,
node: *mut _xmlNode,
nameSpace: *const xmlChar,
) -> *mut _xmlNs {
crate::xml::tree::search_ns(doc, node, nameSpace)
}
#[no_mangle]
pub unsafe extern "C" fn xmlSearchNsByHref(
doc: *mut _xmlDoc,
node: *mut _xmlNode,
href: *const xmlChar,
) -> *mut _xmlNs {
crate::xml::tree::search_ns_by_href(doc, node, href)
}
#[no_mangle]
pub unsafe extern "C" fn xmlSetProp(
node: *mut _xmlNode,
name: *const xmlChar,
value: *const xmlChar,
) -> *mut _xmlAttr {
crate::xml::tree::set_prop(node, name, value)
}
#[no_mangle]
pub unsafe extern "C" fn xmlGetProp(node: *const _xmlNode, name: *const xmlChar) -> *mut xmlChar {
crate::xml::tree::get_prop(node as *mut _xmlNode, name)
}
#[no_mangle]
pub unsafe extern "C" fn xmlGetNsProp(
node: *const _xmlNode,
name: *const xmlChar,
nameSpace: *const xmlChar,
) -> *mut xmlChar {
crate::xml::tree::get_ns_prop(node as *mut _xmlNode, name, nameSpace)
}
#[no_mangle]
pub unsafe extern "C" fn xmlSetNsProp(
node: *mut _xmlNode,
ns: *mut _xmlNs,
name: *const xmlChar,
value: *const xmlChar,
) -> *mut _xmlAttr {
crate::xml::tree::set_ns_prop(node, ns, name, value)
}
#[no_mangle]
pub unsafe extern "C" fn xmlRemoveProp(attr: *mut _xmlAttr) -> c_int {
crate::xml::tree::remove_prop(attr)
}
#[no_mangle]
pub unsafe extern "C" fn xmlHasProp(node: *const _xmlNode, name: *const xmlChar) -> *mut _xmlAttr {
crate::xml::tree::has_prop(node as *mut _xmlNode, name)
}
#[no_mangle]
pub unsafe extern "C" fn xmlHasNsProp(
node: *const _xmlNode,
name: *const xmlChar,
nameSpace: *const xmlChar,
) -> *mut _xmlAttr {
crate::xml::tree::has_ns_prop(node as *mut _xmlNode, name, nameSpace)
}
#[no_mangle]
pub unsafe extern "C" fn xmlUnsetProp(node: *mut _xmlNode, name: *const xmlChar) -> c_int {
crate::xml::tree::unset_prop(node, name)
}
#[no_mangle]
pub unsafe extern "C" fn xmlUnsetNsProp(
node: *mut _xmlNode,
name: *const xmlChar,
nameSpace: *const xmlChar,
) -> c_int {
crate::xml::tree::unset_ns_prop(node, name, nameSpace)
}
#[no_mangle]
pub unsafe extern "C" fn xmlFirstElementChild(parent: *mut _xmlNode) -> *mut _xmlNode {
crate::xml::tree::first_element_child(parent)
}
#[no_mangle]
pub unsafe extern "C" fn xmlLastElementChild(parent: *mut _xmlNode) -> *mut _xmlNode {
crate::xml::tree::last_element_child(parent)
}
#[no_mangle]
pub unsafe extern "C" fn xmlNextElementSibling(node: *mut _xmlNode) -> *mut _xmlNode {
crate::xml::tree::next_element_sibling(node)
}
#[no_mangle]
pub unsafe extern "C" fn xmlPreviousElementSibling(node: *mut _xmlNode) -> *mut _xmlNode {
crate::xml::tree::previous_element_sibling(node)
}
#[no_mangle]
pub unsafe extern "C" fn xmlChildElementCount(parent: *mut _xmlNode) -> c_ulong {
crate::xml::tree::child_element_count(parent)
}
#[no_mangle]
pub unsafe extern "C" fn xmlTextConcat(
node: *mut _xmlNode,
content: *const xmlChar,
len: c_int,
) -> c_int {
crate::xml::tree::text_concat(node, content, len)
}
#[no_mangle]
pub unsafe extern "C" fn xmlTextMerge(
first: *mut _xmlNode,
second: *mut _xmlNode,
) -> *mut _xmlNode {
crate::xml::tree::text_merge(first, second)
}
#[no_mangle]
pub const extern "C" fn xmlGetIntSubset(doc: *const _xmlDoc) -> *mut _xmlDtd {
crate::xml::tree::get_int_subset(doc)
}
#[no_mangle]
pub unsafe extern "C" fn xmlNewDtd(
doc: *mut _xmlDoc,
name: *const xmlChar,
ExternalID: *const xmlChar,
SystemID: *const xmlChar,
) -> *mut _xmlDtd {
crate::xml::tree::new_dtd(doc, name, ExternalID, SystemID)
}
#[no_mangle]
pub unsafe extern "C" fn xmlNewEntity(
doc: *mut _xmlDoc,
name: *const xmlChar,
type_: c_int,
ExternalID: *const xmlChar,
SystemID: *const xmlChar,
content: *const xmlChar,
) -> *mut _xmlEntity {
crate::xml::tree::new_entity(doc, name, type_, ExternalID, SystemID, content)
}
#[no_mangle]
pub unsafe extern "C" fn xmlGetDocEntity(
doc: *const _xmlDoc,
name: *const xmlChar,
) -> *mut _xmlEntity {
crate::xml::tree::get_doc_entity(doc, name)
}
#[no_mangle]
pub unsafe extern "C" fn xmlGetParameterEntity(
doc: *const _xmlDoc,
name: *const xmlChar,
) -> *mut _xmlEntity {
crate::xml::tree::get_parameter_entity(doc, name)
}
#[no_mangle]
pub unsafe extern "C" fn xmlCreateIntSubset(
doc: *mut _xmlDoc,
name: *const xmlChar,
ExternalID: *const xmlChar,
SystemID: *const xmlChar,
) -> *mut _xmlDtd {
crate::xml::dtd::create_int_subset(doc, name, ExternalID, SystemID)
}
#[no_mangle]
pub unsafe extern "C" fn xmlFreeDtd(dtd: *mut _xmlDtd) {
crate::xml::dtd::free_dtd(dtd);
}
#[no_mangle]
pub unsafe extern "C" fn xmlAddNotationDecl(
_ctxt: *mut _xmlValidCtxt,
dtd: *mut _xmlDtd,
name: *const xmlChar,
PublicID: *const xmlChar,
SystemID: *const xmlChar,
) -> *mut _xmlNotation {
crate::xml::dtd::add_notation_decl(dtd, name, PublicID, SystemID)
}
#[no_mangle]
pub unsafe extern "C" fn xmlGetNotationDecl(
dtd: *mut _xmlDtd,
name: *const xmlChar,
) -> *mut _xmlNotation {
crate::xml::dtd::get_notation_decl(dtd, name)
}
#[no_mangle]
pub unsafe extern "C" fn xmlCopyNotation(notation: *mut _xmlNotation) -> *mut _xmlNotation {
crate::xml::dtd::copy_notation(notation)
}
#[no_mangle]
pub unsafe extern "C" fn xmlFreeNotation(notation: *mut _xmlNotation) {
crate::xml::dtd::free_notation(notation);
}
#[no_mangle]
pub unsafe extern "C" fn xmlAddElementDecl(
_ctxt: *mut _xmlValidCtxt,
dtd: *mut _xmlDtd,
name: *const xmlChar,
type_: c_int,
content: *mut _xmlElementContent,
) -> *mut _xmlElement {
crate::xml::dtd::add_element_decl(dtd, name, type_, content)
}
#[no_mangle]
pub unsafe extern "C" fn xmlGetElementDecl(
dtd: *mut _xmlDtd,
name: *const xmlChar,
) -> *mut _xmlElement {
crate::xml::dtd::get_element_decl(dtd, name)
}
#[no_mangle]
pub unsafe extern "C" fn xmlCopyElement(elem: *mut _xmlElement) -> *mut _xmlElement {
crate::xml::dtd::copy_element(elem)
}
#[no_mangle]
pub unsafe extern "C" fn xmlFreeElement(elem: *mut _xmlElement) {
crate::xml::dtd::free_element(elem);
}
#[no_mangle]
pub unsafe extern "C" fn xmlAddAttributeDecl(
_ctxt: *mut _xmlValidCtxt,
dtd: *mut _xmlDtd,
elem: *mut _xmlElement,
name: *const xmlChar,
ns: *const xmlChar,
type_: c_int,
def: c_int,
defaultValue: *const xmlChar,
tree: *mut _xmlEnumeration,
) -> *mut _xmlAttribute {
crate::xml::dtd::add_attribute_decl(dtd, elem, name, ns, type_, def, defaultValue, tree)
}
#[no_mangle]
pub unsafe extern "C" fn xmlGetAttributeDecl(
dtd: *mut _xmlDtd,
elem: *mut _xmlElement,
name: *const xmlChar,
namePrefix: c_int,
) -> *mut _xmlAttribute {
crate::xml::dtd::get_attribute_decl(dtd, elem, name, namePrefix)
}
#[no_mangle]
pub unsafe extern "C" fn xmlCopyAttribute(attr: *mut _xmlAttribute) -> *mut _xmlAttribute {
crate::xml::dtd::copy_attribute_decl(attr)
}
#[no_mangle]
pub unsafe extern "C" fn xmlFreeAttribute(attr: *mut _xmlAttribute) {
crate::xml::dtd::free_attribute(attr);
}
#[no_mangle]
pub unsafe extern "C" fn xmlNewElementContent(
name: *const xmlChar,
type_: c_int,
) -> *mut _xmlElementContent {
crate::xml::dtd::create_content_model(name, type_)
}
#[no_mangle]
pub unsafe extern "C" fn xmlCopyElementContent(
content: *mut _xmlElementContent,
) -> *mut _xmlElementContent {
crate::xml::dtd::copy_content_model(content)
}
#[no_mangle]
pub unsafe extern "C" fn xmlFreeElementContent(cur: *mut _xmlElementContent) {
crate::xml::dtd::free_content_model(cur);
}
#[no_mangle]
pub unsafe extern "C" fn xmlAddEntity(
doc: *mut _xmlDoc,
extSubset: c_int,
name: *const xmlChar,
type_: c_int,
publicId: *const xmlChar,
systemId: *const xmlChar,
content: *const xmlChar,
out: *mut *mut _xmlEntity,
) -> c_int {
crate::xml::entities::add_entity_doc(
doc, extSubset, name, type_, publicId, systemId, content, out,
)
}
#[no_mangle]
pub unsafe extern "C" fn xmlAddDocEntity(
doc: *mut _xmlDoc,
name: *const xmlChar,
type_: c_int,
ExternalID: *const xmlChar,
SystemID: *const xmlChar,
content: *const xmlChar,
) -> *mut _xmlEntity {
crate::xml::tree::add_doc_entity(doc, name, type_, ExternalID, SystemID, content)
}
#[no_mangle]
pub unsafe extern "C" fn xmlAddDtdEntity(
doc: *mut _xmlDoc,
name: *const xmlChar,
type_: c_int,
ExternalID: *const xmlChar,
SystemID: *const xmlChar,
content: *const xmlChar,
) -> *mut _xmlEntity {
crate::xml::tree::add_dtd_entity(doc, name, type_, ExternalID, SystemID, content)
}
#[no_mangle]
pub unsafe extern "C" fn xmlGetDtdEntity(
doc: *mut _xmlDoc,
name: *const xmlChar,
) -> *mut _xmlEntity {
crate::xml::tree::get_dtd_entity(doc, name)
}
#[no_mangle]
pub unsafe extern "C" fn xmlGetEntity(doc: *mut _xmlDoc, name: *const xmlChar) -> *mut _xmlEntity {
crate::xml::entities::get_entity(doc, name)
}
#[no_mangle]
pub unsafe extern "C" fn xmlCopyEntity(entity: *mut _xmlEntity) -> *mut _xmlEntity {
crate::xml::entities::copy_entity(entity)
}
#[no_mangle]
pub unsafe extern "C" fn xmlFreeEntity(entity: *mut _xmlEntity) {
crate::xml::entities::free_entity(entity);
}
#[no_mangle]
pub unsafe extern "C" fn xmlEncodeEntitiesReentrant(
doc: *mut _xmlDoc,
input: *const xmlChar,
) -> *mut xmlChar {
crate::xml::entities::encode_entities_reentrant(doc, input)
}
#[no_mangle]
pub unsafe extern "C" fn xmlEncodeSpecialChars(
_doc: *const _xmlDoc,
input: *const xmlChar,
) -> *mut xmlChar {
if input.is_null() {
return ptr::null_mut();
}
unsafe {
let len = crate::xml::string::xml_strlen(input);
let cap = len * 6 + 1;
let out = crate::abi::allocator::xmlMallocImpl(cap) as *mut xmlChar;
if out.is_null() {
return ptr::null_mut();
}
let mut o = 0usize;
let mut i = 0usize;
while i < len {
let c = *input.add(i);
let rep: &[u8] = match c {
b'<' => b"<",
b'>' => b">",
b'&' => b"&",
b'"' => b""",
b'\r' => b" ",
_ => {
*out.add(o) = c;
o += 1;
i += 1;
continue;
}
};
core::ptr::copy_nonoverlapping(rep.as_ptr(), out.add(o), rep.len());
o += rep.len();
i += 1;
}
*out.add(o) = 0;
out
}
}
#[no_mangle]
pub unsafe extern "C" fn xmlEncodeEntities(
_doc: *mut _xmlDoc,
_input: *const xmlChar,
) -> *mut xmlChar {
use core::sync::atomic::{AtomicBool, Ordering};
static WARNED: AtomicBool = AtomicBool::new(false);
if !WARNED.swap(true, Ordering::Relaxed) {
let msg = b"xmlEncodeEntities is deprecated, use xmlEncodeSpecialChars or xmlEncodeEntitiesReentrant\n";
unsafe {
libc::fwrite(
msg.as_ptr() as *const c_void,
1,
msg.len(),
libc::fdopen(2, b"w\0" as *const u8 as *const c_char),
);
}
}
ptr::null_mut()
}
#[no_mangle]
pub extern "C" fn xmlGetLineNo(node: *const _xmlNode) -> c_long {
crate::xml::tree::get_line_no(node)
}
#[no_mangle]
pub unsafe extern "C" fn xmlNodeDump(
buf: *mut _xmlBuffer,
doc: *mut _xmlDoc,
cur: *mut _xmlNode,
level: c_int,
format: c_int,
) -> c_int {
if buf.is_null() || cur.is_null() {
return -1;
}
crate::xml::tree::xmlNodeDump(buf, doc, cur, level, format)
}
#[no_mangle]
pub unsafe extern "C" fn xmlDocDump(fp: *mut c_void, doc: *mut _xmlDoc) -> c_int {
if fp.is_null() || doc.is_null() {
return -1;
}
crate::xml::tree::xmlDocDump(fp, doc)
}
#[no_mangle]
pub unsafe extern "C" fn xmlDocDumpFormatMemory(
doc: *mut _xmlDoc,
mem: *mut *mut xmlChar,
size: *mut c_int,
format: c_int,
) {
if doc.is_null() || mem.is_null() {
return;
}
crate::xml::tree::xmlDocDumpFormatMemory(doc, mem, size, format)
}
#[no_mangle]
pub unsafe extern "C" fn xmlDocDumpMemory(
doc: *mut _xmlDoc,
mem: *mut *mut xmlChar,
size: *mut c_int,
) {
if doc.is_null() || mem.is_null() {
return;
}
crate::xml::tree::xmlDocDumpMemory(doc, mem, size)
}
#[no_mangle]
pub unsafe extern "C" fn xmlSaveFile(filename: *const c_char, cur: *mut _xmlDoc) -> c_int {
if filename.is_null() || cur.is_null() {
return -1;
}
crate::xml::tree::xmlSaveFile(filename, cur)
}
#[no_mangle]
pub unsafe extern "C" fn xmlSaveFileEnc(
filename: *const c_char,
cur: *mut _xmlDoc,
encoding: *const c_char,
) -> c_int {
if filename.is_null() || cur.is_null() {
return -1;
}
crate::xml::tree::xmlSaveFileEnc(filename, cur, encoding)
}
#[no_mangle]
pub unsafe extern "C" fn xmlSaveFormatFile(
filename: *const c_char,
cur: *mut _xmlDoc,
format: c_int,
) -> c_int {
if filename.is_null() || cur.is_null() {
return -1;
}
crate::xml::tree::xmlSaveFormatFile(filename, cur, format)
}
#[no_mangle]
pub unsafe extern "C" fn xmlSaveFormatFileEnc(
filename: *const c_char,
cur: *mut _xmlDoc,
encoding: *const c_char,
format: c_int,
) -> c_int {
if filename.is_null() || cur.is_null() {
return -1;
}
crate::xml::tree::xmlSaveFormatFileEnc(filename, cur, encoding, format)
}
#[no_mangle]
pub unsafe extern "C" fn xmlReadDoc(
cur: *const xmlChar,
URL: *const c_char,
encoding: *const c_char,
options: c_int,
) -> *mut _xmlDoc {
if cur.is_null() {
return ptr::null_mut();
}
let ctxt = crate::xml::parser::helpers::create_parser_ctxt();
if ctxt.is_null() {
return ptr::null_mut();
}
let len = crate::xml::string::xml_strlen(cur);
let input = crate::xml::parser::helpers::input_from_memory(cur as *const c_char, len as c_int);
crate::xml::parser::helpers::setup_parser_input(ctxt, input);
(*ctxt).options = options;
if crate::xml::parser::helpers::parse_document(ctxt) != 0 {
let doc = (*ctxt).myDoc;
crate::xml::parser::helpers::free_parser_ctxt(ctxt);
return doc;
}
let doc = (*ctxt).myDoc;
if !doc.is_null() {
(*doc).URL = crate::xml::string::xml_strdup(URL as *const xmlChar);
}
crate::xml::parser::helpers::free_parser_ctxt(ctxt);
doc
}
#[no_mangle]
pub unsafe extern "C" fn xmlReadFile(
URL: *const c_char,
encoding: *const c_char,
options: c_int,
) -> *mut _xmlDoc {
if URL.is_null() {
return ptr::null_mut();
}
let ctxt = crate::xml::parser::helpers::create_parser_ctxt();
if ctxt.is_null() {
return ptr::null_mut();
}
(*ctxt).options = options;
(*ctxt).replaceEntities = (options & crate::abi::types::XML_PARSE_NOENT != 0) as c_int;
let input = match crate::abi::exports_parser::open_filename_routed(URL, ctxt) {
crate::abi::exports_parser::RoutedFileOpen::Loaded(i) => i,
crate::abi::exports_parser::RoutedFileOpen::Failed => {
crate::abi::exports_parser::emit_io_warning(
ctxt,
crate::abi::exports_parser::io_load_failure_message(URL),
);
crate::xml::parser::helpers::free_parser_ctxt(ctxt);
return ptr::null_mut();
}
crate::abi::exports_parser::RoutedFileOpen::EntityLoaderFailed => {
crate::xml::parser::helpers::free_parser_ctxt(ctxt);
return ptr::null_mut();
}
crate::abi::exports_parser::RoutedFileOpen::Builtin => {
match crate::xml::parser::helpers::input_from_file(URL) {
Ok(input) => input,
Err(_) => {
crate::xml::parser::helpers::free_parser_ctxt(ctxt);
return ptr::null_mut();
}
}
}
};
crate::xml::parser::helpers::setup_parser_input(ctxt, input);
if crate::xml::parser::helpers::parse_document(ctxt) != 0 {
let doc = (*ctxt).myDoc;
crate::xml::parser::helpers::free_parser_ctxt(ctxt);
if options & 1 << 0 != 0 {
return doc;
}
if !doc.is_null() {
crate::xml::tree::free_doc(doc);
}
return ptr::null_mut();
}
let doc = (*ctxt).myDoc;
crate::xml::parser::helpers::free_parser_ctxt(ctxt);
doc
}
#[no_mangle]
pub unsafe extern "C" fn xmlRecoverDoc(cur: *const xmlChar) -> *mut _xmlDoc {
unsafe { xmlReadDoc(cur, ptr::null(), ptr::null(), 1 << 0) }
}
#[no_mangle]
pub unsafe extern "C" fn xmlRecoverFile(filename: *const c_char) -> *mut _xmlDoc {
unsafe { xmlReadFile(filename, ptr::null(), 1 << 0) }
}
#[no_mangle]
pub unsafe extern "C" fn xmlRecoverMemory(buffer: *const c_char, size: c_int) -> *mut _xmlDoc {
unsafe { xmlReadMemory(buffer, size, ptr::null(), ptr::null(), 1 << 0) }
}
unsafe fn canonical_doc_encoding(doc: *mut _xmlDoc, encoding: *const c_char) {
let handler = crate::xml::encoding::xmlFindCharEncodingHandler(encoding);
if handler.is_null() {
return;
}
let name = unsafe { (*handler).name }; if name.is_null() {
return;
}
unsafe {
(*doc).encoding = crate::xml::string::xml_strdup(name as *const xmlChar);
}
}
#[no_mangle]
pub unsafe extern "C" fn xmlReadMemory(
buffer: *const c_char,
size: c_int,
URL: *const c_char,
encoding: *const c_char,
options: c_int,
) -> *mut _xmlDoc {
if buffer.is_null() || size < 0 {
return ptr::null_mut();
}
if size == c_int::MAX {
return ptr::null_mut();
}
let ctxt = crate::xml::parser::helpers::create_parser_ctxt();
if ctxt.is_null() {
return ptr::null_mut();
}
let mut input = crate::xml::parser::helpers::input_from_memory_named(buffer, size, URL);
if !encoding.is_null() {
let name = core::ffi::CStr::from_ptr(encoding).to_bytes();
input.apply_explicit_input_encoding(name);
}
crate::xml::parser::helpers::setup_parser_input(ctxt, input);
crate::abi::exports_parser::apply_options(ctxt, options);
let parsed = crate::xml::parser::helpers::parse_document(ctxt);
let doc = (*ctxt).myDoc;
if !doc.is_null() && !URL.is_null() && (*doc).URL.is_null() {
(*doc).URL = crate::xml::string::xml_strdup(URL as *const xmlChar);
}
if !doc.is_null() && (*doc).encoding.is_null() && !encoding.is_null() {
canonical_doc_encoding(doc, encoding);
}
crate::xml::parser::helpers::free_parser_ctxt(ctxt);
if parsed != 0 {
if options & 1 << 0 != 0 {
return doc;
}
if !doc.is_null() {
crate::xml::tree::free_doc(doc);
}
return ptr::null_mut();
}
doc
}
#[no_mangle]
pub unsafe extern "C" fn xmlLoadCatalogs(catalogs: *const c_char) {
if !catalogs.is_null() {
crate::xml::catalog::load_catalog(catalogs);
}
}
#[no_mangle]
pub unsafe extern "C" fn xmlLoadCatalog(catalogs: *const c_char) -> c_int {
let handle = crate::xml::catalog::load_catalog(catalogs);
if handle.is_null() {
1
} else {
0
}
}
#[no_mangle]
pub unsafe extern "C" fn xmlReadFd(
fd: c_int,
URL: *const c_char,
encoding: *const c_char,
options: c_int,
) -> *mut _xmlDoc {
let ctxt = crate::xml::parser::helpers::create_parser_ctxt();
if ctxt.is_null() {
return ptr::null_mut();
}
let mut buf = Vec::new();
let mut tmp = [0u8; 4096];
loop {
let n = libc::read(fd, tmp.as_mut_ptr() as *mut c_void, tmp.len());
if n <= 0 {
break;
}
buf.extend_from_slice(&tmp[..n as usize]);
}
let input = crate::xml::parser::helpers::input_from_memory(
buf.as_ptr() as *const c_char,
buf.len() as c_int,
);
crate::xml::parser::helpers::setup_parser_input(ctxt, input);
(*ctxt).options = options;
if crate::xml::parser::helpers::parse_document(ctxt) != 0 {
let doc = (*ctxt).myDoc;
crate::xml::parser::helpers::free_parser_ctxt(ctxt);
return doc;
}
let doc = (*ctxt).myDoc;
if !doc.is_null() && !URL.is_null() {
(*doc).URL = crate::xml::string::xml_strdup(URL as *const xmlChar);
}
crate::xml::parser::helpers::free_parser_ctxt(ctxt);
doc
}
#[no_mangle]
pub unsafe extern "C" fn xmlReadIO(
ioread: Option<xmlInputReadCallback>,
ioclose: Option<xmlInputCloseCallback>,
ioctx: *mut c_void,
URL: *const c_char,
encoding: *const c_char,
options: c_int,
) -> *mut _xmlDoc {
let ctxt = crate::xml::parser::helpers::create_parser_ctxt();
if ctxt.is_null() {
return ptr::null_mut();
}
let input = crate::xml::parser::helpers::input_from_io(ioread, ioclose, ioctx);
crate::xml::parser::helpers::setup_parser_input(ctxt, input);
(*ctxt).options = options;
let parsed = crate::xml::parser::helpers::parse_document(ctxt);
let doc = (*ctxt).myDoc;
if !doc.is_null() && !URL.is_null() && (*doc).URL.is_null() {
(*doc).URL = crate::xml::string::xml_strdup(URL as *const xmlChar);
}
if !doc.is_null() && (*doc).encoding.is_null() && !encoding.is_null() {
canonical_doc_encoding(doc, encoding);
}
crate::xml::parser::helpers::free_parser_ctxt(ctxt);
if parsed != 0 {
if options & 1 << 0 != 0 {
return doc;
}
if !doc.is_null() {
crate::xml::tree::free_doc(doc);
}
return ptr::null_mut();
}
doc
}
#[no_mangle]
pub unsafe extern "C" fn xmlSAXParseDoc(
sax: *mut _xmlSAXHandler,
cur: *const xmlChar,
recovery: c_int,
) -> *mut _xmlDoc {
if cur.is_null() {
return ptr::null_mut();
}
let ctxt = crate::xml::parser::helpers::create_parser_ctxt();
if ctxt.is_null() {
return ptr::null_mut();
}
if !sax.is_null() {
(*ctxt).sax = sax;
(*ctxt).userData = (*ctxt).sax as *mut c_void;
}
if recovery != 0 {
(*ctxt).recovery = 1;
(*ctxt).options |= 1; }
let len = crate::xml::string::xml_strlen(cur);
let input = crate::xml::parser::helpers::input_from_memory(cur as *const c_char, len as c_int);
crate::xml::parser::helpers::setup_parser_input(ctxt, input);
crate::xml::parser::helpers::parse_document(ctxt);
let doc = (*ctxt).myDoc;
crate::xml::parser::helpers::free_parser_ctxt(ctxt);
doc
}
#[no_mangle]
pub unsafe extern "C" fn xmlSAXParseDocWithData(
sax: *mut _xmlSAXHandler,
cur: *const xmlChar,
recovery: c_int,
data: *mut c_void,
) -> *mut _xmlDoc {
if cur.is_null() {
return ptr::null_mut();
}
let ctxt = crate::xml::parser::helpers::create_parser_ctxt();
if ctxt.is_null() {
return ptr::null_mut();
}
if !sax.is_null() {
(*ctxt).sax = sax;
}
(*ctxt).userData = data;
if recovery != 0 {
(*ctxt).recovery = 1;
(*ctxt).options |= 1; }
let len = crate::xml::string::xml_strlen(cur);
let input = crate::xml::parser::helpers::input_from_memory(cur as *const c_char, len as c_int);
crate::xml::parser::helpers::setup_parser_input(ctxt, input);
crate::xml::parser::helpers::parse_document(ctxt);
let doc = (*ctxt).myDoc;
crate::xml::parser::helpers::free_parser_ctxt(ctxt);
doc
}
#[no_mangle]
pub unsafe extern "C" fn xmlSAXParseFileWithData(
sax: *mut _xmlSAXHandler,
filename: *const c_char,
recovery: c_int,
data: *mut c_void,
) -> *mut _xmlDoc {
if filename.is_null() {
return ptr::null_mut();
}
let ctxt = crate::xml::parser::helpers::create_parser_ctxt();
if ctxt.is_null() {
return ptr::null_mut();
}
if !sax.is_null() {
(*ctxt).sax = sax;
}
(*ctxt).userData = data;
if recovery != 0 {
(*ctxt).recovery = 1;
(*ctxt).options |= 1; }
let input = match crate::abi::exports_parser::open_filename_routed(filename, ctxt) {
crate::abi::exports_parser::RoutedFileOpen::Loaded(input) => input,
crate::abi::exports_parser::RoutedFileOpen::Failed => {
crate::abi::exports_parser::emit_io_warning(
ctxt,
crate::abi::exports_parser::io_load_failure_message(filename),
);
crate::xml::parser::helpers::free_parser_ctxt(ctxt);
return ptr::null_mut();
}
crate::abi::exports_parser::RoutedFileOpen::EntityLoaderFailed => {
crate::xml::parser::helpers::free_parser_ctxt(ctxt);
return ptr::null_mut();
}
crate::abi::exports_parser::RoutedFileOpen::Builtin => {
match crate::xml::parser::helpers::input_from_file(filename) {
Ok(input) => input,
Err(_) => {
crate::xml::parser::helpers::free_parser_ctxt(ctxt);
return ptr::null_mut();
}
}
}
};
crate::xml::parser::helpers::setup_parser_input(ctxt, input);
crate::xml::parser::helpers::parse_document(ctxt);
let doc = (*ctxt).myDoc;
crate::xml::parser::helpers::free_parser_ctxt(ctxt);
doc
}
#[no_mangle]
pub unsafe extern "C" fn xmlSAXParseMemoryWithData(
sax: *mut _xmlSAXHandler,
buffer: *const c_char,
size: c_int,
recovery: c_int,
data: *mut c_void,
) -> *mut _xmlDoc {
if buffer.is_null() || size <= 0 {
return ptr::null_mut();
}
let ctxt = crate::xml::parser::helpers::create_parser_ctxt();
if ctxt.is_null() {
return ptr::null_mut();
}
if !sax.is_null() {
(*ctxt).sax = sax;
}
(*ctxt).userData = data;
if recovery != 0 {
(*ctxt).recovery = 1;
(*ctxt).options |= 1; }
let input = crate::xml::parser::helpers::input_from_memory(buffer, size);
crate::xml::parser::helpers::setup_parser_input(ctxt, input);
crate::xml::parser::helpers::parse_document(ctxt);
let doc = (*ctxt).myDoc;
crate::xml::parser::helpers::free_parser_ctxt(ctxt);
doc
}
#[no_mangle]
pub unsafe extern "C" fn xmlSAXParseFile(
sax: *mut _xmlSAXHandler,
filename: *const c_char,
recovery: c_int,
) -> *mut _xmlDoc {
if filename.is_null() {
return ptr::null_mut();
}
let ctxt = crate::xml::parser::helpers::create_parser_ctxt();
if ctxt.is_null() {
return ptr::null_mut();
}
if !sax.is_null() {
(*ctxt).sax = sax;
(*ctxt).userData = (*ctxt).sax as *mut c_void;
}
if recovery != 0 {
(*ctxt).recovery = 1;
(*ctxt).options |= 1;
}
let input = match crate::abi::exports_parser::open_filename_routed(filename, ctxt) {
crate::abi::exports_parser::RoutedFileOpen::Loaded(input) => input,
crate::abi::exports_parser::RoutedFileOpen::Failed => {
crate::abi::exports_parser::emit_io_warning(
ctxt,
crate::abi::exports_parser::io_load_failure_message(filename),
);
crate::xml::parser::helpers::free_parser_ctxt(ctxt);
return ptr::null_mut();
}
crate::abi::exports_parser::RoutedFileOpen::EntityLoaderFailed => {
crate::xml::parser::helpers::free_parser_ctxt(ctxt);
return ptr::null_mut();
}
crate::abi::exports_parser::RoutedFileOpen::Builtin => {
match crate::xml::parser::helpers::input_from_file(filename) {
Ok(input) => input,
Err(_) => {
crate::xml::parser::helpers::free_parser_ctxt(ctxt);
return ptr::null_mut();
}
}
}
};
crate::xml::parser::helpers::setup_parser_input(ctxt, input);
crate::xml::parser::helpers::parse_document(ctxt);
let doc = (*ctxt).myDoc;
crate::xml::parser::helpers::free_parser_ctxt(ctxt);
doc
}
#[no_mangle]
pub unsafe extern "C" fn xmlSAXParseMemory(
sax: *mut _xmlSAXHandler,
buffer: *const c_char,
size: c_int,
recovery: c_int,
) -> *mut _xmlDoc {
if buffer.is_null() || size <= 0 {
return ptr::null_mut();
}
let ctxt = crate::xml::parser::helpers::create_parser_ctxt();
if ctxt.is_null() {
return ptr::null_mut();
}
if !sax.is_null() {
(*ctxt).sax = sax;
(*ctxt).userData = (*ctxt).sax as *mut c_void;
}
if recovery != 0 {
(*ctxt).recovery = 1;
(*ctxt).options |= 1;
}
let input = crate::xml::parser::helpers::input_from_memory(buffer, size);
crate::xml::parser::helpers::setup_parser_input(ctxt, input);
crate::xml::parser::helpers::parse_document(ctxt);
let doc = (*ctxt).myDoc;
crate::xml::parser::helpers::free_parser_ctxt(ctxt);
doc
}
#[no_mangle]
pub unsafe extern "C" fn xmlSAXUserParseFile(
sax: *mut _xmlSAXHandler,
user_data: *mut c_void,
filename: *const c_char,
) -> c_int {
if filename.is_null() {
return -1;
}
let ctxt = crate::xml::parser::helpers::create_parser_ctxt();
if ctxt.is_null() {
return -1;
}
if !sax.is_null() {
if unsafe { (*sax).initialized } == XML_SAX2_MAGIC as c_uint {
unsafe {
ptr::copy_nonoverlapping(sax as *const _xmlSAXHandler, (*ctxt).sax, 1);
}
} else {
unsafe {
ptr::copy_nonoverlapping(
sax as *const u8,
(*ctxt).sax as *mut u8,
size_of::<crate::abi::structs::_xmlSAXHandlerV1>(),
);
}
}
}
(*ctxt).userData = if !user_data.is_null() {
user_data
} else {
ctxt as *mut c_void
};
let input = match crate::abi::exports_parser::open_filename_routed(filename, ctxt) {
crate::abi::exports_parser::RoutedFileOpen::Loaded(input) => input,
crate::abi::exports_parser::RoutedFileOpen::Failed => {
crate::abi::exports_parser::emit_io_warning(
ctxt,
crate::abi::exports_parser::io_load_failure_message(filename),
);
crate::xml::parser::helpers::free_parser_ctxt(ctxt);
return -1;
}
crate::abi::exports_parser::RoutedFileOpen::EntityLoaderFailed => {
crate::xml::parser::helpers::free_parser_ctxt(ctxt);
return -1;
}
crate::abi::exports_parser::RoutedFileOpen::Builtin => {
match crate::xml::parser::helpers::input_from_file(filename) {
Ok(input) => input,
Err(_) => {
crate::xml::parser::helpers::free_parser_ctxt(ctxt);
return -1;
}
}
}
};
crate::xml::parser::helpers::setup_parser_input(ctxt, input);
let ret = crate::xml::parser::helpers::parse_document(ctxt);
let ret = if ret == 0 {
0
} else {
let err = unsafe { (*ctxt).errNo };
if err != crate::abi::types::XML_ERR_OK {
err
} else {
-1
}
};
crate::xml::parser::helpers::free_parser_ctxt(ctxt);
ret
}
#[no_mangle]
pub unsafe extern "C" fn xmlSAXUserParseMemory(
sax: *mut _xmlSAXHandler,
user_data: *mut c_void,
buffer: *const c_char,
size: c_int,
) -> c_int {
if buffer.is_null() || size <= 0 {
return -1;
}
let ctxt = crate::xml::parser::helpers::create_parser_ctxt();
if ctxt.is_null() {
return -1;
}
if !sax.is_null() {
if unsafe { (*sax).initialized } == XML_SAX2_MAGIC as c_uint {
unsafe {
ptr::copy_nonoverlapping(sax as *const _xmlSAXHandler, (*ctxt).sax, 1);
}
} else {
unsafe {
ptr::copy_nonoverlapping(
sax as *const u8,
(*ctxt).sax as *mut u8,
size_of::<crate::abi::structs::_xmlSAXHandlerV1>(),
);
}
}
}
(*ctxt).userData = if !user_data.is_null() {
user_data
} else {
ctxt as *mut c_void
};
let input = crate::xml::parser::helpers::input_from_memory(buffer, size);
crate::xml::parser::helpers::setup_parser_input(ctxt, input);
let ret = crate::xml::parser::helpers::parse_document(ctxt);
let ret = if ret == 0 {
0
} else {
let err = unsafe { (*ctxt).errNo };
if err != crate::abi::types::XML_ERR_OK {
err
} else {
-1
}
};
crate::xml::parser::helpers::free_parser_ctxt(ctxt);
ret
}
#[no_mangle]
pub unsafe extern "C" fn xmlParseDoc(cur: *const xmlChar) -> *mut _xmlDoc {
if cur.is_null() {
return ptr::null_mut();
}
xmlReadDoc(cur, ptr::null(), ptr::null(), 0)
}
#[no_mangle]
pub unsafe extern "C" fn xmlParseFile(filename: *const c_char) -> *mut _xmlDoc {
if filename.is_null() {
return ptr::null_mut();
}
xmlReadFile(filename, ptr::null(), 0)
}
#[no_mangle]
pub unsafe extern "C" fn xmlParseMemory(buffer: *const c_char, size: c_int) -> *mut _xmlDoc {
if buffer.is_null() || size <= 0 {
return ptr::null_mut();
}
xmlReadMemory(buffer, size, ptr::null(), ptr::null(), 0)
}
#[no_mangle]
pub unsafe extern "C" fn xmlCreateFileParserCtxt(filename: *const c_char) -> *mut _xmlParserCtxt {
if filename.is_null() {
return ptr::null_mut();
}
let ctxt = crate::xml::parser::helpers::create_parser_ctxt();
if ctxt.is_null() {
return ptr::null_mut();
}
let input = match crate::abi::exports_parser::open_filename_routed(filename, ctxt) {
crate::abi::exports_parser::RoutedFileOpen::Loaded(input) => input,
crate::abi::exports_parser::RoutedFileOpen::Failed => {
crate::abi::exports_parser::emit_io_warning(
ctxt,
crate::abi::exports_parser::io_load_failure_message(filename),
);
crate::xml::parser::helpers::free_parser_ctxt(ctxt);
return ptr::null_mut();
}
crate::abi::exports_parser::RoutedFileOpen::EntityLoaderFailed => {
crate::xml::parser::helpers::free_parser_ctxt(ctxt);
return ptr::null_mut();
}
crate::abi::exports_parser::RoutedFileOpen::Builtin => {
match crate::xml::parser::helpers::input_from_file(filename) {
Ok(input) => input,
Err(_) => {
crate::xml::parser::helpers::free_parser_ctxt(ctxt);
return ptr::null_mut();
}
}
}
};
crate::xml::parser::helpers::setup_parser_input(ctxt, input);
ctxt
}
#[no_mangle]
pub unsafe extern "C" fn xmlCreateDocParserCtxt(cur: *const xmlChar) -> *mut _xmlParserCtxt {
if cur.is_null() {
return ptr::null_mut();
}
let ctxt = crate::xml::parser::helpers::create_parser_ctxt();
if ctxt.is_null() {
return ptr::null_mut();
}
let len = crate::xml::string::xml_strlen(cur);
let input = crate::xml::parser::helpers::input_from_memory(cur as *const c_char, len as c_int);
crate::xml::parser::helpers::setup_parser_input(ctxt, input);
ctxt
}
#[no_mangle]
pub unsafe extern "C" fn xmlParseDocument(ctxt: *mut _xmlParserCtxt) -> c_int {
if ctxt.is_null() {
return -1;
}
crate::xml::parser::helpers::parse_document(ctxt)
}
#[no_mangle]
pub unsafe extern "C" fn xmlFreeParserCtxt(ctxt: *mut _xmlParserCtxt) {
if ctxt.is_null() {
return;
}
crate::xml::parser::helpers::free_parser_ctxt(ctxt);
}
#[no_mangle]
pub unsafe extern "C" fn xmlCtxtUseOptions(ctxt: *mut _xmlParserCtxt, options: c_int) -> c_int {
if ctxt.is_null() {
return -1;
}
const KEEP_MASK: c_int = XML_PARSE_NOERROR
| XML_PARSE_NOWARNING
| XML_PARSE_NONET
| XML_PARSE_NSCLEAN
| XML_PARSE_NOCDATA
| XML_PARSE_COMPACT
| XML_PARSE_OLD10
| XML_PARSE_HUGE
| XML_PARSE_OLDSAX
| XML_PARSE_IGNORE_ENC
| XML_PARSE_BIG_LINES;
const ALL_MASK: c_int = XML_PARSE_RECOVER
| XML_PARSE_NOENT
| XML_PARSE_DTDLOAD
| XML_PARSE_DTDATTR
| XML_PARSE_DTDVALID
| XML_PARSE_NOERROR
| XML_PARSE_NOWARNING
| XML_PARSE_PEDANTIC
| XML_PARSE_NOBLANKS
| XML_PARSE_SAX1
| XML_PARSE_NONET
| XML_PARSE_NODICT
| XML_PARSE_NSCLEAN
| XML_PARSE_NOCDATA
| XML_PARSE_COMPACT
| XML_PARSE_OLD10
| XML_PARSE_HUGE
| XML_PARSE_OLDSAX
| XML_PARSE_IGNORE_ENC
| XML_PARSE_BIG_LINES
| XML_PARSE_NO_XXE;
unsafe {
let merged = ((*ctxt).options & KEEP_MASK) | (options & ALL_MASK);
crate::abi::exports_parser::apply_options(ctxt, merged);
}
options & !ALL_MASK
}
#[no_mangle]
pub unsafe extern "C" fn xmlParseChunk(
ctxt: *mut _xmlParserCtxt,
chunk: *const c_char,
size: c_int,
terminate: c_int,
) -> c_int {
if ctxt.is_null() || size < 0 || (chunk.is_null() && size > 0) {
return XML_ERR_ARGUMENT;
}
crate::xml::parser::helpers::parse_chunk(ctxt, chunk, size, terminate)
}
#[no_mangle]
pub unsafe extern "C" fn xmlParserInputBufferCreateMem(
buffer: *const c_char,
size: c_int,
enc: c_int,
) -> *mut _xmlParserInputBuffer {
if buffer.is_null() || size <= 0 {
return ptr::null_mut();
}
let _ = enc;
crate::xml::parser::helpers::alloc_parser_input_buffer_with_mem(buffer, size)
}
#[no_mangle]
pub unsafe extern "C" fn xmlParserInputBufferCreateFilename(
URI: *const c_char,
enc: c_int,
) -> *mut _xmlParserInputBuffer {
if URI.is_null() {
return ptr::null_mut();
}
crate::xml::parser::helpers::alloc_parser_input_buffer()
}
#[no_mangle]
pub unsafe extern "C" fn xmlParserInputBufferCreateIO(
ioread: Option<xmlInputReadCallback>,
ioclose: Option<xmlInputCloseCallback>,
ioctx: *mut c_void,
enc: c_int,
) -> *mut _xmlParserInputBuffer {
let buf = crate::xml::parser::helpers::alloc_parser_input_buffer();
if !buf.is_null() {
(*buf).readcallback = ioread;
(*buf).closecallback = ioclose;
(*buf).context = ioctx;
}
buf
}
#[no_mangle]
pub unsafe extern "C" fn xmlFreeParserInputBuffer(buf: *mut _xmlParserInputBuffer) {
if buf.is_null() {
return;
}
crate::xml::parser::helpers::free_parser_input_buffer(buf);
}
#[no_mangle]
pub unsafe extern "C" fn xmlNewInputFromFile(
ctxt: *mut _xmlParserCtxt,
filename: *const c_char,
) -> *mut _xmlParserInput {
if filename.is_null() {
return ptr::null_mut();
}
crate::xml::parser::helpers::alloc_parser_input_buffer() as *mut _xmlParserInput
}
#[no_mangle]
pub unsafe extern "C" fn xmlFreeInputStream(input: *mut _xmlParserInput) {
if input.is_null() {
return;
}
crate::xml::parser::helpers::free_parser_input(input);
}
#[no_mangle]
pub unsafe extern "C" fn xmlOutputBufferCreateFilename(
URI: *const c_char,
encoder: *mut c_void,
compression: c_int,
) -> *mut _xmlOutputBuffer {
if URI.is_null() {
return ptr::null_mut();
}
crate::xml::io::output_buffer_create_filename_routed(
URI,
encoder as *mut crate::abi::structs::_xmlCharEncodingHandler,
compression,
)
}
#[no_mangle]
pub unsafe extern "C" fn xmlOutputBufferCreateFd(
fd: c_int,
encoder: *mut c_void,
) -> *mut _xmlOutputBuffer {
if fd < 0 {
return ptr::null_mut();
}
crate::xml::io::output_buffer_create_fd(
fd,
encoder as *mut crate::abi::structs::_xmlCharEncodingHandler,
)
}
#[no_mangle]
pub unsafe extern "C" fn xmlOutputBufferCreateIO(
iowrite: Option<xmlOutputWriteCallback>,
ioclose: Option<xmlOutputCloseCallback>,
ioctx: *mut c_void,
encoder: *mut c_void,
) -> *mut _xmlOutputBuffer {
crate::xml::io::output_buffer_create_io(
iowrite,
ioclose,
ioctx,
encoder as *mut crate::abi::structs::_xmlCharEncodingHandler,
)
}
#[no_mangle]
pub unsafe extern "C" fn xmlOutputBufferClose(out: *mut _xmlOutputBuffer) -> c_int {
if out.is_null() {
return -1;
}
crate::xml::io::output_buffer_close(out)
}
#[no_mangle]
pub unsafe extern "C" fn xmlOutputBufferFlush(out: *mut _xmlOutputBuffer) -> c_int {
if out.is_null() {
return -1;
}
crate::xml::io::output_buffer_flush(out)
}
#[no_mangle]
pub unsafe extern "C" fn xmlOutputBufferWrite(
out: *mut _xmlOutputBuffer,
len: c_int,
data: *const c_char,
) -> c_int {
if out.is_null() || data.is_null() || len < 0 {
return -1;
}
if len == 0 {
return 0;
}
crate::xml::io::output_buffer_write(out, len, data)
}
#[no_mangle]
pub unsafe extern "C" fn xmlOutputBufferWriteString(
out: *mut _xmlOutputBuffer,
str: *const c_char,
) -> c_int {
if str.is_null() {
return 0;
}
unsafe { xmlOutputBufferWrite(out, xmlStrlen(str as *const xmlChar), str) }
}
#[no_mangle]
pub unsafe extern "C" fn xmlAllocOutputBuffer(encoder: *mut c_void) -> *mut _xmlOutputBuffer {
crate::xml::io::output_buffer_create(
encoder as *mut crate::abi::structs::_xmlCharEncodingHandler,
)
}
#[no_mangle]
pub unsafe extern "C" fn xmlOutputBufferCreateBuffer(
buffer: *mut crate::abi::structs::_xmlBuffer,
encoder: *mut c_void,
) -> *mut _xmlOutputBuffer {
crate::xml::io::output_buffer_create_buffer(
buffer,
encoder as *mut crate::abi::structs::_xmlCharEncodingHandler,
)
}
#[no_mangle]
pub unsafe extern "C" fn xmlOutputBufferCreateFile(
file: *mut libc::FILE,
encoder: *mut c_void,
) -> *mut _xmlOutputBuffer {
crate::xml::io::output_buffer_create_file(
file,
encoder as *mut crate::abi::structs::_xmlCharEncodingHandler,
)
}
#[no_mangle]
pub unsafe extern "C" fn xmlOutputBufferGetContent(out: *mut _xmlOutputBuffer) -> *const c_char {
crate::xml::io::output_buffer_get_content(out) as *const c_char
}
#[no_mangle]
pub unsafe extern "C" fn xmlOutputBufferGetSize(out: *mut _xmlOutputBuffer) -> usize {
crate::xml::io::output_buffer_get_size(out)
}
#[no_mangle]
pub unsafe extern "C" fn xmlOutputBufferWriteEscape(
out: *mut _xmlOutputBuffer,
str: *const xmlChar,
escaping: Option<xmlCharEncodingOutputFunc>,
) -> c_int {
if out.is_null() || str.is_null() {
return -1;
}
crate::xml::io::output_buffer_write_escape(out, str, escaping)
}
#[no_mangle]
pub unsafe extern "C" fn xmlOutputBufferCreateFilenameDefault(
func: Option<
unsafe extern "C" fn(
*const c_char,
*mut crate::abi::structs::_xmlCharEncodingHandler,
c_int,
) -> *mut _xmlOutputBuffer,
>,
) -> Option<
unsafe extern "C" fn(
*const c_char,
*mut crate::abi::structs::_xmlCharEncodingHandler,
c_int,
) -> *mut _xmlOutputBuffer,
> {
let old = crate::xml::globals::get_output_buffer_create_filename_value();
if func.is_some() {
crate::xml::globals::set_output_buffer_create_filename_value(func);
}
old
}
#[no_mangle]
pub unsafe extern "C" fn __xmlOutputBufferCreateFilename() -> *mut Option<
unsafe extern "C" fn(
*const c_char,
*mut crate::abi::structs::_xmlCharEncodingHandler,
c_int,
) -> *mut _xmlOutputBuffer,
> {
crate::xml::globals::output_create_filename_ptr()
}
#[no_mangle]
pub extern "C" fn xmlDictCreate() -> *mut c_void {
crate::xml::dictionary::dict_create() as *mut c_void
}
#[no_mangle]
pub extern "C" fn xmlDictCreateSub(sub: *mut c_void) -> *mut c_void {
unsafe {
crate::xml::dictionary::dict_create_sub(sub as *mut crate::xml::dictionary::Dict)
as *mut c_void
}
}
#[no_mangle]
pub unsafe extern "C" fn xmlDictLookup(
dict: *mut c_void,
name: *const xmlChar,
len: c_int,
) -> *const xmlChar {
unsafe {
crate::xml::dictionary::dict_lookup(dict as *mut crate::xml::dictionary::Dict, name, len)
}
}
#[no_mangle]
pub unsafe extern "C" fn xmlDictExists(
dict: *mut c_void,
name: *const xmlChar,
len: c_int,
) -> *const xmlChar {
unsafe {
crate::xml::dictionary::dict_exists(dict as *mut crate::xml::dictionary::Dict, name, len)
}
}
#[no_mangle]
pub const extern "C" fn xmlDictSize(dict: *const c_void) -> c_int {
{
crate::xml::dictionary::dict_size(dict as *const crate::xml::dictionary::Dict)
}
}
#[no_mangle]
pub extern "C" fn xmlDictFree(dict: *mut c_void) {
if dict.is_null() {
return;
}
let d = dict as *mut crate::xml::dictionary::Dict;
let prev = unsafe {
(*d).ref_count
.fetch_sub(1, core::sync::atomic::Ordering::Relaxed)
};
if prev == 1 {
unsafe { crate::xml::dictionary::dict_free(dict as *mut crate::xml::dictionary::Dict) };
}
}
#[no_mangle]
pub extern "C" fn xmlDictSetLimit(dict: *mut c_void, limit: usize) -> usize {
{
crate::xml::dictionary::dict_set_limit(dict as *mut crate::xml::dictionary::Dict, limit)
}
}
#[no_mangle]
pub extern "C" fn xmlDictGetUsage(dict: *const c_void) -> usize {
{
crate::xml::dictionary::dict_get_usage(dict as *mut crate::xml::dictionary::Dict)
}
}
#[no_mangle]
pub extern "C" fn xmlHashCreate(size: c_int) -> *mut c_void {
crate::xml::hash::hash_create(size) as *mut c_void
}
#[no_mangle]
pub extern "C" fn xmlHashCreateDict(size: c_int, dict: *mut c_void) -> *mut c_void {
crate::xml::hash::hash_create_dict(size, dict) as *mut c_void
}
#[no_mangle]
pub extern "C" fn xmlHashFree(
table: *mut c_void,
f: Option<unsafe extern "C" fn(*mut c_void, *mut xmlChar)>,
) {
unsafe { crate::xml::hash::hash_free(table as *mut crate::xml::hash::HashTable, f) }
}
#[no_mangle]
pub unsafe extern "C" fn xmlHashAddEntry(
table: *mut c_void,
name: *const xmlChar,
userdata: *mut c_void,
) -> c_int {
unsafe {
crate::xml::hash::hash_add_entry(table as *mut crate::xml::hash::HashTable, name, userdata)
}
}
#[no_mangle]
pub unsafe extern "C" fn xmlHashAddEntry2(
table: *mut c_void,
name: *const xmlChar,
name2: *const xmlChar,
userdata: *mut c_void,
) -> c_int {
unsafe {
crate::xml::hash::hash_add_entry2(
table as *mut crate::xml::hash::HashTable,
name,
name2,
userdata,
)
}
}
#[no_mangle]
pub unsafe extern "C" fn xmlHashAddEntry3(
table: *mut c_void,
name: *const xmlChar,
name2: *const xmlChar,
name3: *const xmlChar,
userdata: *mut c_void,
) -> c_int {
unsafe {
crate::xml::hash::hash_add_entry3(
table as *mut crate::xml::hash::HashTable,
name,
name2,
name3,
userdata,
)
}
}
#[no_mangle]
pub unsafe extern "C" fn xmlHashUpdateEntry(
table: *mut c_void,
name: *const xmlChar,
userdata: *mut c_void,
f: Option<unsafe extern "C" fn(*mut c_void, *mut xmlChar)>,
) -> c_int {
unsafe {
crate::xml::hash::hash_update_entry(
table as *mut crate::xml::hash::HashTable,
name,
userdata,
f,
)
}
}
#[no_mangle]
pub unsafe extern "C" fn xmlHashUpdateEntry2(
table: *mut c_void,
name: *const xmlChar,
name2: *const xmlChar,
userdata: *mut c_void,
f: Option<unsafe extern "C" fn(*mut c_void, *mut xmlChar)>,
) -> c_int {
unsafe {
crate::xml::hash::hash_update_entry2(
table as *mut crate::xml::hash::HashTable,
name,
name2,
userdata,
f,
)
}
}
#[no_mangle]
pub unsafe extern "C" fn xmlHashUpdateEntry3(
table: *mut c_void,
name: *const xmlChar,
name2: *const xmlChar,
name3: *const xmlChar,
userdata: *mut c_void,
f: Option<unsafe extern "C" fn(*mut c_void, *mut xmlChar)>,
) -> c_int {
unsafe {
crate::xml::hash::hash_update_entry3(
table as *mut crate::xml::hash::HashTable,
name,
name2,
name3,
userdata,
f,
)
}
}
#[no_mangle]
pub unsafe extern "C" fn xmlHashLookup(table: *mut c_void, name: *const xmlChar) -> *mut c_void {
unsafe { crate::xml::hash::hash_lookup(table as *mut crate::xml::hash::HashTable, name) }
}
#[no_mangle]
pub unsafe extern "C" fn xmlHashLookup2(
table: *mut c_void,
name: *const xmlChar,
name2: *const xmlChar,
) -> *mut c_void {
unsafe {
crate::xml::hash::hash_lookup2(table as *mut crate::xml::hash::HashTable, name, name2)
}
}
#[no_mangle]
pub unsafe extern "C" fn xmlHashLookup3(
table: *mut c_void,
name: *const xmlChar,
name2: *const xmlChar,
name3: *const xmlChar,
) -> *mut c_void {
unsafe {
crate::xml::hash::hash_lookup3(
table as *mut crate::xml::hash::HashTable,
name,
name2,
name3,
)
}
}
#[no_mangle]
pub extern "C" fn xmlHashSize(table: *mut c_void) -> c_int {
crate::xml::hash::hash_size(table as *mut crate::xml::hash::HashTable)
}
#[no_mangle]
pub unsafe extern "C" fn xmlHashRemoveEntry(
table: *mut c_void,
name: *const xmlChar,
f: Option<unsafe extern "C" fn(*mut c_void, *mut xmlChar)>,
) -> c_int {
unsafe {
crate::xml::hash::hash_remove_entry(table as *mut crate::xml::hash::HashTable, name, f)
}
}
#[no_mangle]
pub unsafe extern "C" fn xmlHashRemoveEntry2(
table: *mut c_void,
name: *const xmlChar,
name2: *const xmlChar,
f: Option<unsafe extern "C" fn(*mut c_void, *mut xmlChar)>,
) -> c_int {
unsafe {
crate::xml::hash::hash_remove_entry2(
table as *mut crate::xml::hash::HashTable,
name,
name2,
f,
)
}
}
#[no_mangle]
pub unsafe extern "C" fn xmlHashRemoveEntry3(
table: *mut c_void,
name: *const xmlChar,
name2: *const xmlChar,
name3: *const xmlChar,
f: Option<unsafe extern "C" fn(*mut c_void, *mut xmlChar)>,
) -> c_int {
unsafe {
crate::xml::hash::hash_remove_entry3(
table as *mut crate::xml::hash::HashTable,
name,
name2,
name3,
f,
)
}
}
#[no_mangle]
pub extern "C" fn xmlHashScan(table: *mut c_void, f: Option<xmlHashScanner>, data: *mut c_void) {
unsafe { crate::xml::hash::hash_scan(table as *mut crate::xml::hash::HashTable, f, data) }
}
#[no_mangle]
pub extern "C" fn xmlHashScanFull(
table: *mut c_void,
f: Option<xmlHashScannerFull>,
data: *mut c_void,
) {
unsafe { crate::xml::hash::hash_scan_full(table as *mut crate::xml::hash::HashTable, f, data) }
}
#[no_mangle]
pub extern "C" fn xmlHashCopy(
table: *mut c_void,
f: Option<unsafe extern "C" fn(*mut c_void, *const xmlChar) -> *mut c_void>,
) -> *mut c_void {
unsafe {
crate::xml::hash::hash_copy(table as *mut crate::xml::hash::HashTable, f) as *mut c_void
}
}
#[no_mangle]
pub extern "C" fn xmlListCreate(
deallocator: Option<unsafe extern "C" fn(*mut c_void)>,
compare: Option<unsafe extern "C" fn(*const c_void, *const c_void) -> c_int>,
) -> *mut c_void {
crate::xml::list::list_create(deallocator, compare) as *mut c_void
}
#[no_mangle]
pub extern "C" fn xmlListDelete(list: *mut c_void) {
unsafe { crate::xml::list::list_delete(list as *mut crate::xml::list::List) }
}
#[no_mangle]
pub extern "C" fn xmlListSearch(list: *mut c_void, data: *mut c_void) -> *mut c_void {
unsafe { crate::xml::list::list_search(list as *mut crate::xml::list::List, data) }
}
#[no_mangle]
pub extern "C" fn xmlListWalk(
list: *mut c_void,
walker: Option<unsafe extern "C" fn(*mut c_void, *mut c_void) -> c_int>,
data: *mut c_void,
) {
unsafe { crate::xml::list::list_walk(list as *mut crate::xml::list::List, walker, data) }
}
#[no_mangle]
pub extern "C" fn xmlListPushBack(list: *mut c_void, data: *mut c_void) -> c_int {
unsafe { crate::xml::list::list_push_back(list as *mut crate::xml::list::List, data) }
}
#[no_mangle]
pub extern "C" fn xmlListPushFront(list: *mut c_void, data: *mut c_void) -> c_int {
unsafe { crate::xml::list::list_push_front(list as *mut crate::xml::list::List, data) }
}
#[no_mangle]
pub extern "C" fn xmlListPopBack(list: *mut c_void) {
unsafe { crate::xml::list::list_pop_back(list as *mut crate::xml::list::List) }
}
#[no_mangle]
pub extern "C" fn xmlListPopFront(list: *mut c_void) {
unsafe { crate::xml::list::list_pop_front(list as *mut crate::xml::list::List) }
}
#[no_mangle]
pub extern "C" fn xmlListInsert(list: *mut c_void, data: *mut c_void) -> c_int {
unsafe { crate::xml::list::list_insert(list as *mut crate::xml::list::List, data) }
}
#[no_mangle]
pub extern "C" fn xmlListAppend(list: *mut c_void, data: *mut c_void) -> c_int {
unsafe { crate::xml::list::list_append(list as *mut crate::xml::list::List, data) }
}
#[no_mangle]
pub extern "C" fn xmlListRemoveFirst(list: *mut c_void, data: *mut c_void) -> c_int {
unsafe { crate::xml::list::list_remove_first(list as *mut crate::xml::list::List, data) }
}
#[no_mangle]
pub extern "C" fn xmlListRemoveLast(list: *mut c_void, data: *mut c_void) -> c_int {
unsafe { crate::xml::list::list_remove_last(list as *mut crate::xml::list::List, data) }
}
#[no_mangle]
pub extern "C" fn xmlListRemoveAll(list: *mut c_void, data: *mut c_void) -> c_int {
unsafe { crate::xml::list::list_remove_all(list as *mut crate::xml::list::List, data) }
}
#[no_mangle]
pub extern "C" fn xmlListClear(list: *mut c_void) {
unsafe { crate::xml::list::list_clear(list as *mut crate::xml::list::List) }
}
#[no_mangle]
pub extern "C" fn xmlListEmpty(list: *mut c_void) -> c_int {
crate::xml::list::list_empty(list as *mut crate::xml::list::List)
}
#[no_mangle]
pub extern "C" fn xmlListFront(list: *mut c_void) -> *mut c_void {
crate::xml::list::list_front(list as *mut crate::xml::list::List)
}
#[no_mangle]
pub extern "C" fn xmlListBack(list: *mut c_void) -> *mut c_void {
crate::xml::list::list_back(list as *mut crate::xml::list::List)
}
#[no_mangle]
pub extern "C" fn xmlListSize(list: *mut c_void) -> c_int {
crate::xml::list::list_size(list as *mut crate::xml::list::List)
}
#[no_mangle]
pub extern "C" fn xmlListSort(list: *mut c_void) {
unsafe { crate::xml::list::list_sort(list as *mut crate::xml::list::List) }
}
#[no_mangle]
pub extern "C" fn xmlListReverse(list: *mut c_void) {
unsafe { crate::xml::list::list_reverse(list as *mut crate::xml::list::List) }
}
#[no_mangle]
pub extern "C" fn xmlListReverseSplice(list: *mut c_void, list2: *mut c_void) {
unsafe {
crate::xml::list::list_reverse_splice(
list as *mut crate::xml::list::List,
list2 as *mut crate::xml::list::List,
)
}
}
#[no_mangle]
pub extern "C" fn xmlListMerge(list: *mut c_void, list2: *mut c_void) {
unsafe {
crate::xml::list::list_merge(
list as *mut crate::xml::list::List,
list2 as *mut crate::xml::list::List,
)
}
}
#[no_mangle]
pub unsafe extern "C" fn xmlListEnd(l: *mut c_void) -> *mut c_void {
crate::xml::list::list_end(l as *mut crate::xml::list::List)
}
#[no_mangle]
pub unsafe extern "C" fn xmlListReverseSearch(l: *mut c_void, data: *mut c_void) -> *mut c_void {
crate::xml::list::list_reverse_search(l as *mut crate::xml::list::List, data)
}
#[no_mangle]
pub unsafe extern "C" fn xmlListReverseWalk(
l: *mut c_void,
walker: Option<unsafe extern "C" fn(*mut c_void, *mut c_void) -> c_int>,
data: *mut c_void,
) {
crate::xml::list::list_reverse_walk(l as *mut crate::xml::list::List, walker, data)
}
#[no_mangle]
pub unsafe extern "C" fn xmlListDup(l: *mut c_void) -> *mut c_void {
crate::xml::list::list_dup(l as *mut crate::xml::list::List) as *mut c_void
}
#[no_mangle]
pub unsafe extern "C" fn xmlListCopy(cur: *mut c_void, old: *mut c_void) -> c_int {
crate::xml::list::list_copy(
cur as *mut crate::xml::list::List,
old as *mut crate::xml::list::List,
)
}
#[no_mangle]
pub unsafe extern "C" fn xmlLinkGetData(lk: *mut c_void) -> *mut c_void {
crate::xml::list::link_get_data(lk)
}
#[no_mangle]
pub extern "C" fn xmlBufferCreate() -> *mut _xmlBuffer {
unsafe { xml_buffer_create_upstream(256) }
}
#[no_mangle]
pub extern "C" fn xmlBufferCreateSize(size: usize) -> *mut _xmlBuffer {
if size >= c_int::MAX as usize {
return ptr::null_mut();
}
unsafe { xml_buffer_create_upstream(size) }
}
unsafe fn xml_buffer_create_upstream(size: usize) -> *mut _xmlBuffer {
let ret = unsafe { xmlMallocImpl(size_of::<_xmlBuffer>()) as *mut _xmlBuffer };
if ret.is_null() {
return ptr::null_mut();
}
let sz = if size != 0 { size + 1 } else { 0 };
unsafe {
if sz != 0 {
let content = xmlMallocImpl(sz) as *mut xmlChar;
if content.is_null() {
xmlFreeImpl(ret as *mut c_void);
return ptr::null_mut();
}
*content = 0;
(*ret).content = content;
(*ret).contentIO = content;
} else {
(*ret).content = ptr::null_mut();
(*ret).contentIO = ptr::null_mut();
}
(*ret).use_ = 0;
(*ret).size = sz as c_uint;
(*ret).alloc = crate::abi::types::xmlBufferAllocationScheme::XML_BUFFER_ALLOC_IO as c_int;
}
ret
}
#[no_mangle]
pub extern "C" fn xmlBufferCreateStatic(mem: *mut c_void, size: usize) -> *mut _xmlBuffer {
if mem.is_null() || size == 0 {
return ptr::null_mut();
}
crate::xml::io::buf_create_static(mem as *const xmlChar, size as c_int)
}
#[no_mangle]
pub extern "C" fn xmlBufferFree(buf: *mut _xmlBuffer) {
crate::xml::io::buf_free(buf)
}
#[no_mangle]
pub extern "C" fn xmlBufferEmpty(buf: *mut _xmlBuffer) {
if buf.is_null() {
return;
}
unsafe {
if !(*buf).content.is_null() {
*(*buf).content = 0;
}
(*buf).use_ = 0;
}
}
#[no_mangle]
pub extern "C" fn xmlBufferContent(buf: *const _xmlBuffer) -> *mut xmlChar {
crate::xml::io::buf_content(buf as *mut _xmlBuffer)
}
#[no_mangle]
pub extern "C" fn xmlBufferLength(buf: *const _xmlBuffer) -> c_int {
crate::xml::io::buf_length(buf as *mut _xmlBuffer)
}
#[no_mangle]
pub unsafe extern "C" fn xmlBufferAdd(
buf: *mut _xmlBuffer,
str: *const xmlChar,
len: c_int,
) -> c_int {
crate::xml::io::buf_add(buf, str, len)
}
#[no_mangle]
pub unsafe extern "C" fn xmlBufferAddHead(
buf: *mut _xmlBuffer,
str: *const xmlChar,
len: c_int,
) -> c_int {
crate::xml::io::buf_add_head(buf, str, len)
}
#[no_mangle]
pub unsafe extern "C" fn xmlBufferCat(buf: *mut _xmlBuffer, str: *const xmlChar) -> c_int {
if str.is_null() {
return -1;
}
let len = crate::xml::string::xml_strlen(str) as c_int;
crate::xml::io::buf_add(buf, str, len)
}
#[no_mangle]
pub extern "C" fn xmlBufferSetAllocationScheme(buf: *mut _xmlBuffer, scheme: c_int) {
if buf.is_null() {
return;
}
unsafe {
(*buf).alloc = scheme;
}
}
#[no_mangle]
pub extern "C" fn xmlBufferShrink(buf: *mut _xmlBuffer, len: c_uint) -> c_int {
if buf.is_null() {
return -1;
}
if len == 0 {
return 0;
}
unsafe {
let b = &mut *buf;
if len > b.use_ {
return -1;
}
let remaining = b.use_ - len;
if remaining > 0 {
core::ptr::copy(b.content.add(len as usize), b.content, remaining as usize);
}
*b.content.add(remaining as usize) = 0;
b.use_ = remaining;
}
len as c_int
}
#[no_mangle]
pub extern "C" fn xmlBufferGrow(buf: *mut _xmlBuffer, len: c_uint) -> c_int {
if buf.is_null() || len == 0 {
return 0;
}
let cur_use = unsafe { (*buf).use_ };
let new_size = cur_use + len + 1;
crate::xml::io::buf_grow(buf, new_size)
}
#[no_mangle]
pub extern "C" fn xmlBufferReserve(buf: *mut _xmlBuffer, len: c_int) -> c_int {
xmlBufferGrow(buf, len as c_uint)
}
#[no_mangle]
pub extern "C" fn xmlBufferDetach(buf: *mut _xmlBuffer) -> *mut xmlChar {
if buf.is_null() {
return ptr::null_mut();
}
unsafe {
let content = (*buf).content;
(*buf).content = ptr::null_mut();
(*buf).use_ = 0;
(*buf).size = 0;
content
}
}
#[no_mangle]
pub extern "C" fn xmlGetCharEncoding(name: *const c_char) -> c_int {
if name.is_null() {
return 0; }
let name_bytes = unsafe {
let len = libc::strlen(name);
core::slice::from_raw_parts(name as *const u8, len)
};
crate::xml::encoding::encoding_from_name(name_bytes) as c_int
}
#[no_mangle]
pub extern "C" fn xmlFindCharEncodingHandler(name: *const c_char) -> *mut c_void {
if name.is_null() {
return ptr::null_mut();
}
crate::xml::encoding::xmlFindCharEncodingHandler_owned(
name as *const crate::abi::types::xmlChar,
) as *mut c_void
}
#[no_mangle]
pub extern "C" fn xmlCharEncCloseFunc(handler: *mut c_void) -> c_int {
if handler.is_null() {
return -1;
}
unsafe {
let h = handler as *mut crate::abi::structs::_xmlCharEncodingHandler;
if (*h).flags & crate::xml::encoding::XML_HANDLER_STATIC != 0 {
return 0;
}
if !(*h).name.is_null() {
crate::abi::allocator::xmlFreeImpl((*h).name as *mut c_void);
}
if let Some(dtor) = (*h).ctxtDtor {
if !(*h).inputCtxt.is_null() {
dtor((*h).inputCtxt);
}
if !(*h).outputCtxt.is_null() {
dtor((*h).outputCtxt);
}
}
crate::abi::allocator::xmlFreeImpl(handler);
}
0
}
#[no_mangle]
pub unsafe extern "C" fn xmlIsolat1ToUTF8(
out: *mut u8,
outlen: *mut c_int,
input: *const u8,
inlen: *mut c_int,
) -> c_int {
const XML_ENC_ERR_SPACE: c_int = -2;
const XML_ENC_ERR_INTERNAL: c_int = -1;
unsafe {
if out.is_null() || input.is_null() || outlen.is_null() || inlen.is_null() {
return XML_ENC_ERR_INTERNAL;
}
let outstart = out;
let instart = input;
let outend = out.add(*outlen as usize);
let inend = input.add(*inlen as usize);
let mut cur = input;
let mut o = out;
while cur < inend {
let c = *cur;
if c < 0x80 {
if o >= outend {
break;
}
*o = c;
o = o.add(1);
} else {
if (outend as usize) - (o as usize) < 2 {
break;
}
*o = (c >> 6) | 0xC0;
*o.add(1) = (c & 0x3F) | 0x80;
o = o.add(2);
}
cur = cur.add(1);
}
let mut ret = XML_ENC_ERR_SPACE;
if cur == inend {
ret = (o as usize - outstart as usize) as c_int;
}
*outlen = (o as usize - outstart as usize) as c_int;
*inlen = (cur as usize - instart as usize) as c_int;
ret
}
}
#[no_mangle]
pub unsafe extern "C" fn xmlUTF8ToIsolat1(
out: *mut u8,
outlen: *mut c_int,
input: *const u8,
inlen: *mut c_int,
) -> c_int {
const XML_ENC_ERR_SPACE: c_int = -2;
const XML_ENC_ERR_INTERNAL: c_int = -1;
const XML_ENC_ERR_INPUT: c_int = -3;
const XML_ENC_ERR_SUCCESS: c_int = 0;
unsafe {
if out.is_null() || outlen.is_null() || inlen.is_null() {
return XML_ENC_ERR_INTERNAL;
}
if input.is_null() {
*inlen = 0;
*outlen = 0;
return XML_ENC_ERR_SUCCESS;
}
let outstart = out;
let instart = input;
let outend = out.add(*outlen as usize);
let inend = input.add(*inlen as usize);
let mut cur = input;
let mut o = out;
let mut ret = XML_ENC_ERR_SPACE;
while cur < inend {
if o >= outend {
break;
}
let c = *cur;
if c < 0x80 {
*o = c;
o = o.add(1);
} else if (0xC2..=0xC3).contains(&c) {
if (inend as usize) - (cur as usize) < 2 {
break;
}
cur = cur.add(1);
*o = (c << 6) | (*cur & 0x3F);
o = o.add(1);
} else {
ret = XML_ENC_ERR_INPUT;
break;
}
cur = cur.add(1);
}
if ret != XML_ENC_ERR_INPUT {
ret = (o as usize - outstart as usize) as c_int;
}
*outlen = (o as usize - outstart as usize) as c_int;
*inlen = (cur as usize - instart as usize) as c_int;
ret
}
}
#[no_mangle]
pub extern "C" fn xmlGetCharEncodingName(enc: c_int) -> *const c_char {
if !(-1..=22).contains(&enc) {
return match enc {
23 => c"UTF-16".as_ptr(),
24 => c"HTML".as_ptr(),
31 => c"windows-1252".as_ptr(),
_ => ptr::null(),
};
}
let e: crate::abi::types::xmlCharEncoding = unsafe { core::mem::transmute(enc) };
crate::xml::encoding::xmlGetCharEncodingName(e)
}
#[no_mangle]
pub extern "C" fn xmlParseCharEncoding(name: *const c_char) -> c_int {
crate::xml::encoding::xmlParseCharEncoding(name)
}
#[no_mangle]
pub extern "C" fn xmlAddEncodingAlias(name: *const c_char, alias: *const c_char) -> c_int {
crate::xml::encoding::add_encoding_alias(name, alias)
}
#[no_mangle]
pub extern "C" fn xmlDelEncodingAlias(alias: *const c_char) -> c_int {
crate::xml::encoding::del_encoding_alias(alias)
}
#[no_mangle]
pub extern "C" fn xmlGetEncodingAlias(alias: *const c_char) -> *const c_char {
crate::xml::encoding::get_encoding_alias(alias)
}
#[no_mangle]
pub extern "C" fn xmlCleanupEncodingAliases() {
crate::xml::encoding::cleanup_encoding_aliases();
}
#[no_mangle]
pub extern "C" fn xmlCharEncInFunc(
handler: *mut c_void,
out: *mut c_void,
in_: *mut c_void,
) -> c_int {
crate::xml::encoding::xmlCharEncInFunc(
handler as *mut crate::abi::structs::_xmlCharEncodingHandler,
out as *mut crate::abi::structs::_xmlBuffer,
in_ as *mut crate::abi::structs::_xmlBuffer,
)
}
#[no_mangle]
pub extern "C" fn xmlCharEncOutFunc(
handler: *mut c_void,
out: *mut c_void,
in_: *mut c_void,
) -> c_int {
crate::xml::encoding::xmlCharEncOutFunc(
handler as *mut crate::abi::structs::_xmlCharEncodingHandler,
out as *mut crate::abi::structs::_xmlBuffer,
in_ as *mut crate::abi::structs::_xmlBuffer,
)
}
#[no_mangle]
pub extern "C" fn xmlNewCharEncodingHandler(
name: *const c_char,
input: crate::abi::callbacks::xmlCharEncodingInputFunc,
output: crate::abi::callbacks::xmlCharEncodingOutputFunc,
) -> *mut c_void {
crate::xml::encoding::xmlNewCharEncodingHandler(name, input, output) as *mut c_void
}
#[no_mangle]
pub extern "C" fn xmlInitCharEncodingHandlers() {
crate::xml::encoding::xmlInitCharEncodingHandlers();
}
#[no_mangle]
pub extern "C" fn xmlCleanupCharEncodingHandlers() {
crate::xml::encoding::xmlCleanupCharEncodingHandlers();
}
#[no_mangle]
pub extern "C" fn xmlLookupCharEncodingHandler(enc: c_int, out: *mut *mut c_void) -> c_int {
crate::xml::encoding::xmlLookupCharEncodingHandler(enc, out)
}
#[no_mangle]
pub extern "C" fn xmlGetCharEncodingHandler(enc: c_int) -> *mut c_void {
crate::xml::encoding::xmlGetCharEncodingHandler(enc)
}
#[no_mangle]
pub extern "C" fn xmlOpenCharEncodingHandler(
name: *const c_char,
output: c_int,
out: *mut *mut c_void,
) -> c_int {
crate::xml::encoding::xmlOpenCharEncodingHandler(name, output, out)
}
#[no_mangle]
pub extern "C" fn xmlCreateCharEncodingHandler(
name: *const c_char,
flags: c_int,
impl_: Option<crate::abi::callbacks::xmlCharEncConvImpl>,
implCtxt: *mut c_void,
out: *mut *mut c_void,
) -> c_int {
crate::xml::encoding::xmlCreateCharEncodingHandler(name, flags, impl_, implCtxt, out)
}
#[no_mangle]
pub extern "C" fn xmlCharEncNewCustomHandler(
name: *const c_char,
input: crate::abi::callbacks::xmlCharEncConvFunc,
output: crate::abi::callbacks::xmlCharEncConvFunc,
ctxtDtor: Option<crate::abi::callbacks::xmlCharEncConvCtxtDtor>,
inputCtxt: *mut c_void,
outputCtxt: *mut c_void,
out: *mut *mut c_void,
) -> c_int {
crate::xml::encoding::xmlCharEncNewCustomHandler(
name, input, output, ctxtDtor, inputCtxt, outputCtxt, out,
)
}
#[no_mangle]
pub unsafe extern "C" fn xmlCharEncInput(input: *mut _xmlParserInputBuffer, _to: c_int) -> c_int {
if input.is_null() {
return -1;
}
let handler = (*input).encoder as *mut crate::abi::structs::_xmlCharEncodingHandler;
if handler.is_null() {
return -1;
}
let raw = (*input).raw as *mut crate::abi::structs::_xmlBuffer;
let buf = (*input).buffer as *mut crate::abi::structs::_xmlBuffer;
if raw.is_null() || buf.is_null() {
return -1;
}
crate::xml::encoding::char_enc_in(handler, buf, raw)
}
#[no_mangle]
pub unsafe extern "C" fn xmlCharEncOutput(output: *mut _xmlOutputBuffer, _to: c_int) -> c_int {
if output.is_null() {
return -1;
}
let handler = (*output).encoder as *mut crate::abi::structs::_xmlCharEncodingHandler;
if handler.is_null() {
return -1;
}
let buf = (*output).buffer as *mut crate::abi::structs::_xmlBuffer;
let conv = (*output).conv as *mut crate::abi::structs::_xmlBuffer;
if buf.is_null() || conv.is_null() {
return -1;
}
crate::xml::encoding::char_enc_out(handler, conv, buf)
}
#[no_mangle]
pub unsafe extern "C" fn xmlParseURI(str: *const c_char) -> *mut c_void {
crate::xml::uri::xmlParseURI(str)
}
#[no_mangle]
pub unsafe extern "C" fn xmlParseURIRaw(str: *const c_char, raw: c_int) -> *mut c_void {
let _ = raw;
crate::xml::uri::xmlParseURI(str)
}
#[no_mangle]
pub unsafe extern "C" fn xmlFreeURI(uri: *mut c_void) {
crate::xml::uri::xmlFreeURI(uri)
}
#[no_mangle]
pub extern "C" fn xmlCreateURI() -> *mut c_void {
crate::xml::uri::xmlCreateURI()
}
#[no_mangle]
pub unsafe extern "C" fn xmlSaveUri(uri: *mut c_void) -> *mut xmlChar {
crate::xml::uri::xmlSaveUri(uri)
}
#[no_mangle]
pub unsafe extern "C" fn xmlParseURIReference(uri: *mut c_void, str: *const c_char) -> c_int {
crate::xml::uri::xmlParseURIReference(uri, str)
}
#[no_mangle]
pub unsafe extern "C" fn xmlNormalizeURIPath(path: *mut c_char) -> c_int {
crate::xml::uri::xmlNormalizeURIPath(path)
}
#[no_mangle]
pub unsafe extern "C" fn xmlURIEscapeStr(
str: *const xmlChar,
list: *const xmlChar,
) -> *mut xmlChar {
crate::xml::uri::xmlURIEscapeStr(str, list)
}
#[no_mangle]
pub unsafe extern "C" fn xmlURIUnescapeString(
str: *const c_char,
len: c_int,
target: *mut c_char,
) -> *mut c_char {
crate::xml::uri::xmlURIUnescapeString(str, len, target)
}
unsafe fn xpath_to_object(val: XPathValue) -> *mut _xmlXPathObject {
let obj = xmlMallocZero(size_of::<_xmlXPathObject>()) as *mut _xmlXPathObject;
if obj.is_null() {
return ptr::null_mut();
}
match val {
XPathValue::NodeSet(ns) => {
(*obj).type_ = xmlXPathObjectType::XPATH_NODESET as c_int;
(*obj).nodesetval = ns.to_raw() as *mut c_void;
}
XPathValue::Boolean(b) => {
(*obj).type_ = xmlXPathObjectType::XPATH_BOOLEAN as c_int;
(*obj).boolval = if b { 1 } else { 0 };
}
XPathValue::Number(n) => {
(*obj).type_ = xmlXPathObjectType::XPATH_NUMBER as c_int;
(*obj).floatval = n;
}
XPathValue::String(s) => {
(*obj).type_ = xmlXPathObjectType::XPATH_STRING as c_int;
let bytes = s.as_bytes();
let len = bytes.len();
let buf = xmlMallocImpl(len + 1) as *mut xmlChar;
if !buf.is_null() {
ptr::copy_nonoverlapping(bytes.as_ptr(), buf, len);
*buf.add(len) = 0; }
(*obj).stringval = buf;
}
}
obj
}
unsafe fn object_to_xpathvalue(obj: *mut _xmlXPathObject) -> XPathValue {
let typ = (*obj).type_;
if typ == xmlXPathObjectType::XPATH_NODESET as c_int {
let ns_ptr = (*obj).nodesetval as *mut _xmlNodeSet;
if ns_ptr.is_null() {
return XPathValue::NodeSet(NodeSet::new());
}
let node_nr = (*ns_ptr).nodeNr;
let node_tab = (*ns_ptr).nodeTab;
let mut ns = NodeSet::new();
if !node_tab.is_null() {
for i in 0..node_nr as isize {
let node = *node_tab.add(i as usize);
ns.push(node);
}
}
XPathValue::NodeSet(ns)
} else if typ == xmlXPathObjectType::XPATH_BOOLEAN as c_int {
XPathValue::Boolean((*obj).boolval != 0)
} else if typ == xmlXPathObjectType::XPATH_NUMBER as c_int {
XPathValue::Number((*obj).floatval)
} else if typ == xmlXPathObjectType::XPATH_STRING as c_int {
let s_ptr = (*obj).stringval;
if s_ptr.is_null() {
XPathValue::String(String::new())
} else {
let s = CStr::from_ptr(s_ptr as *const c_char)
.to_string_lossy()
.into_owned();
XPathValue::String(s)
}
} else if typ == xmlXPathObjectType::XPATH_XSLT_TREE as c_int {
let frag_doc = (*obj).nodesetval as *mut _xmlDoc;
if frag_doc.is_null() {
XPathValue::NodeSet(NodeSet::new())
} else {
let mut ns = NodeSet::new();
ns.push(frag_doc as *mut _xmlNode);
XPathValue::NodeSet(ns)
}
} else {
XPathValue::Boolean(false)
}
}
pub unsafe fn xpath_to_object_pub(val: XPathValue) -> *mut _xmlXPathObject {
xpath_to_object(val)
}
pub unsafe fn object_to_xpathvalue_pub(obj: *mut _xmlXPathObject) -> XPathValue {
object_to_xpathvalue(obj)
}
static COMPILED_EXPRS: Lazy<Mutex<HashMap<u64, Box<CompiledExpr>>>> =
Lazy::new(|| Mutex::new(HashMap::new()));
static NEXT_COMPILED_KEY: Lazy<Mutex<u64>> = Lazy::new(|| Mutex::new(1));
pub(crate) fn xpath_compiled_registry() -> &'static Mutex<HashMap<u64, Box<CompiledExpr>>> {
&COMPILED_EXPRS
}
type CXPathFunc = unsafe extern "C" fn(*mut c_void, c_int);
#[derive(Clone, Copy, PartialEq, Eq, Hash)]
struct SendSyncPtr(*mut c_void);
unsafe impl Send for SendSyncPtr {}
unsafe impl Sync for SendSyncPtr {}
static C_FUNCTIONS: Lazy<Mutex<HashMap<(SendSyncPtr, String), CXPathFunc>>> =
Lazy::new(|| Mutex::new(HashMap::new()));
pub(crate) fn xpath_cfunc_lookup(extra: *mut c_void, qualified: &str) -> Option<CXPathFunc> {
C_FUNCTIONS
.lock()
.get(&(SendSyncPtr(extra), qualified.to_string()))
.copied()
}
pub(crate) fn xpath_cfunc_cleanup(extra: *mut c_void) {
C_FUNCTIONS.lock().retain(|(k, _), _| k.0 != extra);
}
fn c_func_bridge_closure(c_ctxt: SendSyncPtr, qualified: String) -> BoxedXPathFunction {
let (local_name, ns_uri) = split_qualified(&qualified);
Box::new(move |_ctx: &mut XPathContext, args: &[XPathValue]| {
let cc = c_ctxt;
unsafe {
c_func_call_bridge(
cc.0 as *mut _xmlXPathContext,
&qualified,
&local_name,
ns_uri.as_deref(),
args,
)
}
})
}
fn split_qualified(qualified: &str) -> (String, Option<String>) {
if let Some(rest) = qualified.strip_prefix('{') {
if let Some(end) = rest.find('}') {
let uri = rest[..end].to_string();
let local = rest[end + 1..].to_string();
return (local, Some(uri));
}
}
(qualified.to_string(), None)
}
pub(crate) unsafe fn call_c_xpath_function(
fnptr: Option<unsafe extern "C" fn(*mut c_void, c_int)>,
c_ctxt: *mut _xmlXPathContext,
name: &str,
ns_uri: Option<&str>,
args: &[XPathValue],
) -> Result<XPathValue, String> {
let func = match fnptr {
Some(f) => f,
None => return Err("XPath: missing C function pointer".to_string()),
};
let pc = crate::xml::xpath::parser_context::new_parser_context(ptr::null(), c_ctxt);
if pc.is_null() {
return Err("XPath: parser-context allocation failure".to_string());
}
let mut push_ok = true;
for v in args {
let obj = xpath_to_object(v.clone());
if obj.is_null() || crate::xml::xpath::parser_context::value_push(pc, obj).is_null() {
push_ok = false;
break;
}
}
let result = if push_ok {
let mut name_nul: Vec<xmlChar> = name.as_bytes().to_vec();
name_nul.push(0);
let uri_nul: Option<Vec<xmlChar>> = ns_uri.map(|u| {
let mut v = u.as_bytes().to_vec();
v.push(0);
v
});
let saved_function = (*c_ctxt).function;
let saved_function_uri = (*c_ctxt).functionURI;
(*c_ctxt).function = name_nul.as_ptr() as *const xmlChar;
(*c_ctxt).functionURI = uri_nul
.as_ref()
.map_or(ptr::null(), |v| v.as_ptr() as *const xmlChar);
unsafe { func(pc as *mut c_void, args.len() as c_int) };
(*c_ctxt).function = saved_function;
(*c_ctxt).functionURI = saved_function_uri;
let ret = crate::xml::xpath::parser_context::value_pop(pc);
if ret.is_null() {
Err("XPath: C function returned no value".to_string())
} else {
let v = object_to_xpathvalue(ret);
unsafe { xmlXPathFreeObject(ret) };
Ok(v)
}
} else {
Err("XPath: failed to push arguments to C function".to_string())
};
unsafe {
loop {
let leftover = crate::xml::xpath::parser_context::value_pop(pc);
if leftover.is_null() {
break;
}
xmlXPathFreeObject(leftover);
}
crate::xml::xpath::parser_context::free_parser_context(pc);
}
result
}
pub(crate) unsafe fn call_xslt_ext_function(
fnptr: Option<unsafe extern "C" fn(*mut c_void, c_int)>,
tctxt: *mut crate::abi::structs::_xsltTransformContext,
xpath_ctxt: *mut _xmlXPathContext,
name: &str,
ns_uri: Option<&str>,
args: &[XPathValue],
) -> Result<XPathValue, String> {
let func = match fnptr {
Some(f) => f,
None => return Err("XPath: missing C function pointer".to_string()),
};
if tctxt.is_null() || xpath_ctxt.is_null() {
return Err("XPath: null XSLT context in extension-function bridge".to_string());
}
let mirror = libc::calloc(1, core::mem::size_of::<_xmlXPathContext>()) as *mut _xmlXPathContext;
if mirror.is_null() {
return Err("XPath: mirror-context allocation failure".to_string());
}
unsafe {
libc::memcpy(
mirror as *mut libc::c_void,
xpath_ctxt as *const libc::c_void,
core::mem::size_of::<_xmlXPathContext>(),
);
(*mirror).extra = tctxt as *mut c_void;
let pc = crate::xml::xpath::parser_context::new_parser_context(ptr::null(), mirror);
if pc.is_null() {
libc::free(mirror as *mut libc::c_void);
return Err("XPath: parser-context allocation failure".to_string());
}
let mut push_ok = true;
for v in args {
let obj = xpath_to_object(v.clone());
if obj.is_null() || crate::xml::xpath::parser_context::value_push(pc, obj).is_null() {
push_ok = false;
break;
}
}
let result = if push_ok {
let mut name_nul: Vec<xmlChar> = name.as_bytes().to_vec();
name_nul.push(0);
let uri_nul: Option<Vec<xmlChar>> = ns_uri.map(|u| {
let mut v = u.as_bytes().to_vec();
v.push(0);
v
});
(*mirror).function = name_nul.as_ptr() as *const xmlChar;
(*mirror).functionURI = uri_nul
.as_ref()
.map_or(ptr::null(), |v| v.as_ptr() as *const xmlChar);
func(pc as *mut c_void, args.len() as c_int);
let ret = crate::xml::xpath::parser_context::value_pop(pc);
if ret.is_null() {
Err("XPath: C function returned no value".to_string())
} else {
let v = object_to_xpathvalue(ret);
xmlXPathFreeObject(ret);
Ok(v)
}
} else {
Err("XPath: failed to push arguments to C function".to_string())
};
loop {
let leftover = crate::xml::xpath::parser_context::value_pop(pc);
if leftover.is_null() {
break;
}
xmlXPathFreeObject(leftover);
}
crate::xml::xpath::parser_context::free_parser_context(pc);
libc::free(mirror as *mut libc::c_void);
result
}
}
unsafe fn c_func_call_bridge(
c_ctxt: *mut _xmlXPathContext,
qualified: &str,
name: &str,
ns_uri: Option<&str>,
args: &[XPathValue],
) -> Result<XPathValue, String> {
if c_ctxt.is_null() {
return Err("XPath: null context in C function bridge".to_string());
}
let func = xpath_cfunc_lookup((*c_ctxt).extra, qualified);
if func.is_none() {
return Err(format!("XPath: unknown C function '{}'", qualified));
}
unsafe { call_c_xpath_function(func, c_ctxt, name, ns_uri, args) }
}
#[no_mangle]
pub unsafe extern "C" fn xmlXPathNewContext(doc: *mut _xmlDoc) -> *mut _xmlXPathContext {
let ctxt = xmlMallocZero(size_of::<_xmlXPathContext>()) as *mut _xmlXPathContext;
if ctxt.is_null() {
return ptr::null_mut();
}
(*ctxt).doc = doc;
(*ctxt).node = ptr::null_mut();
(*ctxt).contextSize = 1;
(*ctxt).proximityPosition = 1;
let mut internal = Box::new(XPathContext::new(doc));
for (name, func) in crate::xml::xpath::functions::core_functions() {
internal.register_function(&name, func);
}
internal.c_context = ctxt;
(*ctxt).extra = Box::into_raw(internal) as *mut c_void;
ctxt
}
pub(crate) unsafe extern "C" fn free_ns_uri_payload(payload: *mut c_void, _key: *mut xmlChar) {
if !payload.is_null() {
crate::abi::allocator::xmlFreeImpl(payload);
}
}
#[no_mangle]
pub unsafe extern "C" fn xmlXPathFreeContext(ctxt: *mut _xmlXPathContext) {
if ctxt.is_null() {
return;
}
if !(*ctxt).extra.is_null() {
let _ = Box::from_raw((*ctxt).extra as *mut XPathContext);
(*ctxt).extra = ptr::null_mut();
}
if !(*ctxt).nsHash.is_null() {
xmlHashFree((*ctxt).nsHash, Some(free_ns_uri_payload));
(*ctxt).nsHash = ptr::null_mut();
}
xmlFreeImpl(ctxt as *mut c_void);
}
#[no_mangle]
pub unsafe extern "C" fn xmlXPathEvalExpression(
str_: *const xmlChar,
ctxt: *mut _xmlXPathContext,
) -> *mut _xmlXPathObject {
if str_.is_null() || ctxt.is_null() {
return ptr::null_mut();
}
let expr_str = match CStr::from_ptr(str_ as *const c_char).to_str() {
Ok(s) => s,
Err(_) => return ptr::null_mut(),
};
let internal = (*ctxt).extra as *mut XPathContext;
if internal.is_null() {
return ptr::null_mut();
}
let internal = &mut *internal;
internal.set_context_node((*ctxt).node);
internal.context_position = (*ctxt).proximityPosition;
internal.context_size = (*ctxt).contextSize;
internal.proximity_position = (*ctxt).proximityPosition;
crate::abi::exports_xml2::sync_xpath_context_namespaces(ctxt, internal);
internal.clear_error();
match crate::xml::xpath::evaluate_str(expr_str, internal) {
Some(val) => xpath_to_object(val),
None => {
raise_internal_xpath_error(ctxt, internal, expr_str);
ptr::null_mut()
}
}
}
pub(crate) unsafe fn raise_internal_xpath_error(
ctxt: *mut _xmlXPathContext,
internal: &mut XPathContext,
expr: &str,
) {
let (xpath_code, message) = match internal.error.as_deref() {
Some(m) if m.starts_with("Undefined namespace prefix") => (XPATH_UNDEF_PREFIX_ERROR, m),
Some(m) if m.starts_with("Unregistered function") => (XPATH_UNKNOWN_FUNC_ERROR, m),
Some(m) if m.starts_with("Undefined variable") => (XPATH_UNDEF_VARIABLE_ERROR, m),
Some(m) => (XPATH_EXPR_ERROR, m),
None => {
internal.set_error("Invalid expression");
(XPATH_EXPR_ERROR, "Invalid expression")
}
};
unsafe { raise_xpath_error(ctxt, xpath_code, message, expr) }
}
pub(crate) unsafe fn sync_xpath_context_namespaces(
ctxt: *mut _xmlXPathContext,
internal: &mut crate::xml::xpath::context::XPathContext,
) {
if ctxt.is_null() {
return;
}
unsafe {
let tab = (*ctxt).namespaces;
if tab.is_null() {
return;
}
let count = (*ctxt).nsNr;
if count <= 0 {
return;
}
let mut i = 0;
while i < count {
let ns = *tab.add(i as usize);
if !ns.is_null() && !(*ns).prefix.is_null() && !(*ns).href.is_null() {
let prefix_len = libc::strlen((*ns).prefix as *const libc::c_char) as usize;
let href_len = libc::strlen((*ns).href as *const libc::c_char) as usize;
let prefix =
String::from_utf8_lossy(core::slice::from_raw_parts((*ns).prefix, prefix_len))
.into_owned();
let href =
String::from_utf8_lossy(core::slice::from_raw_parts((*ns).href, href_len))
.into_owned();
internal.register_namespace(&prefix, &href);
}
i += 1;
}
}
}
pub(crate) unsafe fn raise_xpath_error(
ctxt: *mut _xmlXPathContext,
code: c_int,
message: &str,
expr: &str,
) {
unsafe {
use crate::xml::errors::{raise_error_streamed, GenericDelivery};
use crate::xml::globals;
let msg_c = CString::new(format!("{}\n", message)).unwrap_or_default();
let expr_c = CString::new(expr).unwrap_or_default();
let xerr_code = code + XML_XPATH_EXPRESSION_OK;
globals::free_error_strings(&(*ctxt).lastError);
let pre = _xmlError {
domain: XML_FROM_XPATH,
code: xerr_code,
message: ptr::null_mut(),
level: xmlErrorLevel::XML_ERR_ERROR as c_int,
file: ptr::null_mut(),
line: 0,
str1: xmlMemStrdupImpl(expr_c.as_ptr()) as *mut c_char,
str2: ptr::null_mut(),
str3: ptr::null_mut(),
int1: 0,
int2: 0,
ctxt: ctxt as *mut c_void,
node: (*ctxt).debugNode as *mut c_void,
};
ptr::write(&mut (*ctxt).lastError, pre);
let xslt_bound = {
let extra = (*ctxt).extra;
if extra.is_null() || !crate::xml::xpath::context::has_signature(extra) {
false
} else {
let internal: *mut crate::xml::xpath::context::XPathContext =
extra as *mut crate::xml::xpath::context::XPathContext;
!(*internal).func_lookup_data.is_null()
}
};
let xslt_global = crate::abi::data_globals::xsltGenericError;
let xslt_default = crate::abi::data_globals::xslt_default_generic_error_func()
.map_or(ptr::null(), |d| d as *const ());
if xslt_bound {
if let Some(g) = xslt_global {
if g as *const () != xslt_default {
let hv: unsafe extern "C" fn(*mut c_void, *const c_char, ...) =
core::mem::transmute(g);
hv(
crate::abi::data_globals::xsltGenericErrorContext,
c"%s".as_ptr() as *const c_char,
msg_c.as_ptr() as *const c_char,
);
return;
}
}
}
let delivery = match globals::get_generic_error_func() {
Some(f) => GenericDelivery::Custom(f, globals::get_generic_error_ctx()),
None => GenericDelivery::Stream,
};
raise_error_streamed(
ctxt as *mut c_void,
XML_FROM_XPATH,
xerr_code,
xmlErrorLevel::XML_ERR_ERROR as c_int,
ptr::null_mut(),
0,
0,
expr_c.as_ptr(),
ptr::null_mut(),
ptr::null_mut(),
0,
msg_c.as_ptr(),
None,
None,
delivery,
None,
);
}
}
#[no_mangle]
pub unsafe extern "C" fn xmlXPathEval(
str_: *const xmlChar,
ctxt: *mut _xmlXPathContext,
) -> *mut _xmlXPathObject {
xmlXPathEvalExpression(str_, ctxt)
}
#[no_mangle]
pub unsafe extern "C" fn xmlXPathFreeObject(obj: *mut _xmlXPathObject) {
if obj.is_null() {
return;
}
let typ = (*obj).type_;
if typ == xmlXPathObjectType::XPATH_STRING as c_int && !(*obj).stringval.is_null() {
xmlFreeImpl((*obj).stringval as *mut c_void);
(*obj).stringval = ptr::null_mut();
}
if typ == xmlXPathObjectType::XPATH_NODESET as c_int {
let ns = (*obj).nodesetval as *mut _xmlNodeSet;
if !ns.is_null() {
if !(*ns).nodeTab.is_null() {
xmlFreeImpl((*ns).nodeTab as *mut c_void);
}
xmlFreeImpl(ns as *mut c_void);
}
(*obj).nodesetval = ptr::null_mut();
}
xmlFreeImpl(obj as *mut c_void);
}
#[no_mangle]
pub unsafe extern "C" fn xmlXPathObjectCopy(val: *mut _xmlXPathObject) -> *mut _xmlXPathObject {
if val.is_null() {
return ptr::null_mut();
}
let typ = (*val).type_;
let obj = xmlMallocZero(size_of::<_xmlXPathObject>()) as *mut _xmlXPathObject;
if obj.is_null() {
return ptr::null_mut();
}
(*obj).type_ = typ;
if typ == xmlXPathObjectType::XPATH_NODESET as c_int {
let src_ns = (*val).nodesetval as *mut _xmlNodeSet;
if !src_ns.is_null() {
let nr = (*src_ns).nodeNr;
let ns = xmlMallocZero(size_of::<_xmlNodeSet>()) as *mut _xmlNodeSet;
if ns.is_null() {
xmlFreeImpl(obj as *mut c_void);
return ptr::null_mut();
}
(*ns).nodeNr = nr;
(*ns).nodeMax = nr;
if nr > 0 && !(*src_ns).nodeTab.is_null() {
let tab = xmlMallocImpl((nr as usize) * core::mem::size_of::<*mut _xmlNode>())
as *mut *mut _xmlNode;
if tab.is_null() {
xmlFreeImpl(ns as *mut c_void);
xmlFreeImpl(obj as *mut c_void);
return ptr::null_mut();
}
ptr::copy_nonoverlapping((*src_ns).nodeTab, tab, nr as usize);
(*ns).nodeTab = tab;
} else {
(*ns).nodeTab = ptr::null_mut();
}
(*obj).nodesetval = ns as *mut c_void;
}
} else if typ == xmlXPathObjectType::XPATH_BOOLEAN as c_int {
(*obj).boolval = (*val).boolval;
} else if typ == xmlXPathObjectType::XPATH_NUMBER as c_int {
(*obj).floatval = (*val).floatval;
} else if typ == xmlXPathObjectType::XPATH_STRING as c_int {
let src = (*val).stringval;
if !src.is_null() {
let len = libc::strlen(src as *const libc::c_char);
let buf = xmlMallocImpl(len + 1) as *mut xmlChar;
if !buf.is_null() {
ptr::copy_nonoverlapping(src, buf, len);
*buf.add(len) = 0;
}
(*obj).stringval = buf;
}
}
obj
}
#[no_mangle]
pub unsafe extern "C" fn xmlXPathCastToString(val: *mut _xmlXPathObject) -> *mut xmlChar {
if val.is_null() {
return ptr::null_mut();
}
let typ = (*val).type_;
let mut result: Vec<u8> = Vec::new();
if typ == xmlXPathObjectType::XPATH_STRING as c_int {
if !(*val).stringval.is_null() {
let len = libc::strlen((*val).stringval as *const libc::c_char);
result.extend_from_slice(core::slice::from_raw_parts((*val).stringval, len));
}
} else if typ == xmlXPathObjectType::XPATH_NUMBER as c_int {
let n = (*val).floatval;
result.extend_from_slice(xml_number_to_string(n).as_bytes());
} else if typ == xmlXPathObjectType::XPATH_BOOLEAN as c_int {
result.extend_from_slice(if (*val).boolval != 0 {
b"true"
} else {
b"false"
});
} else if typ == xmlXPathObjectType::XPATH_NODESET as c_int {
let ns = (*val).nodesetval as *mut _xmlNodeSet;
if !ns.is_null() && (*ns).nodeNr > 0 && !(*ns).nodeTab.is_null() {
let node = *(*ns).nodeTab;
if !node.is_null() {
let content = crate::xml::tree::node_get_content(node);
if !content.is_null() {
let len = libc::strlen(content as *const libc::c_char);
result.extend_from_slice(core::slice::from_raw_parts(content, len));
xmlFreeImpl(content as *mut c_void);
}
}
}
}
let buf = xmlMallocImpl(result.len() + 1) as *mut xmlChar;
if buf.is_null() {
return ptr::null_mut();
}
if !result.is_empty() {
ptr::copy_nonoverlapping(result.as_ptr(), buf, result.len());
}
*buf.add(result.len()) = 0;
buf
}
pub fn xml_number_to_string(n: f64) -> String {
crate::xml::xpath::types::number_to_string(n)
}
fn xpath_string_eval_number(bytes: &[u8]) -> f64 {
crate::xml::xpath::types::string_bytes_to_number(bytes)
}
#[no_mangle]
pub unsafe extern "C" fn xmlXPathCastStringToNumber(val: *const xmlChar) -> f64 {
if val.is_null() {
return f64::NAN;
}
let len = libc::strlen(val as *const libc::c_char);
let bytes = core::slice::from_raw_parts(val, len);
xpath_string_eval_number(bytes)
}
#[no_mangle]
pub unsafe extern "C" fn xmlXPathCmpNodes(node1: *mut _xmlNode, node2: *mut _xmlNode) -> c_int {
if node1.is_null() || node2.is_null() {
return -2;
}
if node1 == node2 {
return 0;
}
let mut chain1: Vec<*mut _xmlNode> = Vec::new();
let mut chain2: Vec<*mut _xmlNode> = Vec::new();
let mut n = node1;
while !n.is_null() {
chain1.push(n);
n = (*n).parent;
}
let mut n = node2;
while !n.is_null() {
chain2.push(n);
n = (*n).parent;
}
if chain1[chain1.len() - 1] != chain2[chain2.len() - 1] {
return -2;
}
let mut i = chain1.len();
let mut j = chain2.len();
while i > 0 && j > 0 && chain1[i - 1] == chain2[j - 1] {
i -= 1;
j -= 1;
}
if i == 0 {
return 1;
}
if j == 0 {
return -1;
}
let mut a = chain1[i - 1];
let mut b = chain2[j - 1];
while !a.is_null() && !b.is_null() {
let pa = (*a).parent;
let pb = (*b).parent;
if pa == pb {
break;
}
a = pa;
b = pb;
}
let parent = (*a).parent;
let mut child = if parent.is_null() {
ptr::null_mut()
} else {
(*parent).children
};
while !child.is_null() {
if child == a {
return 1; }
if child == b {
return -1; }
child = (*child).next;
}
0
}
#[no_mangle]
pub unsafe extern "C" fn xmlXPathNodeSetCreate(val: *mut _xmlNode) -> *mut _xmlNodeSet {
let ns = xmlMallocZero(size_of::<_xmlNodeSet>()) as *mut _xmlNodeSet;
if ns.is_null() {
return ptr::null_mut();
}
if val.is_null() {
return ns;
}
let tab = xmlMallocImpl(core::mem::size_of::<*mut _xmlNode>()) as *mut *mut _xmlNode;
if tab.is_null() {
xmlFreeImpl(ns as *mut c_void);
return ptr::null_mut();
}
*tab = val;
(*ns).nodeTab = tab;
(*ns).nodeNr = 1;
(*ns).nodeMax = 1;
ns
}
#[no_mangle]
pub unsafe extern "C" fn xmlXPathFreeNodeSet(ns: *mut _xmlNodeSet) {
if ns.is_null() {
return;
}
if !(*ns).nodeTab.is_null() {
xmlFreeImpl((*ns).nodeTab as *mut c_void);
(*ns).nodeTab = ptr::null_mut();
}
(*ns).nodeNr = 0;
(*ns).nodeMax = 0;
xmlFreeImpl(ns as *mut c_void);
}
pub(crate) fn xpath_compile_store(
expr_str: &str,
) -> Result<*mut c_void, crate::xml::xpath::parser::ParseError> {
match crate::xml::xpath::compile_result(expr_str) {
Ok(compiled) => {
let mut map = COMPILED_EXPRS.lock();
let mut counter = NEXT_COMPILED_KEY.lock();
let key = *counter;
*counter += 1;
map.insert(key, Box::new(compiled));
Ok(key as *mut c_void)
}
Err(e) => Err(e),
}
}
#[no_mangle]
pub unsafe extern "C" fn xmlXPathCompile(str_: *const xmlChar) -> *mut c_void {
if str_.is_null() {
return ptr::null_mut();
}
let expr_str = match CStr::from_ptr(str_ as *const c_char).to_str() {
Ok(s) => s,
Err(_) => return ptr::null_mut(),
};
match xpath_compile_store(expr_str) {
Ok(key) => key,
Err(e) => {
let msg_cstr = std::ffi::CString::new("Invalid expression\n").unwrap_or_default();
let expr_cstr = std::ffi::CString::new(expr_str).unwrap_or_default();
let off = e.pos;
let window = if off < 100 && off < expr_str.len() {
Some((expr_str.as_bytes(), off))
} else {
None
};
unsafe {
crate::xml::errors::raise_error_streamed(
ptr::null_mut(),
crate::abi::types::XML_FROM_XPATH,
crate::abi::types::XPATH_EXPR_ERROR
+ crate::abi::types::XML_XPATH_EXPRESSION_OK,
crate::abi::types::xmlErrorLevel::XML_ERR_ERROR as c_int,
ptr::null(),
0,
0,
expr_cstr.as_ptr(),
ptr::null(),
ptr::null(),
off as c_int,
msg_cstr.as_ptr(),
window,
None,
crate::xml::errors::GenericDelivery::Stream,
None,
);
}
ptr::null_mut()
}
}
}
#[no_mangle]
pub unsafe extern "C" fn xmlXPathFreeCompExpr(comp: *mut c_void) {
if comp.is_null() {
return;
}
let mut map = COMPILED_EXPRS.lock();
map.remove(&(comp as u64));
}
#[no_mangle]
pub unsafe extern "C" fn xmlXPathRegisterNs(
ctxt: *mut _xmlXPathContext,
prefix: *const xmlChar,
ns_uri: *const xmlChar,
) -> c_int {
if ctxt.is_null() || prefix.is_null() || ns_uri.is_null() {
return -1;
}
let internal = (*ctxt).extra as *mut XPathContext;
if internal.is_null() {
return -1;
}
let internal = &mut *internal;
let prefix_str = match CStr::from_ptr(prefix as *const c_char).to_str() {
Ok(s) => s,
Err(_) => return -1,
};
let uri_str = match CStr::from_ptr(ns_uri as *const c_char).to_str() {
Ok(s) => s,
Err(_) => return -1,
};
internal.register_namespace(prefix_str, uri_str);
if (*ctxt).nsHash.is_null() {
(*ctxt).nsHash = xmlHashCreate(10);
}
if !(*ctxt).nsHash.is_null() {
let uri_dup = crate::xml::string::xml_strdup(ns_uri);
let rc = xmlHashAddEntry((*ctxt).nsHash, prefix, uri_dup as *mut c_void);
if rc != 0 {
crate::abi::allocator::xmlFreeImpl(uri_dup as *mut c_void);
}
}
0
}
#[no_mangle]
pub unsafe extern "C" fn xmlXPathRegisterFunc(
ctxt: *mut _xmlXPathContext,
name: *const xmlChar,
f: Option<unsafe extern "C" fn(*mut c_void, c_int)>,
) -> c_int {
if ctxt.is_null() || name.is_null() {
return -1;
}
let internal = (*ctxt).extra as *mut XPathContext;
if internal.is_null() {
return -1;
}
let internal = &mut *internal;
let name_str = match CStr::from_ptr(name as *const c_char).to_str() {
Ok(s) => s,
Err(_) => return -1,
};
if let Some(func) = f {
let key = (SendSyncPtr((*ctxt).extra), name_str.to_string());
C_FUNCTIONS.lock().insert(key, func);
let c_ctxt = SendSyncPtr(ctxt as *mut c_void);
let name_owned = name_str.to_string();
internal.register_function(name_str, c_func_bridge_closure(c_ctxt, name_owned));
}
0
}
#[no_mangle]
pub unsafe extern "C" fn xmlXPathRegisterFuncNS(
ctxt: *mut _xmlXPathContext,
name: *const xmlChar,
ns_uri: *const xmlChar,
f: Option<unsafe extern "C" fn(*mut c_void, c_int)>,
) -> c_int {
if ctxt.is_null() || name.is_null() {
return -1;
}
let internal = (*ctxt).extra as *mut XPathContext;
if internal.is_null() {
return -1;
}
let internal = &mut *internal;
let name_str = match CStr::from_ptr(name as *const c_char).to_str() {
Ok(s) => s,
Err(_) => return -1,
};
let ns_str = if ns_uri.is_null() {
String::new()
} else {
match CStr::from_ptr(ns_uri as *const c_char).to_str() {
Ok(s) => s.to_string(),
Err(_) => return -1,
}
};
let qualified = if ns_str.is_empty() {
name_str.to_string()
} else {
format!("{{{}}}{}", ns_str, name_str)
};
if let Some(func) = f {
let key = (SendSyncPtr((*ctxt).extra), qualified.clone());
C_FUNCTIONS.lock().insert(key, func);
let c_ctxt = SendSyncPtr(ctxt as *mut c_void);
let qualified_owned = qualified.clone();
internal.register_function(&qualified, c_func_bridge_closure(c_ctxt, qualified_owned));
}
0
}
#[no_mangle]
pub unsafe extern "C" fn xmlXPathRegisterVariable(
ctxt: *mut _xmlXPathContext,
name: *const xmlChar,
value: *mut _xmlXPathObject,
) -> c_int {
if ctxt.is_null() || name.is_null() || value.is_null() {
return -1;
}
let internal = (*ctxt).extra as *mut XPathContext;
if internal.is_null() {
return -1;
}
let internal = &mut *internal;
let name_str = match CStr::from_ptr(name as *const c_char).to_str() {
Ok(s) => s,
Err(_) => return -1,
};
let xpath_val = object_to_xpathvalue(value);
internal.register_variable(name_str, xpath_val);
0
}
#[no_mangle]
pub unsafe extern "C" fn xmlXPathNewNodeSet(val: *mut _xmlNode) -> *mut _xmlXPathObject {
let ns = if val.is_null() {
NodeSet::new()
} else {
NodeSet::singleton(val)
};
xpath_to_object(XPathValue::NodeSet(ns))
}
#[no_mangle]
pub unsafe extern "C" fn xmlXPathNewCString(val: *const xmlChar) -> *mut _xmlXPathObject {
if val.is_null() {
return xpath_to_object(XPathValue::String(String::new()));
}
let s = match CStr::from_ptr(val as *const c_char).to_str() {
Ok(s) => s.to_string(),
Err(_) => return ptr::null_mut(),
};
xpath_to_object(XPathValue::String(s))
}
#[no_mangle]
pub extern "C" fn xmlXPathNewFloat(val: f64) -> *mut _xmlXPathObject {
unsafe { xpath_to_object(XPathValue::Number(val)) }
}
#[no_mangle]
pub extern "C" fn xmlXPathNewBoolean(val: c_int) -> *mut _xmlXPathObject {
unsafe { xpath_to_object(XPathValue::Boolean(val != 0)) }
}
#[no_mangle]
pub unsafe extern "C" fn xmlXPtrEval(expr: *const c_char, doc: *mut _xmlDoc) -> *mut _xmlNode {
crate::xml::xpointer::xmlXPtrEval(expr, doc)
}
#[no_mangle]
pub unsafe extern "C" fn xmlXIncludeProcess(doc: *mut _xmlDoc) -> c_int {
crate::xml::xinclude::xinclude_process(doc)
}
#[no_mangle]
pub unsafe extern "C" fn xmlXIncludeProcessFlags(doc: *mut _xmlDoc, flags: c_int) -> c_int {
crate::xml::xinclude::xinclude_process_flags(doc, flags)
}
#[no_mangle]
pub extern "C" fn xmlCatalogLoad(catalogs: *const c_char) -> *mut c_void {
if catalogs.is_null() {
return ptr::null_mut();
}
crate::xml::catalog::load_catalog(catalogs)
}
#[no_mangle]
pub unsafe extern "C" fn xmlCatalogResolvePublic(pubID: *const xmlChar) -> *mut xmlChar {
if pubID.is_null() {
return ptr::null_mut();
}
crate::xml::catalog::resolve_public(pubID)
}
#[no_mangle]
pub unsafe extern "C" fn xmlCatalogResolveSystem(sysID: *const xmlChar) -> *mut xmlChar {
if sysID.is_null() {
return ptr::null_mut();
}
crate::xml::catalog::resolve_system(sysID)
}
#[no_mangle]
pub unsafe extern "C" fn xmlCatalogResolveURI(URI: *const xmlChar) -> *mut xmlChar {
if URI.is_null() {
return ptr::null_mut();
}
crate::xml::catalog::resolve_uri(URI)
}
#[no_mangle]
pub extern "C" fn xmlCatalogSetDefaults(allow: c_int) {
crate::xml::catalog::set_defaults(allow)
}
#[no_mangle]
pub extern "C" fn xmlCatalogGetDefaults() -> c_int {
crate::xml::catalog::get_defaults()
}
#[no_mangle]
pub unsafe extern "C" fn xmlCatalogAdd(
type_: *const xmlChar,
orig: *const xmlChar,
replace: *const xmlChar,
) -> c_int {
if type_.is_null() || orig.is_null() || replace.is_null() {
return -1;
}
crate::xml::catalog::add(type_, orig, replace)
}
#[no_mangle]
pub unsafe extern "C" fn xmlCatalogRemove(value: *const xmlChar) -> c_int {
if value.is_null() {
return 0;
}
crate::xml::catalog::remove(value)
}
#[no_mangle]
pub unsafe extern "C" fn xmlCatalogDump(output: *mut c_void) {
if output.is_null() {
return;
}
let doc = crate::xml::catalog::dump_doc();
if doc.is_null() {
return;
}
let mut mem: *mut xmlChar = ptr::null_mut();
let mut size: c_int = 0;
crate::xml::tree::xmlDocDumpFormatMemory(doc, &mut mem, &mut size, 1);
if !mem.is_null() {
libc::fwrite(
mem as *const c_void,
1,
size as usize,
output as *mut libc::FILE,
);
xmlFreeImpl(mem as *mut c_void);
}
crate::xml::tree::free_doc(doc);
}
#[no_mangle]
pub unsafe extern "C" fn xmlCatalogSave(filename: *const c_char) -> c_int {
if filename.is_null() {
return -1;
}
let doc = crate::xml::catalog::dump_doc();
if doc.is_null() {
return -1;
}
let mut mem: *mut xmlChar = ptr::null_mut();
let mut size: c_int = 0;
crate::xml::tree::xmlDocDumpFormatMemory(doc, &mut mem, &mut size, 1);
let mut ret: c_int = -1;
if !mem.is_null() {
let fp = libc::fopen(filename, c"w".as_ptr() as *const c_char);
if !fp.is_null() {
let written = libc::fwrite(mem as *const c_void, 1, size as usize, fp);
ret = if written == size as usize { 0 } else { -1 };
libc::fclose(fp);
}
xmlFreeImpl(mem as *mut c_void);
}
crate::xml::tree::free_doc(doc);
ret
}
#[no_mangle]
pub extern "C" fn xmlCatalogCleanup() {
crate::xml::catalog::cleanup();
}
#[no_mangle]
pub extern "C" fn xmlCatalogConvert() -> c_int {
if !crate::xml::catalog::is_initialized() {
return -1;
}
0
}
#[no_mangle]
pub const unsafe extern "C" fn htmlParseFile(
_filename: *const c_char,
_encoding: *const c_char,
) -> *mut _xmlDoc {
ptr::null_mut()
}
#[no_mangle]
pub const unsafe extern "C" fn htmlParseMemory(
_buffer: *const c_char,
_size: c_int,
) -> *mut _xmlDoc {
ptr::null_mut()
}
#[no_mangle]
pub const unsafe extern "C" fn htmlParseDoc(
_cur: *const xmlChar,
_encoding: *const c_char,
) -> *mut _xmlDoc {
ptr::null_mut()
}
#[no_mangle]
pub extern "C" fn htmlFreeParserCtxt(ctxt: *mut c_void) {
unsafe { crate::xml::html::free_parser_ctxt(ctxt) }
}
#[no_mangle]
pub const extern "C" fn htmlInitParser() {
}
#[no_mangle]
pub const extern "C" fn htmlCleanupParser() {
}
#[no_mangle]
pub unsafe extern "C" fn xmlNewValidCtxt() -> *mut _xmlValidCtxt {
crate::xml::validation::new_valid_ctxt()
}
#[no_mangle]
pub unsafe extern "C" fn xmlFreeValidCtxt(ctxt: *mut _xmlValidCtxt) {
crate::xml::validation::free_valid_ctxt(ctxt);
}
#[no_mangle]
pub unsafe extern "C" fn xmlSetValidErrors(
ctxt: *mut _xmlValidCtxt,
err: Option<xmlGenericErrorFunc>,
warn: Option<xmlGenericErrorFunc>,
data: *mut c_void,
) {
crate::xml::validation::set_valid_errors(ctxt, err, warn, data);
}
#[no_mangle]
pub unsafe extern "C" fn xmlValidateDocument(ctxt: *mut _xmlValidCtxt, doc: *mut _xmlDoc) -> c_int {
crate::xml::validation::validate_document(ctxt, doc)
}
#[no_mangle]
pub unsafe extern "C" fn xmlValidateDocumentFinal(
ctxt: *mut _xmlValidCtxt,
doc: *mut _xmlDoc,
) -> c_int {
crate::xml::validation::validate_document_final(ctxt, doc)
}
#[no_mangle]
pub unsafe extern "C" fn xmlValidateElement(
ctxt: *mut _xmlValidCtxt,
doc: *mut _xmlDoc,
elem: *mut _xmlNode,
) -> c_int {
crate::xml::validation::validate_element(ctxt, doc, elem)
}
#[no_mangle]
pub unsafe extern "C" fn xmlValidateAttributeDecl(
ctxt: *mut _xmlValidCtxt,
doc: *mut _xmlDoc,
attr: *mut _xmlAttribute,
) -> c_int {
crate::xml::validation::validate_attribute_decl(ctxt, doc, attr)
}
#[no_mangle]
pub unsafe extern "C" fn xmlValidateAttributeValue(atype: c_int, value: *const xmlChar) -> c_int {
crate::xml::validation::validate_attribute_value(atype, value)
}
#[no_mangle]
pub unsafe extern "C" fn xmlValidateNotationUse(
ctxt: *mut _xmlValidCtxt,
doc: *mut _xmlDoc,
notation_name: *const xmlChar,
) -> c_int {
crate::xml::validation::validate_notation_use(ctxt, doc, notation_name)
}
#[no_mangle]
pub unsafe extern "C" fn xmlValidateID(
ctxt: *mut _xmlValidCtxt,
doc: *mut _xmlDoc,
node: *mut _xmlNode,
value: *const xmlChar,
) -> c_int {
crate::xml::validation::validate_id(ctxt, doc, node, value)
}
#[no_mangle]
pub unsafe extern "C" fn xmlValidateIDRef(
ctxt: *mut _xmlValidCtxt,
doc: *mut _xmlDoc,
value: *const xmlChar,
) -> c_int {
crate::xml::validation::validate_id_ref(ctxt, doc, ptr::null_mut(), value)
}
#[no_mangle]
pub unsafe extern "C" fn xmlValidateIDRefs(
ctxt: *mut _xmlValidCtxt,
doc: *mut _xmlDoc,
value: *const xmlChar,
) -> c_int {
crate::xml::validation::validate_id_refs(ctxt, doc, ptr::null_mut(), value)
}
#[no_mangle]
pub unsafe extern "C" fn xmlValidateNCName(value: *const xmlChar, space: c_int) -> c_int {
crate::xml::validation::validate_ncname(value, space)
}
#[no_mangle]
pub unsafe extern "C" fn xmlValidateQName(value: *const xmlChar, space: c_int) -> c_int {
crate::xml::validation::validate_qname(value, space)
}
#[no_mangle]
pub unsafe extern "C" fn xmlValidateName(value: *const xmlChar, space: c_int) -> c_int {
crate::xml::validation::validate_name_space(value, space)
}
#[no_mangle]
pub unsafe extern "C" fn xmlValidateNMToken(value: *const xmlChar, space: c_int) -> c_int {
crate::xml::validation::validate_nmtoken_space(value, space)
}
#[no_mangle]
pub unsafe extern "C" fn xmlValidateNameValue(value: *const xmlChar) -> c_int {
crate::xml::validation::validate_name_value(value)
}
#[no_mangle]
pub unsafe extern "C" fn xmlValidateNamesValue(value: *const xmlChar) -> c_int {
crate::xml::validation::validate_names_value(value)
}
#[no_mangle]
pub unsafe extern "C" fn xmlValidateNmtokenValue(value: *const xmlChar) -> c_int {
crate::xml::validation::validate_nmtoken_value(value)
}
#[no_mangle]
pub unsafe extern "C" fn xmlValidateNmtokensValue(value: *const xmlChar) -> c_int {
crate::xml::validation::validate_nmtokens_value(value)
}
#[no_mangle]
pub unsafe extern "C" fn xmlValidateElementDecl(
ctxt: *mut _xmlValidCtxt,
doc: *mut _xmlDoc,
elem: *mut _xmlElement,
) -> c_int {
crate::xml::validation::validate_element_decl(ctxt, doc, elem)
}
#[no_mangle]
pub const unsafe extern "C" fn xmlValidateNotationDecl(
ctxt: *mut _xmlValidCtxt,
doc: *mut _xmlDoc,
nota: *mut _xmlNotation,
) -> c_int {
crate::xml::validation::validate_notation_decl(ctxt, doc, nota)
}
#[no_mangle]
pub unsafe extern "C" fn xmlValidateOneAttribute(
ctxt: *mut _xmlValidCtxt,
doc: *mut _xmlDoc,
elem: *mut _xmlNode,
attr: *mut _xmlAttr,
value: *const xmlChar,
) -> c_int {
crate::xml::validation::validate_one_attribute(ctxt, doc, elem, attr, value)
}
#[no_mangle]
pub unsafe extern "C" fn xmlValidateOneElement(
ctxt: *mut _xmlValidCtxt,
doc: *mut _xmlDoc,
elem: *mut _xmlNode,
) -> c_int {
crate::xml::validation::validate_one_element(ctxt, doc, elem)
}
#[no_mangle]
pub unsafe extern "C" fn xmlValidateOneNamespace(
ctxt: *mut _xmlValidCtxt,
doc: *mut _xmlDoc,
elem: *mut _xmlNode,
prefix: *const xmlChar,
ns: *mut _xmlNs,
value: *const xmlChar,
) -> c_int {
crate::xml::validation::validate_one_namespace(ctxt, doc, elem, prefix, ns, value)
}
#[no_mangle]
pub unsafe extern "C" fn xmlValidatePushElement(
ctxt: *mut _xmlValidCtxt,
doc: *mut _xmlDoc,
elem: *mut _xmlNode,
qname: *const xmlChar,
) -> c_int {
crate::xml::validation::validate_push_element(ctxt, doc, elem, qname)
}
#[no_mangle]
pub unsafe extern "C" fn xmlValidatePushCData(
ctxt: *mut _xmlValidCtxt,
data: *const xmlChar,
len: c_int,
) -> c_int {
crate::xml::validation::validate_push_cdata(ctxt, data, len)
}
#[no_mangle]
pub unsafe extern "C" fn xmlValidatePopElement(
ctxt: *mut _xmlValidCtxt,
doc: *mut _xmlDoc,
elem: *mut _xmlNode,
qname: *const xmlChar,
) -> c_int {
crate::xml::validation::validate_pop_element(ctxt, doc, elem, qname)
}
#[no_mangle]
pub unsafe extern "C" fn xmlValidBuildContentModel(
ctxt: *mut _xmlValidCtxt,
elem: *mut _xmlElement,
) -> c_int {
crate::xml::validation::validate_build_content_model(ctxt, elem)
}
#[no_mangle]
pub unsafe extern "C" fn xmlAddID(
ctxt: *mut _xmlValidCtxt,
doc: *mut _xmlDoc,
value: *const xmlChar,
attr: *mut _xmlAttr,
) -> *mut _xmlID {
crate::xml::validation::add_id(ctxt, doc, value, attr)
}
#[no_mangle]
pub unsafe extern "C" fn xmlRemoveID(doc: *mut _xmlDoc, attr: *mut _xmlAttr) -> c_int {
crate::xml::validation::remove_id(doc, attr)
}
#[no_mangle]
pub unsafe extern "C" fn xmlAddRef(
ctxt: *mut _xmlValidCtxt,
doc: *mut _xmlDoc,
value: *const xmlChar,
attr: *mut _xmlAttr,
) -> *mut _xmlRef {
crate::xml::validation::add_ref(ctxt, doc, value, attr)
}
#[no_mangle]
pub unsafe extern "C" fn xmlRemoveRef(doc: *mut _xmlDoc, attr: *mut _xmlAttr) -> c_int {
crate::xml::validation::remove_ref(doc, attr)
}
#[no_mangle]
pub unsafe extern "C" fn xmlAddIDSafe(attr: *mut _xmlAttr, value: *const xmlChar) -> c_int {
crate::xml::validation::add_id_safe(attr, value)
}
#[no_mangle]
pub unsafe extern "C" fn xmlFreeIDTable(table: *mut c_void) {
crate::xml::validation::free_id_table(table as *mut crate::xml::hash::HashTable);
}
#[no_mangle]
pub unsafe extern "C" fn xmlFreeRefTable(table: *mut c_void) {
crate::xml::validation::free_ref_table(table as *mut crate::xml::hash::HashTable);
}
#[no_mangle]
pub unsafe extern "C" fn xmlGetID(doc: *mut _xmlDoc, id: *const xmlChar) -> *mut _xmlAttr {
crate::xml::validation::get_id(doc, id)
}
#[no_mangle]
pub unsafe extern "C" fn xmlGetRefs(doc: *mut _xmlDoc, id: *const xmlChar) -> *mut c_void {
crate::xml::validation::get_refs(doc, id) as *mut c_void
}
#[no_mangle]
pub unsafe extern "C" fn xmlIsID(
doc: *mut _xmlDoc,
elem: *mut _xmlNode,
attr: *mut _xmlAttr,
) -> c_int {
crate::xml::validation::is_id(doc, elem, attr)
}
#[no_mangle]
pub unsafe extern "C" fn xmlIsRef(
doc: *mut _xmlDoc,
elem: *mut _xmlNode,
attr: *mut _xmlAttr,
) -> c_int {
crate::xml::validation::is_ref(doc, elem, attr)
}
#[no_mangle]
pub unsafe extern "C" fn xmlGetDtdElementDesc(
dtd: *mut _xmlDtd,
name: *const xmlChar,
) -> *mut _xmlElement {
crate::xml::validation::get_dtd_element_desc(dtd, name)
}
#[no_mangle]
pub unsafe extern "C" fn xmlGetDtdAttrDesc(
dtd: *mut _xmlDtd,
elem: *const xmlChar,
name: *const xmlChar,
) -> *mut _xmlAttribute {
crate::xml::validation::get_dtd_attr_desc(dtd, elem, name)
}
#[no_mangle]
pub unsafe extern "C" fn xmlGetDtdQElementDesc(
dtd: *mut _xmlDtd,
name: *const xmlChar,
prefix: *const xmlChar,
) -> *mut _xmlElement {
crate::xml::validation::get_dtd_qelement_desc(dtd, name, prefix)
}
#[no_mangle]
pub unsafe extern "C" fn xmlGetDtdQAttrDesc(
dtd: *mut _xmlDtd,
elem: *const xmlChar,
name: *const xmlChar,
prefix: *const xmlChar,
) -> *mut _xmlAttribute {
crate::xml::validation::get_dtd_qattr_desc(dtd, elem, name, prefix)
}
#[no_mangle]
pub unsafe extern "C" fn xmlGetDtdNotationDesc(
dtd: *mut _xmlDtd,
name: *const xmlChar,
) -> *mut _xmlNotation {
crate::xml::validation::get_dtd_notation_desc(dtd, name)
}
#[no_mangle]
pub unsafe extern "C" fn xmlValidateRoot(ctxt: *mut _xmlValidCtxt, doc: *mut _xmlDoc) -> c_int {
crate::xml::validation::validate_root(ctxt, doc)
}
#[no_mangle]
pub unsafe extern "C" fn xmlValidateContent(
ctxt: *mut _xmlValidCtxt,
node: *mut _xmlNode,
doc: *mut _xmlDoc,
) -> c_int {
crate::xml::validation::validate_content(ctxt, node, doc)
}
#[no_mangle]
pub unsafe extern "C" fn xmlIsMixedElement(doc: *mut _xmlDoc, name: *const xmlChar) -> c_int {
crate::xml::validation::is_mixed_element(doc, name)
}
#[no_mangle]
pub unsafe extern "C" fn xmlIsEmptyElement(doc: *mut _xmlDoc, name: *const xmlChar) -> c_int {
crate::xml::validation::is_empty_element(doc, name)
}
#[no_mangle]
pub unsafe extern "C" fn xmlValidateDtd(
ctxt: *mut _xmlValidCtxt,
doc: *mut _xmlDoc,
dtd: *mut _xmlDtd,
) -> c_int {
crate::xml::validation::validate_dtd(ctxt, doc, dtd)
}
#[no_mangle]
pub unsafe extern "C" fn xmlValidateDtdFinal(ctxt: *mut _xmlValidCtxt, doc: *mut _xmlDoc) -> c_int {
crate::xml::validation::validate_dtd_final(ctxt, doc)
}
#[no_mangle]
pub unsafe extern "C" fn xmlValidateEnumeration(
ctxt: *mut _xmlValidCtxt,
value: *const xmlChar,
tree: *mut _xmlEnumeration,
) -> c_int {
crate::xml::validation::validate_enumeration(ctxt, value, tree)
}
#[no_mangle]
pub const extern "C" fn xmlGetBinaryPath() -> *mut c_char {
ptr::null_mut()
}
#[no_mangle]
pub const extern "C" fn xmlGetHomeOfBinary() -> *mut c_char {
ptr::null_mut()
}
#[no_mangle]
pub unsafe extern "C" fn xmlSAX2StartDocument(ctx: *mut c_void) {
crate::xml::sax::default::default_sax_handler::startDocument(ctx)
}
#[no_mangle]
pub unsafe extern "C" fn xmlSAX2EndDocument(ctx: *mut c_void) {
crate::xml::sax::default::default_sax_handler::endDocument(ctx)
}
#[no_mangle]
pub unsafe extern "C" fn xmlSAX2StartElementNs(
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,
) {
crate::xml::sax::default::default_sax_handler::startElementNs(
ctx,
localname,
prefix,
URI,
nb_namespaces,
namespaces,
nb_attributes,
nb_defaulted,
attributes,
)
}
#[no_mangle]
pub unsafe extern "C" fn xmlSAX2EndElementNs(
ctx: *mut c_void,
localname: *const xmlChar,
prefix: *const xmlChar,
URI: *const xmlChar,
) {
crate::xml::sax::default::default_sax_handler::endElementNs(ctx, localname, prefix, URI)
}
#[no_mangle]
pub unsafe extern "C" fn xmlSAX2Characters(ctx: *mut c_void, ch: *const xmlChar, len: c_int) {
crate::xml::sax::default::default_sax_handler::characters(ctx, ch, len)
}
#[no_mangle]
pub unsafe extern "C" fn xmlSAX2IgnorableWhitespace(
ctx: *mut c_void,
ch: *const xmlChar,
len: c_int,
) {
crate::xml::sax::default::default_sax_handler::ignorableWhitespace(ctx, ch, len)
}
#[no_mangle]
pub unsafe extern "C" fn xmlSAX2Comment(ctx: *mut c_void, value: *const xmlChar) {
crate::xml::sax::default::default_sax_handler::comment(ctx, value)
}
#[no_mangle]
pub unsafe extern "C" fn xmlSAX2ProcessingInstruction(
ctx: *mut c_void,
target: *const xmlChar,
data: *const xmlChar,
) {
crate::xml::sax::default::default_sax_handler::processingInstruction(ctx, target, data)
}
#[no_mangle]
pub unsafe extern "C" fn xmlSAX2CDataBlock(ctx: *mut c_void, value: *const xmlChar, len: c_int) {
crate::xml::sax::default::default_sax_handler::cdataBlock(ctx, value, len)
}
#[no_mangle]
pub unsafe extern "C" fn xmlSAX2InternalSubset(
ctx: *mut c_void,
name: *const xmlChar,
ExternalID: *const xmlChar,
SystemID: *const xmlChar,
) {
crate::xml::sax::default::default_sax_handler::internalSubset(ctx, name, ExternalID, SystemID)
}
#[no_mangle]
pub unsafe extern "C" fn xmlSAX2ExternalSubset(
ctx: *mut c_void,
name: *const xmlChar,
ExternalID: *const xmlChar,
SystemID: *const xmlChar,
) {
crate::xml::sax::default::default_sax_handler::externalSubset(ctx, name, ExternalID, SystemID)
}
#[no_mangle]
pub unsafe extern "C" fn xmlSAX2EntityDecl(
ctx: *mut c_void,
name: *const xmlChar,
type_: c_int,
publicId: *const xmlChar,
systemId: *const xmlChar,
content: *mut xmlChar,
) {
crate::xml::sax::default::default_sax_handler::entityDecl(
ctx, name, type_, publicId, systemId, content,
)
}
#[no_mangle]
pub const unsafe extern "C" fn xmlSAX2AttributeDecl(
ctx: *mut c_void,
elem: *const xmlChar,
fullname: *const xmlChar,
type_: c_int,
def: c_int,
defaultValue: *const xmlChar,
tree: *mut crate::abi::structs::_xmlEnumeration,
) {
crate::xml::sax::default::default_sax_handler::attributeDecl(
ctx,
elem,
fullname,
type_,
def,
defaultValue,
tree,
)
}
#[no_mangle]
pub const unsafe extern "C" fn xmlSAX2ElementDecl(
ctx: *mut c_void,
name: *const xmlChar,
type_: c_int,
content: *mut crate::abi::structs::_xmlElementContent,
) {
crate::xml::sax::default::default_sax_handler::elementDecl(ctx, name, type_, content)
}
#[no_mangle]
pub const unsafe extern "C" fn xmlSAX2NotationDecl(
ctx: *mut c_void,
name: *const xmlChar,
publicId: *const xmlChar,
systemId: *const xmlChar,
) {
crate::xml::sax::default::default_sax_handler::notationDecl(ctx, name, publicId, systemId)
}
#[no_mangle]
pub const unsafe extern "C" fn xmlSAX2UnparsedEntityDecl(
ctx: *mut c_void,
name: *const xmlChar,
publicId: *const xmlChar,
systemId: *const xmlChar,
notationName: *const xmlChar,
) {
crate::xml::sax::default::default_sax_handler::unparsedEntityDecl(
ctx,
name,
publicId,
systemId,
notationName,
)
}
#[no_mangle]
pub const unsafe extern "C" fn xmlSAX2ResolveEntity(
ctx: *mut c_void,
publicId: *const xmlChar,
systemId: *const xmlChar,
) -> *mut crate::abi::structs::_xmlParserInput {
crate::xml::sax::default::default_sax_handler::resolveEntity(ctx, publicId, systemId)
}
#[no_mangle]
pub const unsafe extern "C" fn xmlSAX2IsStandalone(ctx: *mut c_void) -> c_int {
crate::xml::sax::default::default_sax_handler::isStandalone(ctx)
}
#[no_mangle]
pub unsafe extern "C" fn xmlSAX2HasInternalSubset(ctx: *mut c_void) -> c_int {
crate::xml::sax::default::default_sax_handler::hasInternalSubset(ctx)
}
#[no_mangle]
pub unsafe extern "C" fn xmlSAX2HasExternalSubset(ctx: *mut c_void) -> c_int {
crate::xml::sax::default::default_sax_handler::hasExternalSubset(ctx)
}
#[no_mangle]
pub unsafe extern "C" fn xmlSAX2GetEntity(
ctx: *mut c_void,
name: *const xmlChar,
) -> *mut crate::abi::structs::_xmlEntity {
crate::xml::sax::default::default_sax_handler::getEntity(ctx, name)
}
#[no_mangle]
pub unsafe extern "C" fn xmlSAX2GetParameterEntity(
ctx: *mut c_void,
name: *const xmlChar,
) -> *mut crate::abi::structs::_xmlEntity {
crate::xml::sax::default::default_sax_handler::getParameterEntity(ctx, name)
}
#[no_mangle]
pub unsafe extern "C" fn xmlSAX2GetLineNumber(ctx: *mut c_void) -> c_int {
crate::xml::sax::default::default_sax_handler::getLineNumber(ctx)
}
#[no_mangle]
pub unsafe extern "C" fn xmlSAX2GetColumnNumber(ctx: *mut c_void) -> c_int {
crate::xml::sax::default::default_sax_handler::getColumnNumber(ctx)
}
#[no_mangle]
pub const unsafe extern "C" fn xmlSAX2GetPublicId(ctx: *mut c_void) -> *const xmlChar {
crate::xml::sax::default::default_sax_handler::getPublicId(ctx)
}
#[no_mangle]
pub unsafe extern "C" fn xmlSAX2GetSystemId(ctx: *mut c_void) -> *const xmlChar {
crate::xml::sax::default::default_sax_handler::getSystemId(ctx)
}
#[no_mangle]
pub unsafe extern "C" fn xmlSAX2StartElement(
ctx: *mut c_void,
name: *const xmlChar,
atts: *mut *const xmlChar,
) {
crate::xml::sax::dispatch::SaxDispatcher::sax1_start_element(ctx, name, atts);
}
#[no_mangle]
pub unsafe extern "C" fn xmlSAX2EndElement(ctx: *mut c_void, name: *const xmlChar) {
crate::xml::sax::dispatch::SaxDispatcher::sax1_end_element(ctx, name);
}
#[no_mangle]
pub const unsafe extern "C" fn xmlSAX2SetDocumentLocator(
ctx: *mut c_void,
loc: *mut crate::abi::callbacks::_xmlSAXLocator,
) {
crate::xml::sax::default::default_sax_handler::setDocumentLocator(ctx, loc)
}
#[no_mangle]
pub unsafe extern "C" fn xmlSAX2Reference(ctx: *mut c_void, name: *const xmlChar) {
crate::xml::sax::default::default_sax_handler::reference(ctx, name)
}
#[cfg(test)]
mod tests {
use super::xml_number_to_string;
#[allow(clippy::approx_constant)]
#[test]
fn test_xml_number_to_string_parity_cases() {
let cases: &[(f64, &str)] = &[
(1234567.891, "1234567.891"),
(0.1 + 0.2, "0.3"),
(1.0 / 3.0, "0.333333333333333"),
(1e20, "1e+20"),
(1e-5, "0.00001"),
(123456789012345678901234567890.0, "1.23456789012346e+29"),
(1e100, "1e+100"),
(-1e100, "-1e+100"),
(1.5e-100, "1.5e-100"),
(1e9, "1000000000"),
(0.00001, "0.00001"),
(9.99e-6, "9.99e-06"),
(2147483646.0, "2147483646"),
(2147483648.0, "2.147483648e+09"),
(-2147483647.0, "-2147483647"),
(-2147483649.0, "-2.147483649e+09"),
(0.5, "0.5"),
(1.0 / 7.0, "0.142857142857143"),
(2.675, "2.675"),
(3.141592653589793, "3.141592653589793"),
(-0.0, "0"),
(0.0, "0"),
(f64::INFINITY, "Infinity"),
(f64::NEG_INFINITY, "-Infinity"),
(f64::NAN, "NaN"),
(0.30000000000000004, "0.3"),
(2.2250738585072014e-308, "2.2250738585072e-308"),
(5e-324, "4.94065645841247e-324"),
];
for (n, expected) in cases {
assert_eq!(&xml_number_to_string(*n), expected, "value: {}", n);
}
}
#[test]
fn test_xml_new_child_with_content() {
unsafe {
let doc =
crate::xml::tree::new_doc(c"1.0".as_ptr() as *const crate::abi::types::xmlChar);
assert!(!doc.is_null());
let root = crate::xml::tree::new_node(
core::ptr::null_mut(),
c"root".as_ptr() as *const crate::abi::types::xmlChar,
);
assert!(!root.is_null());
crate::xml::tree::doc_set_root_element(doc, root);
let child = super::xmlNewChild(
root,
core::ptr::null_mut(),
c"node1".as_ptr() as *const crate::abi::types::xmlChar,
c"content of node 1".as_ptr() as *const crate::abi::types::xmlChar,
);
assert!(!child.is_null());
assert!(
!(*child).children.is_null(),
"content must become a text child"
);
assert_eq!(
crate::abi::types::xmlElementType::XML_TEXT_NODE as i32,
(*(*child).children).type_
);
let text = crate::xml::string::xmlstr_to_bytes((*(*child).children).content);
assert_eq!(text, b"content of node 1");
let empty = super::xmlNewChild(
root,
core::ptr::null_mut(),
c"node2".as_ptr() as *const crate::abi::types::xmlChar,
core::ptr::null(),
);
assert!(!empty.is_null());
assert!((*empty).children.is_null());
crate::xml::tree::free_doc(doc);
}
}
#[test]
fn test_xml_new_child_parses_content_as_att_value() {
unsafe {
let doc =
crate::xml::tree::new_doc(c"1.0".as_ptr() as *const crate::abi::types::xmlChar);
assert!(!doc.is_null());
let root = crate::xml::tree::new_node(
core::ptr::null_mut(),
c"root".as_ptr() as *const crate::abi::types::xmlChar,
);
assert!(!root.is_null());
crate::xml::tree::doc_set_root_element(doc, root);
let e = super::xmlNewChild(
root,
core::ptr::null_mut(),
c"empty".as_ptr() as *const crate::abi::types::xmlChar,
c"".as_ptr() as *const crate::abi::types::xmlChar,
);
assert!(!e.is_null());
assert!(
(*e).children.is_null(),
"empty content must not add a text child"
);
let r = super::xmlNewChild(
root,
core::ptr::null_mut(),
c"ref".as_ptr() as *const crate::abi::types::xmlChar,
c"a & b".as_ptr() as *const crate::abi::types::xmlChar,
);
assert!(!r.is_null());
assert!(!(*r).children.is_null());
let txt = crate::xml::string::xmlstr_to_bytes((*(*r).children).content);
assert_eq!(txt, b"a & b");
let b = super::xmlNewChild(
root,
core::ptr::null_mut(),
c"bare".as_ptr() as *const crate::abi::types::xmlChar,
c"x & y".as_ptr() as *const crate::abi::types::xmlChar,
);
assert!(!b.is_null());
assert!(!(*b).children.is_null());
let txt = crate::xml::string::xmlstr_to_bytes((*(*b).children).content);
assert_eq!(txt, b"x y");
crate::xml::tree::free_doc(doc);
}
}
#[test]
fn test_xml_free_prop_preserves_dict_interned_attr_name() {
unsafe {
use crate::abi::allocator::xmlMallocZero;
use crate::abi::structs::{_xmlAttr, _xmlNode};
use core::mem::size_of;
let dict = super::xmlDictCreate();
assert!(!dict.is_null());
let doc =
crate::xml::tree::new_doc(c"1.0".as_ptr() as *const crate::abi::types::xmlChar);
assert!(!doc.is_null());
(*doc).dict = dict;
let root = crate::xml::tree::new_node(
core::ptr::null_mut(),
c"root".as_ptr() as *const crate::abi::types::xmlChar,
);
assert!(!root.is_null());
crate::xml::tree::doc_set_root_element(doc, root);
let iname = super::xmlDictLookup(
dict,
c"id".as_ptr() as *const crate::abi::types::xmlChar,
-1,
);
assert!(!iname.is_null());
let attr = xmlMallocZero(size_of::<_xmlAttr>()) as *mut _xmlAttr;
assert!(!attr.is_null());
(*attr).type_ = crate::abi::types::xmlElementType::XML_ATTRIBUTE_NODE as i32;
(*attr).name = iname as *mut crate::abi::types::xmlChar;
(*attr).parent = root;
(*attr).doc = doc;
(*root).properties = attr;
crate::xml::tree::unlink_node(attr as *mut _xmlNode);
crate::abi::exports_tree::xmlFreeProp(attr);
crate::xml::tree::free_doc(doc);
}
}
#[test]
fn test_nodelist_getstring_empty_from_element_chain() {
unsafe {
let doc =
crate::xml::tree::new_doc(c"1.0".as_ptr() as *const crate::abi::types::xmlChar);
assert!(!doc.is_null());
let root = crate::xml::tree::new_node(
core::ptr::null_mut(),
c"people".as_ptr() as *const crate::abi::types::xmlChar,
);
assert!(!root.is_null());
crate::xml::tree::doc_set_root_element(doc, root);
let person = crate::abi::exports_tree::xmlNewTextChild(
root,
core::ptr::null_mut(),
c"person".as_ptr() as *const crate::abi::types::xmlChar,
c"Joe".as_ptr() as *const crate::abi::types::xmlChar,
);
assert!(!person.is_null());
super::xmlSetProp(
person,
c"gender".as_ptr() as *const crate::abi::types::xmlChar,
c"male".as_ptr() as *const crate::abi::types::xmlChar,
);
let s1 = crate::abi::exports_treedump::xmlNodeListGetString(doc, (*root).children, 1);
assert!(!s1.is_null());
assert_eq!(*s1 as u8, 0);
crate::abi::allocator::xmlFreeImpl(s1 as *mut core::ffi::c_void);
let s2 = crate::abi::exports_treedump::xmlNodeListGetString(doc, (*person).children, 1);
assert!(!s2.is_null());
let b = crate::xml::string::xmlstr_to_bytes(s2);
assert_eq!(b, b"Joe");
crate::abi::allocator::xmlFreeImpl(s2 as *mut core::ffi::c_void);
crate::xml::tree::free_doc(doc);
}
}
#[test]
fn test_xpath_compile_error_verbatim_to_generic_channel() {
use crate::abi::callbacks::xmlGenericErrorFunc;
use core::ffi::{c_char, c_void};
let _guard = crate::xml::globals::ERROR_HANDLER_TEST_LOCK.lock();
unsafe {
let mut captured: Vec<u8> = Vec::new();
let captured_ptr = &mut captured as *mut Vec<u8> as *mut c_void;
unsafe extern "C" fn record(ctx: *mut c_void, msg: *const c_char) {
if msg.is_null() {
return;
}
let out = &mut *(ctx as *mut Vec<u8>);
let bytes = std::ffi::CStr::from_ptr(msg).to_bytes();
out.extend_from_slice(bytes);
}
super::xmlSetGenericErrorFunc(captured_ptr, Some(record as xmlGenericErrorFunc));
let doc =
crate::xml::tree::new_doc(c"1.0".as_ptr() as *const crate::abi::types::xmlChar);
assert!(!doc.is_null());
let ctxt = super::xmlXPathNewContext(doc);
assert!(!ctxt.is_null());
(*ctxt).error = None;
let comp = crate::xml::xpath::exports::xmlXPathCtxtCompile(
ctxt,
c"**".as_ptr() as *const crate::abi::types::xmlChar,
);
assert!(comp.is_null(), "`**` must fail to compile");
assert_eq!(
captured, b"Invalid expression\n",
"generic channel must receive the raw message, no \"XPath error : \" prefix"
);
super::xmlSetGenericErrorFunc(core::ptr::null_mut(), None);
super::xmlXPathFreeContext(ctxt);
crate::xml::tree::free_doc(doc);
}
}
#[test]
fn test_copies_do_not_carry_private() {
unsafe {
let doc =
crate::xml::tree::new_doc(c"1.0".as_ptr() as *const crate::abi::types::xmlChar);
assert!(!doc.is_null());
let root = crate::xml::tree::new_node(
core::ptr::null_mut(),
c"a".as_ptr() as *const crate::abi::types::xmlChar,
);
assert!(!root.is_null());
crate::xml::tree::doc_set_root_element(doc, root);
let marker: usize = 0x5A5A;
(*root)._private = marker as *mut core::ffi::c_void;
let cdoc = super::xmlCopyDoc(doc, 1);
assert!(!cdoc.is_null());
let croot = (*cdoc).children;
assert!(!croot.is_null());
assert!(
(*croot)._private.is_null(),
"xmlCopyDoc must not carry the source node _private"
);
assert_eq!(
(*root)._private as usize,
marker,
"source _private is untouched"
);
crate::xml::tree::free_doc(cdoc);
let copy = crate::abi::exports_treedump::xmlDocCopyNode(root, doc, 1);
assert!(!copy.is_null());
assert!(
(*copy)._private.is_null(),
"xmlDocCopyNode must not carry the source node's _private"
);
super::xmlFreeNode(copy);
crate::xml::tree::free_doc(doc);
}
}
#[test]
fn test_c_xpath_function_bridge_exposes_function_and_uri() {
unsafe {
use crate::xml::xpath::exports::{xmlXPathNewString, xmlXPathValuePush};
use crate::xml::xpath::parser_context::XmlXPathParserContext;
use std::os::raw::{c_char, c_int};
unsafe extern "C" fn capture_identity(ctxt: *mut core::ffi::c_void, _nargs: c_int) {
let pc = ctxt as *mut XmlXPathParserContext;
let ctx = (*pc).context;
assert!(!ctx.is_null());
let name = (*ctx).function;
let uri = (*ctx).functionURI;
assert!(!name.is_null());
let name_s = std::ffi::CStr::from_ptr(name as *const c_char)
.to_string_lossy()
.into_owned();
let uri_s = if uri.is_null() {
"(null)".to_string()
} else {
std::ffi::CStr::from_ptr(uri as *const c_char)
.to_string_lossy()
.into_owned()
};
let out = std::ffi::CString::new(format!("{}@{}", name_s, uri_s)).unwrap();
let obj = xmlXPathNewString(out.as_ptr() as *const crate::abi::types::xmlChar);
assert!(!obj.is_null());
assert_eq!(xmlXPathValuePush(ctxt, obj), 0);
}
let doc =
crate::xml::tree::new_doc(c"1.0".as_ptr() as *const crate::abi::types::xmlChar);
assert!(!doc.is_null());
let ctxt = super::xmlXPathNewContext(doc);
assert!(!ctxt.is_null());
super::xmlXPathRegisterNs(
ctxt,
c"t".as_ptr() as *const crate::abi::types::xmlChar,
c"urn:t".as_ptr() as *const crate::abi::types::xmlChar,
);
super::xmlXPathRegisterFuncNS(
ctxt,
c"capture".as_ptr() as *const crate::abi::types::xmlChar,
c"urn:t".as_ptr() as *const crate::abi::types::xmlChar,
Some(capture_identity),
);
let res = super::xmlXPathEvalExpression(
c"t:capture()".as_ptr() as *const crate::abi::types::xmlChar,
ctxt,
);
assert!(!res.is_null());
let s = crate::xml::string::xmlstr_to_bytes((*res).stringval);
assert_eq!(
s, b"capture@urn:t",
"bridge must set context->function (local name) and ->functionURI (ns)"
);
super::xmlXPathFreeObject(res);
super::xmlXPathFreeContext(ctxt);
crate::xml::tree::free_doc(doc);
}
}
}