mirror of
https://gitlab.gnome.org/GNOME/libxslt
synced 2025-11-04 00:53:12 +03:00
Infrastructure to store extra data in source nodes
Provide a mechanism to store bit flags in nodes from the source document. This will later be used to store key and id status. Provide a function to find the psvi member of a node. Revert any changes to the source document after the transformation.
This commit is contained in:
@@ -5746,6 +5746,37 @@ xsltCountKeys(xsltTransformContextPtr ctxt)
|
|||||||
return(ctxt->nbKeys);
|
return(ctxt->nbKeys);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* xsltCleanupSourceDoc:
|
||||||
|
* @doc: Document
|
||||||
|
*
|
||||||
|
* Resets source node flags and ids stored in 'psvi' member.
|
||||||
|
*/
|
||||||
|
static void
|
||||||
|
xsltCleanupSourceDoc(xmlDocPtr doc) {
|
||||||
|
xmlNodePtr cur = (xmlNodePtr) doc;
|
||||||
|
void **psviPtr;
|
||||||
|
|
||||||
|
while (1) {
|
||||||
|
xsltClearSourceNodeFlags(cur, XSLT_SOURCE_NODE_MASK);
|
||||||
|
psviPtr = xsltGetPSVIPtr(cur);
|
||||||
|
if (psviPtr)
|
||||||
|
*psviPtr = NULL;
|
||||||
|
|
||||||
|
if (cur->children != NULL && cur->type != XML_ENTITY_REF_NODE) {
|
||||||
|
cur = cur->children;
|
||||||
|
} else {
|
||||||
|
while (cur->next == NULL) {
|
||||||
|
cur = cur->parent;
|
||||||
|
if (cur == (xmlNodePtr) doc)
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
cur = cur->next;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* xsltApplyStylesheetInternal:
|
* xsltApplyStylesheetInternal:
|
||||||
* @style: a parsed XSLT stylesheet
|
* @style: a parsed XSLT stylesheet
|
||||||
@@ -6144,6 +6175,9 @@ xsltApplyStylesheetInternal(xsltStylesheetPtr style, xmlDocPtr doc,
|
|||||||
printf("# Reused variables : %d\n", ctxt->cache->dbgReusedVars);
|
printf("# Reused variables : %d\n", ctxt->cache->dbgReusedVars);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
if (ctxt->sourceDocDirty)
|
||||||
|
xsltCleanupSourceDoc(doc);
|
||||||
|
|
||||||
if ((ctxt != NULL) && (userCtxt == NULL))
|
if ((ctxt != NULL) && (userCtxt == NULL))
|
||||||
xsltFreeTransformContext(ctxt);
|
xsltFreeTransformContext(ctxt);
|
||||||
|
|
||||||
|
|||||||
@@ -1786,6 +1786,7 @@ struct _xsltTransformContext {
|
|||||||
int maxTemplateVars;
|
int maxTemplateVars;
|
||||||
unsigned long opLimit;
|
unsigned long opLimit;
|
||||||
unsigned long opCount;
|
unsigned long opCount;
|
||||||
|
int sourceDocDirty;
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|||||||
@@ -1834,6 +1834,141 @@ xsltSaveResultToString(xmlChar **doc_txt_ptr, int * doc_txt_len,
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* xsltGetSourceNodeFlags:
|
||||||
|
* @node: Node from source document
|
||||||
|
*
|
||||||
|
* Returns the flags for a source node.
|
||||||
|
*/
|
||||||
|
int
|
||||||
|
xsltGetSourceNodeFlags(xmlNodePtr node) {
|
||||||
|
/*
|
||||||
|
* Squeeze the bit flags into the upper bits of
|
||||||
|
*
|
||||||
|
* - 'int properties' member in struct _xmlDoc
|
||||||
|
* - 'xmlAttributeType atype' member in struct _xmlAttr
|
||||||
|
* - 'unsigned short extra' member in struct _xmlNode
|
||||||
|
*/
|
||||||
|
switch (node->type) {
|
||||||
|
case XML_DOCUMENT_NODE:
|
||||||
|
case XML_HTML_DOCUMENT_NODE:
|
||||||
|
return ((xmlDocPtr) node)->properties >> 27;
|
||||||
|
|
||||||
|
case XML_ATTRIBUTE_NODE:
|
||||||
|
return ((xmlAttrPtr) node)->atype >> 27;
|
||||||
|
|
||||||
|
case XML_ELEMENT_NODE:
|
||||||
|
case XML_TEXT_NODE:
|
||||||
|
case XML_CDATA_SECTION_NODE:
|
||||||
|
case XML_PI_NODE:
|
||||||
|
case XML_COMMENT_NODE:
|
||||||
|
return node->extra >> 12;
|
||||||
|
|
||||||
|
default:
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* xsltSetSourceNodeFlags:
|
||||||
|
* @node: Node from source document
|
||||||
|
* @flags: Flags
|
||||||
|
*
|
||||||
|
* Sets the specified flags to 1.
|
||||||
|
*
|
||||||
|
* Returns 0 on success, -1 on error.
|
||||||
|
*/
|
||||||
|
int
|
||||||
|
xsltSetSourceNodeFlags(xsltTransformContextPtr ctxt, xmlNodePtr node,
|
||||||
|
int flags) {
|
||||||
|
if (node->doc == ctxt->initialContextDoc)
|
||||||
|
ctxt->sourceDocDirty = 1;
|
||||||
|
|
||||||
|
switch (node->type) {
|
||||||
|
case XML_DOCUMENT_NODE:
|
||||||
|
case XML_HTML_DOCUMENT_NODE:
|
||||||
|
((xmlDocPtr) node)->properties |= flags << 27;
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
case XML_ATTRIBUTE_NODE:
|
||||||
|
((xmlAttrPtr) node)->atype |= flags << 27;
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
case XML_ELEMENT_NODE:
|
||||||
|
case XML_TEXT_NODE:
|
||||||
|
case XML_CDATA_SECTION_NODE:
|
||||||
|
case XML_PI_NODE:
|
||||||
|
case XML_COMMENT_NODE:
|
||||||
|
node->extra |= flags << 12;
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
default:
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* xsltClearSourceNodeFlags:
|
||||||
|
* @node: Node from source document
|
||||||
|
* @flags: Flags
|
||||||
|
*
|
||||||
|
* Sets the specified flags to 0.
|
||||||
|
*
|
||||||
|
* Returns 0 on success, -1 on error.
|
||||||
|
*/
|
||||||
|
int
|
||||||
|
xsltClearSourceNodeFlags(xmlNodePtr node, int flags) {
|
||||||
|
switch (node->type) {
|
||||||
|
case XML_DOCUMENT_NODE:
|
||||||
|
case XML_HTML_DOCUMENT_NODE:
|
||||||
|
((xmlDocPtr) node)->properties &= ~(flags << 27);
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
case XML_ATTRIBUTE_NODE:
|
||||||
|
((xmlAttrPtr) node)->atype &= ~(flags << 27);
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
case XML_ELEMENT_NODE:
|
||||||
|
case XML_TEXT_NODE:
|
||||||
|
case XML_CDATA_SECTION_NODE:
|
||||||
|
case XML_PI_NODE:
|
||||||
|
case XML_COMMENT_NODE:
|
||||||
|
node->extra &= ~(flags << 12);
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
default:
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* xsltGetPSVIPtr:
|
||||||
|
* @cur: Node
|
||||||
|
*
|
||||||
|
* Returns a pointer to the psvi member of a node or NULL on error.
|
||||||
|
*/
|
||||||
|
void **
|
||||||
|
xsltGetPSVIPtr(xmlNodePtr cur) {
|
||||||
|
switch (cur->type) {
|
||||||
|
case XML_DOCUMENT_NODE:
|
||||||
|
case XML_HTML_DOCUMENT_NODE:
|
||||||
|
return &((xmlDocPtr) cur)->psvi;
|
||||||
|
|
||||||
|
case XML_ATTRIBUTE_NODE:
|
||||||
|
return &((xmlAttrPtr) cur)->psvi;
|
||||||
|
|
||||||
|
case XML_ELEMENT_NODE:
|
||||||
|
case XML_TEXT_NODE:
|
||||||
|
case XML_CDATA_SECTION_NODE:
|
||||||
|
case XML_PI_NODE:
|
||||||
|
case XML_COMMENT_NODE:
|
||||||
|
return &cur->psvi;
|
||||||
|
|
||||||
|
default:
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
#ifdef WITH_PROFILER
|
#ifdef WITH_PROFILER
|
||||||
|
|
||||||
/************************************************************************
|
/************************************************************************
|
||||||
|
|||||||
@@ -244,6 +244,19 @@ XSLTPUBFUN xmlXPathCompExprPtr XSLTCALL
|
|||||||
const xmlChar *str,
|
const xmlChar *str,
|
||||||
int flags);
|
int flags);
|
||||||
|
|
||||||
|
#ifdef IN_LIBXSLT
|
||||||
|
#define XSLT_SOURCE_NODE_MASK 15
|
||||||
|
int
|
||||||
|
xsltGetSourceNodeFlags(xmlNodePtr node);
|
||||||
|
int
|
||||||
|
xsltSetSourceNodeFlags(xsltTransformContextPtr ctxt, xmlNodePtr node,
|
||||||
|
int flags);
|
||||||
|
int
|
||||||
|
xsltClearSourceNodeFlags(xmlNodePtr node, int flags);
|
||||||
|
void **
|
||||||
|
xsltGetPSVIPtr(xmlNodePtr cur);
|
||||||
|
#endif
|
||||||
|
|
||||||
#ifdef WITH_PROFILER
|
#ifdef WITH_PROFILER
|
||||||
/*
|
/*
|
||||||
* Profiling.
|
* Profiling.
|
||||||
|
|||||||
Reference in New Issue
Block a user