1
0
mirror of https://gitlab.gnome.org/GNOME/libxml2.git synced 2025-07-29 11:41:22 +03:00

- added the patch from Carl Nygard <cnygard@bellatlantic.net>

which allow impressive speed improvement on dataset with large text
   pieces, but at the cost of broken binary compatibility and slightly
   bigger memory usage.  Configure with --with-buffers to activate them,
   they are protected with XML_USE_BUFFER_CONTENT define.
 - added xmlCleanupPredefinedEntities(), memory allocation cleanup
Daniel
This commit is contained in:
Daniel Veillard
1999-12-01 09:51:45 +00:00
parent a0555cc9ec
commit f5c2c8707a
11 changed files with 484 additions and 123 deletions

View File

@ -1,3 +1,17 @@
Wed Dec 1 10:27:47 CET 1999 Daniel Veillard <Daniel.Veillard@w3.org>
* tree.[ch] HTMLtree.c, debugXML.c, configure.in, xml-config.in:
added the patch from Carl Nygard <cnygard@bellatlantic.net>
which allow impressive speed improvement on dataset with
large text pieces, but at the cost of broken binary
compatibility and slightly bigger memory usage.
Configure with --with-buffers to activate them, they
are protected with XML_USE_BUFFER_CONTENT define.
* entities.[ch], parser.c: added xmlCleanupPredefinedEntities(),
goal is 0 memory left allocated once parser is no more used
* testDAV.c, testHTML.c, testSAX.c, testXPath.c: make sure we
call xmlCleanupParser() and xmlMemoryDump()
Wed Nov 24 19:00:06 CET 1999 Daniel Veillard <Daniel.Veillard@w3.org> Wed Nov 24 19:00:06 CET 1999 Daniel Veillard <Daniel.Veillard@w3.org>
* tree.[ch] xmlIO.[ch] parser.c valid.c: code cleanup with -pedantic * tree.[ch] xmlIO.[ch] parser.c valid.c: code cleanup with -pedantic

View File

@ -103,6 +103,11 @@ XML_LIBDIR='-L${libdir}'
XML_INCLUDEDIR='-I${includedir}/gnome-xml' XML_INCLUDEDIR='-I${includedir}/gnome-xml'
XML_LIBS="-lxml $Z_LIBS $M_LIBS $LIBS" XML_LIBS="-lxml $Z_LIBS $M_LIBS $LIBS"
dnl
dnl Extra flags
dnl
XML_CFLAGS=""
dnl dnl
dnl Workaround wor HP native compiler dnl Workaround wor HP native compiler
dnl http://bugs.gnome.org/db/31/3163.html dnl http://bugs.gnome.org/db/31/3163.html
@ -114,7 +119,19 @@ if test "${CC}" != "gcc" ; then
;; ;;
esac esac
fi fi
dnl
dnl Use buffers for content
dnl
AC_ARG_WITH(buffers, [ --with-buffers Use buffers for node content])
if test "$with_buffers" = "yes" ; then
CFLAGS="${CFLAGS} -DXML_USE_BUFFER_CONTENT"
XML_CFLAGS="${XML_CFLAGS} -DXML_USE_BUFFER_CONTENT"
fi
AC_SUBST(CFLAGS) AC_SUBST(CFLAGS)
AC_SUBST(XML_CFLAGS)
AC_SUBST(XML_LIBDIR) AC_SUBST(XML_LIBDIR)
AC_SUBST(XML_LIBS) AC_SUBST(XML_LIBS)

View File

