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#[repr(C)]
279pub struct _xmlSAXLocator {
280 /// Get the public ID of the current document position.
281 pub getPublicId:
282 Option<unsafe extern "C" fn(ctx: *mut c_void) -> *const crate::abi::types::xmlChar>,
283 /// Get the system ID of the current document position.
284 pub getSystemId:
285 Option<unsafe extern "C" fn(ctx: *mut c_void) -> *const crate::abi::types::xmlChar>,
286 /// Get the line number of the current document position.
287 pub getLineNumber: Option<unsafe extern "C" fn(ctx: *mut c_void) -> c_int>,
288 /// Get the column number of the current document position.
289 pub getColumnNumber: Option<unsafe extern "C" fn(ctx: *mut c_void) -> c_int>,
290}
291
292/// Pointer to a SAX locator.
293pub type xmlSAXLocatorPtr = *mut _xmlSAXLocator;
294
295// ═══════════════════════════════════════════════════════════════════════════════
296// Error Callbacks
297// ═══════════════════════════════════════════════════════════════════════════════
298
299/// Structured error handler callback.
300///
301/// Called with a pointer to the error structure. The error structure is valid
302/// only during the callback invocation.
303pub type xmlStructuredErrorFunc = unsafe extern "C" fn(ctx: *mut c_void, error: *const _xmlError);
304
305/// Generic error handler callback (printf-style, variadic at C call site).
306///
307/// # UPSTREAM-PARITY
308///
309/// This is the older error reporting mechanism. New code should use the structured
310/// error handler (`xmlStructuredErrorFunc`) instead.
311pub type xmlGenericErrorFunc = unsafe extern "C" fn(ctx: *mut c_void, msg: *const c_char);
312
313// ═══════════════════════════════════════════════════════════════════════════════
314// Validity Callbacks
315// ═══════════════════════════════════════════════════════════════════════════════
316
317/// Validity error handler callback (printf-style, variadic at C call site).
318pub type xmlValidityErrorFunc = unsafe extern "C" fn(ctx: *mut c_void, msg: *const c_char);
319
320/// Validity warning handler callback (printf-style, variadic at C call site).
321pub type xmlValidityWarningFunc = unsafe extern "C" fn(ctx: *mut c_void, msg: *const c_char);
322
323// ═══════════════════════════════════════════════════════════════════════════════
324// I/O Callbacks
325// ═══════════════════════════════════════════════════════════════════════════════
326
327/// Read callback for custom input.
328///
329/// Should fill `buffer` with up to `len` bytes.
330/// Returns the number of bytes read, 0 on EOF, or -1 on error.
331pub type xmlInputReadCallback =
332 unsafe extern "C" fn(context: *mut c_void, buffer: *mut c_char, len: c_int) -> c_int;
333
334/// Close callback for custom input.
335///
336/// Returns 0 on success, -1 on error.
337pub type xmlInputCloseCallback = unsafe extern "C" fn(context: *mut c_void) -> c_int;
338
339/// Write callback for custom output.
340///
341/// Should write up to `len` bytes from `buffer`.
342/// Returns the number of bytes written, or -1 on error.
343pub type xmlOutputWriteCallback =
344 unsafe extern "C" fn(context: *mut c_void, buffer: *const c_char, len: c_int) -> c_int;
345
346/// Close callback for custom output.
347///
348/// Returns 0 on success, -1 on error.
349pub type xmlOutputCloseCallback = unsafe extern "C" fn(context: *mut c_void) -> c_int;
350
351// ═══════════════════════════════════════════════════════════════════════════════
352// XPath Callbacks
353// ═══════════════════════════════════════════════════════════════════════════════
354
355/// Variable lookup function for XPath.
356///
357/// Returns an `xmlXPathObjectPtr` representing the variable's value, or NULL.
358///
359/// # UPSTREAM-PARITY
360///
361/// Ownership: The returned object is owned by the caller (must be freed).
362pub type xmlXPathVariableLookupFunc = unsafe extern "C" fn(
363 ctxt: *mut c_void,
364 name: *const crate::abi::types::xmlChar,
365 ns_uri: *const crate::abi::types::xmlChar,
366) -> *mut _xmlXPathObject;
367
368/// Function lookup function for XPath extensions.
369///
370/// Returns a function pointer or NULL.
371pub type xmlXPathFuncLookupFunc = unsafe extern "C" fn(
372 ctxt: *mut c_void,
373 name: *const crate::abi::types::xmlChar,
374 ns_uri: *const crate::abi::types::xmlChar,
375) -> *mut c_void;
376
377// ═══════════════════════════════════════════════════════════════════════════════
378// Resource Loader Callbacks
379// ═══════════════════════════════════════════════════════════════════════════════
380
381/// Resource loader callback.
382///
383/// Loads a resource identified by `url` and returns a parser input.
384///
385/// # UPSTREAM-PARITY
386///
387/// Declared in upstream `parser.h` (2.15+):
388///
389/// ```c
390/// typedef xmlParserErrors
391/// (*xmlResourceLoader)(void *ctxt, const char *url, const char *publicId,
392/// xmlResourceType type, xmlParserInputFlags flags,
393/// xmlParserInput **out);
394/// ```
395///
396/// Note: a different, older `void *(*)(const char*, const char*, int, void*)`
397/// signature appears in very old libxml2 headers; the 2.15 contract wins.
398pub type xmlResourceLoader = unsafe extern "C" fn(
399 ctxt: *mut c_void,
400 url: *const c_char,
401 publicId: *const c_char,
402 type_: c_int, // xmlResourceType
403 flags: c_int, // xmlParserInputFlags
404 out: *mut *mut _xmlParserInput,
405) -> c_int; // xmlParserErrors
406
407// ═══════════════════════════════════════════════════════════════════════════════
408// Encoding Callbacks
409// ═══════════════════════════════════════════════════════════════════════════════
410
411/// Character encoding input conversion function.
412///
413/// Converts from the handler's input encoding to UTF-8.
414/// `in` and `inlen` describe input; `out` and `outlen` describe output buffer.
415/// Returns the number of bytes written, or -1 on error.
416pub type xmlCharEncodingInputFunc = unsafe extern "C" fn(
417 out: *mut c_uchar,
418 outlen: *mut c_int,
419 in_: *const c_uchar,
420 inlen: *mut c_int,
421) -> c_int;
422
423/// Modern character encoding conversion function (upstream encoding.h).
424///
425/// ```c
426/// typedef xmlCharEncError
427/// (*xmlCharEncConvFunc)(void *vctxt, unsigned char *out, int *outlen,
428/// const unsigned char *in, int *inlen, int flush);
429/// ```
430pub type xmlCharEncConvFunc = unsafe extern "C" fn(
431 vctxt: *mut c_void,
432 out: *mut c_uchar,
433 outlen: *mut c_int,
434 in_: *const c_uchar,
435 inlen: *mut c_int,
436 flush: c_int,
437) -> c_int; // xmlCharEncError
438
439/// Conversion-context destructor (upstream encoding.h).
440///
441/// ```c
442/// typedef void (*xmlCharEncConvCtxtDtor)(void *vctxt);
443/// ```
444pub type xmlCharEncConvCtxtDtor = unsafe extern "C" fn(vctxt: *mut c_void);
445
446/// Character encoding output conversion function.
447///
448/// Converts from UTF-8 to the handler's output encoding.
449/// `in` and `inlen` describe input; `out` and `outlen` describe output buffer.
450/// Returns the number of bytes written, or -1 on error.
451pub type xmlCharEncodingOutputFunc = unsafe extern "C" fn(
452 out: *mut c_uchar,
453 outlen: *mut c_int,
454 in_: *const c_uchar,
455 inlen: *mut c_int,
456) -> c_int;
457
458/// Character encoding conversion implementation.
459///
460/// # UPSTREAM-PARITY
461///
462/// Declared in upstream `encoding.h` (2.15+):
463///
464/// ```c
465/// typedef xmlParserErrors
466/// (*xmlCharEncConvImpl)(void *vctxt, const char *name, xmlCharEncFlags flags,
467/// xmlCharEncodingHandler **out);
468/// ```
469///
470/// Returns an xmlParserErrors code; `out` receives a new handler on success.
471pub type xmlCharEncConvImpl = unsafe extern "C" fn(
472 vctxt: *mut c_void,
473 name: *const c_char,
474 flags: c_int, // xmlCharEncFlags
475 out: *mut *mut crate::abi::structs::_xmlCharEncodingHandler,
476) -> c_int; // xmlParserErrors
477
478// ═══════════════════════════════════════════════════════════════════════════════
479// Catalog Callbacks
480// ═══════════════════════════════════════════════════════════════════════════════
481
482/// Catalog preference callback.
483///
484/// Returns 1 if the system prefers XML catalogs, 0 otherwise.
485pub type xmlCatalogPreferFunc = unsafe extern "C" fn() -> c_int;
486
487// ═══════════════════════════════════════════════════════════════════════════════
488// Allocator Callback Types
489// ═══════════════════════════════════════════════════════════════════════════════
490
491/// Free function type for allocator hooks.
492pub type xmlFreeFunc = unsafe extern "C" fn(ptr: *mut c_void);
493
494/// Malloc function type for allocator hooks.
495pub type xmlMallocFunc = unsafe extern "C" fn(size: usize) -> *mut c_void;
496
497/// Realloc function type for allocator hooks.
498pub type xmlReallocFunc = unsafe extern "C" fn(ptr: *mut c_void, size: usize) -> *mut c_void;
499
500/// Strdup function type for allocator hooks.
501pub type xmlStrdupFunc = unsafe extern "C" fn(str: *const c_char) -> *mut c_void;
502
503// ═══════════════════════════════════════════════════════════════════════════════
504// Module Callbacks
505// ═══════════════════════════════════════════════════════════════════════════════
506
507/// Module register/unregister callback.
508pub type xmlModuleRegisterFunc = unsafe extern "C" fn(module: *mut c_void) -> c_int;
509
510// ═══════════════════════════════════════════════════════════════════════════════
511// Pattern Callbacks
512// ═══════════════════════════════════════════════════════════════════════════════
513
514/// Stream callback for pattern matching.
515pub type xmlStreamCtxtPtr = *mut c_void;
516
517// ═══════════════════════════════════════════════════════════════════════════════
518// Hash Table Callbacks
519// ═══════════════════════════════════════════════════════════════════════════════
520
521/// Deallocator function for hash table entries.
522///
523/// Called when removing an entry from a hash table.
524/// The function receives the payload and the name (key) of the entry.
525pub type xmlHashDeallocator =
526 unsafe extern "C" fn(payload: *mut c_void, name: *mut crate::abi::types::xmlChar);
527
528/// Copier function for hash table entries.
529///
530/// Called when copying a hash table. Returns a copy of the payload.
531pub type xmlHashCopier = unsafe extern "C" fn(
532 payload: *mut c_void,
533 name: *const crate::abi::types::xmlChar,
534) -> *mut c_void;
535
536/// Scanner function for hash table entries.
537///
538/// Called for each entry during xmlHashScan.
539pub type xmlHashScanner = unsafe extern "C" fn(
540 payload: *mut c_void,
541 data: *mut c_void,
542 name: *const crate::abi::types::xmlChar,
543);
544
545/// Full scanner function for hash table entries.
546///
547/// Called for each entry during xmlHashScanFull. Includes all three key parts.
548pub type xmlHashScannerFull = unsafe extern "C" fn(
549 payload: *mut c_void,
550 data: *mut c_void,
551 name: *const crate::abi::types::xmlChar,
552 name2: *const crate::abi::types::xmlChar,
553 name3: *const crate::abi::types::xmlChar,
554);