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_uint};
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/// - `type_`: The type of resource being loaded
388/// (1 = parser entity, 2 = stylesheet include, 3 = stylesheet import, 4 = document)
389pub type xmlResourceLoader = unsafe extern "C" fn(
390 ctxt: *mut c_void,
391 url: *const c_char,
392 options: c_int,
393 type_: c_int,
394) -> *mut _xmlParserInput;
395
396// ═══════════════════════════════════════════════════════════════════════════════
397// Encoding Callbacks
398// ═══════════════════════════════════════════════════════════════════════════════
399
400/// Character encoding conversion implementation.
401///
402/// # UPSTREAM-PARITY
403///
404/// This is used to plug custom encoding converters into the I/O subsystem.
405/// Returns the number of bytes written, or -1 on error.
406pub type xmlCharEncConvImpl = unsafe extern "C" fn(
407 name: *mut *const crate::abi::types::xmlChar,
408 out: *mut *mut crate::abi::types::xmlChar,
409 outlen: *mut c_int,
410 in_: *const crate::abi::types::xmlChar,
411 inlen: *mut c_int,
412) -> c_int;
413
414// ═══════════════════════════════════════════════════════════════════════════════
415// Catalog Callbacks
416// ═══════════════════════════════════════════════════════════════════════════════
417
418/// Catalog preference callback.
419///
420/// Returns 1 if the system prefers XML catalogs, 0 otherwise.
421pub type xmlCatalogPreferFunc = unsafe extern "C" fn() -> c_int;
422
423// ═══════════════════════════════════════════════════════════════════════════════
424// Allocator Callback Types
425// ═══════════════════════════════════════════════════════════════════════════════
426
427/// Free function type for allocator hooks.
428pub type xmlFreeFunc = unsafe extern "C" fn(ptr: *mut c_void);
429
430/// Malloc function type for allocator hooks.
431pub type xmlMallocFunc = unsafe extern "C" fn(size: usize) -> *mut c_void;
432
433/// Realloc function type for allocator hooks.
434pub type xmlReallocFunc = unsafe extern "C" fn(ptr: *mut c_void, size: usize) -> *mut c_void;
435
436/// Strdup function type for allocator hooks.
437pub type xmlStrdupFunc = unsafe extern "C" fn(str: *const c_char) -> *mut c_void;
438
439// ═══════════════════════════════════════════════════════════════════════════════
440// Module Callbacks
441// ═══════════════════════════════════════════════════════════════════════════════
442
443/// Module register/unregister callback.
444pub type xmlModuleRegisterFunc = unsafe extern "C" fn(module: *mut c_void) -> c_int;
445
446// ═══════════════════════════════════════════════════════════════════════════════
447// Pattern Callbacks
448// ═══════════════════════════════════════════════════════════════════════════════
449
450/// Stream callback for pattern matching.
451pub type xmlStreamCtxtPtr = *mut c_void;
452
453// ═══════════════════════════════════════════════════════════════════════════════
454// Hash Table Callbacks
455// ═══════════════════════════════════════════════════════════════════════════════
456
457/// Deallocator function for hash table entries.
458///
459/// Called when removing an entry from a hash table.
460/// The function receives the payload and the name (key) of the entry.
461pub type xmlHashDeallocator =
462 unsafe extern "C" fn(payload: *mut c_void, name: *mut crate::abi::types::xmlChar);
463
464/// Copier function for hash table entries.
465///
466/// Called when copying a hash table. Returns a copy of the payload.
467pub type xmlHashCopier = unsafe extern "C" fn(
468 payload: *mut c_void,
469 name: *const crate::abi::types::xmlChar,
470) -> *mut c_void;
471
472/// Scanner function for hash table entries.
473///
474/// Called for each entry during xmlHashScan.
475pub type xmlHashScanner = unsafe extern "C" fn(
476 payload: *mut c_void,
477 data: *mut c_void,
478 name: *const crate::abi::types::xmlChar,
479);
480
481/// Full scanner function for hash table entries.
482///
483/// Called for each entry during xmlHashScanFull. Includes all three key parts.
484pub type xmlHashScannerFull = unsafe extern "C" fn(
485 payload: *mut c_void,
486 data: *mut c_void,
487 name: *const crate::abi::types::xmlChar,
488 name2: *const crate::abi::types::xmlChar,
489 name3: *const crate::abi::types::xmlChar,
490);