@ -179,7 +179,11 @@ void xmlDebugDumpOneNode(FILE *output, xmlNodePtr node, int depth) {
if (node->content != NULL) { if (node->content != NULL) {
fprintf(output, shift); fprintf(output, shift);
fprintf(output, "content="); fprintf(output, "content=");
#ifndef XML_USE_BUFFER_CONTENT
xmlDebugDumpString(output, node->content); xmlDebugDumpString(output, node->content);
#else
xmlDebugDumpString(output, xmlBufferContent(node->content));
#endif
fprintf(output, "\n"); fprintf(output, "\n");
} }
} else { } else {

View File

@ -229,6 +229,24 @@ typedef struct xmlRef {
} xmlRef; } xmlRef;
typedef xmlRef *xmlRefPtr; typedef xmlRef *xmlRefPtr;
/*
* A buffer structure
*/
typedef enum {
XML_BUFFER_ALLOC_DOUBLEIT,
XML_BUFFER_ALLOC_EXACT
} xmlBufferAllocationScheme;
typedef struct xmlBuffer {
xmlChar *content; /* The buffer content UTF8 */
unsigned int use; /* The buffer size used */
unsigned int size; /* The buffer size */
xmlBufferAllocationScheme alloc; /* The realloc method */
} _xmlBuffer;
typedef _xmlBuffer xmlBuffer;
typedef xmlBuffer *xmlBufferPtr;
/* /*
* A node in an XML tree. * A node in an XML tree.
*/ */
@ -248,7 +266,11 @@ typedef struct xmlNode {
const xmlChar *name; /* the name of the node, or the entity */ const xmlChar *name; /* the name of the node, or the entity */
xmlNs *ns; /* pointer to the associated namespace */ xmlNs *ns; /* pointer to the associated namespace */
xmlNs *nsDef; /* namespace definitions on this node */ xmlNs *nsDef; /* namespace definitions on this node */
#ifndef XML_USE_BUFFER_CONTENT
xmlChar *content; /* the content */ xmlChar *content; /* the content */
#else
xmlBufferPtr content; /* the content in a buffer */
#endif
} _xmlNode; } _xmlNode;
typedef _xmlNode xmlNode; typedef _xmlNode xmlNode;
typedef _xmlNode *xmlNodePtr; typedef _xmlNode *xmlNodePtr;
@ -277,30 +299,20 @@ typedef struct xmlDoc {
typedef _xmlDoc xmlDoc; typedef _xmlDoc xmlDoc;
typedef xmlDoc *xmlDocPtr; typedef xmlDoc *xmlDocPtr;
/*
* A buffer structure
*/
typedef struct xmlBuffer {
xmlChar *content; /* The buffer content UTF8 */
unsigned int use; /* The buffer size used */
unsigned int size; /* The buffer size */
} _xmlBuffer;
typedef _xmlBuffer xmlBuffer;
typedef xmlBuffer *xmlBufferPtr;
/* /*
* Variables. * Variables.
*/ */
extern xmlNsPtr baseDTD; extern xmlNsPtr baseDTD;
extern int oldXMLWDcompatibility;/* maintain compatibility with old WD */ extern int oldXMLWDcompatibility;/* maintain compatibility with old WD */
extern int xmlIndentTreeOutput; /* try to indent the tree dumps */ extern int xmlIndentTreeOutput; /* try to indent the tree dumps */
extern xmlBufferAllocationScheme xmlBufferAllocScheme; /* alloc scheme to use */
/* /*
* Handling Buffers. * Handling Buffers.
*/ */
xmlBufferPtr xmlBufferCreate (void); xmlBufferPtr xmlBufferCreate (void);
xmlBufferPtr xmlBufferCreateSize (size_t size);
void xmlBufferFree (xmlBufferPtr buf); void xmlBufferFree (xmlBufferPtr buf);
int xmlBufferDump (FILE *file, int xmlBufferDump (FILE *file,
xmlBufferPtr buf); xmlBufferPtr buf);
@ -314,6 +326,11 @@ void xmlBufferCCat (xmlBufferPtr buf,
int xmlBufferShrink (xmlBufferPtr buf, int xmlBufferShrink (xmlBufferPtr buf,
int len); int len);
void xmlBufferEmpty (xmlBufferPtr buf); void xmlBufferEmpty (xmlBufferPtr buf);
const xmlChar* xmlBufferContent (const xmlBufferPtr buf);
int xmlBufferUse (const xmlBufferPtr buf);
void xmlBufferSetAllocationScheme(xmlBufferPtr buf,
xmlBufferAllocationScheme scheme);
int xmlBufferLength (const xmlBufferPtr buf);
/* /*
* Creating/freeing new structures * Creating/freeing new structures

View File

@ -6740,6 +6740,7 @@ int xmlSAXUserParseMemory(xmlSAXHandlerPtr sax, void *user_data,
void void
xmlCleanupParser(void) { xmlCleanupParser(void) {
xmlCleanupCharEncodingHandlers(); xmlCleanupCharEncodingHandlers();
xmlCleanupPredefinedEntities();
} }
/** /**

View File

@ -712,6 +712,7 @@ int main(int argc, char **argv) {
printf("\t--repeat : parse the file 100 times, for timing or profiling\n"); printf("\t--repeat : parse the file 100 times, for timing or profiling\n");
printf("\t--noout : do not print the result\n"); printf("\t--noout : do not print the result\n");
} }
xmlCleanupParser();
xmlMemoryDump(); xmlMemoryDump();
return(0); return(0);

View File

@ -41,6 +41,7 @@
#include "parserInternals.h" /* only for xmlNewInputFromFile() */ #include "parserInternals.h" /* only for xmlNewInputFromFile() */
#include "tree.h" #include "tree.h"
#include "debugXML.h" #include "debugXML.h"
#include "xmlmemory.h"
static int debug = 0; static int debug = 0;
static int copy = 0; static int copy = 0;
@ -648,6 +649,8 @@ int main(int argc, char **argv) {
printf("\nFirst test for the parser, with errors\n"); printf("\nFirst test for the parser, with errors\n");
parseAndPrintBuffer(buffer); parseAndPrintBuffer(buffer);
} }
xmlCleanupParser();
xmlMemoryDump();
return(0); return(0);
} }

View File

@ -37,6 +37,7 @@
#include "tree.h" #include "tree.h"
#include "parser.h" #include "parser.h"
#include "debugXML.h" #include "debugXML.h"
#include "xmlmemory.h"
static int debug = 0; static int debug = 0;
static int expr = 0; static int expr = 0;
@ -204,6 +205,10 @@ int main(int argc, char **argv) {
printf("\t--file : or\n"); printf("\t--file : or\n");
printf("\t-f : read queries from files, args\n"); printf("\t-f : read queries from files, args\n");
} }
if (document != NULL)
xmlFreeDoc(document);
xmlCleanupParser();
xmlMemoryDump();
return(0); return(0);
} }

478
tree.c
View File

