libxml_rs/abi/callbacks.rs
1//! C ABI callback function type definitions — matching upstream callback signatures (§14, §20).
2//!
3//! This module defines all function pointer types used in public upstream structures:
4//! SAX1 callbacks, SAX2 callbacks, error callbacks, validity callbacks, XPath callbacks,
5//! I/O callbacks, resource loader callbacks, encoding callbacks, and the SAX locator.
6//!
7//! # Phase 1 status
8//!
9//! Complete — all callback types from upstream headers are defined.
10//!
11//! # Safety
12//!
13//! All callback types are `unsafe extern "C"` because they are called across the FFI boundary
14//! with C calling conventions. The caller must ensure:
15//! - Function pointers are non-null before invocation (unless nullable per upstream contract)
16//! - Pointers passed to callbacks remain valid for the callback's duration
17//! - Callbacks observe the upstream ownership/lifetime contract
18//! - Thread safety matches upstream expectations
19
20#![allow(non_camel_case_types)]
21
22use core::ffi::c_void;
23use std::os::raw::{c_char, c_int, c_uchar};
24
25use crate::abi::structs::*;
26
27// ═══════════════════════════════════════════════════════════════════════════════
28// SAX1 Callbacks (xmlSAXHandler)
29// ═══════════════════════════════════════════════════════════════════════════════
30
31/// Callback for internal DTD subset notification.
32///
33/// # UPSTREAM-PARITY
34///
35/// Oracle behavior: Called when `<!DOCTYPE ... [ ... ]>` internal subset is parsed.
36/// Parameters are the DOCTYPE name, external ID (or NULL), system ID (or NULL).
37pub type internalSubsetSAXFunc = unsafe extern "C" fn(
38 ctx: *mut c_void,
39 name: *const crate::abi::types::xmlChar,
40 ExternalID: *const crate::abi::types::xmlChar,
41 SystemID: *const crate::abi::types::xmlChar,
42);
43
44/// Callback for standalone document declaration.
45///
46/// Returns 1 if standalone="yes", 0 if standalone="no", -1 if not declared.
47pub type isStandaloneSAXFunc = unsafe extern "C" fn(ctx: *mut c_void) -> c_int;
48
49/// Callback: does the document have an internal subset?
50pub type hasInternalSubsetSAXFunc = unsafe extern "C" fn(ctx: *mut c_void) -> c_int;
51
52/// Callback: does the document have an external subset?
53pub type hasExternalSubsetSAXFunc = unsafe extern "C" fn(ctx: *mut c_void) -> c_int;
54
55/// Callback to resolve an external entity.
56///
57/// Returns a newly allocated `xmlParserInputPtr` or NULL.
58///
59/// # UPSTREAM-PARITY
60///
61/// Ownership: The returned `xmlParserInputPtr` is owned by the parser context.
62pub type resolveEntitySAXFunc = unsafe extern "C" fn(
63 ctx: *mut c_void,
64 publicId: *const crate::abi::types::xmlChar,
65 systemId: *const crate::abi::types::xmlChar,
66) -> *mut _xmlParserInput;
67
68/// Callback to get an entity.
69///
70/// Returns a pointer to an entity or NULL.
71///
72/// # UPSTREAM-PARITY
73///
74/// Ownership: The returned entity is owned by the document's entity table.
75/// The caller must not free it.
76pub type getEntitySAXFunc = unsafe extern "C" fn(
77 ctx: *mut c_void,
78 name: *const crate::abi::types::xmlChar,
79) -> *mut _xmlEntity;
80
81/// Callback for entity declaration.
82pub type entityDeclSAXFunc = unsafe extern "C" fn(
83 ctx: *mut c_void,
84 name: *const crate::abi::types::xmlChar,
85 type_: c_int,
86 publicId: *const crate::abi::types::xmlChar,
87 systemId: *const crate::abi::types::xmlChar,
88 content: *mut crate::abi::types::xmlChar,
89);
90
91/// Callback for notation declaration.
92pub type notationDeclSAXFunc = unsafe extern "C" fn(
93 ctx: *mut c_void,
94 name: *const crate::abi::types::xmlChar,
95 publicId: *const crate::abi::types::xmlChar,
96 systemId: *const crate::abi::types::xmlChar,
97);
98
99/// Callback for attribute declaration.
100pub type attributeDeclSAXFunc = unsafe extern "C" fn(
101 ctx: *mut c_void,
102 elem: *const crate::abi::types::xmlChar,
103 name: *const crate::abi::types::xmlChar,
104 type_: c_int,
105 def: c_int,
106 defaultValue: *const crate::abi::types::xmlChar,
107 tree: *mut _xmlEnumeration,
108);
109
110/// Callback for element declaration.
111pub type elementDeclSAXFunc = unsafe extern "C" fn(
112 ctx: *mut c_void,
113 name: *const crate::abi::types::xmlChar,
114 type_: c_int,
115 content: *mut _xmlElementContent,
116);
117
118/// Callback for unparsed entity declaration.
119pub type unparsedEntityDeclSAXFunc = unsafe extern "C" fn(
120 ctx: *mut c_void,
121 name: *const crate::abi::types::xmlChar,
122 publicId: *const crate::abi::types::xmlChar,
123 systemId: *const crate::abi::types::xmlChar,
124 notationName: *const crate::abi::types::xmlChar,
125);
126
127/// Callback to set the document locator.
128///
129/// # UPSTREAM-PARITY
130///
131/// The locator is an opaque structure that provides line/column information.
132pub type setDocumentLocatorSAXFunc =
133 unsafe extern "C" fn(ctx: *mut c_void, loc: *mut _xmlSAXLocator);
134
135/// Callback for document start.
136pub type startDocumentSAXFunc = unsafe extern "C" fn(ctx: *mut c_void);
137
138/// Callback for document end.
139pub type endDocumentSAXFunc = unsafe extern "C" fn(ctx: *mut c_void);
140
141/// Callback for element start (SAX1).
142///
143/// # Parameters
144/// - `name`: element name
145/// - `atts`: NULL-terminated array of [name, value, name, value, ..., NULL]
146pub type startElementSAXFunc = unsafe extern "C" fn(
147 ctx: *mut c_void,
148 name: *const crate::abi::types::xmlChar,
149 atts: *mut *const crate::abi::types::xmlChar,
150);
151
152/// Callback for element end (SAX1).
153pub type endElementSAXFunc =
154 unsafe extern "C" fn(ctx: *mut c_void, name: *const crate::abi::types::xmlChar);
155
156/// Callback for entity reference.
157pub type referenceSAXFunc =
158 unsafe extern "C" fn(ctx: *mut c_void, name: *const crate::abi::types::xmlChar);
159
160/// Callback for character data.
161pub type charactersSAXFunc =
162 unsafe extern "C" fn(ctx: *mut c_void, ch: *const crate::abi::types::xmlChar, len: c_int);
163
164/// Callback for ignorable whitespace.
165pub type ignorableWhitespaceSAXFunc =
166 unsafe extern "C" fn(ctx: *mut c_void, ch: *const crate::abi::types::xmlChar, len: c_int);
167
168/// Callback for processing instructions.
169pub type processingInstructionSAXFunc = unsafe extern "C" fn(
170 ctx: *mut c_void,
171 target: *const crate::abi::types::xmlChar,
172 data: *const crate::abi::types::xmlChar,
173);
174
175/// Callback for comments.
176pub type commentSAXFunc =
177 unsafe extern "C" fn(ctx: *mut c_void, value: *const crate::abi::types::xmlChar);
178
179/// Callback for warnings (printf-style, variadic at C call site).
180///
181/// # UPSTREAM-PARITY
182///
183/// The `...` is implicit in C; Rust type cannot express variadic extern "C"
184/// on stable. The function pointer ABI is identical — C callers pass variadic
185/// arguments and the callee uses va_list internally.
186pub type warningSAXFunc = unsafe extern "C" fn(ctx: *mut c_void, msg: *const c_char);
187
188/// Callback for errors (printf-style, variadic at C call site).
189pub type errorSAXFunc = unsafe extern "C" fn(ctx: *mut c_void, msg: *const c_char);
190
191/// Callback for fatal errors (printf-style, variadic at C call site).
192pub type fatalErrorSAXFunc = unsafe extern "C" fn(ctx: *mut c_void, msg: *const c_char);
193
194/// Callback to get a parameter entity.
195///
196/// Returns a pointer to a parameter entity or NULL.
197pub type getParameterEntitySAXFunc = unsafe extern "C" fn(
198 ctx: *mut c_void,
199 name: *const crate::abi::types::xmlChar,
200) -> *mut _xmlEntity;
201
202/// Callback for CDATA block.
203pub type cdataBlockSAXFunc =
204 unsafe extern "C" fn(ctx: *mut c_void, value: *const crate::abi::types::xmlChar, len: c_int);
205
206/// Callback for external subset notification.
207pub type externalSubsetSAXFunc = unsafe extern "C" fn(
208 ctx: *mut c_void,
209 name: *const crate::abi::types::xmlChar,
210 ExternalID: *const crate::abi::types::xmlChar,
211 SystemID: *const crate::abi::types::xmlChar,
212);
213
214/// Callback for initializing the SAX handler.
215///
216/// # UPSTREAM-PARITY
217///
218/// This is a libxml2-internal callback used to set SAX2 callbacks when SAX1 callbacks
219/// are not provided. Not typically set by downstream users.
220pub type initSAXFunc = unsafe extern "C" fn(ctx: *mut c_void, handler: *mut _xmlSAXHandler);
221
222// ═══════════════════════════════════════════════════════════════════════════════
223// SAX2 Callbacks
224// ═══════════════════════════════════════════════════════════════════════════════
225
226/// Callback for element start (SAX2/namespaced).
227///
228/// # Parameters
229/// - `localname`: element local name
230/// - `prefix`: element namespace prefix (or NULL)
231/// - `URI`: element namespace URI (or NULL)
232/// - `nb_namespaces`: number of namespace declarations
233/// - `namespaces`: array of [prefix, URI, prefix, URI, ...] (size 2*nb_namespaces)
234/// - `nb_attributes`: total number of attributes
235/// - `nb_defaulted`: number of defaulted attributes (from DTD)
236/// - `attributes`: array of [localname, prefix, URI, value, value_end, ...]
237/// each attribute is 5 entries, value_end is pointer past last char of value
238pub type startElementNsSAX2Func = unsafe extern "C" fn(
239 ctx: *mut c_void,
240 localname: *const crate::abi::types::xmlChar,
241 prefix: *const crate::abi::types::xmlChar,
242 URI: *const crate::abi::types::xmlChar,
243 nb_namespaces: c_int,
244 namespaces: *mut *const crate::abi::types::xmlChar,
245 nb_attributes: c_int,
246 nb_defaulted: c_int,
247 attributes: *mut *const crate::abi::types::xmlChar,
248);
249
250/// Callback for element end (SAX2/namespaced).
251pub type endElementNsSAX2Func = unsafe extern "C" fn(
252 ctx: *mut c_void,
253 localname: *const crate::abi::types::xmlChar,
254 prefix: *const crate::abi::types::xmlChar,
255 URI: *const crate::abi::types::xmlChar,
256);
257
258// ═══════════════════════════════════════════════════════════════════════════════
259// SAX Locator
260// ═══════════════════════════════════════════════════════════════════════════════
261
262/// The SAX locator structure providing line/column information.
263///
264/// # UPSTREAM-PARITY
265///
266/// This is an opaque structure from the perspective of SAX handlers.
267/// Upstream defines it as:
268/// ```c
269/// typedef struct _xmlSAXLocator xmlSAXLocator;
270/// typedef xmlSAXLocator *xmlSAXLocatorPtr;
271/// struct _xmlSAXLocator {
272/// xmlChar *(*getPublicId)(void *ctx);
273/// xmlChar *(*getSystemId)(void *ctx);
274/// int (*getLineNumber)(void *ctx);
275/// int (*getColumnNumber)(void *ctx);
276/// };
277/// ```
278#[derive(Debug)]
279#[repr(C)]
280pub struct _xmlSAXLocator {
281 /// Get the public ID of the current document position.
282 pub getPublicId:
283 Option<unsafe extern "C" fn(ctx: *mut c_void) -> *const crate::abi::types::xmlChar>,
284 /// Get the system ID of the current document position.
285 pub getSystemId:
286 Option<unsafe extern "C" fn(ctx: *mut c_void) -> *const crate::abi::types::xmlChar>,
287 /// Get the line number of the current document position.
288 pub getLineNumber: Option<unsafe extern "C" fn(ctx: *mut c_void) -> c_int>,
289 /// Get the column number of the current document position.
290 pub getColumnNumber: Option<unsafe extern "C" fn(ctx: *mut c_void) -> c_int>,
291}
292
293/// Pointer to a SAX locator.
294pub type xmlSAXLocatorPtr = *mut _xmlSAXLocator;
295
296// ═══════════════════════════════════════════════════════════════════════════════
297// Error Callbacks
298// ═══════════════════════════════════════════════════════════════════════════════
299
300/// Structured error handler callback.
301///
302/// Called with a pointer to the error structure. The error structure is valid
303/// only during the callback invocation.
304pub type xmlStructuredErrorFunc = unsafe extern "C" fn(ctx: *mut c_void, error: *const _xmlError);
305
306/// Generic error handler callback (printf-style, variadic at C call site).
307///
308/// # UPSTREAM-PARITY
309///
310/// This is the older error reporting mechanism. New code should use the structured
311/// error handler (`xmlStructuredErrorFunc`) instead.
312pub type xmlGenericErrorFunc = unsafe extern "C" fn(ctx: *mut c_void, msg: *const c_char);
313
314// ═══════════════════════════════════════════════════════════════════════════════
315// Validity Callbacks
316// ═══════════════════════════════════════════════════════════════════════════════
317
318/// Validity error handler callback (printf-style, variadic at C call site).
319pub type xmlValidityErrorFunc = unsafe extern "C" fn(ctx: *mut c_void, msg: *const c_char);
320
321/// Validity warning handler callback (printf-style, variadic at C call site).
322pub type xmlValidityWarningFunc = unsafe extern "C" fn(ctx: *mut c_void, msg: *const c_char);
323
324// ═══════════════════════════════════════════════════════════════════════════════
325// I/O Callbacks
326// ═══════════════════════════════════════════════════════════════════════════════
327
328/// Read callback for custom input.
329///
330/// Should fill `buffer` with up to `len` bytes.
331/// Returns the number of bytes read, 0 on EOF, or -1 on error.
332pub type xmlInputReadCallback =
333 unsafe extern "C" fn(context: *mut c_void, buffer: *mut c_char, len: c_int) -> c_int;
334
335/// Close callback for custom input.
336///
337/// Returns 0 on success, -1 on error.
338pub type xmlInputCloseCallback = unsafe extern "C" fn(context: *mut c_void) -> c_int;
339
340/// Write callback for custom output.
341///
342/// Should write up to `len` bytes from `buffer`.
343/// Returns the number of bytes written, or -1 on error.
344pub type xmlOutputWriteCallback =
345 unsafe extern "C" fn(context: *mut c_void, buffer: *const c_char, len: c_int) -> c_int;
346
347/// Close callback for custom output.
348///
349/// Returns 0 on success, -1 on error.
350pub type xmlOutputCloseCallback = unsafe extern "C" fn(context: *mut c_void) -> c_int;
351
352// ═══════════════════════════════════════════════════════════════════════════════
353// XPath Callbacks
354// ═══════════════════════════════════════════════════════════════════════════════
355
356/// Variable lookup function for XPath.
357///
358/// Returns an `xmlXPathObjectPtr` representing the variable's value, or NULL.
359///
360/// # UPSTREAM-PARITY
361///
362/// Ownership: The returned object is owned by the caller (must be freed).
363pub type xmlXPathVariableLookupFunc = unsafe extern "C" fn(
364 ctxt: *mut c_void,
365 name: *const crate::abi::types::xmlChar,
366 ns_uri: *const crate::abi::types::xmlChar,
367) -> *mut _xmlXPathObject;
368
369/// Function lookup function for XPath extensions.
370///
371/// Returns a function pointer or NULL.
372pub type xmlXPathFuncLookupFunc = unsafe extern "C" fn(
373 ctxt: *mut c_void,
374 name: *const crate::abi::types::xmlChar,
375 ns_uri: *const crate::abi::types::xmlChar,
376) -> *mut c_void;
377
378// ═══════════════════════════════════════════════════════════════════════════════
379// Resource Loader Callbacks
380// ═══════════════════════════════════════════════════════════════════════════════
381
382/// Resource loader callback.
383///
384/// Loads a resource identified by `url` and returns a parser input.
385///
386/// # UPSTREAM-PARITY
387///
388/// Declared in upstream `parser.h` (2.15+):
389///
390/// ```c
391/// typedef xmlParserErrors
392/// (*xmlResourceLoader)(void *ctxt, const char *url, const char *publicId,
393/// xmlResourceType type, xmlParserInputFlags flags,
394/// xmlParserInput **out);
395/// ```
396///
397/// Note: a different, older `void *(*)(const char*, const char*, int, void*)`
398/// signature appears in very old libxml2 headers; the 2.15 contract wins.
399pub type xmlResourceLoader = unsafe extern "C" fn(
400 ctxt: *mut c_void,
401 url: *const c_char,
402 publicId: *const c_char,
403 type_: c_int, // xmlResourceType
404 flags: c_int, // xmlParserInputFlags
405 out: *mut *mut _xmlParserInput,
406) -> c_int; // xmlParserErrors
407
408// ═══════════════════════════════════════════════════════════════════════════════
409// Encoding Callbacks
410// ═══════════════════════════════════════════════════════════════════════════════
411
412/// Character encoding input conversion function.
413///
414/// Converts from the handler's input encoding to UTF-8.
415/// `in` and `inlen` describe input; `out` and `outlen` describe output buffer.
416/// Returns the number of bytes written, or -1 on error.
417pub type xmlCharEncodingInputFunc = unsafe extern "C" fn(
418 out: *mut c_uchar,
419 outlen: *mut c_int,
420 in_: *const c_uchar,
421 inlen: *mut c_int,
422) -> c_int;
423
424/// Modern character encoding conversion function (upstream encoding.h).
425///
426/// ```c
427/// typedef xmlCharEncError
428/// (*xmlCharEncConvFunc)(void *vctxt, unsigned char *out, int *outlen,
429/// const unsigned char *in, int *inlen, int flush);
430/// ```
431pub type xmlCharEncConvFunc = unsafe extern "C" fn(
432 vctxt: *mut c_void,
433 out: *mut c_uchar,
434 outlen: *mut c_int,
435 in_: *const c_uchar,
436 inlen: *mut c_int,
437 flush: c_int,
438) -> c_int; // xmlCharEncError
439
440/// Conversion-context destructor (upstream encoding.h).
441///
442/// ```c
443/// typedef void (*xmlCharEncConvCtxtDtor)(void *vctxt);
444/// ```
445pub type xmlCharEncConvCtxtDtor = unsafe extern "C" fn(vctxt: *mut c_void);
446
447/// Character encoding output conversion function.
448///
449/// Converts from UTF-8 to the handler's output encoding.
450/// `in` and `inlen` describe input; `out` and `outlen` describe output buffer.
451/// Returns the number of bytes written, or -1 on error.
452pub type xmlCharEncodingOutputFunc = unsafe extern "C" fn(
453 out: *mut c_uchar,
454 outlen: *mut c_int,
455 in_: *const c_uchar,
456 inlen: *mut c_int,
457) -> c_int;
458
459/// Character encoding conversion implementation.
460///
461/// # UPSTREAM-PARITY
462///
463/// Declared in upstream `encoding.h` (2.15+):
464///
465/// ```c
466/// typedef xmlParserErrors
467/// (*xmlCharEncConvImpl)(void *vctxt, const char *name, xmlCharEncFlags flags,
468/// xmlCharEncodingHandler **out);
469/// ```
470///
471/// Returns an xmlParserErrors code; `out` receives a new handler on success.
472pub type xmlCharEncConvImpl = unsafe extern "C" fn(
473 vctxt: *mut c_void,
474 name: *const c_char,
475 flags: c_int, // xmlCharEncFlags
476 out: *mut *mut crate::abi::structs::_xmlCharEncodingHandler,
477) -> c_int; // xmlParserErrors
478
479// ═══════════════════════════════════════════════════════════════════════════════
480// Catalog Callbacks
481// ═══════════════════════════════════════════════════════════════════════════════
482
483/// Catalog preference callback.
484///
485/// Returns 1 if the system prefers XML catalogs, 0 otherwise.
486pub type xmlCatalogPreferFunc = unsafe extern "C" fn() -> c_int;
487
488// ═══════════════════════════════════════════════════════════════════════════════
489// Allocator Callback Types
490// ═══════════════════════════════════════════════════════════════════════════════
491
492/// Free function type for allocator hooks.
493pub type xmlFreeFunc = unsafe extern "C" fn(ptr: *mut c_void);
494
495/// Malloc function type for allocator hooks.
496pub type xmlMallocFunc = unsafe extern "C" fn(size: usize) -> *mut c_void;
497
498/// Realloc function type for allocator hooks.
499pub type xmlReallocFunc = unsafe extern "C" fn(ptr: *mut c_void, size: usize) -> *mut c_void;
500
501/// Strdup function type for allocator hooks.
502pub type xmlStrdupFunc = unsafe extern "C" fn(str: *const c_char) -> *mut c_void;
503
504// ═══════════════════════════════════════════════════════════════════════════════
505// Module Callbacks
506// ═══════════════════════════════════════════════════════════════════════════════
507
508/// Module register/unregister callback.
509pub type xmlModuleRegisterFunc = unsafe extern "C" fn(module: *mut c_void) -> c_int;
510
511// ═══════════════════════════════════════════════════════════════════════════════
512// Pattern Callbacks
513// ═══════════════════════════════════════════════════════════════════════════════
514
515/// Stream callback for pattern matching.
516pub type xmlStreamCtxtPtr = *mut c_void;
517
518// ═══════════════════════════════════════════════════════════════════════════════
519// Hash Table Callbacks
520// ═══════════════════════════════════════════════════════════════════════════════
521
522/// Deallocator function for hash table entries.
523///
524/// Called when removing an entry from a hash table.
525/// The function receives the payload and the name (key) of the entry.
526pub type xmlHashDeallocator =
527 unsafe extern "C" fn(payload: *mut c_void, name: *mut crate::abi::types::xmlChar);
528
529/// Copier function for hash table entries.
530///
531/// Called when copying a hash table. Returns a copy of the payload.
532pub type xmlHashCopier = unsafe extern "C" fn(
533 payload: *mut c_void,
534 name: *const crate::abi::types::xmlChar,
535) -> *mut c_void;
536
537/// Scanner function for hash table entries.
538///
539/// Called for each entry during xmlHashScan.
540pub type xmlHashScanner = unsafe extern "C" fn(
541 payload: *mut c_void,
542 data: *mut c_void,
543 name: *const crate::abi::types::xmlChar,
544);
545
546/// Full scanner function for hash table entries.
547///
548/// Called for each entry during xmlHashScanFull. Includes all three key parts.
549pub type xmlHashScannerFull = unsafe extern "C" fn(
550 payload: *mut c_void,
551 data: *mut c_void,
552 name: *const crate::abi::types::xmlChar,
553 name2: *const crate::abi::types::xmlChar,
554 name3: *const crate::abi::types::xmlChar,
555);