fix for #309761 from Dylan Shell added xmlSchemaSAXPlug and
* parser.c: fix for #309761 from Dylan Shell
* xmlschemas.c include/libxml/xmlschemas.h: added xmlSchemaSAXPlug
and xmlSchemaSAXUnplug generic APIs for SAX Schemas validation.
* xmllint.c: couple of fixes plus added descriptions for --sax and
--sax1
Daniel
diff --git a/xmlschemas.c b/xmlschemas.c
index 05ed65e..7eeef21 100644
--- a/xmlschemas.c
+++ b/xmlschemas.c
@@ -1571,6 +1571,8 @@
if (ctxt != NULL) {
if (ctxt->type == XML_SCHEMA_CTXT_VALIDATOR) {
xmlSchemaValidCtxtPtr vctxt = (xmlSchemaValidCtxtPtr) ctxt;
+ int line = 0;
+ const char *file = NULL;
vctxt->nberrors++;
vctxt->err = error;
@@ -1578,11 +1580,17 @@
schannel = vctxt->serror;
data = vctxt->userData;
if ((node == NULL) && (vctxt->depth >= 0) &&
- (vctxt->inode != NULL))
+ (vctxt->inode != NULL)) {
node = vctxt->inode->node;
+ }
+ if ((node == NULL) && (vctxt->parserCtxt != NULL) &&
+ (vctxt->parserCtxt->input != NULL)) {
+ file = vctxt->parserCtxt->input->filename;
+ line = vctxt->parserCtxt->input->line;
+ }
__xmlRaiseError(schannel, channel, data, ctxt,
node, XML_FROM_SCHEMASV,
- error, XML_ERR_ERROR, NULL, 0,
+ error, XML_ERR_ERROR, file, line,
(const char *) str1, (const char *) str2,
(const char *) str3, 0, 0, msg, str1, str2, str3);
@@ -23999,12 +24007,28 @@
xmlSAXHandlerPtr schemas_sax;
};
+#define XML_SAX_PLUG_MAGIC 0xdc43ba21
+
+struct _xmlSchemaSAXPlug {
+ unsigned int magic;
+
+ /* the original callbacks informations */
+ xmlSAXHandlerPtr *user_sax_ptr;
+ xmlSAXHandlerPtr user_sax;
+ void **user_data_ptr;
+ void *user_data;
+
+ /* the block plugged back and validation informations */
+ xmlSAXHandler schemas_sax;
+ xmlSchemaValidCtxtPtr ctxt;
+};
+
/* All those functions just bounces to the user provided SAX handlers */
static void
internalSubsetSplit(void *ctx, const xmlChar *name,
const xmlChar *ExternalID, const xmlChar *SystemID)
{
- xmlSchemaSplitSAXDataPtr ctxt = (xmlSchemaSplitSAXDataPtr) ctx;
+ xmlSchemaSAXPlugPtr ctxt = (xmlSchemaSAXPlugPtr) ctx;
if ((ctxt != NULL) && (ctxt->user_sax != NULL) &&
(ctxt->user_sax->internalSubset != NULL))
ctxt->user_sax->internalSubset(ctxt->user_data, name, ExternalID,
@@ -24014,7 +24038,7 @@
static int
isStandaloneSplit(void *ctx)
{
- xmlSchemaSplitSAXDataPtr ctxt = (xmlSchemaSplitSAXDataPtr) ctx;
+ xmlSchemaSAXPlugPtr ctxt = (xmlSchemaSAXPlugPtr) ctx;
if ((ctxt != NULL) && (ctxt->user_sax != NULL) &&
(ctxt->user_sax->isStandalone != NULL))
return(ctxt->user_sax->isStandalone(ctxt->user_data));
@@ -24024,7 +24048,7 @@
static int
hasInternalSubsetSplit(void *ctx)
{
- xmlSchemaSplitSAXDataPtr ctxt = (xmlSchemaSplitSAXDataPtr) ctx;
+ xmlSchemaSAXPlugPtr ctxt = (xmlSchemaSAXPlugPtr) ctx;
if ((ctxt != NULL) && (ctxt->user_sax != NULL) &&
(ctxt->user_sax->hasInternalSubset != NULL))
return(ctxt->user_sax->hasInternalSubset(ctxt->user_data));
@@ -24034,7 +24058,7 @@
static int
hasExternalSubsetSplit(void *ctx)
{
- xmlSchemaSplitSAXDataPtr ctxt = (xmlSchemaSplitSAXDataPtr) ctx;
+ xmlSchemaSAXPlugPtr ctxt = (xmlSchemaSAXPlugPtr) ctx;
if ((ctxt != NULL) && (ctxt->user_sax != NULL) &&
(ctxt->user_sax->hasExternalSubset != NULL))
return(ctxt->user_sax->hasExternalSubset(ctxt->user_data));
@@ -24045,7 +24069,7 @@
externalSubsetSplit(void *ctx, const xmlChar *name,
const xmlChar *ExternalID, const xmlChar *SystemID)
{
- xmlSchemaSplitSAXDataPtr ctxt = (xmlSchemaSplitSAXDataPtr) ctx;
+ xmlSchemaSAXPlugPtr ctxt = (xmlSchemaSAXPlugPtr) ctx;
if ((ctxt != NULL) && (ctxt->user_sax != NULL) &&
(ctxt->user_sax->internalSubset != NULL))
ctxt->user_sax->internalSubset(ctxt->user_data, name, ExternalID,
@@ -24055,7 +24079,7 @@
static xmlParserInputPtr
resolveEntitySplit(void *ctx, const xmlChar *publicId, const xmlChar *systemId)
{
- xmlSchemaSplitSAXDataPtr ctxt = (xmlSchemaSplitSAXDataPtr) ctx;
+ xmlSchemaSAXPlugPtr ctxt = (xmlSchemaSAXPlugPtr) ctx;
if ((ctxt != NULL) && (ctxt->user_sax != NULL) &&
(ctxt->user_sax->resolveEntity != NULL))
return(ctxt->user_sax->resolveEntity(ctxt->user_data, publicId,
@@ -24066,7 +24090,7 @@
static xmlEntityPtr
getEntitySplit(void *ctx, const xmlChar *name)
{
- xmlSchemaSplitSAXDataPtr ctxt = (xmlSchemaSplitSAXDataPtr) ctx;
+ xmlSchemaSAXPlugPtr ctxt = (xmlSchemaSAXPlugPtr) ctx;
if ((ctxt != NULL) && (ctxt->user_sax != NULL) &&
(ctxt->user_sax->getEntity != NULL))
return(ctxt->user_sax->getEntity(ctxt->user_data, name));
@@ -24076,7 +24100,7 @@
static xmlEntityPtr
getParameterEntitySplit(void *ctx, const xmlChar *name)
{
- xmlSchemaSplitSAXDataPtr ctxt = (xmlSchemaSplitSAXDataPtr) ctx;
+ xmlSchemaSAXPlugPtr ctxt = (xmlSchemaSAXPlugPtr) ctx;
if ((ctxt != NULL) && (ctxt->user_sax != NULL) &&
(ctxt->user_sax->getParameterEntity != NULL))
return(ctxt->user_sax->getParameterEntity(ctxt->user_data, name));
@@ -24088,7 +24112,7 @@
entityDeclSplit(void *ctx, const xmlChar *name, int type,
const xmlChar *publicId, const xmlChar *systemId, xmlChar *content)
{
- xmlSchemaSplitSAXDataPtr ctxt = (xmlSchemaSplitSAXDataPtr) ctx;
+ xmlSchemaSAXPlugPtr ctxt = (xmlSchemaSAXPlugPtr) ctx;
if ((ctxt != NULL) && (ctxt->user_sax != NULL) &&
(ctxt->user_sax->entityDecl != NULL))
ctxt->user_sax->entityDecl(ctxt->user_data, name, type, publicId,
@@ -24100,7 +24124,7 @@
const xmlChar * name, int type, int def,
const xmlChar * defaultValue, xmlEnumerationPtr tree)
{
- xmlSchemaSplitSAXDataPtr ctxt = (xmlSchemaSplitSAXDataPtr) ctx;
+ xmlSchemaSAXPlugPtr ctxt = (xmlSchemaSAXPlugPtr) ctx;
if ((ctxt != NULL) && (ctxt->user_sax != NULL) &&
(ctxt->user_sax->attributeDecl != NULL)) {
ctxt->user_sax->attributeDecl(ctxt->user_data, elem, name, type,
@@ -24114,7 +24138,7 @@
elementDeclSplit(void *ctx, const xmlChar *name, int type,
xmlElementContentPtr content)
{
- xmlSchemaSplitSAXDataPtr ctxt = (xmlSchemaSplitSAXDataPtr) ctx;
+ xmlSchemaSAXPlugPtr ctxt = (xmlSchemaSAXPlugPtr) ctx;
if ((ctxt != NULL) && (ctxt->user_sax != NULL) &&
(ctxt->user_sax->elementDecl != NULL))
ctxt->user_sax->elementDecl(ctxt->user_data, name, type, content);
@@ -24124,7 +24148,7 @@
notationDeclSplit(void *ctx, const xmlChar *name,
const xmlChar *publicId, const xmlChar *systemId)
{
- xmlSchemaSplitSAXDataPtr ctxt = (xmlSchemaSplitSAXDataPtr) ctx;
+ xmlSchemaSAXPlugPtr ctxt = (xmlSchemaSAXPlugPtr) ctx;
if ((ctxt != NULL) && (ctxt->user_sax != NULL) &&
(ctxt->user_sax->notationDecl != NULL))
ctxt->user_sax->notationDecl(ctxt->user_data, name, publicId,
@@ -24136,7 +24160,7 @@
const xmlChar *publicId, const xmlChar *systemId,
const xmlChar *notationName)
{
- xmlSchemaSplitSAXDataPtr ctxt = (xmlSchemaSplitSAXDataPtr) ctx;
+ xmlSchemaSAXPlugPtr ctxt = (xmlSchemaSAXPlugPtr) ctx;
if ((ctxt != NULL) && (ctxt->user_sax != NULL) &&
(ctxt->user_sax->unparsedEntityDecl != NULL))
ctxt->user_sax->unparsedEntityDecl(ctxt->user_data, name, publicId,
@@ -24146,7 +24170,7 @@
static void
setDocumentLocatorSplit(void *ctx, xmlSAXLocatorPtr loc)
{
- xmlSchemaSplitSAXDataPtr ctxt = (xmlSchemaSplitSAXDataPtr) ctx;
+ xmlSchemaSAXPlugPtr ctxt = (xmlSchemaSAXPlugPtr) ctx;
if ((ctxt != NULL) && (ctxt->user_sax != NULL) &&
(ctxt->user_sax->setDocumentLocator != NULL))
ctxt->user_sax->setDocumentLocator(ctxt->user_data, loc);
@@ -24155,7 +24179,7 @@
static void
startDocumentSplit(void *ctx)
{
- xmlSchemaSplitSAXDataPtr ctxt = (xmlSchemaSplitSAXDataPtr) ctx;
+ xmlSchemaSAXPlugPtr ctxt = (xmlSchemaSAXPlugPtr) ctx;
if ((ctxt != NULL) && (ctxt->user_sax != NULL) &&
(ctxt->user_sax->startDocument != NULL))
ctxt->user_sax->startDocument(ctxt->user_data);
@@ -24164,7 +24188,7 @@
static void
endDocumentSplit(void *ctx)
{
- xmlSchemaSplitSAXDataPtr ctxt = (xmlSchemaSplitSAXDataPtr) ctx;
+ xmlSchemaSAXPlugPtr ctxt = (xmlSchemaSAXPlugPtr) ctx;
if ((ctxt != NULL) && (ctxt->user_sax != NULL) &&
(ctxt->user_sax->endDocument != NULL))
ctxt->user_sax->endDocument(ctxt->user_data);
@@ -24174,7 +24198,7 @@
processingInstructionSplit(void *ctx, const xmlChar *target,
const xmlChar *data)
{
- xmlSchemaSplitSAXDataPtr ctxt = (xmlSchemaSplitSAXDataPtr) ctx;
+ xmlSchemaSAXPlugPtr ctxt = (xmlSchemaSAXPlugPtr) ctx;
if ((ctxt != NULL) && (ctxt->user_sax != NULL) &&
(ctxt->user_sax->processingInstruction != NULL))
ctxt->user_sax->processingInstruction(ctxt->user_data, target, data);
@@ -24183,7 +24207,7 @@
static void
commentSplit(void *ctx, const xmlChar *value)
{
- xmlSchemaSplitSAXDataPtr ctxt = (xmlSchemaSplitSAXDataPtr) ctx;
+ xmlSchemaSAXPlugPtr ctxt = (xmlSchemaSAXPlugPtr) ctx;
if ((ctxt != NULL) && (ctxt->user_sax != NULL) &&
(ctxt->user_sax->comment != NULL))
ctxt->user_sax->comment(ctxt->user_data, value);
@@ -24195,7 +24219,7 @@
static void
warningSplit(void *ctx, const char *msg, ...) {
- xmlSchemaSplitSAXDataPtr ctxt = (xmlSchemaSplitSAXDataPtr) ctx;
+ xmlSchemaSAXPlugPtr ctxt = (xmlSchemaSAXPlugPtr) ctx;
if ((ctxt != NULL) && (ctxt->user_sax != NULL) &&
(ctxt->user_sax->warning != NULL)) {
TODO
@@ -24203,7 +24227,7 @@
}
static void
errorSplit(void *ctx, const char *msg, ...) {
- xmlSchemaSplitSAXDataPtr ctxt = (xmlSchemaSplitSAXDataPtr) ctx;
+ xmlSchemaSAXPlugPtr ctxt = (xmlSchemaSAXPlugPtr) ctx;
if ((ctxt != NULL) && (ctxt->user_sax != NULL) &&
(ctxt->user_sax->error != NULL)) {
TODO
@@ -24211,7 +24235,7 @@
}
static void
fatalErrorSplit(void *ctx, const char *msg, ...) {
- xmlSchemaSplitSAXDataPtr ctxt = (xmlSchemaSplitSAXDataPtr) ctx;
+ xmlSchemaSAXPlugPtr ctxt = (xmlSchemaSAXPlugPtr) ctx;
if ((ctxt != NULL) && (ctxt->user_sax != NULL) &&
(ctxt->user_sax->fatalError != NULL)) {
TODO
@@ -24225,7 +24249,7 @@
static void
charactersSplit(void *ctx, const xmlChar *ch, int len)
{
- xmlSchemaSplitSAXDataPtr ctxt = (xmlSchemaSplitSAXDataPtr) ctx;
+ xmlSchemaSAXPlugPtr ctxt = (xmlSchemaSAXPlugPtr) ctx;
if (ctxt == NULL)
return;
if ((ctxt->user_sax != NULL) && (ctxt->user_sax->characters != NULL))
@@ -24237,7 +24261,7 @@
static void
ignorableWhitespaceSplit(void *ctx, const xmlChar *ch, int len)
{
- xmlSchemaSplitSAXDataPtr ctxt = (xmlSchemaSplitSAXDataPtr) ctx;
+ xmlSchemaSAXPlugPtr ctxt = (xmlSchemaSAXPlugPtr) ctx;
if (ctxt == NULL)
return;
if ((ctxt->user_sax != NULL) &&
@@ -24250,7 +24274,7 @@
static void
cdataBlockSplit(void *ctx, const xmlChar *value, int len)
{
- xmlSchemaSplitSAXDataPtr ctxt = (xmlSchemaSplitSAXDataPtr) ctx;
+ xmlSchemaSAXPlugPtr ctxt = (xmlSchemaSAXPlugPtr) ctx;
if (ctxt == NULL)
return;
if ((ctxt->user_sax != NULL) &&
@@ -24263,7 +24287,7 @@
static void
referenceSplit(void *ctx, const xmlChar *name)
{
- xmlSchemaSplitSAXDataPtr ctxt = (xmlSchemaSplitSAXDataPtr) ctx;
+ xmlSchemaSAXPlugPtr ctxt = (xmlSchemaSAXPlugPtr) ctx;
if ((ctxt != NULL) && (ctxt->user_sax != NULL) &&
(ctxt->user_sax->reference != NULL))
ctxt->user_sax->reference(ctxt->user_data, name);
@@ -24277,7 +24301,7 @@
int nb_namespaces, const xmlChar ** namespaces,
int nb_attributes, int nb_defaulted,
const xmlChar ** attributes) {
- xmlSchemaSplitSAXDataPtr ctxt = (xmlSchemaSplitSAXDataPtr) ctx;
+ xmlSchemaSAXPlugPtr ctxt = (xmlSchemaSAXPlugPtr) ctx;
if (ctxt == NULL)
return;
if ((ctxt->user_sax != NULL) &&
@@ -24296,7 +24320,7 @@
static void
endElementNsSplit(void *ctx, const xmlChar * localname,
const xmlChar * prefix, const xmlChar * URI) {
- xmlSchemaSplitSAXDataPtr ctxt = (xmlSchemaSplitSAXDataPtr) ctx;
+ xmlSchemaSAXPlugPtr ctxt = (xmlSchemaSAXPlugPtr) ctx;
if (ctxt == NULL)
return;
if ((ctxt->user_sax != NULL) &&
@@ -24307,6 +24331,181 @@
}
/**
+ * xmlSchemaSAXPlug:
+ * @ctxt: a schema validation context
+ * @saxptr: a pointer to the original xmlSAXHandlerPtr
+ * @dataptr: a pointer to the original SAX user data pointer
+ *
+ * Plug a SAX based validation layer in a SAX parsing event flow.
+ * The original @saxptr and @dataptr data are replaced by new pointers
+ * but the calls to the original will be maintained.
+ *
+ * Returns a pointer to a data structure needed to unplug the validation layer
+ * or NULL in case of errors.
+ */
+xmlSchemaSAXPlugPtr
+xmlSchemaSAXPlug(xmlSchemaValidCtxtPtr ctxt,
+ xmlSAXHandlerPtr *sax, void **user_data)
+{
+ xmlSchemaSAXPlugPtr ret;
+ xmlSAXHandlerPtr old_sax;
+
+ if ((ctxt == NULL) || (sax == NULL) || (user_data == NULL))
+ return(NULL);
+
+ /*
+ * We only allow to plug into SAX2 event streams
+ */
+ old_sax = *sax;
+ if ((old_sax != NULL) && (old_sax->initialized != XML_SAX2_MAGIC))
+ return(NULL);
+ if ((old_sax != NULL) &&
+ (old_sax->startElementNs == NULL) && (old_sax->endElementNs == NULL) &&
+ ((old_sax->startElement != NULL) || (old_sax->endElement != NULL)))
+ return(NULL);
+
+ /*
+ * everything seems right allocate the local data needed for that layer
+ */
+ ret = (xmlSchemaSAXPlugPtr) xmlMalloc(sizeof(xmlSchemaSAXPlugStruct));
+ if (ret == NULL) {
+ return(NULL);
+ }
+ memset(ret, 0, sizeof(xmlSchemaSAXPlugStruct));
+ ret->magic = XML_SAX_PLUG_MAGIC;
+ ret->schemas_sax.initialized = XML_SAX2_MAGIC;
+ ret->ctxt = ctxt;
+ ret->user_sax_ptr = sax;
+ ret->user_sax = old_sax;
+ if (old_sax == NULL) {
+ /*
+ * go direct, no need for the split block and functions.
+ */
+ ret->schemas_sax.startElementNs = xmlSchemaSAXHandleStartElementNs;
+ ret->schemas_sax.endElementNs = xmlSchemaSAXHandleEndElementNs;
+ /*
+ * Note that we use the same text-function for both, to prevent
+ * the parser from testing for ignorable whitespace.
+ */
+ ret->schemas_sax.ignorableWhitespace = xmlSchemaSAXHandleText;
+ ret->schemas_sax.characters = xmlSchemaSAXHandleText;
+
+ ret->schemas_sax.cdataBlock = xmlSchemaSAXHandleCDataSection;
+ ret->schemas_sax.reference = xmlSchemaSAXHandleReference;
+
+ ret->user_data = ctxt;
+ *user_data = ctxt;
+ } else {
+ /*
+ * for each callback unused by Schemas initialize it to the Split
+ * routine only if non NULL in the user block, this can speed up
+ * things at the SAX level.
+ */
+ if (old_sax->internalSubset != NULL)
+ ret->schemas_sax.internalSubset = internalSubsetSplit;
+ if (old_sax->isStandalone != NULL)
+ ret->schemas_sax.isStandalone = isStandaloneSplit;
+ if (old_sax->hasInternalSubset != NULL)
+ ret->schemas_sax.hasInternalSubset = hasInternalSubsetSplit;
+ if (old_sax->hasExternalSubset != NULL)
+ ret->schemas_sax.hasExternalSubset = hasExternalSubsetSplit;
+ if (old_sax->resolveEntity != NULL)
+ ret->schemas_sax.resolveEntity = resolveEntitySplit;
+ if (old_sax->getEntity != NULL)
+ ret->schemas_sax.getEntity = getEntitySplit;
+ if (old_sax->entityDecl != NULL)
+ ret->schemas_sax.entityDecl = entityDeclSplit;
+ if (old_sax->notationDecl != NULL)
+ ret->schemas_sax.notationDecl = notationDeclSplit;
+ if (old_sax->attributeDecl != NULL)
+ ret->schemas_sax.attributeDecl = attributeDeclSplit;
+ if (old_sax->elementDecl != NULL)
+ ret->schemas_sax.elementDecl = elementDeclSplit;
+ if (old_sax->unparsedEntityDecl != NULL)
+ ret->schemas_sax.unparsedEntityDecl = unparsedEntityDeclSplit;
+ if (old_sax->setDocumentLocator != NULL)
+ ret->schemas_sax.setDocumentLocator = setDocumentLocatorSplit;
+ if (old_sax->startDocument != NULL)
+ ret->schemas_sax.startDocument = startDocumentSplit;
+ if (old_sax->endDocument != NULL)
+ ret->schemas_sax.endDocument = endDocumentSplit;
+ if (old_sax->processingInstruction != NULL)
+ ret->schemas_sax.processingInstruction = processingInstructionSplit;
+ if (old_sax->comment != NULL)
+ ret->schemas_sax.comment = commentSplit;
+ if (old_sax->warning != NULL)
+ ret->schemas_sax.warning = warningSplit;
+ if (old_sax->error != NULL)
+ ret->schemas_sax.error = errorSplit;
+ if (old_sax->fatalError != NULL)
+ ret->schemas_sax.fatalError = fatalErrorSplit;
+ if (old_sax->getParameterEntity != NULL)
+ ret->schemas_sax.getParameterEntity = getParameterEntitySplit;
+ if (old_sax->externalSubset != NULL)
+ ret->schemas_sax.externalSubset = externalSubsetSplit;
+
+ /*
+ * the 6 schemas callback have to go to the splitter functions
+ * Note that we use the same text-function for ignorableWhitespace
+ * if possible, to prevent the parser from testing for ignorable
+ * whitespace.
+ */
+ ret->schemas_sax.characters = charactersSplit;
+ if ((old_sax->ignorableWhitespace != NULL) &&
+ (old_sax->ignorableWhitespace != old_sax->characters))
+ ret->schemas_sax.ignorableWhitespace = ignorableWhitespaceSplit;
+ else
+ ret->schemas_sax.ignorableWhitespace = charactersSplit;
+ ret->schemas_sax.cdataBlock = cdataBlockSplit;
+ ret->schemas_sax.reference = referenceSplit;
+ ret->schemas_sax.startElementNs = startElementNsSplit;
+ ret->schemas_sax.endElementNs = endElementNsSplit;
+
+ ret->user_data_ptr = user_data;
+ ret->user_data = *user_data;
+ *user_data = ret;
+ }
+
+ /*
+ * plug the pointers back.
+ */
+ *sax = &(ret->schemas_sax);
+ return(ret);
+}
+
+/**
+ * xmlSchemaSAXUnplug:
+ * @plug: a data structure returned by xmlSchemaSAXPlug
+ *
+ * Unplug a SAX based validation layer in a SAX parsing event flow.
+ * The original pointers used in the call are restored.
+ *
+ * Returns 0 in case of success and -1 in case of failure.
+ */
+int
+xmlSchemaSAXUnplug(xmlSchemaSAXPlugPtr plug)
+{
+ xmlSAXHandlerPtr *sax;
+ void **user_data;
+
+ if ((plug == NULL) || (plug->magic != XML_SAX_PLUG_MAGIC))
+ return(-1);
+ plug->magic = 0;
+
+ /* restore the data */
+ sax = plug->user_sax_ptr;
+ *sax = plug->user_sax;
+ if (plug->user_sax != NULL) {
+ user_data = plug->user_data_ptr;
+ *user_data = plug->user_data;
+ }
+
+ /* free and return */
+ xmlFree(plug);
+ return(0);
+}
+
+/**
* xmlSchemaValidateStream:
* @ctxt: a schema validation context
* @input: the input to use for reading the data
@@ -24326,115 +24525,15 @@
xmlParserInputBufferPtr input, xmlCharEncoding enc,
xmlSAXHandlerPtr sax, void *user_data)
{
- xmlSchemaSplitSAXData split_block;
- xmlSAXHandler schemas_sax;
- xmlSAXHandlerPtr old_sax;
- xmlParserCtxtPtr pctxt;
- xmlParserInputPtr inputStream;
+ xmlSchemaSAXPlugPtr plug = NULL;
+ xmlSAXHandlerPtr old_sax = NULL;
+ xmlParserCtxtPtr pctxt = NULL;
+ xmlParserInputPtr inputStream = NULL;
int ret;
if ((ctxt == NULL) || (input == NULL))
return (-1);
-
- memset(&schemas_sax, 0, sizeof(xmlSAXHandler));
- schemas_sax.initialized = XML_SAX2_MAGIC;
- if (sax == NULL) {
- /*
- * go direct, no need for the split block and functions.
- */
- schemas_sax.startElementNs = xmlSchemaSAXHandleStartElementNs;
- schemas_sax.endElementNs = xmlSchemaSAXHandleEndElementNs;
- /*
- * Note that we use the same text-function for both, to prevent
- * the parser from testing for ignorable whitespace.
- */
- schemas_sax.ignorableWhitespace = xmlSchemaSAXHandleText;
- schemas_sax.characters = xmlSchemaSAXHandleText;
- schemas_sax.cdataBlock = xmlSchemaSAXHandleCDataSection;
- schemas_sax.reference = xmlSchemaSAXHandleReference;
- /* ctxt->user_data = &split_block; */
- } else {
- /*
- * Return -1 without parsing if passed a SAXv1 block
- */
- if (sax->initialized != XML_SAX2_MAGIC)
- return(-1);
- if ((sax->startElementNs == NULL) && (sax->endElementNs == NULL) &&
- ((sax->startElement != NULL) || (sax->endElement != NULL)))
- return(-1);
-
- /*
- * for each callback unused by Schemas initialize it to the Split
- * routine only if non NULL in the user block, this can speed up
- * things at the SAX level.
- */
- if (sax->internalSubset != NULL)
- schemas_sax.internalSubset = internalSubsetSplit;
- if (sax->isStandalone != NULL)
- schemas_sax.isStandalone = isStandaloneSplit;
- if (sax->hasInternalSubset != NULL)
- schemas_sax.hasInternalSubset = hasInternalSubsetSplit;
- if (sax->hasExternalSubset != NULL)
- schemas_sax.hasExternalSubset = hasExternalSubsetSplit;
- if (sax->resolveEntity != NULL)
- schemas_sax.resolveEntity = resolveEntitySplit;
- if (sax->getEntity != NULL)
- schemas_sax.getEntity = getEntitySplit;
- if (sax->entityDecl != NULL)
- schemas_sax.entityDecl = entityDeclSplit;
- if (sax->notationDecl != NULL)
- schemas_sax.notationDecl = notationDeclSplit;
- if (sax->attributeDecl != NULL)
- schemas_sax.attributeDecl = attributeDeclSplit;
- if (sax->elementDecl != NULL)
- schemas_sax.elementDecl = elementDeclSplit;
- if (sax->unparsedEntityDecl != NULL)
- schemas_sax.unparsedEntityDecl = unparsedEntityDeclSplit;
- if (sax->setDocumentLocator != NULL)
- schemas_sax.setDocumentLocator = setDocumentLocatorSplit;
- if (sax->startDocument != NULL)
- schemas_sax.startDocument = startDocumentSplit;
- if (sax->endDocument != NULL)
- schemas_sax.endDocument = endDocumentSplit;
- if (sax->processingInstruction != NULL)
- schemas_sax.processingInstruction = processingInstructionSplit;
- if (sax->comment != NULL)
- schemas_sax.comment = commentSplit;
- if (sax->warning != NULL)
- schemas_sax.warning = warningSplit;
- if (sax->error != NULL)
- schemas_sax.error = errorSplit;
- if (sax->fatalError != NULL)
- schemas_sax.fatalError = fatalErrorSplit;
- if (sax->getParameterEntity != NULL)
- schemas_sax.getParameterEntity = getParameterEntitySplit;
- if (sax->externalSubset != NULL)
- schemas_sax.externalSubset = externalSubsetSplit;
-
- /*
- * the 6 schemas callback have to go to the splitter functions
- * Note that we use the same text-function for ignorableWhitespace
- * if possible, to prevent the parser from testing for ignorable
- * whitespace.
- */
- schemas_sax.characters = charactersSplit;
- if ((sax->ignorableWhitespace != NULL) &&
- (sax->ignorableWhitespace != sax->characters))
- schemas_sax.ignorableWhitespace = ignorableWhitespaceSplit;
- else
- schemas_sax.ignorableWhitespace = charactersSplit;
- schemas_sax.cdataBlock = cdataBlockSplit;
- schemas_sax.reference = referenceSplit;
- schemas_sax.startElementNs = startElementNsSplit;
- schemas_sax.endElementNs = endElementNsSplit;
- /* ctxt->user_data = &split_block; */
- split_block.user_sax = sax;
- split_block.user_data = user_data;
- }
- ctxt->input = input;
- ctxt->enc = enc;
- ctxt->sax = &schemas_sax;
/*
* prepare the parser
*/
@@ -24442,11 +24541,8 @@
if (pctxt == NULL)
return (-1);
old_sax = pctxt->sax;
- pctxt->sax = &schemas_sax;
- if (sax == NULL)
- pctxt->userData = (void *) ctxt;
- else
- pctxt->userData = &split_block;
+ pctxt->sax = sax;
+ pctxt->userData = user_data;
#if 0
if (options)
xmlCtxtUseOptions(pctxt, options);
@@ -24463,8 +24559,16 @@
ctxt->input = input;
/*
- * Launch the validation
+ * Plug the validation and launch the parsing
*/
+ plug = xmlSchemaSAXPlug(ctxt, &(pctxt->sax), &(pctxt->userData));
+ if (plug == NULL) {
+ ret = -1;
+ goto done;
+ }
+ ctxt->input = input;
+ ctxt->enc = enc;
+ ctxt->sax = pctxt->sax;
ctxt->flags |= XML_SCHEMA_VALID_CTXT_FLAG_STREAM;
ret = xmlSchemaVStart(ctxt);
@@ -24473,15 +24577,19 @@
if (ret == 0)
ret = 1;
}
- ctxt->parserCtxt = NULL;
- ctxt->sax = NULL;
- /* ctxt->user_data = NULL; */
- ctxt->input = NULL;
done:
+ ctxt->parserCtxt = NULL;
+ ctxt->sax = NULL;
+ ctxt->input = NULL;
+ if (plug != NULL) {
+ xmlSchemaSAXUnplug(plug);
+ }
/* cleanup */
- pctxt->sax = old_sax;
- xmlFreeParserCtxt(pctxt);
+ if (pctxt != NULL) {
+ pctxt->sax = old_sax;
+ xmlFreeParserCtxt(pctxt);
+ }
return (ret);
}