more performance hunting reducing memory allocation and free and avoiding
* SAX2.c xmlreader.c include/libxml/parser.h: more performance hunting
reducing memory allocation and free and avoiding expensive routines
Daniel
diff --git a/SAX2.c b/SAX2.c
index ff26fcf..82bc4a7 100644
--- a/SAX2.c
+++ b/SAX2.c
@@ -1565,6 +1565,47 @@
}
/*
+ * xmlSAX2TextNode:
+ * @ctxt: the parser context
+ * @str: the input string
+ * @len: the string length
+ *
+ * Remove the entities from an attribute value
+ *
+ * Returns the newly allocated string or NULL if not needed or error
+ */
+static xmlNodePtr
+xmlSAX2TextNode(xmlParserCtxtPtr ctxt, const xmlChar *str, int len) {
+ xmlNodePtr ret;
+
+ if (ctxt->freeElems != NULL) {
+ ret = ctxt->freeElems;
+ ctxt->freeElems = ret->next;
+ ctxt->freeElemsNr--;
+ memset(ret, 0, sizeof(xmlNode));
+ ret->type = XML_TEXT_NODE;
+
+ ret->name = xmlStringText;
+ ret->content = xmlStrndup(str, len);
+
+ if ((__xmlRegisterCallbacks) && (xmlRegisterNodeDefaultValue))
+ xmlRegisterNodeDefaultValue(ret);
+ } else {
+ ret = xmlNewTextLen(str, len);
+ }
+ if (ret == NULL) {
+ if ((ctxt->sax != NULL) && (ctxt->sax->error != NULL))
+ ctxt->sax->error(ctxt->userData,
+ "SAX.xmlSAX2Characters(): out of memory\n");
+ ctxt->errNo = XML_ERR_NO_MEMORY;
+ ctxt->instate = XML_PARSER_EOF;
+ ctxt->disableSAX = 1;
+ return(NULL);
+ }
+ return(ret);
+}
+
+/*
* xmlSAX2DecodeAttrEntities:
* @ctxt: the parser context
* @str: the input string
@@ -1630,6 +1671,7 @@
if (ctxt->freeAttrs != NULL) {
ret = ctxt->freeAttrs;
ctxt->freeAttrs = ret->next;
+ ctxt->freeAttrsNr--;
memset(ret, 0, sizeof(xmlAttr));
ret->type = XML_ATTRIBUTE_NODE;
@@ -1672,21 +1714,40 @@
if ((ctxt->replaceEntities == 0) && (!ctxt->html)) {
xmlNodePtr tmp;
- ret->children = xmlStringLenGetNodeList(ctxt->myDoc, value,
- valueend - value);
- tmp = ret->children;
- while (tmp != NULL) {
- tmp->parent = (xmlNodePtr) ret;
- if (tmp->next == NULL)
- ret->last = tmp;
- tmp = tmp->next;
+ /*
+ * We know that if there is an entity reference, then
+ * the string has been dup'ed and terminates with 0
+ * otherwise with ' or "
+ */
+ if (*valueend != 0) {
+ tmp = xmlSAX2TextNode(ctxt, value, valueend - value);
+ ret->children = tmp;
+ ret->last = tmp;
+ if (tmp != NULL) {
+ tmp->doc = ret->doc;
+ tmp->parent = (xmlNodePtr) ret;
+ }
+ } else {
+ ret->children = xmlStringLenGetNodeList(ctxt->myDoc, value,
+ valueend - value);
+ tmp = ret->children;
+ while (tmp != NULL) {
+ tmp->parent = (xmlNodePtr) ret;
+ if (tmp->next == NULL)
+ ret->last = tmp;
+ tmp = tmp->next;
+ }
}
} else if (value != NULL) {
- ret->children = xmlNewDocTextLen(ctxt->myDoc, value,
- valueend - value);
- ret->last = ret->children;
- if (ret->children != NULL)
- ret->children->parent = (xmlNodePtr) ret;
+ xmlNodePtr tmp;
+
+ tmp = xmlSAX2TextNode(ctxt, value, valueend - value);
+ ret->children = tmp;
+ ret->last = tmp;
+ if (tmp != NULL) {
+ tmp->doc = ret->doc;
+ tmp->parent = (xmlNodePtr) ret;
+ }
}
if ((!ctxt->html) && ctxt->validate && ctxt->wellFormed &&
@@ -1837,6 +1898,7 @@
if (ctxt->freeElems != NULL) {
ret = ctxt->freeElems;
ctxt->freeElems = ret->next;
+ ctxt->freeElemsNr--;
memset(ret, 0, sizeof(xmlNode));
ret->type = XML_ELEMENT_NODE;
@@ -2056,7 +2118,7 @@
#endif
return;
}
- lastChild = xmlGetLastChild(ctxt->node);
+ lastChild = ctxt->node->last;
#ifdef DEBUG_SAX_TREE
xmlGenericError(xmlGenericErrorContext,
"add chars to %s \n", ctxt->node->name);
@@ -2067,9 +2129,12 @@
* elements. Use an attribute in the structure !!!
*/
if (lastChild == NULL) {
- /* first node, first time */
- xmlNodeAddContentLen(ctxt->node, ch, len);
- if (ctxt->node->children != NULL) {
+ lastChild = xmlSAX2TextNode(ctxt, ch, len);
+ if (lastChild != NULL) {
+ ctxt->node->children = lastChild;
+ ctxt->node->last = lastChild;
+ lastChild->parent = ctxt->node;
+ lastChild->doc = ctxt->node->doc;
ctxt->nodelen = len;
ctxt->nodemem = len + 1;
}
@@ -2122,15 +2187,8 @@
}
} else {
/* Mixed content, first time */
- lastChild = xmlNewTextLen(ch, len);
- if (lastChild == NULL) {
- if ((ctxt->sax != NULL) && (ctxt->sax->error != NULL))
- ctxt->sax->error(ctxt->userData,
- "SAX.xmlSAX2Characters(): out of memory\n");
- ctxt->errNo = XML_ERR_NO_MEMORY;
- ctxt->instate = XML_PARSER_EOF;
- ctxt->disableSAX = 1;
- } else {
+ lastChild = xmlSAX2TextNode(ctxt, ch, len);
+ if (lastChild != NULL) {
xmlAddChild(ctxt->node, lastChild);
if (ctxt->node->children != NULL) {
ctxt->nodelen = len;