1
0
mirror of https://gitlab.gnome.org/GNOME/libxml2.git synced 2024-10-26 20:25:14 +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>
* 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_LIBS="-lxml $Z_LIBS $M_LIBS $LIBS"
dnl
dnl Extra flags
dnl
XML_CFLAGS=""
dnl
dnl Workaround wor HP native compiler
dnl http://bugs.gnome.org/db/31/3163.html
@ -114,7 +119,19 @@ if test "${CC}" != "gcc" ; then
;;
esac
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(XML_CFLAGS)
AC_SUBST(XML_LIBDIR)
AC_SUBST(XML_LIBS)

View File

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

View File

@ -229,6 +229,24 @@ typedef struct xmlRef {
} xmlRef;
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.
*/
@ -248,7 +266,11 @@ typedef struct xmlNode {
const xmlChar *name; /* the name of the node, or the entity */
xmlNs *ns; /* pointer to the associated namespace */
xmlNs *nsDef; /* namespace definitions on this node */
#ifndef XML_USE_BUFFER_CONTENT
xmlChar *content; /* the content */
#else
xmlBufferPtr content; /* the content in a buffer */
#endif
} _xmlNode;
typedef _xmlNode xmlNode;
typedef _xmlNode *xmlNodePtr;
@ -277,30 +299,20 @@ typedef struct xmlDoc {
typedef _xmlDoc xmlDoc;
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.
*/
extern xmlNsPtr baseDTD;
extern int oldXMLWDcompatibility;/* maintain compatibility with old WD */
extern int xmlIndentTreeOutput; /* try to indent the tree dumps */
extern xmlBufferAllocationScheme xmlBufferAllocScheme; /* alloc scheme to use */
/*
* Handling Buffers.
*/
xmlBufferPtr xmlBufferCreate (void);
xmlBufferPtr xmlBufferCreateSize (size_t size);
void xmlBufferFree (xmlBufferPtr buf);
int xmlBufferDump (FILE *file,
xmlBufferPtr buf);
@ -314,6 +326,11 @@ void xmlBufferCCat (xmlBufferPtr buf,
int xmlBufferShrink (xmlBufferPtr buf,
int len);
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

View File

@ -6740,6 +6740,7 @@ int xmlSAXUserParseMemory(xmlSAXHandlerPtr sax, void *user_data,
void
xmlCleanupParser(void) {
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--noout : do not print the result\n");
}
xmlCleanupParser();
xmlMemoryDump();
return(0);

View File

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

View File

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

478
tree.c
View File

@ -34,6 +34,7 @@
static xmlChar xmlStringText[] = { 't', 'e', 'x', 't', 0 };
int oldXMLWDcompatibility = 0;
int xmlIndentTreeOutput = 1;
xmlBufferAllocationScheme xmlBufferAllocScheme = XML_BUFFER_ALLOC_EXACT;
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:
* @doc: a document pointer
@ -684,12 +714,21 @@ xmlNodeListGetString(xmlDocPtr doc, xmlNodePtr list, int inLine) {
while (node != NULL) {
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);
else {
#else
ret = xmlStrcat(ret, xmlBufferContent(node->content));
#endif
} else {
xmlChar *buffer;
#ifndef XML_USE_BUFFER_CONTENT
buffer = xmlEncodeEntitiesReentrant(doc, node->content);
#else
buffer = xmlEncodeEntitiesReentrant(doc,
xmlBufferContent(node->content));
#endif
if (buffer != NULL) {
ret = xmlStrcat(ret, buffer);
xmlFree(buffer);
@ -700,8 +739,13 @@ xmlNodeListGetString(xmlDocPtr doc, xmlNodePtr list, int inLine) {
ent = xmlGetDocEntity(doc, node->name);
if (ent != NULL)
ret = xmlStrcat(ret, ent->content);
else
else {
#ifndef XML_USE_BUFFER_CONTENT
ret = xmlStrcat(ret, node->content);
#else
ret = xmlStrcat(ret, xmlBufferContent(node->content));
#endif
}
} else {
xmlChar buf[2];
buf[0] = '&'; buf[1] = 0;
@ -964,9 +1008,16 @@ xmlNewPI(const xmlChar *name, const xmlChar *content) {
cur->name = xmlStrdup(name);
cur->ns = NULL;
cur->nsDef = NULL;
if (content != NULL)
if (content != NULL) {
#ifndef XML_USE_BUFFER_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;
#ifndef XML_WITHOUT_CORBA
cur->_private = NULL;
@ -1116,9 +1167,16 @@ xmlNewText(const xmlChar *content) {
cur->name = xmlStrdup(xmlStringText);
cur->ns = NULL;
cur->nsDef = NULL;
if (content != NULL)
if (content != NULL) {
#ifndef XML_USE_BUFFER_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;
#ifndef XML_WITHOUT_CORBA
cur->_private = NULL;
@ -1227,9 +1285,22 @@ xmlNewReference(xmlDocPtr doc, const xmlChar *name) {
cur->nsDef = NULL;
ent = xmlGetDocEntity(doc, cur->name);
if (ent != NULL)
if (ent != NULL) {
#ifndef XML_USE_BUFFER_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;
#ifndef XML_WITHOUT_CORBA
cur->_private = NULL;
@ -1288,9 +1359,16 @@ xmlNewTextLen(const xmlChar *content, int len) {
cur->name = xmlStrdup(xmlStringText);
cur->ns = NULL;
cur->nsDef = NULL;
if (content != NULL)
if (content != NULL) {
#ifndef XML_USE_BUFFER_CONTENT
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;
#ifndef XML_WITHOUT_CORBA
cur->_private = NULL;
@ -1350,9 +1428,16 @@ xmlNewComment(const xmlChar *content) {
cur->name = xmlStrdup(xmlStringText);
cur->ns = NULL;
cur->nsDef = NULL;
if (content != NULL)
if (content != NULL) {
#ifndef XML_USE_BUFFER_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;
#ifndef XML_WITHOUT_CORBA
cur->_private = NULL;
@ -1394,8 +1479,15 @@ xmlNewCDataBlock(xmlDocPtr doc, const xmlChar *content, int len) {
cur->name = xmlStrdup(xmlStringText);
cur->ns = NULL;
cur->nsDef = NULL;
if ((content != NULL) && (len > 0)) {
if (content != NULL) {
#ifndef XML_USE_BUFFER_CONTENT
cur->content = xmlStrndup(content, len);
#else
cur->content = xmlBufferCreateSize(len);
xmlBufferSetAllocationScheme(cur->content,
xmlGetBufferAllocationScheme());
xmlBufferAdd(cur->content, content, len);
#endif
} else
cur->content = NULL;
#ifndef XML_WITHOUT_CORBA
@ -1567,14 +1659,22 @@ xmlAddChild(xmlNodePtr parent, xmlNodePtr cur) {
if (parent->content != NULL) {
xmlNodePtr text;
#ifndef XML_USE_BUFFER_CONTENT
text = xmlNewDocText(parent->doc, parent->content);
#else
text = xmlNewDocText(parent->doc, xmlBufferContent(parent->content));
#endif
if (text != NULL) {
text->next = parent->childs;
if (text->next != NULL)
text->next->prev = text;
parent->childs = text;
UPDATE_LAST_CHILD(parent)
#ifndef XML_USE_BUFFER_CONTENT
xmlFree(parent->content);
#else
xmlBufferFree(parent->content);
#endif
parent->content = NULL;
}
}
@ -1647,7 +1747,11 @@ xmlFreeNode(xmlNodePtr cur) {
if (cur->childs != NULL) xmlFreeNodeList(cur->childs);
if (cur->properties != NULL) xmlFreePropList(cur->properties);
if (cur->type != XML_ENTITY_REF_NODE)
#ifndef XML_USE_BUFFER_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->nsDef != NULL) xmlFreeNsList(cur->nsDef);
memset(cur, -1, sizeof(xmlNode));
@ -1844,9 +1948,18 @@ xmlStaticCopyNode(xmlNodePtr node, xmlDocPtr doc, xmlNodePtr parent,
ret->name = NULL;
ret->ns = 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);
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;
#ifndef XML_WITHOUT_CORBA
ret->_private = NULL;
@ -2107,7 +2220,11 @@ xmlNodeGetContent(xmlNodePtr cur) {
}
case XML_PI_NODE:
if (cur->content != NULL)
#ifndef XML_USE_BUFFER_CONTENT
return(xmlStrdup(cur->content));
#else
return(xmlStrdup(xmlBufferContent(cur->content)));
#endif
return(NULL);
case XML_ENTITY_REF_NODE:
case XML_ENTITY_NODE:
@ -2120,7 +2237,11 @@ xmlNodeGetContent(xmlNodePtr cur) {
case XML_CDATA_SECTION_NODE:
case XML_TEXT_NODE:
if (cur->content != NULL)
#ifndef XML_USE_BUFFER_CONTENT
return(xmlStrdup(cur->content));
#else
return(xmlStrdup(xmlBufferContent(cur->content)));
#endif
return(NULL);
}
return(NULL);
@ -2143,7 +2264,11 @@ xmlNodeSetContent(xmlNodePtr cur, const xmlChar *content) {
case XML_DOCUMENT_FRAG_NODE:
case XML_ELEMENT_NODE:
if (cur->content != NULL) {
#ifndef XML_USE_BUFFER_CONTENT
xmlFree(cur->content);
#else
xmlBufferFree(cur->content);
#endif
cur->content = NULL;
}
if (cur->childs != NULL) xmlFreeNodeList(cur->childs);
@ -2158,12 +2283,25 @@ xmlNodeSetContent(xmlNodePtr cur, const xmlChar *content) {
case XML_ENTITY_NODE:
case XML_PI_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);
cur->last = cur->childs = NULL;
if (content != NULL)
if (content != NULL) {
#ifndef XML_USE_BUFFER_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;
break;
case XML_DOCUMENT_NODE:
@ -2193,7 +2331,11 @@ xmlNodeSetContentLen(xmlNodePtr cur, const xmlChar *content, int len) {
case XML_DOCUMENT_FRAG_NODE:
case XML_ELEMENT_NODE:
if (cur->content != NULL) {
#ifndef XML_USE_BUFFER_CONTENT
xmlFree(cur->content);
#else
xmlBufferFree(cur->content);
#endif
cur->content = NULL;
}
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_PI_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);
cur->childs = cur->last = NULL;
if (content != NULL)
if (content != NULL) {
#ifndef XML_USE_BUFFER_CONTENT
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;
break;
case XML_DOCUMENT_NODE:
case XML_HTML_DOCUMENT_NODE:
case XML_DOCUMENT_TYPE_NODE:
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;
} else {
if (cur->content != NULL) {
#ifndef XML_USE_BUFFER_CONTENT
cur->childs = xmlStringGetNodeList(cur->doc, cur->content);
#else
cur->childs = xmlStringGetNodeList(cur->doc,
xmlBufferContent(cur->content));
#endif
UPDATE_LAST_CHILD(cur)
#ifndef XML_USE_BUFFER_CONTENT
xmlFree(cur->content);
#else
xmlBufferFree(cur->content);
#endif
cur->content = NULL;
last = cur->last;
}
@ -2280,16 +2436,18 @@ xmlNodeAddContentLen(xmlNodePtr cur, const xmlChar *content, int len) {
case XML_ENTITY_NODE:
case XML_PI_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);
#else
xmlBufferAdd(cur->content, content, len);
#endif
}
case XML_DOCUMENT_NODE:
case XML_HTML_DOCUMENT_NODE:
case XML_DOCUMENT_TYPE_NODE:
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 (first->type != XML_TEXT_NODE) return(first);
if (second->type != XML_TEXT_NODE) return(first);
#ifndef XML_USE_BUFFER_CONTENT
xmlNodeAddContent(first, second->content);
#else
xmlNodeAddContent(first, xmlBufferContent(second->content));
#endif
xmlUnlinkNode(second);
xmlFreeNode(second);
return(first);
@ -2554,7 +2716,11 @@ xmlTextConcat(xmlNodePtr node, const xmlChar *content, int len) {
fprintf(stderr, "xmlTextConcat: node is not text\n");
return;
}
#ifndef XML_USE_BUFFER_CONTENT
node->content = xmlStrncat(node->content, content, len);
#else
xmlBufferAdd(node->content, content, len);
#endif
}
/************************************************************************
@ -2592,6 +2758,55 @@ xmlBufferCreate(void) {
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:
* @buf: the buffer to free
@ -2604,10 +2819,12 @@ xmlBufferFree(xmlBufferPtr buf) {
fprintf(stderr, "xmlBufferFree: buf == NULL\n");
return;
}
if (buf->content == NULL) {
fprintf(stderr, "xmlBufferFree: buf->content == NULL\n");
} else {
if (buf->content != NULL) {
#ifndef XML_USE_BUFFER_CONTENT
memset(buf->content, -1, BASE_BUFFER_SIZE);
#else
memset(buf->content, -1, buf->size);
#endif
xmlFree(buf->content);
}
memset(buf, -1, sizeof(xmlBuffer));
@ -2672,6 +2889,84 @@ xmlBufferDump(FILE *file, xmlBufferPtr buf) {
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:
* @buf: the buffer to dump
@ -2682,30 +2977,32 @@ xmlBufferDump(FILE *file, xmlBufferPtr buf) {
*/
void
xmlBufferAdd(xmlBufferPtr buf, const xmlChar *str, int len) {
int l;
int l, needSize;
if (str == NULL) {
fprintf(stderr, "xmlBufferAdd: str == NULL\n");
return;
}
/* CJN What's this for??? */
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 (buf->use + len + 10 >= buf->size) {
xmlChar *rebuf;
buf->size *= 2;
if (buf->use + len + 10 > buf->size)
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;
needSize = buf->use + len + 2;
if(needSize > buf->size){
if(!xmlBufferResize(buf, needSize)){
fprintf(stderr, "xmlBufferAdd : out of memory!\n");
return;
}
}
memmove(&buf->content[buf->use], str, len);
memmove(&buf->content[buf->use], str, len*sizeof(xmlChar));
buf->use += len;
buf->content[buf->use] = 0;
}
@ -2719,26 +3016,8 @@ xmlBufferAdd(xmlBufferPtr buf, const xmlChar *str, int len) {
*/
void
xmlBufferCat(xmlBufferPtr buf, const xmlChar *str) {
const xmlChar *cur;
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;
}
if (str != NULL)
xmlBufferAdd(buf, str, -1);
}
/**
@ -2758,34 +3037,15 @@ xmlBufferCCat(xmlBufferPtr buf, const char *str) {
}
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;
}
if(!xmlBufferResize(buf, buf->use+10)){
fprintf(stderr, "xmlBufferCCat : out of memory!\n");
return;
}
}
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:
* @buf: the XML buffer
@ -3081,7 +3341,12 @@ xmlNodeDump(xmlBufferPtr buf, xmlDocPtr doc, xmlNodePtr cur, int level,
if (cur->content != NULL) {
xmlChar *buffer;
#ifndef XML_USE_BUFFER_CONTENT
buffer = xmlEncodeEntitiesReentrant(doc, cur->content);
#else
buffer = xmlEncodeEntitiesReentrant(doc,
xmlBufferContent(cur->content));
#endif
if (buffer != NULL) {
xmlBufferWriteCHAR(buf, buffer);
xmlFree(buffer);
@ -3095,7 +3360,11 @@ xmlNodeDump(xmlBufferPtr buf, xmlDocPtr doc, xmlNodePtr cur, int level,
xmlBufferWriteCHAR(buf, cur->name);
if (cur->content != NULL) {
xmlBufferWriteChar(buf, " ");
#ifndef XML_USE_BUFFER_CONTENT
xmlBufferWriteCHAR(buf, cur->content);
#else
xmlBufferWriteCHAR(buf, xmlBufferContent(cur->content));
#endif
}
xmlBufferWriteChar(buf, "?>");
}
@ -3104,7 +3373,11 @@ xmlNodeDump(xmlBufferPtr buf, xmlDocPtr doc, xmlNodePtr cur, int level,
if (cur->type == XML_COMMENT_NODE) {
if (cur->content != NULL) {
xmlBufferWriteChar(buf, "<!--");
#ifndef XML_USE_BUFFER_CONTENT
xmlBufferWriteCHAR(buf, cur->content);
#else
xmlBufferWriteCHAR(buf, xmlBufferContent(cur->content));
#endif
xmlBufferWriteChar(buf, "-->");
}
return;
@ -3118,7 +3391,11 @@ xmlNodeDump(xmlBufferPtr buf, xmlDocPtr doc, xmlNodePtr cur, int level,
if (cur->type == XML_CDATA_SECTION_NODE) {
xmlBufferWriteChar(buf, "<![CDATA[");
if (cur->content != NULL)
#ifndef XML_USE_BUFFER_CONTENT
xmlBufferWriteCHAR(buf, cur->content);
#else
xmlBufferWriteCHAR(buf, xmlBufferContent(cur->content));
#endif
xmlBufferWriteChar(buf, "]]>");
return;
}
@ -3154,7 +3431,12 @@ xmlNodeDump(xmlBufferPtr buf, xmlDocPtr doc, xmlNodePtr cur, int level,
if (cur->content != NULL) {
xmlChar *buffer;
#ifndef XML_USE_BUFFER_CONTENT
buffer = xmlEncodeEntitiesReentrant(doc, cur->content);
#else
buffer = xmlEncodeEntitiesReentrant(doc,
xmlBufferContent(cur->content));
#endif
if (buffer != NULL) {
xmlBufferWriteCHAR(buf, buffer);
xmlFree(buffer);

41
tree.h
View File

@ -229,6 +229,24 @@ typedef struct xmlRef {
} xmlRef;
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.
*/
@ -248,7 +266,11 @@ typedef struct xmlNode {
const xmlChar *name; /* the name of the node, or the entity */
xmlNs *ns; /* pointer to the associated namespace */
xmlNs *nsDef; /* namespace definitions on this node */
#ifndef XML_USE_BUFFER_CONTENT
xmlChar *content; /* the content */
#else
xmlBufferPtr content; /* the content in a buffer */
#endif
} _xmlNode;
typedef _xmlNode xmlNode;
typedef _xmlNode *xmlNodePtr;
@ -277,30 +299,20 @@ typedef struct xmlDoc {
typedef _xmlDoc xmlDoc;
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.
*/
extern xmlNsPtr baseDTD;
extern int oldXMLWDcompatibility;/* maintain compatibility with old WD */
extern int xmlIndentTreeOutput; /* try to indent the tree dumps */
extern xmlBufferAllocationScheme xmlBufferAllocScheme; /* alloc scheme to use */
/*
* Handling Buffers.
*/
xmlBufferPtr xmlBufferCreate (void);
xmlBufferPtr xmlBufferCreateSize (size_t size);
void xmlBufferFree (xmlBufferPtr buf);
int xmlBufferDump (FILE *file,
xmlBufferPtr buf);
@ -314,6 +326,11 @@ void xmlBufferCCat (xmlBufferPtr buf,
int xmlBufferShrink (xmlBufferPtr buf,
int len);
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

View File

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