@ -34,6 +34,7 @@
static xmlChar xmlStringText[] = { 't', 'e', 'x', 't', 0 }; static xmlChar xmlStringText[] = { 't', 'e', 'x', 't', 0 };
int oldXMLWDcompatibility = 0; int oldXMLWDcompatibility = 0;
int xmlIndentTreeOutput = 1; int xmlIndentTreeOutput = 1;
xmlBufferAllocationScheme xmlBufferAllocScheme = XML_BUFFER_ALLOC_EXACT;
static int xmlCompressMode = 0; static int xmlCompressMode = 0;
@ -52,6 +53,35 @@ static int xmlCompressMode = 0;
* * * *
************************************************************************/ ************************************************************************/
/**
* xmlSetBufferAllocationScheme:
* @scheme: allocation method to use
*
* Set the buffer allocation method. Types are
* XML_BUFFER_ALLOC_EXACT - use exact sizes, keeps memory usage down
* XML_BUFFER_ALLOC_DOUBLEIT - double buffer when extra needed,
* improves performance
*/
void
xmlSetBufferAllocationScheme(xmlBufferAllocationScheme scheme) {
xmlBufferAllocScheme = scheme;
}
/**
* xmlGetBufferAllocationScheme:
*
* Types are
* XML_BUFFER_ALLOC_EXACT - use exact sizes, keeps memory usage down
* XML_BUFFER_ALLOC_DOUBLEIT - double buffer when extra needed,
* improves performance
*
* Returns the current allocation scheme
*/
xmlBufferAllocationScheme
xmlGetBufferAllocationScheme() {
return xmlBufferAllocScheme;
}
/** /**
* xmlUpgradeOldNs: * xmlUpgradeOldNs:
* @doc: a document pointer * @doc: a document pointer
@ -684,12 +714,21 @@ xmlNodeListGetString(xmlDocPtr doc, xmlNodePtr list, int inLine) {
while (node != NULL) { while (node != NULL) {
if (node->type == XML_TEXT_NODE) { if (node->type == XML_TEXT_NODE) {
if ((inLine) || (doc->type == XML_HTML_DOCUMENT_NODE)) if ((inLine) || (doc->type == XML_HTML_DOCUMENT_NODE)) {
#ifndef XML_USE_BUFFER_CONTENT
ret = xmlStrcat(ret, node->content); ret = xmlStrcat(ret, node->content);
else { #else
ret = xmlStrcat(ret, xmlBufferContent(node->content));
#endif
} else {
xmlChar *buffer; xmlChar *buffer;
#ifndef XML_USE_BUFFER_CONTENT
buffer = xmlEncodeEntitiesReentrant(doc, node->content); buffer = xmlEncodeEntitiesReentrant(doc, node->content);
#else
buffer = xmlEncodeEntitiesReentrant(doc,
xmlBufferContent(node->content));
#endif
if (buffer != NULL) { if (buffer != NULL) {
ret = xmlStrcat(ret, buffer); ret = xmlStrcat(ret, buffer);
xmlFree(buffer); xmlFree(buffer);
@ -700,8 +739,13 @@ xmlNodeListGetString(xmlDocPtr doc, xmlNodePtr list, int inLine) {
ent = xmlGetDocEntity(doc, node->name); ent = xmlGetDocEntity(doc, node->name);
if (ent != NULL) if (ent != NULL)
ret = xmlStrcat(ret, ent->content); ret = xmlStrcat(ret, ent->content);
else else {
#ifndef XML_USE_BUFFER_CONTENT
ret = xmlStrcat(ret, node->content); ret = xmlStrcat(ret, node->content);
#else
ret = xmlStrcat(ret, xmlBufferContent(node->content));
#endif
}
} else { } else {
xmlChar buf[2]; xmlChar buf[2];
buf[0] = '&'; buf[1] = 0; buf[0] = '&'; buf[1] = 0;
@ -964,9 +1008,16 @@ xmlNewPI(const xmlChar *name, const xmlChar *content) {
cur->name = xmlStrdup(name); cur->name = xmlStrdup(name);
cur->ns = NULL; cur->ns = NULL;
cur->nsDef = NULL; cur->nsDef = NULL;
if (content != NULL) if (content != NULL) {
#ifndef XML_USE_BUFFER_CONTENT
cur->content = xmlStrdup(content); cur->content = xmlStrdup(content);
else #else
cur->content = xmlBufferCreateSize(0);
xmlBufferSetAllocationScheme(cur->content,
xmlGetBufferAllocationScheme());
xmlBufferAdd(cur->content, content, -1);
#endif
} else
cur->content = NULL; cur->content = NULL;
#ifndef XML_WITHOUT_CORBA #ifndef XML_WITHOUT_CORBA
cur->_private = NULL; cur->_private = NULL;
@ -1116,9 +1167,16 @@ xmlNewText(const xmlChar *content) {
cur->name = xmlStrdup(xmlStringText); cur->name = xmlStrdup(xmlStringText);
cur->ns = NULL; cur->ns = NULL;
cur->nsDef = NULL; cur->nsDef = NULL;
if (content != NULL) if (content != NULL) {
#ifndef XML_USE_BUFFER_CONTENT
cur->content = xmlStrdup(content); cur->content = xmlStrdup(content);
else #else
cur->content = xmlBufferCreateSize(0);
xmlBufferSetAllocationScheme(cur->content,
xmlGetBufferAllocationScheme());
xmlBufferAdd(cur->content, content, -1);
#endif
} else
cur->content = NULL; cur->content = NULL;
#ifndef XML_WITHOUT_CORBA #ifndef XML_WITHOUT_CORBA
cur->_private = NULL; cur->_private = NULL;
@ -1227,9 +1285,22 @@ xmlNewReference(xmlDocPtr doc, const xmlChar *name) {
cur->nsDef = NULL; cur->nsDef = NULL;
ent = xmlGetDocEntity(doc, cur->name); ent = xmlGetDocEntity(doc, cur->name);
if (ent != NULL) if (ent != NULL) {
#ifndef XML_USE_BUFFER_CONTENT
cur->content = ent->content; cur->content = ent->content;
else #else
/*
* CJN 11.18.99 this might be a problem, since the xmlBuffer gets
* a copy of this pointer. Let's hope we don't manipulate it
* later
*/
cur->content = xmlBufferCreateSize(0);
xmlBufferSetAllocationScheme(cur->content,
xmlGetBufferAllocationScheme());
if (ent->content != NULL)
xmlBufferAdd(cur->content, ent->content, -1);
#endif
} else
cur->content = NULL; cur->content = NULL;
#ifndef XML_WITHOUT_CORBA #ifndef XML_WITHOUT_CORBA
cur->_private = NULL; cur->_private = NULL;
@ -1288,9 +1359,16 @@ xmlNewTextLen(const xmlChar *content, int len) {
cur->name = xmlStrdup(xmlStringText); cur->name = xmlStrdup(xmlStringText);
cur->ns = NULL; cur->ns = NULL;
cur->nsDef = NULL; cur->nsDef = NULL;
if (content != NULL) if (content != NULL) {
#ifndef XML_USE_BUFFER_CONTENT
cur->content = xmlStrndup(content, len); cur->content = xmlStrndup(content, len);
else #else
cur->content = xmlBufferCreateSize(len);
xmlBufferSetAllocationScheme(cur->content,
xmlGetBufferAllocationScheme());
xmlBufferAdd(cur->content, content, len);
#endif
} else
cur->content = NULL; cur->content = NULL;
#ifndef XML_WITHOUT_CORBA #ifndef XML_WITHOUT_CORBA
cur->_private = NULL; cur->_private = NULL;
@ -1350,9 +1428,16 @@ xmlNewComment(const xmlChar *content) {
cur->name = xmlStrdup(xmlStringText); cur->name = xmlStrdup(xmlStringText);
cur->ns = NULL; cur->ns = NULL;
cur->nsDef = NULL; cur->nsDef = NULL;
if (content != NULL) if (content != NULL) {
#ifndef XML_USE_BUFFER_CONTENT
cur->content = xmlStrdup(content); cur->content = xmlStrdup(content);
else #else
cur->content = xmlBufferCreateSize(0);
xmlBufferSetAllocationScheme(cur->content,
xmlGetBufferAllocationScheme());
xmlBufferAdd(cur->content, content, -1);
#endif
} else
cur->content = NULL; cur->content = NULL;
#ifndef XML_WITHOUT_CORBA #ifndef XML_WITHOUT_CORBA
cur->_private = NULL; cur->_private = NULL;
@ -1394,8 +1479,15 @@ xmlNewCDataBlock(xmlDocPtr doc, const xmlChar *content, int len) {
cur->name = xmlStrdup(xmlStringText); cur->name = xmlStrdup(xmlStringText);
cur->ns = NULL; cur->ns = NULL;
cur->nsDef = NULL; cur->nsDef = NULL;
if ((content != NULL) && (len > 0)) { if (content != NULL) {
#ifndef XML_USE_BUFFER_CONTENT
cur->content = xmlStrndup(content, len); cur->content = xmlStrndup(content, len);
#else
cur->content = xmlBufferCreateSize(len);
xmlBufferSetAllocationScheme(cur->content,
xmlGetBufferAllocationScheme());
xmlBufferAdd(cur->content, content, len);
#endif
} else } else
cur->content = NULL; cur->content = NULL;
#ifndef XML_WITHOUT_CORBA #ifndef XML_WITHOUT_CORBA
@ -1567,14 +1659,22 @@ xmlAddChild(xmlNodePtr parent, xmlNodePtr cur) {
if (parent->content != NULL) { if (parent->content != NULL) {
xmlNodePtr text; xmlNodePtr text;
#ifndef XML_USE_BUFFER_CONTENT
text = xmlNewDocText(parent->doc, parent->content); text = xmlNewDocText(parent->doc, parent->content);
#else
text = xmlNewDocText(parent->doc, xmlBufferContent(parent->content));
#endif
if (text != NULL) { if (text != NULL) {
text->next = parent->childs; text->next = parent->childs;
if (text->next != NULL) if (text->next != NULL)
text->next->prev = text; text->next->prev = text;
parent->childs = text; parent->childs = text;
UPDATE_LAST_CHILD(parent) UPDATE_LAST_CHILD(parent)
#ifndef XML_USE_BUFFER_CONTENT
xmlFree(parent->content); xmlFree(parent->content);
#else
xmlBufferFree(parent->content);
#endif
parent->content = NULL; parent->content = NULL;
} }
} }
@ -1647,7 +1747,11 @@ xmlFreeNode(xmlNodePtr cur) {
if (cur->childs != NULL) xmlFreeNodeList(cur->childs); if (cur->childs != NULL) xmlFreeNodeList(cur->childs);
if (cur->properties != NULL) xmlFreePropList(cur->properties); if (cur->properties != NULL) xmlFreePropList(cur->properties);
if (cur->type != XML_ENTITY_REF_NODE) if (cur->type != XML_ENTITY_REF_NODE)
#ifndef XML_USE_BUFFER_CONTENT
if (cur->content != NULL) xmlFree(cur->content); if (cur->content != NULL) xmlFree(cur->content);
#else
if (cur->content != NULL) xmlBufferFree(cur->content);
#endif
if (cur->name != NULL) xmlFree((char *) cur->name); if (cur->name != NULL) xmlFree((char *) cur->name);
if (cur->nsDef != NULL) xmlFreeNsList(cur->nsDef); if (cur->nsDef != NULL) xmlFreeNsList(cur->nsDef);
memset(cur, -1, sizeof(xmlNode)); memset(cur, -1, sizeof(xmlNode));
@ -1844,9 +1948,18 @@ xmlStaticCopyNode(xmlNodePtr node, xmlDocPtr doc, xmlNodePtr parent,
ret->name = NULL; ret->name = NULL;
ret->ns = NULL; ret->ns = NULL;
ret->nsDef = NULL; ret->nsDef = NULL;
if ((node->content != NULL) && (node->type != XML_ENTITY_REF_NODE)) if ((node->content != NULL) && (node->type != XML_ENTITY_REF_NODE)) {
#ifndef XML_USE_BUFFER_CONTENT
ret->content = xmlStrdup(node->content); ret->content = xmlStrdup(node->content);
else #else
ret->content = xmlBufferCreateSize(xmlBufferLength(node->content));
xmlBufferSetAllocationScheme(ret->content,
xmlGetBufferAllocationScheme());
xmlBufferAdd(ret->content,
xmlBufferContent(node->content),
xmlBufferLength(node->content));
#endif
} else
ret->content = NULL; ret->content = NULL;
#ifndef XML_WITHOUT_CORBA #ifndef XML_WITHOUT_CORBA
ret->_private = NULL; ret->_private = NULL;
@ -2107,7 +2220,11 @@ xmlNodeGetContent(xmlNodePtr cur) {
} }
case XML_PI_NODE: case XML_PI_NODE:
if (cur->content != NULL) if (cur->content != NULL)
#ifndef XML_USE_BUFFER_CONTENT
return(xmlStrdup(cur->content)); return(xmlStrdup(cur->content));
#else
return(xmlStrdup(xmlBufferContent(cur->content)));
#endif
return(NULL); return(NULL);
case XML_ENTITY_REF_NODE: case XML_ENTITY_REF_NODE:
case XML_ENTITY_NODE: case XML_ENTITY_NODE:
@ -2120,7 +2237,11 @@ xmlNodeGetContent(xmlNodePtr cur) {
case XML_CDATA_SECTION_NODE: case XML_CDATA_SECTION_NODE:
case XML_TEXT_NODE: case XML_TEXT_NODE:
if (cur->content != NULL) if (cur->content != NULL)
#ifndef XML_USE_BUFFER_CONTENT
return(xmlStrdup(cur->content)); return(xmlStrdup(cur->content));
#else
return(xmlStrdup(xmlBufferContent(cur->content)));
#endif
return(NULL); return(NULL);
} }
return(NULL); return(NULL);
@ -2143,7 +2264,11 @@ xmlNodeSetContent(xmlNodePtr cur, const xmlChar *content) {
case XML_DOCUMENT_FRAG_NODE: case XML_DOCUMENT_FRAG_NODE:
case XML_ELEMENT_NODE: case XML_ELEMENT_NODE:
if (cur->content != NULL) { if (cur->content != NULL) {
#ifndef XML_USE_BUFFER_CONTENT
xmlFree(cur->content); xmlFree(cur->content);
#else
xmlBufferFree(cur->content);
#endif
cur->content = NULL; cur->content = NULL;
} }
if (cur->childs != NULL) xmlFreeNodeList(cur->childs); if (cur->childs != NULL) xmlFreeNodeList(cur->childs);
@ -2158,12 +2283,25 @@ xmlNodeSetContent(xmlNodePtr cur, const xmlChar *content) {
case XML_ENTITY_NODE: case XML_ENTITY_NODE:
case XML_PI_NODE: case XML_PI_NODE:
case XML_COMMENT_NODE: case XML_COMMENT_NODE:
if (cur->content != NULL) xmlFree(cur->content); if (cur->content != NULL) {
#ifndef XML_USE_BUFFER_CONTENT
xmlFree(cur->content);
#else
xmlBufferFree(cur->content);
#endif
}
if (cur->childs != NULL) xmlFreeNodeList(cur->childs); if (cur->childs != NULL) xmlFreeNodeList(cur->childs);
cur->last = cur->childs = NULL; cur->last = cur->childs = NULL;
if (content != NULL) if (content != NULL) {
#ifndef XML_USE_BUFFER_CONTENT
cur->content = xmlStrdup(content); cur->content = xmlStrdup(content);
else #else
cur->content = xmlBufferCreateSize(0);
xmlBufferSetAllocationScheme(cur->content,
xmlGetBufferAllocationScheme());
xmlBufferAdd(cur->content, content, -1);
#endif
} else
cur->content = NULL; cur->content = NULL;
break; break;
case XML_DOCUMENT_NODE: case XML_DOCUMENT_NODE:
@ -2193,7 +2331,11 @@ xmlNodeSetContentLen(xmlNodePtr cur, const xmlChar *content, int len) {
case XML_DOCUMENT_FRAG_NODE: case XML_DOCUMENT_FRAG_NODE:
case XML_ELEMENT_NODE: case XML_ELEMENT_NODE:
if (cur->content != NULL) { if (cur->content != NULL) {
#ifndef XML_USE_BUFFER_CONTENT
xmlFree(cur->content); xmlFree(cur->content);
#else
xmlBufferFree(cur->content);
#endif
cur->content = NULL; cur->content = NULL;
} }
if (cur->childs != NULL) xmlFreeNodeList(cur->childs); if (cur->childs != NULL) xmlFreeNodeList(cur->childs);
@ -2208,27 +2350,32 @@ xmlNodeSetContentLen(xmlNodePtr cur, const xmlChar *content, int len) {
case XML_ENTITY_NODE: case XML_ENTITY_NODE:
case XML_PI_NODE: case XML_PI_NODE:
case XML_COMMENT_NODE: case XML_COMMENT_NODE:
if (cur->content != NULL) xmlFree(cur->content); case XML_NOTATION_NODE:
if (cur->content != NULL) {
#ifndef XML_USE_BUFFER_CONTENT
xmlFree(cur->content);
#else
xmlBufferFree(cur->content);
#endif
}
if (cur->childs != NULL) xmlFreeNodeList(cur->childs); if (cur->childs != NULL) xmlFreeNodeList(cur->childs);
cur->childs = cur->last = NULL; cur->childs = cur->last = NULL;
if (content != NULL) if (content != NULL) {
#ifndef XML_USE_BUFFER_CONTENT
cur->content = xmlStrndup(content, len); cur->content = xmlStrndup(content, len);
else #else
cur->content = xmlBufferCreateSize(len);
xmlBufferSetAllocationScheme(cur->content,
xmlGetBufferAllocationScheme());
xmlBufferAdd(cur->content, content, len);
#endif
} else
cur->content = NULL; cur->content = NULL;
break; break;
case XML_DOCUMENT_NODE: case XML_DOCUMENT_NODE:
case XML_HTML_DOCUMENT_NODE: case XML_HTML_DOCUMENT_NODE:
case XML_DOCUMENT_TYPE_NODE: case XML_DOCUMENT_TYPE_NODE:
break; break;
case XML_NOTATION_NODE:
if (cur->content != NULL) xmlFree(cur->content);
if (cur->childs != NULL) xmlFreeNodeList(cur->childs);
cur->childs = cur->last = NULL;
if (content != NULL)
cur->content = xmlStrndup(content, len);
else
cur->content = NULL;
break;
} }
} }
@ -2256,9 +2403,18 @@ xmlNodeAddContentLen(xmlNodePtr cur, const xmlChar *content, int len) {
last = cur->last; last = cur->last;
} else { } else {
if (cur->content != NULL) { if (cur->content != NULL) {
#ifndef XML_USE_BUFFER_CONTENT
cur->childs = xmlStringGetNodeList(cur->doc, cur->content); cur->childs = xmlStringGetNodeList(cur->doc, cur->content);
#else
cur->childs = xmlStringGetNodeList(cur->doc,
xmlBufferContent(cur->content));
#endif
UPDATE_LAST_CHILD(cur) UPDATE_LAST_CHILD(cur)
#ifndef XML_USE_BUFFER_CONTENT
xmlFree(cur->content); xmlFree(cur->content);
#else
xmlBufferFree(cur->content);
#endif
cur->content = NULL; cur->content = NULL;
last = cur->last; last = cur->last;
} }
@ -2280,16 +2436,18 @@ xmlNodeAddContentLen(xmlNodePtr cur, const xmlChar *content, int len) {
case XML_ENTITY_NODE: case XML_ENTITY_NODE:
case XML_PI_NODE: case XML_PI_NODE:
case XML_COMMENT_NODE: case XML_COMMENT_NODE:
if (content != NULL) case XML_NOTATION_NODE:
if (content != NULL) {
#ifndef XML_USE_BUFFER_CONTENT
cur->content = xmlStrncat(cur->content, content, len); cur->content = xmlStrncat(cur->content, content, len);
#else
xmlBufferAdd(cur->content, content, len);
#endif
}
case XML_DOCUMENT_NODE: case XML_DOCUMENT_NODE:
case XML_HTML_DOCUMENT_NODE: case XML_HTML_DOCUMENT_NODE:
case XML_DOCUMENT_TYPE_NODE: case XML_DOCUMENT_TYPE_NODE:
break; break;
case XML_NOTATION_NODE:
if (content != NULL)
cur->content = xmlStrncat(cur->content, content, len);
break;
} }
} }
@ -2327,7 +2485,11 @@ xmlTextMerge(xmlNodePtr first, xmlNodePtr second) {
if (second == NULL) return(first); if (second == NULL) return(first);
if (first->type != XML_TEXT_NODE) return(first); if (first->type != XML_TEXT_NODE) return(first);
if (second->type != XML_TEXT_NODE) return(first); if (second->type != XML_TEXT_NODE) return(first);
#ifndef XML_USE_BUFFER_CONTENT
xmlNodeAddContent(first, second->content); xmlNodeAddContent(first, second->content);
#else
xmlNodeAddContent(first, xmlBufferContent(second->content));
#endif
xmlUnlinkNode(second); xmlUnlinkNode(second);
xmlFreeNode(second); xmlFreeNode(second);
return(first); return(first);
@ -2554,7 +2716,11 @@ xmlTextConcat(xmlNodePtr node, const xmlChar *content, int len) {
fprintf(stderr, "xmlTextConcat: node is not text\n"); fprintf(stderr, "xmlTextConcat: node is not text\n");
return; return;
} }
#ifndef XML_USE_BUFFER_CONTENT
node->content = xmlStrncat(node->content, content, len); node->content = xmlStrncat(node->content, content, len);
#else
xmlBufferAdd(node->content, content, len);
#endif
} }
/************************************************************************ /************************************************************************
@ -2592,6 +2758,55 @@ xmlBufferCreate(void) {
return(ret); return(ret);
} }
/**
* xmlBufferCreateSize:
* @size: initial size of buffer
*
* routine to create an XML buffer.
* returns the new structure.
*/
xmlBufferPtr
xmlBufferCreateSize(size_t size) {
xmlBufferPtr ret;
ret = (xmlBufferPtr) xmlMalloc(sizeof(xmlBuffer));
if (ret == NULL) {
fprintf(stderr, "xmlBufferCreate : out of memory!\n");
return(NULL);
}
ret->use = 0;
ret->size = (size ? size+2 : 0); /* +1 for ending null */
if(ret->size){
ret->content = (xmlChar *) xmlMalloc(ret->size * sizeof(xmlChar));
if (ret->content == NULL) {
fprintf(stderr, "xmlBufferCreate : out of memory!\n");
xmlFree(ret);
return(NULL);
}
ret->content[0] = 0;
} else
ret->content = NULL;
return(ret);
}
/**
* xmlBufferAllocationScheme:
* @buf: the buffer to free
* @scheme: allocation scheme to use
*
* Sets the allocation scheme for this buffer
*/
void
xmlBufferSetAllocationScheme(xmlBufferPtr buf,
xmlBufferAllocationScheme scheme) {
if (buf == NULL) {
fprintf(stderr, "xmlBufferSetAllocationScheme: buf == NULL\n");
return;
}
buf->alloc = scheme;
}
/** /**
* xmlBufferFree: * xmlBufferFree:
* @buf: the buffer to free * @buf: the buffer to free
@ -2604,10 +2819,12 @@ xmlBufferFree(xmlBufferPtr buf) {
fprintf(stderr, "xmlBufferFree: buf == NULL\n"); fprintf(stderr, "xmlBufferFree: buf == NULL\n");
return; return;
} }
if (buf->content == NULL) { if (buf->content != NULL) {
fprintf(stderr, "xmlBufferFree: buf->content == NULL\n"); #ifndef XML_USE_BUFFER_CONTENT
} else {
memset(buf->content, -1, BASE_BUFFER_SIZE); memset(buf->content, -1, BASE_BUFFER_SIZE);
#else
memset(buf->content, -1, buf->size);
#endif
xmlFree(buf->content); xmlFree(buf->content);
} }
memset(buf, -1, sizeof(xmlBuffer)); memset(buf, -1, sizeof(xmlBuffer));
@ -2672,6 +2889,84 @@ xmlBufferDump(FILE *file, xmlBufferPtr buf) {
return(ret); return(ret);
} }
/**
* xmlBufferContent:
* @buf: the buffer to resize
*
* Returns the internal content
*/
const xmlChar*
xmlBufferContent(const xmlBufferPtr buf)
{
if(!buf)
return NULL;
return buf->content;
}
/**
* xmlBufferLength:
* @buf: the buffer
*
* Returns the length of data in the internal content
*/
int
xmlBufferLength(const xmlBufferPtr buf)
{
if(!buf)
return 0;
return buf->use;
}
/**
* xmlBufferResize:
* @buf: the buffer to resize
* @len: the desired size
*
* Resize a buffer to accomodate minimum size of <len>.
*
* Returns 0 in case of problems, 1 otherwise
*/
int
xmlBufferResize(xmlBufferPtr buf, int size)
{
int newSize = (buf->size ? buf->size*2 : size);/*take care of empty case*/
xmlChar* rebuf = NULL;
/* Don't resize if we don't have to */
if(size < buf->size)
return 1;
/* figure out new size */
switch(buf->alloc){
case XML_BUFFER_ALLOC_DOUBLEIT:
while(size > newSize) newSize *= 2;
break;
case XML_BUFFER_ALLOC_EXACT:
newSize = size+10;
break;
default:
newSize = size+10;
break;
}
if (buf->content == NULL)
rebuf = (xmlChar *) xmlMalloc(newSize * sizeof(xmlChar));
else
rebuf = (xmlChar *) xmlRealloc(buf->content,
newSize * sizeof(xmlChar));
if (rebuf == NULL) {
fprintf(stderr, "xmlBufferAdd : out of memory!\n");
return 0;
}
buf->content = rebuf;
buf->size = newSize;
return 1;
}
/** /**
* xmlBufferAdd: * xmlBufferAdd:
* @buf: the buffer to dump * @buf: the buffer to dump
@ -2682,30 +2977,32 @@ xmlBufferDump(FILE *file, xmlBufferPtr buf) {
*/ */
void void
xmlBufferAdd(xmlBufferPtr buf, const xmlChar *str, int len) { xmlBufferAdd(xmlBufferPtr buf, const xmlChar *str, int len) {
int l; int l, needSize;
if (str == NULL) { if (str == NULL) {
fprintf(stderr, "xmlBufferAdd: str == NULL\n"); fprintf(stderr, "xmlBufferAdd: str == NULL\n");
return; return;
} }
/* CJN What's this for??? */
l = xmlStrlen(str); l = xmlStrlen(str);
if (l < len) len = l; if (l < len){ len = l; printf("xmlBufferAdd bad length\n"); }
/* CJN 11.18.99 okay, now I'm using the length */
if(len == -1) len = l;
if (len <= 0) return; if (len <= 0) return;
if (buf->use + len + 10 >= buf->size) { needSize = buf->use + len + 2;
xmlChar *rebuf; if(needSize > buf->size){
if(!xmlBufferResize(buf, needSize)){
buf->size *= 2; fprintf(stderr, "xmlBufferAdd : out of memory!\n");
if (buf->use + len + 10 > buf->size) return;
buf->size = buf->use + len + 10; }
rebuf = (xmlChar *) xmlRealloc(buf->content, buf->size * sizeof(xmlChar));
if (rebuf == NULL) {
fprintf(stderr, "xmlBufferAdd : out of memory!\n");
return;
}
buf->content = rebuf;
} }
memmove(&buf->content[buf->use], str, len);
memmove(&buf->content[buf->use], str, len*sizeof(xmlChar));
buf->use += len; buf->use += len;
buf->content[buf->use] = 0; buf->content[buf->use] = 0;
} }
@ -2719,26 +3016,8 @@ xmlBufferAdd(xmlBufferPtr buf, const xmlChar *str, int len) {
*/ */
void void
xmlBufferCat(xmlBufferPtr buf, const xmlChar *str) { xmlBufferCat(xmlBufferPtr buf, const xmlChar *str) {
const xmlChar *cur; if (str != NULL)
xmlBufferAdd(buf, str, -1);
if (str == NULL) {
fprintf(stderr, "xmlBufferAdd: str == NULL\n");
return;
}
for (cur = str;*cur != 0;cur++) {
if (buf->use + 10 >= buf->size) {
xmlChar *rebuf;
buf->size *= 2;
rebuf = (xmlChar *) xmlRealloc(buf->content, buf->size * sizeof(xmlChar));
if (rebuf == NULL) {
fprintf(stderr, "xmlBufferAdd : out of memory!\n");
return;
}
buf->content = rebuf;
}
buf->content[buf->use++] = *cur;
}
} }
/** /**
@ -2758,34 +3037,15 @@ xmlBufferCCat(xmlBufferPtr buf, const char *str) {
} }
for (cur = str;*cur != 0;cur++) { for (cur = str;*cur != 0;cur++) {
if (buf->use + 10 >= buf->size) { if (buf->use + 10 >= buf->size) {
xmlChar *rebuf; if(!xmlBufferResize(buf, buf->use+10)){
fprintf(stderr, "xmlBufferCCat : out of memory!\n");
buf->size *= 2; return;
rebuf = (xmlChar *) xmlRealloc(buf->content, buf->size * sizeof(xmlChar)); }
if (rebuf == NULL) { }
fprintf(stderr, "xmlBufferAdd : out of memory!\n");
return;
}
buf->content = rebuf;
}
buf->content[buf->use++] = *cur; buf->content[buf->use++] = *cur;
} }
} }
/**
* xmlBufferLastChar:
* @buf: the buffer to dump
*
* Get the last char of the buffer
*
* Returns the last char from the buffer or 0 if empty
*/
xmlChar
xmlBufferLastChar(xmlBufferPtr buf) {
if ((buf == NULL) || (buf->use <= 0)) return(0);
return(buf->content[buf->use - 1]);
}
/** /**
* xmlBufferWriteCHAR: * xmlBufferWriteCHAR:
* @buf: the XML buffer * @buf: the XML buffer
@ -3081,7 +3341,12 @@ xmlNodeDump(xmlBufferPtr buf, xmlDocPtr doc, xmlNodePtr cur, int level,
if (cur->content != NULL) { if (cur->content != NULL) {
xmlChar *buffer; xmlChar *buffer;
#ifndef XML_USE_BUFFER_CONTENT
buffer = xmlEncodeEntitiesReentrant(doc, cur->content); buffer = xmlEncodeEntitiesReentrant(doc, cur->content);
#else
buffer = xmlEncodeEntitiesReentrant(doc,
xmlBufferContent(cur->content));
#endif
if (buffer != NULL) { if (buffer != NULL) {
xmlBufferWriteCHAR(buf, buffer); xmlBufferWriteCHAR(buf, buffer);
xmlFree(buffer); xmlFree(buffer);
@ -3095,7 +3360,11 @@ xmlNodeDump(xmlBufferPtr buf, xmlDocPtr doc, xmlNodePtr cur, int level,
xmlBufferWriteCHAR(buf, cur->name); xmlBufferWriteCHAR(buf, cur->name);
if (cur->content != NULL) { if (cur->content != NULL) {
xmlBufferWriteChar(buf, " "); xmlBufferWriteChar(buf, " ");
#ifndef XML_USE_BUFFER_CONTENT
xmlBufferWriteCHAR(buf, cur->content); xmlBufferWriteCHAR(buf, cur->content);
#else
xmlBufferWriteCHAR(buf, xmlBufferContent(cur->content));
#endif
} }
xmlBufferWriteChar(buf, "?>"); xmlBufferWriteChar(buf, "?>");
} }
@ -3104,7 +3373,11 @@ xmlNodeDump(xmlBufferPtr buf, xmlDocPtr doc, xmlNodePtr cur, int level,
if (cur->type == XML_COMMENT_NODE) { if (cur->type == XML_COMMENT_NODE) {
if (cur->content != NULL) { if (cur->content != NULL) {
xmlBufferWriteChar(buf, "<!--"); xmlBufferWriteChar(buf, "<!--");
#ifndef XML_USE_BUFFER_CONTENT
xmlBufferWriteCHAR(buf, cur->content); xmlBufferWriteCHAR(buf, cur->content);
#else
xmlBufferWriteCHAR(buf, xmlBufferContent(cur->content));
#endif
xmlBufferWriteChar(buf, "-->"); xmlBufferWriteChar(buf, "-->");
} }
return; return;
@ -3118,7 +3391,11 @@ xmlNodeDump(xmlBufferPtr buf, xmlDocPtr doc, xmlNodePtr cur, int level,
if (cur->type == XML_CDATA_SECTION_NODE) { if (cur->type == XML_CDATA_SECTION_NODE) {
xmlBufferWriteChar(buf, "<![CDATA["); xmlBufferWriteChar(buf, "<![CDATA[");
if (cur->content != NULL) if (cur->content != NULL)
#ifndef XML_USE_BUFFER_CONTENT
xmlBufferWriteCHAR(buf, cur->content); xmlBufferWriteCHAR(buf, cur->content);
#else
xmlBufferWriteCHAR(buf, xmlBufferContent(cur->content));
#endif
xmlBufferWriteChar(buf, "]]>"); xmlBufferWriteChar(buf, "]]>");
return; return;
} }
@ -3154,7 +3431,12 @@ xmlNodeDump(xmlBufferPtr buf, xmlDocPtr doc, xmlNodePtr cur, int level,
if (cur->content != NULL) { if (cur->content != NULL) {
xmlChar *buffer; xmlChar *buffer;
#ifndef XML_USE_BUFFER_CONTENT
buffer = xmlEncodeEntitiesReentrant(doc, cur->content); buffer = xmlEncodeEntitiesReentrant(doc, cur->content);
#else
buffer = xmlEncodeEntitiesReentrant(doc,
xmlBufferContent(cur->content));
#endif
if (buffer != NULL) { if (buffer != NULL) {
xmlBufferWriteCHAR(buf, buffer); xmlBufferWriteCHAR(buf, buffer);
xmlFree(buffer); xmlFree(buffer);

41
tree.h
View File

@ -229,6 +229,24 @@ typedef struct xmlRef {
} xmlRef; } xmlRef;
typedef xmlRef *xmlRefPtr; typedef xmlRef *xmlRefPtr;
/*
* A buffer structure
*/
typedef enum {
XML_BUFFER_ALLOC_DOUBLEIT,
XML_BUFFER_ALLOC_EXACT
} xmlBufferAllocationScheme;
typedef struct xmlBuffer {
xmlChar *content; /* The buffer content UTF8 */
unsigned int use; /* The buffer size used */
unsigned int size; /* The buffer size */
xmlBufferAllocationScheme alloc; /* The realloc method */
} _xmlBuffer;
typedef _xmlBuffer xmlBuffer;
typedef xmlBuffer *xmlBufferPtr;
/* /*
* A node in an XML tree. * A node in an XML tree.
*/ */
@ -248,7 +266,11 @@ typedef struct xmlNode {
const xmlChar *name; /* the name of the node, or the entity */ const xmlChar *name; /* the name of the node, or the entity */
xmlNs *ns; /* pointer to the associated namespace */ xmlNs *ns; /* pointer to the associated namespace */
xmlNs *nsDef; /* namespace definitions on this node */ xmlNs *nsDef; /* namespace definitions on this node */
#ifndef XML_USE_BUFFER_CONTENT
xmlChar *content; /* the content */ xmlChar *content; /* the content */
#else
xmlBufferPtr content; /* the content in a buffer */
#endif
} _xmlNode; } _xmlNode;
typedef _xmlNode xmlNode; typedef _xmlNode xmlNode;
typedef _xmlNode *xmlNodePtr; typedef _xmlNode *xmlNodePtr;
@ -277,30 +299,20 @@ typedef struct xmlDoc {
typedef _xmlDoc xmlDoc; typedef _xmlDoc xmlDoc;
typedef xmlDoc *xmlDocPtr; typedef xmlDoc *xmlDocPtr;
/*
* A buffer structure
*/
typedef struct xmlBuffer {
xmlChar *content; /* The buffer content UTF8 */
unsigned int use; /* The buffer size used */
unsigned int size; /* The buffer size */
} _xmlBuffer;
typedef _xmlBuffer xmlBuffer;
typedef xmlBuffer *xmlBufferPtr;
/* /*
* Variables. * Variables.
*/ */
extern xmlNsPtr baseDTD; extern xmlNsPtr baseDTD;
extern int oldXMLWDcompatibility;/* maintain compatibility with old WD */ extern int oldXMLWDcompatibility;/* maintain compatibility with old WD */
extern int xmlIndentTreeOutput; /* try to indent the tree dumps */ extern int xmlIndentTreeOutput; /* try to indent the tree dumps */
extern xmlBufferAllocationScheme xmlBufferAllocScheme; /* alloc scheme to use */
/* /*
* Handling Buffers. * Handling Buffers.
*/ */
xmlBufferPtr xmlBufferCreate (void); xmlBufferPtr xmlBufferCreate (void);
xmlBufferPtr xmlBufferCreateSize (size_t size);
void xmlBufferFree (xmlBufferPtr buf); void xmlBufferFree (xmlBufferPtr buf);
int xmlBufferDump (FILE *file, int xmlBufferDump (FILE *file,
xmlBufferPtr buf); xmlBufferPtr buf);
@ -314,6 +326,11 @@ void xmlBufferCCat (xmlBufferPtr buf,
int xmlBufferShrink (xmlBufferPtr buf, int xmlBufferShrink (xmlBufferPtr buf,
int len); int len);
void xmlBufferEmpty (xmlBufferPtr buf); void xmlBufferEmpty (xmlBufferPtr buf);
const xmlChar* xmlBufferContent (const xmlBufferPtr buf);
int xmlBufferUse (const xmlBufferPtr buf);
void xmlBufferSetAllocationScheme(xmlBufferPtr buf,
xmlBufferAllocationScheme scheme);
int xmlBufferLength (const xmlBufferPtr buf);
/* /*
* Creating/freeing new structures * Creating/freeing new structures

View File

@ -53,7 +53,7 @@ while test $# -gt 0; do
;; ;;
--cflags) --cflags)
echo -I@includedir@/gnome-xml echo @XML_INCLUDEDIR@ @XML_CFLAGS@
;; ;;
--libs) --libs)