1bca22f40c3b2b34169d8d2919dce4894d8eac1a4Daniel Veillard/*
2bca22f40c3b2b34169d8d2919dce4894d8eac1a4Daniel Veillard * buf.c: memory buffers for libxml2
3bca22f40c3b2b34169d8d2919dce4894d8eac1a4Daniel Veillard *
4bca22f40c3b2b34169d8d2919dce4894d8eac1a4Daniel Veillard * new buffer structures and entry points to simplify the maintainance
5bca22f40c3b2b34169d8d2919dce4894d8eac1a4Daniel Veillard * of libxml2 and ensure we keep good control over memory allocations
6bca22f40c3b2b34169d8d2919dce4894d8eac1a4Daniel Veillard * and stay 64 bits clean.
7bca22f40c3b2b34169d8d2919dce4894d8eac1a4Daniel Veillard * The new entry point use the xmlBufPtr opaque structure and
8bca22f40c3b2b34169d8d2919dce4894d8eac1a4Daniel Veillard * xmlBuf...() counterparts to the old xmlBuf...() functions
9bca22f40c3b2b34169d8d2919dce4894d8eac1a4Daniel Veillard *
10bca22f40c3b2b34169d8d2919dce4894d8eac1a4Daniel Veillard * See Copyright for the status of this software.
11bca22f40c3b2b34169d8d2919dce4894d8eac1a4Daniel Veillard *
12bca22f40c3b2b34169d8d2919dce4894d8eac1a4Daniel Veillard * daniel@veillard.com
13bca22f40c3b2b34169d8d2919dce4894d8eac1a4Daniel Veillard */
14bca22f40c3b2b34169d8d2919dce4894d8eac1a4Daniel Veillard
15bca22f40c3b2b34169d8d2919dce4894d8eac1a4Daniel Veillard#define IN_LIBXML
16bca22f40c3b2b34169d8d2919dce4894d8eac1a4Daniel Veillard#include "libxml.h"
17bca22f40c3b2b34169d8d2919dce4894d8eac1a4Daniel Veillard
18bca22f40c3b2b34169d8d2919dce4894d8eac1a4Daniel Veillard#include <string.h> /* for memset() only ! */
19bca22f40c3b2b34169d8d2919dce4894d8eac1a4Daniel Veillard#include <limits.h>
20bca22f40c3b2b34169d8d2919dce4894d8eac1a4Daniel Veillard#ifdef HAVE_CTYPE_H
21bca22f40c3b2b34169d8d2919dce4894d8eac1a4Daniel Veillard#include <ctype.h>
22bca22f40c3b2b34169d8d2919dce4894d8eac1a4Daniel Veillard#endif
23bca22f40c3b2b34169d8d2919dce4894d8eac1a4Daniel Veillard#ifdef HAVE_STDLIB_H
24bca22f40c3b2b34169d8d2919dce4894d8eac1a4Daniel Veillard#include <stdlib.h>
25bca22f40c3b2b34169d8d2919dce4894d8eac1a4Daniel Veillard#endif
26bca22f40c3b2b34169d8d2919dce4894d8eac1a4Daniel Veillard
27bca22f40c3b2b34169d8d2919dce4894d8eac1a4Daniel Veillard#include <libxml/tree.h>
28bca22f40c3b2b34169d8d2919dce4894d8eac1a4Daniel Veillard#include <libxml/globals.h>
29bca22f40c3b2b34169d8d2919dce4894d8eac1a4Daniel Veillard#include <libxml/tree.h>
30213f1fe0d76d30eaed6e5853057defc43e6df2c9Daniel Veillard#include <libxml/parserInternals.h> /* for XML_MAX_TEXT_LENGTH */
31bca22f40c3b2b34169d8d2919dce4894d8eac1a4Daniel Veillard#include "buf.h"
32bca22f40c3b2b34169d8d2919dce4894d8eac1a4Daniel Veillard
337f713494adbc1f2be3e043a737ba31b616499bc0Daniel Veillard#define WITH_BUFFER_COMPAT
347f713494adbc1f2be3e043a737ba31b616499bc0Daniel Veillard
35bca22f40c3b2b34169d8d2919dce4894d8eac1a4Daniel Veillard/**
36bca22f40c3b2b34169d8d2919dce4894d8eac1a4Daniel Veillard * xmlBuf:
37bca22f40c3b2b34169d8d2919dce4894d8eac1a4Daniel Veillard *
389ee02f80a4d674bac96f88b5a241825aad453a7aDaniel Veillard * A buffer structure. The base of the structure is somehow compatible
399ee02f80a4d674bac96f88b5a241825aad453a7aDaniel Veillard * with struct _xmlBuffer to limit risks on application which accessed
409ee02f80a4d674bac96f88b5a241825aad453a7aDaniel Veillard * directly the input->buf->buffer structures.
41bca22f40c3b2b34169d8d2919dce4894d8eac1a4Daniel Veillard */
42bca22f40c3b2b34169d8d2919dce4894d8eac1a4Daniel Veillard
43bca22f40c3b2b34169d8d2919dce4894d8eac1a4Daniel Veillardstruct _xmlBuf {
44bca22f40c3b2b34169d8d2919dce4894d8eac1a4Daniel Veillard    xmlChar *content;		/* The buffer content UTF8 */
459ee02f80a4d674bac96f88b5a241825aad453a7aDaniel Veillard    unsigned int compat_use;    /* for binary compatibility */
469ee02f80a4d674bac96f88b5a241825aad453a7aDaniel Veillard    unsigned int compat_size;   /* for binary compatibility */
47bca22f40c3b2b34169d8d2919dce4894d8eac1a4Daniel Veillard    xmlBufferAllocationScheme alloc; /* The realloc method */
48bca22f40c3b2b34169d8d2919dce4894d8eac1a4Daniel Veillard    xmlChar *contentIO;		/* in IO mode we may have a different base */
499ee02f80a4d674bac96f88b5a241825aad453a7aDaniel Veillard    size_t use;		        /* The buffer size used */
509ee02f80a4d674bac96f88b5a241825aad453a7aDaniel Veillard    size_t size;		/* The buffer size */
51bca22f40c3b2b34169d8d2919dce4894d8eac1a4Daniel Veillard    xmlBufferPtr buffer;        /* wrapper for an old buffer */
528bbe4508ef2a97110eac02f16782678c38ea97afNick Wellnhofer    int error;                  /* an error code if a failure occurred */
53bca22f40c3b2b34169d8d2919dce4894d8eac1a4Daniel Veillard};
54bca22f40c3b2b34169d8d2919dce4894d8eac1a4Daniel Veillard
557f713494adbc1f2be3e043a737ba31b616499bc0Daniel Veillard#ifdef WITH_BUFFER_COMPAT
567f713494adbc1f2be3e043a737ba31b616499bc0Daniel Veillard/*
577f713494adbc1f2be3e043a737ba31b616499bc0Daniel Veillard * Macro for compatibility with xmlBuffer to be used after an xmlBuf
587f713494adbc1f2be3e043a737ba31b616499bc0Daniel Veillard * is updated. This makes sure the compat fields are updated too.
597f713494adbc1f2be3e043a737ba31b616499bc0Daniel Veillard */
6018e1f1f1180c4d48ed52bf995b3c700c2cefb492Daniel Veillard#define UPDATE_COMPAT(buf)				    \
6118e1f1f1180c4d48ed52bf995b3c700c2cefb492Daniel Veillard     if (buf->size < INT_MAX) buf->compat_size = buf->size; \
6218e1f1f1180c4d48ed52bf995b3c700c2cefb492Daniel Veillard     else buf->compat_size = INT_MAX;			    \
6318e1f1f1180c4d48ed52bf995b3c700c2cefb492Daniel Veillard     if (buf->use < INT_MAX) buf->compat_use = buf->use; \
6418e1f1f1180c4d48ed52bf995b3c700c2cefb492Daniel Veillard     else buf->compat_use = INT_MAX;
6518e1f1f1180c4d48ed52bf995b3c700c2cefb492Daniel Veillard
667f713494adbc1f2be3e043a737ba31b616499bc0Daniel Veillard/*
677f713494adbc1f2be3e043a737ba31b616499bc0Daniel Veillard * Macro for compatibility with xmlBuffer to be used in all the xmlBuf
687f713494adbc1f2be3e043a737ba31b616499bc0Daniel Veillard * entry points, it checks that the compat fields have not been modified
697f713494adbc1f2be3e043a737ba31b616499bc0Daniel Veillard * by direct call to xmlBuffer function from code compiled before 2.9.0 .
707f713494adbc1f2be3e043a737ba31b616499bc0Daniel Veillard */
717f713494adbc1f2be3e043a737ba31b616499bc0Daniel Veillard#define CHECK_COMPAT(buf)				    \
727f713494adbc1f2be3e043a737ba31b616499bc0Daniel Veillard     if (buf->size != (size_t) buf->compat_size)	    \
737f713494adbc1f2be3e043a737ba31b616499bc0Daniel Veillard         if (buf->compat_size < INT_MAX)		    \
747f713494adbc1f2be3e043a737ba31b616499bc0Daniel Veillard	     buf->size = buf->compat_size;		    \
757f713494adbc1f2be3e043a737ba31b616499bc0Daniel Veillard     if (buf->use != (size_t) buf->compat_use)		    \
767f713494adbc1f2be3e043a737ba31b616499bc0Daniel Veillard         if (buf->compat_use < INT_MAX)			    \
777f713494adbc1f2be3e043a737ba31b616499bc0Daniel Veillard	     buf->use = buf->compat_use;
787f713494adbc1f2be3e043a737ba31b616499bc0Daniel Veillard
797f713494adbc1f2be3e043a737ba31b616499bc0Daniel Veillard#else /* ! WITH_BUFFER_COMPAT */
807f713494adbc1f2be3e043a737ba31b616499bc0Daniel Veillard#define UPDATE_COMPAT(buf)
817f713494adbc1f2be3e043a737ba31b616499bc0Daniel Veillard#define CHECK_COMPAT(buf)
827f713494adbc1f2be3e043a737ba31b616499bc0Daniel Veillard#endif /* WITH_BUFFER_COMPAT */
837f713494adbc1f2be3e043a737ba31b616499bc0Daniel Veillard
84bca22f40c3b2b34169d8d2919dce4894d8eac1a4Daniel Veillard/**
85bca22f40c3b2b34169d8d2919dce4894d8eac1a4Daniel Veillard * xmlBufMemoryError:
86bca22f40c3b2b34169d8d2919dce4894d8eac1a4Daniel Veillard * @extra:  extra informations
87bca22f40c3b2b34169d8d2919dce4894d8eac1a4Daniel Veillard *
88bca22f40c3b2b34169d8d2919dce4894d8eac1a4Daniel Veillard * Handle an out of memory condition
89bca22f40c3b2b34169d8d2919dce4894d8eac1a4Daniel Veillard * To be improved...
90bca22f40c3b2b34169d8d2919dce4894d8eac1a4Daniel Veillard */
91bca22f40c3b2b34169d8d2919dce4894d8eac1a4Daniel Veillardstatic void
92bca22f40c3b2b34169d8d2919dce4894d8eac1a4Daniel VeillardxmlBufMemoryError(xmlBufPtr buf, const char *extra)
93bca22f40c3b2b34169d8d2919dce4894d8eac1a4Daniel Veillard{
94bca22f40c3b2b34169d8d2919dce4894d8eac1a4Daniel Veillard    __xmlSimpleError(XML_FROM_BUFFER, XML_ERR_NO_MEMORY, NULL, NULL, extra);
95bca22f40c3b2b34169d8d2919dce4894d8eac1a4Daniel Veillard    if ((buf) && (buf->error == 0))
96bca22f40c3b2b34169d8d2919dce4894d8eac1a4Daniel Veillard        buf->error = XML_ERR_NO_MEMORY;
97bca22f40c3b2b34169d8d2919dce4894d8eac1a4Daniel Veillard}
98bca22f40c3b2b34169d8d2919dce4894d8eac1a4Daniel Veillard
99bca22f40c3b2b34169d8d2919dce4894d8eac1a4Daniel Veillard/**
100bca22f40c3b2b34169d8d2919dce4894d8eac1a4Daniel Veillard * xmlBufOverflowError:
101bca22f40c3b2b34169d8d2919dce4894d8eac1a4Daniel Veillard * @extra:  extra informations
102bca22f40c3b2b34169d8d2919dce4894d8eac1a4Daniel Veillard *
103bca22f40c3b2b34169d8d2919dce4894d8eac1a4Daniel Veillard * Handle a buffer overflow error
104bca22f40c3b2b34169d8d2919dce4894d8eac1a4Daniel Veillard * To be improved...
105bca22f40c3b2b34169d8d2919dce4894d8eac1a4Daniel Veillard */
106bca22f40c3b2b34169d8d2919dce4894d8eac1a4Daniel Veillardstatic void
107bca22f40c3b2b34169d8d2919dce4894d8eac1a4Daniel VeillardxmlBufOverflowError(xmlBufPtr buf, const char *extra)
108bca22f40c3b2b34169d8d2919dce4894d8eac1a4Daniel Veillard{
109bca22f40c3b2b34169d8d2919dce4894d8eac1a4Daniel Veillard    __xmlSimpleError(XML_FROM_BUFFER, XML_BUF_OVERFLOW, NULL, NULL, extra);
110bca22f40c3b2b34169d8d2919dce4894d8eac1a4Daniel Veillard    if ((buf) && (buf->error == 0))
111bca22f40c3b2b34169d8d2919dce4894d8eac1a4Daniel Veillard        buf->error = XML_BUF_OVERFLOW;
112bca22f40c3b2b34169d8d2919dce4894d8eac1a4Daniel Veillard}
113bca22f40c3b2b34169d8d2919dce4894d8eac1a4Daniel Veillard
114bca22f40c3b2b34169d8d2919dce4894d8eac1a4Daniel Veillard
115bca22f40c3b2b34169d8d2919dce4894d8eac1a4Daniel Veillard/**
116bca22f40c3b2b34169d8d2919dce4894d8eac1a4Daniel Veillard * xmlBufCreate:
117bca22f40c3b2b34169d8d2919dce4894d8eac1a4Daniel Veillard *
118bca22f40c3b2b34169d8d2919dce4894d8eac1a4Daniel Veillard * routine to create an XML buffer.
119bca22f40c3b2b34169d8d2919dce4894d8eac1a4Daniel Veillard * returns the new structure.
120bca22f40c3b2b34169d8d2919dce4894d8eac1a4Daniel Veillard */
121bca22f40c3b2b34169d8d2919dce4894d8eac1a4Daniel VeillardxmlBufPtr
122bca22f40c3b2b34169d8d2919dce4894d8eac1a4Daniel VeillardxmlBufCreate(void) {
123bca22f40c3b2b34169d8d2919dce4894d8eac1a4Daniel Veillard    xmlBufPtr ret;
124bca22f40c3b2b34169d8d2919dce4894d8eac1a4Daniel Veillard
125bca22f40c3b2b34169d8d2919dce4894d8eac1a4Daniel Veillard    ret = (xmlBufPtr) xmlMalloc(sizeof(xmlBuf));
126bca22f40c3b2b34169d8d2919dce4894d8eac1a4Daniel Veillard    if (ret == NULL) {
127bca22f40c3b2b34169d8d2919dce4894d8eac1a4Daniel Veillard	xmlBufMemoryError(NULL, "creating buffer");
128bca22f40c3b2b34169d8d2919dce4894d8eac1a4Daniel Veillard        return(NULL);
129bca22f40c3b2b34169d8d2919dce4894d8eac1a4Daniel Veillard    }
1309ee02f80a4d674bac96f88b5a241825aad453a7aDaniel Veillard    ret->compat_use = 0;
131bca22f40c3b2b34169d8d2919dce4894d8eac1a4Daniel Veillard    ret->use = 0;
132bca22f40c3b2b34169d8d2919dce4894d8eac1a4Daniel Veillard    ret->error = 0;
133bca22f40c3b2b34169d8d2919dce4894d8eac1a4Daniel Veillard    ret->buffer = NULL;
134bca22f40c3b2b34169d8d2919dce4894d8eac1a4Daniel Veillard    ret->size = xmlDefaultBufferSize;
1357f713494adbc1f2be3e043a737ba31b616499bc0Daniel Veillard    ret->compat_size = xmlDefaultBufferSize;
136bca22f40c3b2b34169d8d2919dce4894d8eac1a4Daniel Veillard    ret->alloc = xmlBufferAllocScheme;
137bca22f40c3b2b34169d8d2919dce4894d8eac1a4Daniel Veillard    ret->content = (xmlChar *) xmlMallocAtomic(ret->size * sizeof(xmlChar));
138bca22f40c3b2b34169d8d2919dce4894d8eac1a4Daniel Veillard    if (ret->content == NULL) {
139bca22f40c3b2b34169d8d2919dce4894d8eac1a4Daniel Veillard	xmlBufMemoryError(ret, "creating buffer");
140bca22f40c3b2b34169d8d2919dce4894d8eac1a4Daniel Veillard	xmlFree(ret);
141bca22f40c3b2b34169d8d2919dce4894d8eac1a4Daniel Veillard        return(NULL);
142bca22f40c3b2b34169d8d2919dce4894d8eac1a4Daniel Veillard    }
143bca22f40c3b2b34169d8d2919dce4894d8eac1a4Daniel Veillard    ret->content[0] = 0;
144bca22f40c3b2b34169d8d2919dce4894d8eac1a4Daniel Veillard    ret->contentIO = NULL;
145bca22f40c3b2b34169d8d2919dce4894d8eac1a4Daniel Veillard    return(ret);
146bca22f40c3b2b34169d8d2919dce4894d8eac1a4Daniel Veillard}
147bca22f40c3b2b34169d8d2919dce4894d8eac1a4Daniel Veillard
148bca22f40c3b2b34169d8d2919dce4894d8eac1a4Daniel Veillard/**
149bca22f40c3b2b34169d8d2919dce4894d8eac1a4Daniel Veillard * xmlBufCreateSize:
150bca22f40c3b2b34169d8d2919dce4894d8eac1a4Daniel Veillard * @size: initial size of buffer
151bca22f40c3b2b34169d8d2919dce4894d8eac1a4Daniel Veillard *
152bca22f40c3b2b34169d8d2919dce4894d8eac1a4Daniel Veillard * routine to create an XML buffer.
153bca22f40c3b2b34169d8d2919dce4894d8eac1a4Daniel Veillard * returns the new structure.
154bca22f40c3b2b34169d8d2919dce4894d8eac1a4Daniel Veillard */
155bca22f40c3b2b34169d8d2919dce4894d8eac1a4Daniel VeillardxmlBufPtr
156bca22f40c3b2b34169d8d2919dce4894d8eac1a4Daniel VeillardxmlBufCreateSize(size_t size) {
157bca22f40c3b2b34169d8d2919dce4894d8eac1a4Daniel Veillard    xmlBufPtr ret;
158bca22f40c3b2b34169d8d2919dce4894d8eac1a4Daniel Veillard
159bca22f40c3b2b34169d8d2919dce4894d8eac1a4Daniel Veillard    ret = (xmlBufPtr) xmlMalloc(sizeof(xmlBuf));
160bca22f40c3b2b34169d8d2919dce4894d8eac1a4Daniel Veillard    if (ret == NULL) {
161bca22f40c3b2b34169d8d2919dce4894d8eac1a4Daniel Veillard	xmlBufMemoryError(NULL, "creating buffer");
162bca22f40c3b2b34169d8d2919dce4894d8eac1a4Daniel Veillard        return(NULL);
163bca22f40c3b2b34169d8d2919dce4894d8eac1a4Daniel Veillard    }
1649ee02f80a4d674bac96f88b5a241825aad453a7aDaniel Veillard    ret->compat_use = 0;
165bca22f40c3b2b34169d8d2919dce4894d8eac1a4Daniel Veillard    ret->use = 0;
166bca22f40c3b2b34169d8d2919dce4894d8eac1a4Daniel Veillard    ret->error = 0;
167bca22f40c3b2b34169d8d2919dce4894d8eac1a4Daniel Veillard    ret->buffer = NULL;
168bca22f40c3b2b34169d8d2919dce4894d8eac1a4Daniel Veillard    ret->alloc = xmlBufferAllocScheme;
169bca22f40c3b2b34169d8d2919dce4894d8eac1a4Daniel Veillard    ret->size = (size ? size+2 : 0);         /* +1 for ending null */
1707f713494adbc1f2be3e043a737ba31b616499bc0Daniel Veillard    ret->compat_size = (int) ret->size;
171bca22f40c3b2b34169d8d2919dce4894d8eac1a4Daniel Veillard    if (ret->size){
172bca22f40c3b2b34169d8d2919dce4894d8eac1a4Daniel Veillard        ret->content = (xmlChar *) xmlMallocAtomic(ret->size * sizeof(xmlChar));
173bca22f40c3b2b34169d8d2919dce4894d8eac1a4Daniel Veillard        if (ret->content == NULL) {
174bca22f40c3b2b34169d8d2919dce4894d8eac1a4Daniel Veillard	    xmlBufMemoryError(ret, "creating buffer");
175bca22f40c3b2b34169d8d2919dce4894d8eac1a4Daniel Veillard            xmlFree(ret);
176bca22f40c3b2b34169d8d2919dce4894d8eac1a4Daniel Veillard            return(NULL);
177bca22f40c3b2b34169d8d2919dce4894d8eac1a4Daniel Veillard        }
178bca22f40c3b2b34169d8d2919dce4894d8eac1a4Daniel Veillard        ret->content[0] = 0;
179bca22f40c3b2b34169d8d2919dce4894d8eac1a4Daniel Veillard    } else
180bca22f40c3b2b34169d8d2919dce4894d8eac1a4Daniel Veillard	ret->content = NULL;
181bca22f40c3b2b34169d8d2919dce4894d8eac1a4Daniel Veillard    ret->contentIO = NULL;
182bca22f40c3b2b34169d8d2919dce4894d8eac1a4Daniel Veillard    return(ret);
183bca22f40c3b2b34169d8d2919dce4894d8eac1a4Daniel Veillard}
184bca22f40c3b2b34169d8d2919dce4894d8eac1a4Daniel Veillard
185bca22f40c3b2b34169d8d2919dce4894d8eac1a4Daniel Veillard/**
186bca22f40c3b2b34169d8d2919dce4894d8eac1a4Daniel Veillard * xmlBufDetach:
187bca22f40c3b2b34169d8d2919dce4894d8eac1a4Daniel Veillard * @buf:  the buffer
188bca22f40c3b2b34169d8d2919dce4894d8eac1a4Daniel Veillard *
1897f713494adbc1f2be3e043a737ba31b616499bc0Daniel Veillard * Remove the string contained in a buffer and give it back to the
190bca22f40c3b2b34169d8d2919dce4894d8eac1a4Daniel Veillard * caller. The buffer is reset to an empty content.
191bca22f40c3b2b34169d8d2919dce4894d8eac1a4Daniel Veillard * This doesn't work with immutable buffers as they can't be reset.
192bca22f40c3b2b34169d8d2919dce4894d8eac1a4Daniel Veillard *
193bca22f40c3b2b34169d8d2919dce4894d8eac1a4Daniel Veillard * Returns the previous string contained by the buffer.
194bca22f40c3b2b34169d8d2919dce4894d8eac1a4Daniel Veillard */
195bca22f40c3b2b34169d8d2919dce4894d8eac1a4Daniel VeillardxmlChar *
196bca22f40c3b2b34169d8d2919dce4894d8eac1a4Daniel VeillardxmlBufDetach(xmlBufPtr buf) {
197bca22f40c3b2b34169d8d2919dce4894d8eac1a4Daniel Veillard    xmlChar *ret;
198bca22f40c3b2b34169d8d2919dce4894d8eac1a4Daniel Veillard
199bca22f40c3b2b34169d8d2919dce4894d8eac1a4Daniel Veillard    if (buf == NULL)
200bca22f40c3b2b34169d8d2919dce4894d8eac1a4Daniel Veillard        return(NULL);
201bca22f40c3b2b34169d8d2919dce4894d8eac1a4Daniel Veillard    if (buf->alloc == XML_BUFFER_ALLOC_IMMUTABLE)
202bca22f40c3b2b34169d8d2919dce4894d8eac1a4Daniel Veillard        return(NULL);
203bca22f40c3b2b34169d8d2919dce4894d8eac1a4Daniel Veillard    if (buf->buffer != NULL)
204bca22f40c3b2b34169d8d2919dce4894d8eac1a4Daniel Veillard        return(NULL);
205bca22f40c3b2b34169d8d2919dce4894d8eac1a4Daniel Veillard    if (buf->error)
206bca22f40c3b2b34169d8d2919dce4894d8eac1a4Daniel Veillard        return(NULL);
207bca22f40c3b2b34169d8d2919dce4894d8eac1a4Daniel Veillard
208bca22f40c3b2b34169d8d2919dce4894d8eac1a4Daniel Veillard    ret = buf->content;
209bca22f40c3b2b34169d8d2919dce4894d8eac1a4Daniel Veillard    buf->content = NULL;
210bca22f40c3b2b34169d8d2919dce4894d8eac1a4Daniel Veillard    buf->size = 0;
211bca22f40c3b2b34169d8d2919dce4894d8eac1a4Daniel Veillard    buf->use = 0;
21218e1f1f1180c4d48ed52bf995b3c700c2cefb492Daniel Veillard    buf->compat_use = 0;
21318e1f1f1180c4d48ed52bf995b3c700c2cefb492Daniel Veillard    buf->compat_size = 0;
214bca22f40c3b2b34169d8d2919dce4894d8eac1a4Daniel Veillard
215bca22f40c3b2b34169d8d2919dce4894d8eac1a4Daniel Veillard    return ret;
216bca22f40c3b2b34169d8d2919dce4894d8eac1a4Daniel Veillard}
217bca22f40c3b2b34169d8d2919dce4894d8eac1a4Daniel Veillard
218bca22f40c3b2b34169d8d2919dce4894d8eac1a4Daniel Veillard
219bca22f40c3b2b34169d8d2919dce4894d8eac1a4Daniel Veillard/**
220bca22f40c3b2b34169d8d2919dce4894d8eac1a4Daniel Veillard * xmlBufCreateStatic:
221bca22f40c3b2b34169d8d2919dce4894d8eac1a4Daniel Veillard * @mem: the memory area
222bca22f40c3b2b34169d8d2919dce4894d8eac1a4Daniel Veillard * @size:  the size in byte
223bca22f40c3b2b34169d8d2919dce4894d8eac1a4Daniel Veillard *
224bca22f40c3b2b34169d8d2919dce4894d8eac1a4Daniel Veillard * routine to create an XML buffer from an immutable memory area.
225bca22f40c3b2b34169d8d2919dce4894d8eac1a4Daniel Veillard * The area won't be modified nor copied, and is expected to be
226bca22f40c3b2b34169d8d2919dce4894d8eac1a4Daniel Veillard * present until the end of the buffer lifetime.
227bca22f40c3b2b34169d8d2919dce4894d8eac1a4Daniel Veillard *
228bca22f40c3b2b34169d8d2919dce4894d8eac1a4Daniel Veillard * returns the new structure.
229bca22f40c3b2b34169d8d2919dce4894d8eac1a4Daniel Veillard */
230bca22f40c3b2b34169d8d2919dce4894d8eac1a4Daniel VeillardxmlBufPtr
231bca22f40c3b2b34169d8d2919dce4894d8eac1a4Daniel VeillardxmlBufCreateStatic(void *mem, size_t size) {
232bca22f40c3b2b34169d8d2919dce4894d8eac1a4Daniel Veillard    xmlBufPtr ret;
233bca22f40c3b2b34169d8d2919dce4894d8eac1a4Daniel Veillard
23494f6ce838c6a903ef5d0251f061a3af1816b4c50Nick Wellnhofer    if (mem == NULL)
235bca22f40c3b2b34169d8d2919dce4894d8eac1a4Daniel Veillard        return(NULL);
236bca22f40c3b2b34169d8d2919dce4894d8eac1a4Daniel Veillard
237bca22f40c3b2b34169d8d2919dce4894d8eac1a4Daniel Veillard    ret = (xmlBufPtr) xmlMalloc(sizeof(xmlBuf));
238bca22f40c3b2b34169d8d2919dce4894d8eac1a4Daniel Veillard    if (ret == NULL) {
239bca22f40c3b2b34169d8d2919dce4894d8eac1a4Daniel Veillard	xmlBufMemoryError(NULL, "creating buffer");
240bca22f40c3b2b34169d8d2919dce4894d8eac1a4Daniel Veillard        return(NULL);
241bca22f40c3b2b34169d8d2919dce4894d8eac1a4Daniel Veillard    }
2429ee02f80a4d674bac96f88b5a241825aad453a7aDaniel Veillard    if (size < INT_MAX) {
2439ee02f80a4d674bac96f88b5a241825aad453a7aDaniel Veillard        ret->compat_use = size;
2449ee02f80a4d674bac96f88b5a241825aad453a7aDaniel Veillard        ret->compat_size = size;
2459ee02f80a4d674bac96f88b5a241825aad453a7aDaniel Veillard    } else {
24618e1f1f1180c4d48ed52bf995b3c700c2cefb492Daniel Veillard        ret->compat_use = INT_MAX;
24718e1f1f1180c4d48ed52bf995b3c700c2cefb492Daniel Veillard        ret->compat_size = INT_MAX;
2489ee02f80a4d674bac96f88b5a241825aad453a7aDaniel Veillard    }
249bca22f40c3b2b34169d8d2919dce4894d8eac1a4Daniel Veillard    ret->use = size;
250bca22f40c3b2b34169d8d2919dce4894d8eac1a4Daniel Veillard    ret->size = size;
251bca22f40c3b2b34169d8d2919dce4894d8eac1a4Daniel Veillard    ret->alloc = XML_BUFFER_ALLOC_IMMUTABLE;
252bca22f40c3b2b34169d8d2919dce4894d8eac1a4Daniel Veillard    ret->content = (xmlChar *) mem;
253bca22f40c3b2b34169d8d2919dce4894d8eac1a4Daniel Veillard    ret->error = 0;
254bca22f40c3b2b34169d8d2919dce4894d8eac1a4Daniel Veillard    ret->buffer = NULL;
255bca22f40c3b2b34169d8d2919dce4894d8eac1a4Daniel Veillard    return(ret);
256bca22f40c3b2b34169d8d2919dce4894d8eac1a4Daniel Veillard}
257bca22f40c3b2b34169d8d2919dce4894d8eac1a4Daniel Veillard
258bca22f40c3b2b34169d8d2919dce4894d8eac1a4Daniel Veillard/**
25928cc42d06867f46f921ec137b725a124e43936fdDaniel Veillard * xmlBufGetAllocationScheme:
26028cc42d06867f46f921ec137b725a124e43936fdDaniel Veillard * @buf:  the buffer
261bca22f40c3b2b34169d8d2919dce4894d8eac1a4Daniel Veillard *
26228cc42d06867f46f921ec137b725a124e43936fdDaniel Veillard * Get the buffer allocation scheme
263bca22f40c3b2b34169d8d2919dce4894d8eac1a4Daniel Veillard *
26428cc42d06867f46f921ec137b725a124e43936fdDaniel Veillard * Returns the scheme or -1 in case of error
265bca22f40c3b2b34169d8d2919dce4894d8eac1a4Daniel Veillard */
266bca22f40c3b2b34169d8d2919dce4894d8eac1a4Daniel Veillardint
267bca22f40c3b2b34169d8d2919dce4894d8eac1a4Daniel VeillardxmlBufGetAllocationScheme(xmlBufPtr buf) {
268bca22f40c3b2b34169d8d2919dce4894d8eac1a4Daniel Veillard    if (buf == NULL) {
269bca22f40c3b2b34169d8d2919dce4894d8eac1a4Daniel Veillard#ifdef DEBUG_BUFFER
270bca22f40c3b2b34169d8d2919dce4894d8eac1a4Daniel Veillard        xmlGenericError(xmlGenericErrorContext,
271bca22f40c3b2b34169d8d2919dce4894d8eac1a4Daniel Veillard		"xmlBufGetAllocationScheme: buf == NULL\n");
272bca22f40c3b2b34169d8d2919dce4894d8eac1a4Daniel Veillard#endif
273bca22f40c3b2b34169d8d2919dce4894d8eac1a4Daniel Veillard        return(-1);
274bca22f40c3b2b34169d8d2919dce4894d8eac1a4Daniel Veillard    }
275bca22f40c3b2b34169d8d2919dce4894d8eac1a4Daniel Veillard    return(buf->alloc);
276bca22f40c3b2b34169d8d2919dce4894d8eac1a4Daniel Veillard}
277bca22f40c3b2b34169d8d2919dce4894d8eac1a4Daniel Veillard
278bca22f40c3b2b34169d8d2919dce4894d8eac1a4Daniel Veillard/**
279bca22f40c3b2b34169d8d2919dce4894d8eac1a4Daniel Veillard * xmlBufSetAllocationScheme:
280bca22f40c3b2b34169d8d2919dce4894d8eac1a4Daniel Veillard * @buf:  the buffer to tune
281bca22f40c3b2b34169d8d2919dce4894d8eac1a4Daniel Veillard * @scheme:  allocation scheme to use
282bca22f40c3b2b34169d8d2919dce4894d8eac1a4Daniel Veillard *
283bca22f40c3b2b34169d8d2919dce4894d8eac1a4Daniel Veillard * Sets the allocation scheme for this buffer
284bca22f40c3b2b34169d8d2919dce4894d8eac1a4Daniel Veillard *
285bca22f40c3b2b34169d8d2919dce4894d8eac1a4Daniel Veillard * returns 0 in case of success and -1 in case of failure
286bca22f40c3b2b34169d8d2919dce4894d8eac1a4Daniel Veillard */
287bca22f40c3b2b34169d8d2919dce4894d8eac1a4Daniel Veillardint
288bca22f40c3b2b34169d8d2919dce4894d8eac1a4Daniel VeillardxmlBufSetAllocationScheme(xmlBufPtr buf,
289bca22f40c3b2b34169d8d2919dce4894d8eac1a4Daniel Veillard                          xmlBufferAllocationScheme scheme) {
2909ee02f80a4d674bac96f88b5a241825aad453a7aDaniel Veillard    if ((buf == NULL) || (buf->error != 0)) {
291bca22f40c3b2b34169d8d2919dce4894d8eac1a4Daniel Veillard#ifdef DEBUG_BUFFER
292bca22f40c3b2b34169d8d2919dce4894d8eac1a4Daniel Veillard        xmlGenericError(xmlGenericErrorContext,
2939ee02f80a4d674bac96f88b5a241825aad453a7aDaniel Veillard		"xmlBufSetAllocationScheme: buf == NULL or in error\n");
294bca22f40c3b2b34169d8d2919dce4894d8eac1a4Daniel Veillard#endif
295bca22f40c3b2b34169d8d2919dce4894d8eac1a4Daniel Veillard        return(-1);
296bca22f40c3b2b34169d8d2919dce4894d8eac1a4Daniel Veillard    }
297bca22f40c3b2b34169d8d2919dce4894d8eac1a4Daniel Veillard    if ((buf->alloc == XML_BUFFER_ALLOC_IMMUTABLE) ||
298bca22f40c3b2b34169d8d2919dce4894d8eac1a4Daniel Veillard        (buf->alloc == XML_BUFFER_ALLOC_IO))
299bca22f40c3b2b34169d8d2919dce4894d8eac1a4Daniel Veillard        return(-1);
300bca22f40c3b2b34169d8d2919dce4894d8eac1a4Daniel Veillard    if ((scheme == XML_BUFFER_ALLOC_DOUBLEIT) ||
301bca22f40c3b2b34169d8d2919dce4894d8eac1a4Daniel Veillard        (scheme == XML_BUFFER_ALLOC_EXACT) ||
302bca22f40c3b2b34169d8d2919dce4894d8eac1a4Daniel Veillard        (scheme == XML_BUFFER_ALLOC_HYBRID) ||
303213f1fe0d76d30eaed6e5853057defc43e6df2c9Daniel Veillard        (scheme == XML_BUFFER_ALLOC_IMMUTABLE) ||
304213f1fe0d76d30eaed6e5853057defc43e6df2c9Daniel Veillard	(scheme == XML_BUFFER_ALLOC_BOUNDED)) {
305bca22f40c3b2b34169d8d2919dce4894d8eac1a4Daniel Veillard	buf->alloc = scheme;
306bca22f40c3b2b34169d8d2919dce4894d8eac1a4Daniel Veillard        if (buf->buffer)
307bca22f40c3b2b34169d8d2919dce4894d8eac1a4Daniel Veillard            buf->buffer->alloc = scheme;
308bca22f40c3b2b34169d8d2919dce4894d8eac1a4Daniel Veillard        return(0);
309bca22f40c3b2b34169d8d2919dce4894d8eac1a4Daniel Veillard    }
310bca22f40c3b2b34169d8d2919dce4894d8eac1a4Daniel Veillard    /*
311bca22f40c3b2b34169d8d2919dce4894d8eac1a4Daniel Veillard     * Switching a buffer ALLOC_IO has the side effect of initializing
312bca22f40c3b2b34169d8d2919dce4894d8eac1a4Daniel Veillard     * the contentIO field with the current content
313bca22f40c3b2b34169d8d2919dce4894d8eac1a4Daniel Veillard     */
314bca22f40c3b2b34169d8d2919dce4894d8eac1a4Daniel Veillard    if (scheme == XML_BUFFER_ALLOC_IO) {
315bca22f40c3b2b34169d8d2919dce4894d8eac1a4Daniel Veillard        buf->alloc = XML_BUFFER_ALLOC_IO;
316bca22f40c3b2b34169d8d2919dce4894d8eac1a4Daniel Veillard        buf->contentIO = buf->content;
317bca22f40c3b2b34169d8d2919dce4894d8eac1a4Daniel Veillard    }
318bca22f40c3b2b34169d8d2919dce4894d8eac1a4Daniel Veillard    return(-1);
319bca22f40c3b2b34169d8d2919dce4894d8eac1a4Daniel Veillard}
320bca22f40c3b2b34169d8d2919dce4894d8eac1a4Daniel Veillard
321bca22f40c3b2b34169d8d2919dce4894d8eac1a4Daniel Veillard/**
322bca22f40c3b2b34169d8d2919dce4894d8eac1a4Daniel Veillard * xmlBufFree:
323bca22f40c3b2b34169d8d2919dce4894d8eac1a4Daniel Veillard * @buf:  the buffer to free
324bca22f40c3b2b34169d8d2919dce4894d8eac1a4Daniel Veillard *
325bca22f40c3b2b34169d8d2919dce4894d8eac1a4Daniel Veillard * Frees an XML buffer. It frees both the content and the structure which
326bca22f40c3b2b34169d8d2919dce4894d8eac1a4Daniel Veillard * encapsulate it.
327bca22f40c3b2b34169d8d2919dce4894d8eac1a4Daniel Veillard */
328bca22f40c3b2b34169d8d2919dce4894d8eac1a4Daniel Veillardvoid
329bca22f40c3b2b34169d8d2919dce4894d8eac1a4Daniel VeillardxmlBufFree(xmlBufPtr buf) {
330bca22f40c3b2b34169d8d2919dce4894d8eac1a4Daniel Veillard    if (buf == NULL) {
331bca22f40c3b2b34169d8d2919dce4894d8eac1a4Daniel Veillard#ifdef DEBUG_BUFFER
332bca22f40c3b2b34169d8d2919dce4894d8eac1a4Daniel Veillard        xmlGenericError(xmlGenericErrorContext,
333bca22f40c3b2b34169d8d2919dce4894d8eac1a4Daniel Veillard		"xmlBufFree: buf == NULL\n");
334bca22f40c3b2b34169d8d2919dce4894d8eac1a4Daniel Veillard#endif
335bca22f40c3b2b34169d8d2919dce4894d8eac1a4Daniel Veillard	return;
336bca22f40c3b2b34169d8d2919dce4894d8eac1a4Daniel Veillard    }
337bca22f40c3b2b34169d8d2919dce4894d8eac1a4Daniel Veillard
338bca22f40c3b2b34169d8d2919dce4894d8eac1a4Daniel Veillard    if ((buf->alloc == XML_BUFFER_ALLOC_IO) &&
339bca22f40c3b2b34169d8d2919dce4894d8eac1a4Daniel Veillard        (buf->contentIO != NULL)) {
340bca22f40c3b2b34169d8d2919dce4894d8eac1a4Daniel Veillard        xmlFree(buf->contentIO);
341bca22f40c3b2b34169d8d2919dce4894d8eac1a4Daniel Veillard    } else if ((buf->content != NULL) &&
342bca22f40c3b2b34169d8d2919dce4894d8eac1a4Daniel Veillard        (buf->alloc != XML_BUFFER_ALLOC_IMMUTABLE)) {
343bca22f40c3b2b34169d8d2919dce4894d8eac1a4Daniel Veillard        xmlFree(buf->content);
344bca22f40c3b2b34169d8d2919dce4894d8eac1a4Daniel Veillard    }
345bca22f40c3b2b34169d8d2919dce4894d8eac1a4Daniel Veillard    xmlFree(buf);
346bca22f40c3b2b34169d8d2919dce4894d8eac1a4Daniel Veillard}
347bca22f40c3b2b34169d8d2919dce4894d8eac1a4Daniel Veillard
348bca22f40c3b2b34169d8d2919dce4894d8eac1a4Daniel Veillard/**
349bca22f40c3b2b34169d8d2919dce4894d8eac1a4Daniel Veillard * xmlBufEmpty:
350bca22f40c3b2b34169d8d2919dce4894d8eac1a4Daniel Veillard * @buf:  the buffer
351bca22f40c3b2b34169d8d2919dce4894d8eac1a4Daniel Veillard *
352bca22f40c3b2b34169d8d2919dce4894d8eac1a4Daniel Veillard * empty a buffer.
353bca22f40c3b2b34169d8d2919dce4894d8eac1a4Daniel Veillard */
354bca22f40c3b2b34169d8d2919dce4894d8eac1a4Daniel Veillardvoid
355bca22f40c3b2b34169d8d2919dce4894d8eac1a4Daniel VeillardxmlBufEmpty(xmlBufPtr buf) {
3569ee02f80a4d674bac96f88b5a241825aad453a7aDaniel Veillard    if ((buf == NULL) || (buf->error != 0)) return;
357bca22f40c3b2b34169d8d2919dce4894d8eac1a4Daniel Veillard    if (buf->content == NULL) return;
3587f713494adbc1f2be3e043a737ba31b616499bc0Daniel Veillard    CHECK_COMPAT(buf)
359bca22f40c3b2b34169d8d2919dce4894d8eac1a4Daniel Veillard    buf->use = 0;
360bca22f40c3b2b34169d8d2919dce4894d8eac1a4Daniel Veillard    if (buf->alloc == XML_BUFFER_ALLOC_IMMUTABLE) {
361bca22f40c3b2b34169d8d2919dce4894d8eac1a4Daniel Veillard        buf->content = BAD_CAST "";
362bca22f40c3b2b34169d8d2919dce4894d8eac1a4Daniel Veillard    } else if ((buf->alloc == XML_BUFFER_ALLOC_IO) &&
363bca22f40c3b2b34169d8d2919dce4894d8eac1a4Daniel Veillard               (buf->contentIO != NULL)) {
364bca22f40c3b2b34169d8d2919dce4894d8eac1a4Daniel Veillard        size_t start_buf = buf->content - buf->contentIO;
365bca22f40c3b2b34169d8d2919dce4894d8eac1a4Daniel Veillard
366bca22f40c3b2b34169d8d2919dce4894d8eac1a4Daniel Veillard	buf->size += start_buf;
367bca22f40c3b2b34169d8d2919dce4894d8eac1a4Daniel Veillard        buf->content = buf->contentIO;
368bca22f40c3b2b34169d8d2919dce4894d8eac1a4Daniel Veillard        buf->content[0] = 0;
369bca22f40c3b2b34169d8d2919dce4894d8eac1a4Daniel Veillard    } else {
370bca22f40c3b2b34169d8d2919dce4894d8eac1a4Daniel Veillard        buf->content[0] = 0;
371bca22f40c3b2b34169d8d2919dce4894d8eac1a4Daniel Veillard    }
37218e1f1f1180c4d48ed52bf995b3c700c2cefb492Daniel Veillard    UPDATE_COMPAT(buf)
373bca22f40c3b2b34169d8d2919dce4894d8eac1a4Daniel Veillard}
374bca22f40c3b2b34169d8d2919dce4894d8eac1a4Daniel Veillard
375bca22f40c3b2b34169d8d2919dce4894d8eac1a4Daniel Veillard/**
376bca22f40c3b2b34169d8d2919dce4894d8eac1a4Daniel Veillard * xmlBufShrink:
377bca22f40c3b2b34169d8d2919dce4894d8eac1a4Daniel Veillard * @buf:  the buffer to dump
378bca22f40c3b2b34169d8d2919dce4894d8eac1a4Daniel Veillard * @len:  the number of xmlChar to remove
379bca22f40c3b2b34169d8d2919dce4894d8eac1a4Daniel Veillard *
380bca22f40c3b2b34169d8d2919dce4894d8eac1a4Daniel Veillard * Remove the beginning of an XML buffer.
381bca22f40c3b2b34169d8d2919dce4894d8eac1a4Daniel Veillard * NOTE that this routine behaviour differs from xmlBufferShrink()
382bca22f40c3b2b34169d8d2919dce4894d8eac1a4Daniel Veillard * as it will return 0 on error instead of -1 due to size_t being
383bca22f40c3b2b34169d8d2919dce4894d8eac1a4Daniel Veillard * used as the return type.
384bca22f40c3b2b34169d8d2919dce4894d8eac1a4Daniel Veillard *
385bca22f40c3b2b34169d8d2919dce4894d8eac1a4Daniel Veillard * Returns the number of byte removed or 0 in case of failure
386bca22f40c3b2b34169d8d2919dce4894d8eac1a4Daniel Veillard */
387bca22f40c3b2b34169d8d2919dce4894d8eac1a4Daniel Veillardsize_t
388bca22f40c3b2b34169d8d2919dce4894d8eac1a4Daniel VeillardxmlBufShrink(xmlBufPtr buf, size_t len) {
3899ee02f80a4d674bac96f88b5a241825aad453a7aDaniel Veillard    if ((buf == NULL) || (buf->error != 0)) return(0);
3907f713494adbc1f2be3e043a737ba31b616499bc0Daniel Veillard    CHECK_COMPAT(buf)
391bca22f40c3b2b34169d8d2919dce4894d8eac1a4Daniel Veillard    if (len == 0) return(0);
392bca22f40c3b2b34169d8d2919dce4894d8eac1a4Daniel Veillard    if (len > buf->use) return(0);
393bca22f40c3b2b34169d8d2919dce4894d8eac1a4Daniel Veillard
394bca22f40c3b2b34169d8d2919dce4894d8eac1a4Daniel Veillard    buf->use -= len;
395bca22f40c3b2b34169d8d2919dce4894d8eac1a4Daniel Veillard    if ((buf->alloc == XML_BUFFER_ALLOC_IMMUTABLE) ||
396bca22f40c3b2b34169d8d2919dce4894d8eac1a4Daniel Veillard        ((buf->alloc == XML_BUFFER_ALLOC_IO) && (buf->contentIO != NULL))) {
397bca22f40c3b2b34169d8d2919dce4894d8eac1a4Daniel Veillard	/*
398bca22f40c3b2b34169d8d2919dce4894d8eac1a4Daniel Veillard	 * we just move the content pointer, but also make sure
399bca22f40c3b2b34169d8d2919dce4894d8eac1a4Daniel Veillard	 * the perceived buffer size has shrinked accordingly
400bca22f40c3b2b34169d8d2919dce4894d8eac1a4Daniel Veillard	 */
401bca22f40c3b2b34169d8d2919dce4894d8eac1a4Daniel Veillard        buf->content += len;
402bca22f40c3b2b34169d8d2919dce4894d8eac1a4Daniel Veillard	buf->size -= len;
403bca22f40c3b2b34169d8d2919dce4894d8eac1a4Daniel Veillard
404bca22f40c3b2b34169d8d2919dce4894d8eac1a4Daniel Veillard        /*
405bca22f40c3b2b34169d8d2919dce4894d8eac1a4Daniel Veillard	 * sometimes though it maybe be better to really shrink
406bca22f40c3b2b34169d8d2919dce4894d8eac1a4Daniel Veillard	 * on IO buffers
407bca22f40c3b2b34169d8d2919dce4894d8eac1a4Daniel Veillard	 */
408bca22f40c3b2b34169d8d2919dce4894d8eac1a4Daniel Veillard	if ((buf->alloc == XML_BUFFER_ALLOC_IO) && (buf->contentIO != NULL)) {
409bca22f40c3b2b34169d8d2919dce4894d8eac1a4Daniel Veillard	    size_t start_buf = buf->content - buf->contentIO;
410bca22f40c3b2b34169d8d2919dce4894d8eac1a4Daniel Veillard	    if (start_buf >= buf->size) {
411bca22f40c3b2b34169d8d2919dce4894d8eac1a4Daniel Veillard		memmove(buf->contentIO, &buf->content[0], buf->use);
412bca22f40c3b2b34169d8d2919dce4894d8eac1a4Daniel Veillard		buf->content = buf->contentIO;
413bca22f40c3b2b34169d8d2919dce4894d8eac1a4Daniel Veillard		buf->content[buf->use] = 0;
414bca22f40c3b2b34169d8d2919dce4894d8eac1a4Daniel Veillard		buf->size += start_buf;
415bca22f40c3b2b34169d8d2919dce4894d8eac1a4Daniel Veillard	    }
416bca22f40c3b2b34169d8d2919dce4894d8eac1a4Daniel Veillard	}
417bca22f40c3b2b34169d8d2919dce4894d8eac1a4Daniel Veillard    } else {
418bca22f40c3b2b34169d8d2919dce4894d8eac1a4Daniel Veillard	memmove(buf->content, &buf->content[len], buf->use);
419bca22f40c3b2b34169d8d2919dce4894d8eac1a4Daniel Veillard	buf->content[buf->use] = 0;
420bca22f40c3b2b34169d8d2919dce4894d8eac1a4Daniel Veillard    }
42118e1f1f1180c4d48ed52bf995b3c700c2cefb492Daniel Veillard    UPDATE_COMPAT(buf)
422bca22f40c3b2b34169d8d2919dce4894d8eac1a4Daniel Veillard    return(len);
423bca22f40c3b2b34169d8d2919dce4894d8eac1a4Daniel Veillard}
424bca22f40c3b2b34169d8d2919dce4894d8eac1a4Daniel Veillard
425bca22f40c3b2b34169d8d2919dce4894d8eac1a4Daniel Veillard/**
426bca22f40c3b2b34169d8d2919dce4894d8eac1a4Daniel Veillard * xmlBufGrowInternal:
427bca22f40c3b2b34169d8d2919dce4894d8eac1a4Daniel Veillard * @buf:  the buffer
428bca22f40c3b2b34169d8d2919dce4894d8eac1a4Daniel Veillard * @len:  the minimum free size to allocate
429bca22f40c3b2b34169d8d2919dce4894d8eac1a4Daniel Veillard *
430bca22f40c3b2b34169d8d2919dce4894d8eac1a4Daniel Veillard * Grow the available space of an XML buffer, @len is the target value
431bca22f40c3b2b34169d8d2919dce4894d8eac1a4Daniel Veillard * Error checking should be done on buf->error since using the return
432bca22f40c3b2b34169d8d2919dce4894d8eac1a4Daniel Veillard * value doesn't work that well
433bca22f40c3b2b34169d8d2919dce4894d8eac1a4Daniel Veillard *
434bca22f40c3b2b34169d8d2919dce4894d8eac1a4Daniel Veillard * Returns 0 in case of error or the length made available otherwise
435bca22f40c3b2b34169d8d2919dce4894d8eac1a4Daniel Veillard */
436bca22f40c3b2b34169d8d2919dce4894d8eac1a4Daniel Veillardstatic size_t
437bca22f40c3b2b34169d8d2919dce4894d8eac1a4Daniel VeillardxmlBufGrowInternal(xmlBufPtr buf, size_t len) {
438bca22f40c3b2b34169d8d2919dce4894d8eac1a4Daniel Veillard    size_t size;
439bca22f40c3b2b34169d8d2919dce4894d8eac1a4Daniel Veillard    xmlChar *newbuf;
440bca22f40c3b2b34169d8d2919dce4894d8eac1a4Daniel Veillard
4419ee02f80a4d674bac96f88b5a241825aad453a7aDaniel Veillard    if ((buf == NULL) || (buf->error != 0)) return(0);
4427f713494adbc1f2be3e043a737ba31b616499bc0Daniel Veillard    CHECK_COMPAT(buf)
443bca22f40c3b2b34169d8d2919dce4894d8eac1a4Daniel Veillard
444bca22f40c3b2b34169d8d2919dce4894d8eac1a4Daniel Veillard    if (buf->alloc == XML_BUFFER_ALLOC_IMMUTABLE) return(0);
445bca22f40c3b2b34169d8d2919dce4894d8eac1a4Daniel Veillard    if (buf->use + len < buf->size)
446bca22f40c3b2b34169d8d2919dce4894d8eac1a4Daniel Veillard        return(buf->size - buf->use);
447bca22f40c3b2b34169d8d2919dce4894d8eac1a4Daniel Veillard
448bca22f40c3b2b34169d8d2919dce4894d8eac1a4Daniel Veillard    /*
449bca22f40c3b2b34169d8d2919dce4894d8eac1a4Daniel Veillard     * Windows has a BIG problem on realloc timing, so we try to double
450bca22f40c3b2b34169d8d2919dce4894d8eac1a4Daniel Veillard     * the buffer size (if that's enough) (bug 146697)
451bca22f40c3b2b34169d8d2919dce4894d8eac1a4Daniel Veillard     * Apparently BSD too, and it's probably best for linux too
452bca22f40c3b2b34169d8d2919dce4894d8eac1a4Daniel Veillard     * On an embedded system this may be something to change
453bca22f40c3b2b34169d8d2919dce4894d8eac1a4Daniel Veillard     */
454bca22f40c3b2b34169d8d2919dce4894d8eac1a4Daniel Veillard#if 1
455bca22f40c3b2b34169d8d2919dce4894d8eac1a4Daniel Veillard    if (buf->size > (size_t) len)
456bca22f40c3b2b34169d8d2919dce4894d8eac1a4Daniel Veillard        size = buf->size * 2;
457bca22f40c3b2b34169d8d2919dce4894d8eac1a4Daniel Veillard    else
458bca22f40c3b2b34169d8d2919dce4894d8eac1a4Daniel Veillard        size = buf->use + len + 100;
459bca22f40c3b2b34169d8d2919dce4894d8eac1a4Daniel Veillard#else
460bca22f40c3b2b34169d8d2919dce4894d8eac1a4Daniel Veillard    size = buf->use + len + 100;
461bca22f40c3b2b34169d8d2919dce4894d8eac1a4Daniel Veillard#endif
462bca22f40c3b2b34169d8d2919dce4894d8eac1a4Daniel Veillard
463213f1fe0d76d30eaed6e5853057defc43e6df2c9Daniel Veillard    if (buf->alloc == XML_BUFFER_ALLOC_BOUNDED) {
464213f1fe0d76d30eaed6e5853057defc43e6df2c9Daniel Veillard        /*
465213f1fe0d76d30eaed6e5853057defc43e6df2c9Daniel Veillard	 * Used to provide parsing limits
466213f1fe0d76d30eaed6e5853057defc43e6df2c9Daniel Veillard	 */
467213f1fe0d76d30eaed6e5853057defc43e6df2c9Daniel Veillard        if ((buf->use + len >= XML_MAX_TEXT_LENGTH) ||
468213f1fe0d76d30eaed6e5853057defc43e6df2c9Daniel Veillard	    (buf->size >= XML_MAX_TEXT_LENGTH)) {
469213f1fe0d76d30eaed6e5853057defc43e6df2c9Daniel Veillard	    xmlBufMemoryError(buf, "buffer error: text too long\n");
470213f1fe0d76d30eaed6e5853057defc43e6df2c9Daniel Veillard	    return(0);
471213f1fe0d76d30eaed6e5853057defc43e6df2c9Daniel Veillard	}
472213f1fe0d76d30eaed6e5853057defc43e6df2c9Daniel Veillard	if (size >= XML_MAX_TEXT_LENGTH)
473213f1fe0d76d30eaed6e5853057defc43e6df2c9Daniel Veillard	    size = XML_MAX_TEXT_LENGTH;
474213f1fe0d76d30eaed6e5853057defc43e6df2c9Daniel Veillard    }
475bca22f40c3b2b34169d8d2919dce4894d8eac1a4Daniel Veillard    if ((buf->alloc == XML_BUFFER_ALLOC_IO) && (buf->contentIO != NULL)) {
476bca22f40c3b2b34169d8d2919dce4894d8eac1a4Daniel Veillard        size_t start_buf = buf->content - buf->contentIO;
477bca22f40c3b2b34169d8d2919dce4894d8eac1a4Daniel Veillard
478bca22f40c3b2b34169d8d2919dce4894d8eac1a4Daniel Veillard	newbuf = (xmlChar *) xmlRealloc(buf->contentIO, start_buf + size);
479bca22f40c3b2b34169d8d2919dce4894d8eac1a4Daniel Veillard	if (newbuf == NULL) {
480bca22f40c3b2b34169d8d2919dce4894d8eac1a4Daniel Veillard	    xmlBufMemoryError(buf, "growing buffer");
481bca22f40c3b2b34169d8d2919dce4894d8eac1a4Daniel Veillard	    return(0);
482bca22f40c3b2b34169d8d2919dce4894d8eac1a4Daniel Veillard	}
483bca22f40c3b2b34169d8d2919dce4894d8eac1a4Daniel Veillard	buf->contentIO = newbuf;
484bca22f40c3b2b34169d8d2919dce4894d8eac1a4Daniel Veillard	buf->content = newbuf + start_buf;
485bca22f40c3b2b34169d8d2919dce4894d8eac1a4Daniel Veillard    } else {
486bca22f40c3b2b34169d8d2919dce4894d8eac1a4Daniel Veillard	newbuf = (xmlChar *) xmlRealloc(buf->content, size);
487bca22f40c3b2b34169d8d2919dce4894d8eac1a4Daniel Veillard	if (newbuf == NULL) {
488bca22f40c3b2b34169d8d2919dce4894d8eac1a4Daniel Veillard	    xmlBufMemoryError(buf, "growing buffer");
489bca22f40c3b2b34169d8d2919dce4894d8eac1a4Daniel Veillard	    return(0);
490bca22f40c3b2b34169d8d2919dce4894d8eac1a4Daniel Veillard	}
491bca22f40c3b2b34169d8d2919dce4894d8eac1a4Daniel Veillard	buf->content = newbuf;
492bca22f40c3b2b34169d8d2919dce4894d8eac1a4Daniel Veillard    }
493bca22f40c3b2b34169d8d2919dce4894d8eac1a4Daniel Veillard    buf->size = size;
49418e1f1f1180c4d48ed52bf995b3c700c2cefb492Daniel Veillard    UPDATE_COMPAT(buf)
495bca22f40c3b2b34169d8d2919dce4894d8eac1a4Daniel Veillard    return(buf->size - buf->use);
496bca22f40c3b2b34169d8d2919dce4894d8eac1a4Daniel Veillard}
497bca22f40c3b2b34169d8d2919dce4894d8eac1a4Daniel Veillard
498bca22f40c3b2b34169d8d2919dce4894d8eac1a4Daniel Veillard/**
499bca22f40c3b2b34169d8d2919dce4894d8eac1a4Daniel Veillard * xmlBufGrow:
500bca22f40c3b2b34169d8d2919dce4894d8eac1a4Daniel Veillard * @buf:  the buffer
501bca22f40c3b2b34169d8d2919dce4894d8eac1a4Daniel Veillard * @len:  the minimum free size to allocate
502bca22f40c3b2b34169d8d2919dce4894d8eac1a4Daniel Veillard *
503bca22f40c3b2b34169d8d2919dce4894d8eac1a4Daniel Veillard * Grow the available space of an XML buffer, @len is the target value
504bca22f40c3b2b34169d8d2919dce4894d8eac1a4Daniel Veillard * This is been kept compatible with xmlBufferGrow() as much as possible
505bca22f40c3b2b34169d8d2919dce4894d8eac1a4Daniel Veillard *
506bca22f40c3b2b34169d8d2919dce4894d8eac1a4Daniel Veillard * Returns -1 in case of error or the length made available otherwise
507bca22f40c3b2b34169d8d2919dce4894d8eac1a4Daniel Veillard */
508bca22f40c3b2b34169d8d2919dce4894d8eac1a4Daniel Veillardint
509bca22f40c3b2b34169d8d2919dce4894d8eac1a4Daniel VeillardxmlBufGrow(xmlBufPtr buf, int len) {
510bca22f40c3b2b34169d8d2919dce4894d8eac1a4Daniel Veillard    size_t ret;
511bca22f40c3b2b34169d8d2919dce4894d8eac1a4Daniel Veillard
512bca22f40c3b2b34169d8d2919dce4894d8eac1a4Daniel Veillard    if ((buf == NULL) || (len < 0)) return(-1);
513bca22f40c3b2b34169d8d2919dce4894d8eac1a4Daniel Veillard    if (len == 0)
514bca22f40c3b2b34169d8d2919dce4894d8eac1a4Daniel Veillard        return(0);
515bca22f40c3b2b34169d8d2919dce4894d8eac1a4Daniel Veillard    ret = xmlBufGrowInternal(buf, len);
516bca22f40c3b2b34169d8d2919dce4894d8eac1a4Daniel Veillard    if (buf->error != 0)
517bca22f40c3b2b34169d8d2919dce4894d8eac1a4Daniel Veillard        return(-1);
518bca22f40c3b2b34169d8d2919dce4894d8eac1a4Daniel Veillard    return((int) ret);
519bca22f40c3b2b34169d8d2919dce4894d8eac1a4Daniel Veillard}
520bca22f40c3b2b34169d8d2919dce4894d8eac1a4Daniel Veillard
521bca22f40c3b2b34169d8d2919dce4894d8eac1a4Daniel Veillard/**
522bca22f40c3b2b34169d8d2919dce4894d8eac1a4Daniel Veillard * xmlBufInflate:
523bca22f40c3b2b34169d8d2919dce4894d8eac1a4Daniel Veillard * @buf:  the buffer
524bca22f40c3b2b34169d8d2919dce4894d8eac1a4Daniel Veillard * @len:  the minimum extra free size to allocate
525bca22f40c3b2b34169d8d2919dce4894d8eac1a4Daniel Veillard *
526bca22f40c3b2b34169d8d2919dce4894d8eac1a4Daniel Veillard * Grow the available space of an XML buffer, adding at least @len bytes
527bca22f40c3b2b34169d8d2919dce4894d8eac1a4Daniel Veillard *
528bca22f40c3b2b34169d8d2919dce4894d8eac1a4Daniel Veillard * Returns 0 if successful or -1 in case of error
529bca22f40c3b2b34169d8d2919dce4894d8eac1a4Daniel Veillard */
530bca22f40c3b2b34169d8d2919dce4894d8eac1a4Daniel Veillardint
531bca22f40c3b2b34169d8d2919dce4894d8eac1a4Daniel VeillardxmlBufInflate(xmlBufPtr buf, size_t len) {
532bca22f40c3b2b34169d8d2919dce4894d8eac1a4Daniel Veillard    if (buf == NULL) return(-1);
533bca22f40c3b2b34169d8d2919dce4894d8eac1a4Daniel Veillard    xmlBufGrowInternal(buf, len + buf->size);
534bca22f40c3b2b34169d8d2919dce4894d8eac1a4Daniel Veillard    if (buf->error)
535bca22f40c3b2b34169d8d2919dce4894d8eac1a4Daniel Veillard        return(-1);
536bca22f40c3b2b34169d8d2919dce4894d8eac1a4Daniel Veillard    return(0);
537bca22f40c3b2b34169d8d2919dce4894d8eac1a4Daniel Veillard}
538bca22f40c3b2b34169d8d2919dce4894d8eac1a4Daniel Veillard
539bca22f40c3b2b34169d8d2919dce4894d8eac1a4Daniel Veillard/**
540bca22f40c3b2b34169d8d2919dce4894d8eac1a4Daniel Veillard * xmlBufDump:
541bca22f40c3b2b34169d8d2919dce4894d8eac1a4Daniel Veillard * @file:  the file output
542bca22f40c3b2b34169d8d2919dce4894d8eac1a4Daniel Veillard * @buf:  the buffer to dump
543bca22f40c3b2b34169d8d2919dce4894d8eac1a4Daniel Veillard *
544bca22f40c3b2b34169d8d2919dce4894d8eac1a4Daniel Veillard * Dumps an XML buffer to  a FILE *.
545bca22f40c3b2b34169d8d2919dce4894d8eac1a4Daniel Veillard * Returns the number of #xmlChar written
546bca22f40c3b2b34169d8d2919dce4894d8eac1a4Daniel Veillard */
547bca22f40c3b2b34169d8d2919dce4894d8eac1a4Daniel Veillardsize_t
548bca22f40c3b2b34169d8d2919dce4894d8eac1a4Daniel VeillardxmlBufDump(FILE *file, xmlBufPtr buf) {
549bca22f40c3b2b34169d8d2919dce4894d8eac1a4Daniel Veillard    size_t ret;
550bca22f40c3b2b34169d8d2919dce4894d8eac1a4Daniel Veillard
5519ee02f80a4d674bac96f88b5a241825aad453a7aDaniel Veillard    if ((buf == NULL) || (buf->error != 0)) {
552bca22f40c3b2b34169d8d2919dce4894d8eac1a4Daniel Veillard#ifdef DEBUG_BUFFER
553bca22f40c3b2b34169d8d2919dce4894d8eac1a4Daniel Veillard        xmlGenericError(xmlGenericErrorContext,
5549ee02f80a4d674bac96f88b5a241825aad453a7aDaniel Veillard		"xmlBufDump: buf == NULL or in error\n");
555bca22f40c3b2b34169d8d2919dce4894d8eac1a4Daniel Veillard#endif
556bca22f40c3b2b34169d8d2919dce4894d8eac1a4Daniel Veillard	return(0);
557bca22f40c3b2b34169d8d2919dce4894d8eac1a4Daniel Veillard    }
558bca22f40c3b2b34169d8d2919dce4894d8eac1a4Daniel Veillard    if (buf->content == NULL) {
559bca22f40c3b2b34169d8d2919dce4894d8eac1a4Daniel Veillard#ifdef DEBUG_BUFFER
560bca22f40c3b2b34169d8d2919dce4894d8eac1a4Daniel Veillard        xmlGenericError(xmlGenericErrorContext,
561bca22f40c3b2b34169d8d2919dce4894d8eac1a4Daniel Veillard		"xmlBufDump: buf->content == NULL\n");
562bca22f40c3b2b34169d8d2919dce4894d8eac1a4Daniel Veillard#endif
563bca22f40c3b2b34169d8d2919dce4894d8eac1a4Daniel Veillard	return(0);
564bca22f40c3b2b34169d8d2919dce4894d8eac1a4Daniel Veillard    }
5657f713494adbc1f2be3e043a737ba31b616499bc0Daniel Veillard    CHECK_COMPAT(buf)
566bca22f40c3b2b34169d8d2919dce4894d8eac1a4Daniel Veillard    if (file == NULL)
567bca22f40c3b2b34169d8d2919dce4894d8eac1a4Daniel Veillard	file = stdout;
568bca22f40c3b2b34169d8d2919dce4894d8eac1a4Daniel Veillard    ret = fwrite(buf->content, sizeof(xmlChar), buf->use, file);
569bca22f40c3b2b34169d8d2919dce4894d8eac1a4Daniel Veillard    return(ret);
570bca22f40c3b2b34169d8d2919dce4894d8eac1a4Daniel Veillard}
571bca22f40c3b2b34169d8d2919dce4894d8eac1a4Daniel Veillard
572bca22f40c3b2b34169d8d2919dce4894d8eac1a4Daniel Veillard/**
573bca22f40c3b2b34169d8d2919dce4894d8eac1a4Daniel Veillard * xmlBufContent:
574bca22f40c3b2b34169d8d2919dce4894d8eac1a4Daniel Veillard * @buf:  the buffer
575bca22f40c3b2b34169d8d2919dce4894d8eac1a4Daniel Veillard *
576bca22f40c3b2b34169d8d2919dce4894d8eac1a4Daniel Veillard * Function to extract the content of a buffer
577bca22f40c3b2b34169d8d2919dce4894d8eac1a4Daniel Veillard *
578bca22f40c3b2b34169d8d2919dce4894d8eac1a4Daniel Veillard * Returns the internal content
579bca22f40c3b2b34169d8d2919dce4894d8eac1a4Daniel Veillard */
580bca22f40c3b2b34169d8d2919dce4894d8eac1a4Daniel Veillard
581bca22f40c3b2b34169d8d2919dce4894d8eac1a4Daniel VeillardxmlChar *
58295ebe53b50dfcff1fc5378309bc4f3c58173298eKurt RoeckxxmlBufContent(const xmlBuf *buf)
583bca22f40c3b2b34169d8d2919dce4894d8eac1a4Daniel Veillard{
5849ee02f80a4d674bac96f88b5a241825aad453a7aDaniel Veillard    if ((!buf) || (buf->error))
585bca22f40c3b2b34169d8d2919dce4894d8eac1a4Daniel Veillard        return NULL;
586bca22f40c3b2b34169d8d2919dce4894d8eac1a4Daniel Veillard
587bca22f40c3b2b34169d8d2919dce4894d8eac1a4Daniel Veillard    return(buf->content);
588bca22f40c3b2b34169d8d2919dce4894d8eac1a4Daniel Veillard}
589bca22f40c3b2b34169d8d2919dce4894d8eac1a4Daniel Veillard
590bca22f40c3b2b34169d8d2919dce4894d8eac1a4Daniel Veillard/**
591bca22f40c3b2b34169d8d2919dce4894d8eac1a4Daniel Veillard * xmlBufEnd:
592bca22f40c3b2b34169d8d2919dce4894d8eac1a4Daniel Veillard * @buf:  the buffer
593bca22f40c3b2b34169d8d2919dce4894d8eac1a4Daniel Veillard *
594bca22f40c3b2b34169d8d2919dce4894d8eac1a4Daniel Veillard * Function to extract the end of the content of a buffer
595bca22f40c3b2b34169d8d2919dce4894d8eac1a4Daniel Veillard *
596bca22f40c3b2b34169d8d2919dce4894d8eac1a4Daniel Veillard * Returns the end of the internal content or NULL in case of error
597bca22f40c3b2b34169d8d2919dce4894d8eac1a4Daniel Veillard */
598bca22f40c3b2b34169d8d2919dce4894d8eac1a4Daniel Veillard
599bca22f40c3b2b34169d8d2919dce4894d8eac1a4Daniel VeillardxmlChar *
60095ebe53b50dfcff1fc5378309bc4f3c58173298eKurt RoeckxxmlBufEnd(xmlBufPtr buf)
601bca22f40c3b2b34169d8d2919dce4894d8eac1a4Daniel Veillard{
6029ee02f80a4d674bac96f88b5a241825aad453a7aDaniel Veillard    if ((!buf) || (buf->error))
603bca22f40c3b2b34169d8d2919dce4894d8eac1a4Daniel Veillard        return NULL;
6047f713494adbc1f2be3e043a737ba31b616499bc0Daniel Veillard    CHECK_COMPAT(buf)
605bca22f40c3b2b34169d8d2919dce4894d8eac1a4Daniel Veillard
606bca22f40c3b2b34169d8d2919dce4894d8eac1a4Daniel Veillard    return(&buf->content[buf->use]);
607bca22f40c3b2b34169d8d2919dce4894d8eac1a4Daniel Veillard}
608bca22f40c3b2b34169d8d2919dce4894d8eac1a4Daniel Veillard
609bca22f40c3b2b34169d8d2919dce4894d8eac1a4Daniel Veillard/**
610bca22f40c3b2b34169d8d2919dce4894d8eac1a4Daniel Veillard * xmlBufAddLen:
611bca22f40c3b2b34169d8d2919dce4894d8eac1a4Daniel Veillard * @buf:  the buffer
612bca22f40c3b2b34169d8d2919dce4894d8eac1a4Daniel Veillard * @len:  the size which were added at the end
613bca22f40c3b2b34169d8d2919dce4894d8eac1a4Daniel Veillard *
614bca22f40c3b2b34169d8d2919dce4894d8eac1a4Daniel Veillard * Sometime data may be added at the end of the buffer without
615bca22f40c3b2b34169d8d2919dce4894d8eac1a4Daniel Veillard * using the xmlBuf APIs that is used to expand the used space
616bca22f40c3b2b34169d8d2919dce4894d8eac1a4Daniel Veillard * and set the zero terminating at the end of the buffer
617bca22f40c3b2b34169d8d2919dce4894d8eac1a4Daniel Veillard *
618bca22f40c3b2b34169d8d2919dce4894d8eac1a4Daniel Veillard * Returns -1 in case of error and 0 otherwise
619bca22f40c3b2b34169d8d2919dce4894d8eac1a4Daniel Veillard */
620bca22f40c3b2b34169d8d2919dce4894d8eac1a4Daniel Veillardint
621bca22f40c3b2b34169d8d2919dce4894d8eac1a4Daniel VeillardxmlBufAddLen(xmlBufPtr buf, size_t len) {
6227f713494adbc1f2be3e043a737ba31b616499bc0Daniel Veillard    if ((buf == NULL) || (buf->error))
6237f713494adbc1f2be3e043a737ba31b616499bc0Daniel Veillard        return(-1);
6247f713494adbc1f2be3e043a737ba31b616499bc0Daniel Veillard    CHECK_COMPAT(buf)
6257f713494adbc1f2be3e043a737ba31b616499bc0Daniel Veillard    if (len > (buf->size - buf->use))
626bca22f40c3b2b34169d8d2919dce4894d8eac1a4Daniel Veillard        return(-1);
627bca22f40c3b2b34169d8d2919dce4894d8eac1a4Daniel Veillard    buf->use += len;
62818e1f1f1180c4d48ed52bf995b3c700c2cefb492Daniel Veillard    UPDATE_COMPAT(buf)
629bca22f40c3b2b34169d8d2919dce4894d8eac1a4Daniel Veillard    if (buf->size > buf->use)
630bca22f40c3b2b34169d8d2919dce4894d8eac1a4Daniel Veillard        buf->content[buf->use] = 0;
631bca22f40c3b2b34169d8d2919dce4894d8eac1a4Daniel Veillard    else
632bca22f40c3b2b34169d8d2919dce4894d8eac1a4Daniel Veillard        return(-1);
633bca22f40c3b2b34169d8d2919dce4894d8eac1a4Daniel Veillard    return(0);
634bca22f40c3b2b34169d8d2919dce4894d8eac1a4Daniel Veillard}
635bca22f40c3b2b34169d8d2919dce4894d8eac1a4Daniel Veillard
636bca22f40c3b2b34169d8d2919dce4894d8eac1a4Daniel Veillard/**
637bca22f40c3b2b34169d8d2919dce4894d8eac1a4Daniel Veillard * xmlBufErase:
638bca22f40c3b2b34169d8d2919dce4894d8eac1a4Daniel Veillard * @buf:  the buffer
639bca22f40c3b2b34169d8d2919dce4894d8eac1a4Daniel Veillard * @len:  the size to erase at the end
640bca22f40c3b2b34169d8d2919dce4894d8eac1a4Daniel Veillard *
641bca22f40c3b2b34169d8d2919dce4894d8eac1a4Daniel Veillard * Sometime data need to be erased at the end of the buffer
642bca22f40c3b2b34169d8d2919dce4894d8eac1a4Daniel Veillard *
643bca22f40c3b2b34169d8d2919dce4894d8eac1a4Daniel Veillard * Returns -1 in case of error and 0 otherwise
644bca22f40c3b2b34169d8d2919dce4894d8eac1a4Daniel Veillard */
645bca22f40c3b2b34169d8d2919dce4894d8eac1a4Daniel Veillardint
646bca22f40c3b2b34169d8d2919dce4894d8eac1a4Daniel VeillardxmlBufErase(xmlBufPtr buf, size_t len) {
6477f713494adbc1f2be3e043a737ba31b616499bc0Daniel Veillard    if ((buf == NULL) || (buf->error))
6487f713494adbc1f2be3e043a737ba31b616499bc0Daniel Veillard        return(-1);
6497f713494adbc1f2be3e043a737ba31b616499bc0Daniel Veillard    CHECK_COMPAT(buf)
6507f713494adbc1f2be3e043a737ba31b616499bc0Daniel Veillard    if (len > buf->use)
651bca22f40c3b2b34169d8d2919dce4894d8eac1a4Daniel Veillard        return(-1);
652bca22f40c3b2b34169d8d2919dce4894d8eac1a4Daniel Veillard    buf->use -= len;
653bca22f40c3b2b34169d8d2919dce4894d8eac1a4Daniel Veillard    buf->content[buf->use] = 0;
65418e1f1f1180c4d48ed52bf995b3c700c2cefb492Daniel Veillard    UPDATE_COMPAT(buf)
655bca22f40c3b2b34169d8d2919dce4894d8eac1a4Daniel Veillard    return(0);
656bca22f40c3b2b34169d8d2919dce4894d8eac1a4Daniel Veillard}
657bca22f40c3b2b34169d8d2919dce4894d8eac1a4Daniel Veillard
658bca22f40c3b2b34169d8d2919dce4894d8eac1a4Daniel Veillard/**
659bca22f40c3b2b34169d8d2919dce4894d8eac1a4Daniel Veillard * xmlBufLength:
660bca22f40c3b2b34169d8d2919dce4894d8eac1a4Daniel Veillard * @buf:  the buffer
661bca22f40c3b2b34169d8d2919dce4894d8eac1a4Daniel Veillard *
662bca22f40c3b2b34169d8d2919dce4894d8eac1a4Daniel Veillard * Function to get the length of a buffer
663bca22f40c3b2b34169d8d2919dce4894d8eac1a4Daniel Veillard *
664bca22f40c3b2b34169d8d2919dce4894d8eac1a4Daniel Veillard * Returns the length of data in the internal content
665bca22f40c3b2b34169d8d2919dce4894d8eac1a4Daniel Veillard */
666bca22f40c3b2b34169d8d2919dce4894d8eac1a4Daniel Veillard
667bca22f40c3b2b34169d8d2919dce4894d8eac1a4Daniel Veillardsize_t
668bca22f40c3b2b34169d8d2919dce4894d8eac1a4Daniel VeillardxmlBufLength(const xmlBufPtr buf)
669bca22f40c3b2b34169d8d2919dce4894d8eac1a4Daniel Veillard{
6709ee02f80a4d674bac96f88b5a241825aad453a7aDaniel Veillard    if ((!buf) || (buf->error))
671bca22f40c3b2b34169d8d2919dce4894d8eac1a4Daniel Veillard        return 0;
6727f713494adbc1f2be3e043a737ba31b616499bc0Daniel Veillard    CHECK_COMPAT(buf)
673bca22f40c3b2b34169d8d2919dce4894d8eac1a4Daniel Veillard
674bca22f40c3b2b34169d8d2919dce4894d8eac1a4Daniel Veillard    return(buf->use);
675bca22f40c3b2b34169d8d2919dce4894d8eac1a4Daniel Veillard}
676bca22f40c3b2b34169d8d2919dce4894d8eac1a4Daniel Veillard
677bca22f40c3b2b34169d8d2919dce4894d8eac1a4Daniel Veillard/**
678bca22f40c3b2b34169d8d2919dce4894d8eac1a4Daniel Veillard * xmlBufUse:
679bca22f40c3b2b34169d8d2919dce4894d8eac1a4Daniel Veillard * @buf:  the buffer
680bca22f40c3b2b34169d8d2919dce4894d8eac1a4Daniel Veillard *
681bca22f40c3b2b34169d8d2919dce4894d8eac1a4Daniel Veillard * Function to get the length of a buffer
682bca22f40c3b2b34169d8d2919dce4894d8eac1a4Daniel Veillard *
683bca22f40c3b2b34169d8d2919dce4894d8eac1a4Daniel Veillard * Returns the length of data in the internal content
684bca22f40c3b2b34169d8d2919dce4894d8eac1a4Daniel Veillard */
685bca22f40c3b2b34169d8d2919dce4894d8eac1a4Daniel Veillard
686bca22f40c3b2b34169d8d2919dce4894d8eac1a4Daniel Veillardsize_t
687bca22f40c3b2b34169d8d2919dce4894d8eac1a4Daniel VeillardxmlBufUse(const xmlBufPtr buf)
688bca22f40c3b2b34169d8d2919dce4894d8eac1a4Daniel Veillard{
6899ee02f80a4d674bac96f88b5a241825aad453a7aDaniel Veillard    if ((!buf) || (buf->error))
690bca22f40c3b2b34169d8d2919dce4894d8eac1a4Daniel Veillard        return 0;
6917f713494adbc1f2be3e043a737ba31b616499bc0Daniel Veillard    CHECK_COMPAT(buf)
692bca22f40c3b2b34169d8d2919dce4894d8eac1a4Daniel Veillard
693bca22f40c3b2b34169d8d2919dce4894d8eac1a4Daniel Veillard    return(buf->use);
694bca22f40c3b2b34169d8d2919dce4894d8eac1a4Daniel Veillard}
695bca22f40c3b2b34169d8d2919dce4894d8eac1a4Daniel Veillard
696bca22f40c3b2b34169d8d2919dce4894d8eac1a4Daniel Veillard/**
697bca22f40c3b2b34169d8d2919dce4894d8eac1a4Daniel Veillard * xmlBufAvail:
698bca22f40c3b2b34169d8d2919dce4894d8eac1a4Daniel Veillard * @buf:  the buffer
699bca22f40c3b2b34169d8d2919dce4894d8eac1a4Daniel Veillard *
700bca22f40c3b2b34169d8d2919dce4894d8eac1a4Daniel Veillard * Function to find how much free space is allocated but not
701bca22f40c3b2b34169d8d2919dce4894d8eac1a4Daniel Veillard * used in the buffer. It does not account for the terminating zero
702bca22f40c3b2b34169d8d2919dce4894d8eac1a4Daniel Veillard * usually needed
703bca22f40c3b2b34169d8d2919dce4894d8eac1a4Daniel Veillard *
7048bbe4508ef2a97110eac02f16782678c38ea97afNick Wellnhofer * Returns the amount or 0 if none or an error occurred
705bca22f40c3b2b34169d8d2919dce4894d8eac1a4Daniel Veillard */
706bca22f40c3b2b34169d8d2919dce4894d8eac1a4Daniel Veillard
707bca22f40c3b2b34169d8d2919dce4894d8eac1a4Daniel Veillardsize_t
708bca22f40c3b2b34169d8d2919dce4894d8eac1a4Daniel VeillardxmlBufAvail(const xmlBufPtr buf)
709bca22f40c3b2b34169d8d2919dce4894d8eac1a4Daniel Veillard{
7109ee02f80a4d674bac96f88b5a241825aad453a7aDaniel Veillard    if ((!buf) || (buf->error))
711bca22f40c3b2b34169d8d2919dce4894d8eac1a4Daniel Veillard        return 0;
7127f713494adbc1f2be3e043a737ba31b616499bc0Daniel Veillard    CHECK_COMPAT(buf)
713bca22f40c3b2b34169d8d2919dce4894d8eac1a4Daniel Veillard
714bca22f40c3b2b34169d8d2919dce4894d8eac1a4Daniel Veillard    return(buf->size - buf->use);
715bca22f40c3b2b34169d8d2919dce4894d8eac1a4Daniel Veillard}
716bca22f40c3b2b34169d8d2919dce4894d8eac1a4Daniel Veillard
717bca22f40c3b2b34169d8d2919dce4894d8eac1a4Daniel Veillard/**
718bca22f40c3b2b34169d8d2919dce4894d8eac1a4Daniel Veillard * xmlBufIsEmpty:
719bca22f40c3b2b34169d8d2919dce4894d8eac1a4Daniel Veillard * @buf:  the buffer
720bca22f40c3b2b34169d8d2919dce4894d8eac1a4Daniel Veillard *
721bca22f40c3b2b34169d8d2919dce4894d8eac1a4Daniel Veillard * Tell if a buffer is empty
722bca22f40c3b2b34169d8d2919dce4894d8eac1a4Daniel Veillard *
723bca22f40c3b2b34169d8d2919dce4894d8eac1a4Daniel Veillard * Returns 0 if no, 1 if yes and -1 in case of error
724bca22f40c3b2b34169d8d2919dce4894d8eac1a4Daniel Veillard */
725bca22f40c3b2b34169d8d2919dce4894d8eac1a4Daniel Veillardint
726bca22f40c3b2b34169d8d2919dce4894d8eac1a4Daniel VeillardxmlBufIsEmpty(const xmlBufPtr buf)
727bca22f40c3b2b34169d8d2919dce4894d8eac1a4Daniel Veillard{
7289ee02f80a4d674bac96f88b5a241825aad453a7aDaniel Veillard    if ((!buf) || (buf->error))
729bca22f40c3b2b34169d8d2919dce4894d8eac1a4Daniel Veillard        return(-1);
7307f713494adbc1f2be3e043a737ba31b616499bc0Daniel Veillard    CHECK_COMPAT(buf)
731bca22f40c3b2b34169d8d2919dce4894d8eac1a4Daniel Veillard
732bca22f40c3b2b34169d8d2919dce4894d8eac1a4Daniel Veillard    return(buf->use == 0);
733bca22f40c3b2b34169d8d2919dce4894d8eac1a4Daniel Veillard}
734bca22f40c3b2b34169d8d2919dce4894d8eac1a4Daniel Veillard
735bca22f40c3b2b34169d8d2919dce4894d8eac1a4Daniel Veillard/**
736bca22f40c3b2b34169d8d2919dce4894d8eac1a4Daniel Veillard * xmlBufResize:
737bca22f40c3b2b34169d8d2919dce4894d8eac1a4Daniel Veillard * @buf:  the buffer to resize
738bca22f40c3b2b34169d8d2919dce4894d8eac1a4Daniel Veillard * @size:  the desired size
739bca22f40c3b2b34169d8d2919dce4894d8eac1a4Daniel Veillard *
740bca22f40c3b2b34169d8d2919dce4894d8eac1a4Daniel Veillard * Resize a buffer to accommodate minimum size of @size.
741bca22f40c3b2b34169d8d2919dce4894d8eac1a4Daniel Veillard *
742bca22f40c3b2b34169d8d2919dce4894d8eac1a4Daniel Veillard * Returns  0 in case of problems, 1 otherwise
743bca22f40c3b2b34169d8d2919dce4894d8eac1a4Daniel Veillard */
744bca22f40c3b2b34169d8d2919dce4894d8eac1a4Daniel Veillardint
745bca22f40c3b2b34169d8d2919dce4894d8eac1a4Daniel VeillardxmlBufResize(xmlBufPtr buf, size_t size)
746bca22f40c3b2b34169d8d2919dce4894d8eac1a4Daniel Veillard{
747bca22f40c3b2b34169d8d2919dce4894d8eac1a4Daniel Veillard    unsigned int newSize;
748bca22f40c3b2b34169d8d2919dce4894d8eac1a4Daniel Veillard    xmlChar* rebuf = NULL;
749bca22f40c3b2b34169d8d2919dce4894d8eac1a4Daniel Veillard    size_t start_buf;
750bca22f40c3b2b34169d8d2919dce4894d8eac1a4Daniel Veillard
7519ee02f80a4d674bac96f88b5a241825aad453a7aDaniel Veillard    if ((buf == NULL) || (buf->error))
752bca22f40c3b2b34169d8d2919dce4894d8eac1a4Daniel Veillard        return(0);
7537f713494adbc1f2be3e043a737ba31b616499bc0Daniel Veillard    CHECK_COMPAT(buf)
754bca22f40c3b2b34169d8d2919dce4894d8eac1a4Daniel Veillard
755bca22f40c3b2b34169d8d2919dce4894d8eac1a4Daniel Veillard    if (buf->alloc == XML_BUFFER_ALLOC_IMMUTABLE) return(0);
756213f1fe0d76d30eaed6e5853057defc43e6df2c9Daniel Veillard    if (buf->alloc == XML_BUFFER_ALLOC_BOUNDED) {
757213f1fe0d76d30eaed6e5853057defc43e6df2c9Daniel Veillard        /*
758213f1fe0d76d30eaed6e5853057defc43e6df2c9Daniel Veillard	 * Used to provide parsing limits
759213f1fe0d76d30eaed6e5853057defc43e6df2c9Daniel Veillard	 */
760213f1fe0d76d30eaed6e5853057defc43e6df2c9Daniel Veillard        if (size >= XML_MAX_TEXT_LENGTH) {
761213f1fe0d76d30eaed6e5853057defc43e6df2c9Daniel Veillard	    xmlBufMemoryError(buf, "buffer error: text too long\n");
762213f1fe0d76d30eaed6e5853057defc43e6df2c9Daniel Veillard	    return(0);
763213f1fe0d76d30eaed6e5853057defc43e6df2c9Daniel Veillard	}
764213f1fe0d76d30eaed6e5853057defc43e6df2c9Daniel Veillard    }
765bca22f40c3b2b34169d8d2919dce4894d8eac1a4Daniel Veillard
766bca22f40c3b2b34169d8d2919dce4894d8eac1a4Daniel Veillard    /* Don't resize if we don't have to */
767bca22f40c3b2b34169d8d2919dce4894d8eac1a4Daniel Veillard    if (size < buf->size)
768bca22f40c3b2b34169d8d2919dce4894d8eac1a4Daniel Veillard        return 1;
769bca22f40c3b2b34169d8d2919dce4894d8eac1a4Daniel Veillard
770bca22f40c3b2b34169d8d2919dce4894d8eac1a4Daniel Veillard    /* figure out new size */
771bca22f40c3b2b34169d8d2919dce4894d8eac1a4Daniel Veillard    switch (buf->alloc){
772bca22f40c3b2b34169d8d2919dce4894d8eac1a4Daniel Veillard	case XML_BUFFER_ALLOC_IO:
773bca22f40c3b2b34169d8d2919dce4894d8eac1a4Daniel Veillard	case XML_BUFFER_ALLOC_DOUBLEIT:
774bca22f40c3b2b34169d8d2919dce4894d8eac1a4Daniel Veillard	    /*take care of empty case*/
775bca22f40c3b2b34169d8d2919dce4894d8eac1a4Daniel Veillard	    newSize = (buf->size ? buf->size*2 : size + 10);
776bca22f40c3b2b34169d8d2919dce4894d8eac1a4Daniel Veillard	    while (size > newSize) {
777bca22f40c3b2b34169d8d2919dce4894d8eac1a4Daniel Veillard	        if (newSize > UINT_MAX / 2) {
778bca22f40c3b2b34169d8d2919dce4894d8eac1a4Daniel Veillard	            xmlBufMemoryError(buf, "growing buffer");
779bca22f40c3b2b34169d8d2919dce4894d8eac1a4Daniel Veillard	            return 0;
780bca22f40c3b2b34169d8d2919dce4894d8eac1a4Daniel Veillard	        }
781bca22f40c3b2b34169d8d2919dce4894d8eac1a4Daniel Veillard	        newSize *= 2;
782bca22f40c3b2b34169d8d2919dce4894d8eac1a4Daniel Veillard	    }
783bca22f40c3b2b34169d8d2919dce4894d8eac1a4Daniel Veillard	    break;
784bca22f40c3b2b34169d8d2919dce4894d8eac1a4Daniel Veillard	case XML_BUFFER_ALLOC_EXACT:
785bca22f40c3b2b34169d8d2919dce4894d8eac1a4Daniel Veillard	    newSize = size+10;
786bca22f40c3b2b34169d8d2919dce4894d8eac1a4Daniel Veillard	    break;
787bca22f40c3b2b34169d8d2919dce4894d8eac1a4Daniel Veillard        case XML_BUFFER_ALLOC_HYBRID:
788bca22f40c3b2b34169d8d2919dce4894d8eac1a4Daniel Veillard            if (buf->use < BASE_BUFFER_SIZE)
789bca22f40c3b2b34169d8d2919dce4894d8eac1a4Daniel Veillard                newSize = size;
790bca22f40c3b2b34169d8d2919dce4894d8eac1a4Daniel Veillard            else {
791bca22f40c3b2b34169d8d2919dce4894d8eac1a4Daniel Veillard                newSize = buf->size * 2;
792bca22f40c3b2b34169d8d2919dce4894d8eac1a4Daniel Veillard                while (size > newSize) {
793bca22f40c3b2b34169d8d2919dce4894d8eac1a4Daniel Veillard                    if (newSize > UINT_MAX / 2) {
794bca22f40c3b2b34169d8d2919dce4894d8eac1a4Daniel Veillard                        xmlBufMemoryError(buf, "growing buffer");
795bca22f40c3b2b34169d8d2919dce4894d8eac1a4Daniel Veillard                        return 0;
796bca22f40c3b2b34169d8d2919dce4894d8eac1a4Daniel Veillard                    }
797bca22f40c3b2b34169d8d2919dce4894d8eac1a4Daniel Veillard                    newSize *= 2;
798bca22f40c3b2b34169d8d2919dce4894d8eac1a4Daniel Veillard                }
799bca22f40c3b2b34169d8d2919dce4894d8eac1a4Daniel Veillard            }
800bca22f40c3b2b34169d8d2919dce4894d8eac1a4Daniel Veillard            break;
801bca22f40c3b2b34169d8d2919dce4894d8eac1a4Daniel Veillard
802bca22f40c3b2b34169d8d2919dce4894d8eac1a4Daniel Veillard	default:
803bca22f40c3b2b34169d8d2919dce4894d8eac1a4Daniel Veillard	    newSize = size+10;
804bca22f40c3b2b34169d8d2919dce4894d8eac1a4Daniel Veillard	    break;
805bca22f40c3b2b34169d8d2919dce4894d8eac1a4Daniel Veillard    }
806bca22f40c3b2b34169d8d2919dce4894d8eac1a4Daniel Veillard
807bca22f40c3b2b34169d8d2919dce4894d8eac1a4Daniel Veillard    if ((buf->alloc == XML_BUFFER_ALLOC_IO) && (buf->contentIO != NULL)) {
808bca22f40c3b2b34169d8d2919dce4894d8eac1a4Daniel Veillard        start_buf = buf->content - buf->contentIO;
809bca22f40c3b2b34169d8d2919dce4894d8eac1a4Daniel Veillard
810bca22f40c3b2b34169d8d2919dce4894d8eac1a4Daniel Veillard        if (start_buf > newSize) {
811bca22f40c3b2b34169d8d2919dce4894d8eac1a4Daniel Veillard	    /* move data back to start */
812bca22f40c3b2b34169d8d2919dce4894d8eac1a4Daniel Veillard	    memmove(buf->contentIO, buf->content, buf->use);
813bca22f40c3b2b34169d8d2919dce4894d8eac1a4Daniel Veillard	    buf->content = buf->contentIO;
814bca22f40c3b2b34169d8d2919dce4894d8eac1a4Daniel Veillard	    buf->content[buf->use] = 0;
815bca22f40c3b2b34169d8d2919dce4894d8eac1a4Daniel Veillard	    buf->size += start_buf;
816bca22f40c3b2b34169d8d2919dce4894d8eac1a4Daniel Veillard	} else {
817bca22f40c3b2b34169d8d2919dce4894d8eac1a4Daniel Veillard	    rebuf = (xmlChar *) xmlRealloc(buf->contentIO, start_buf + newSize);
818bca22f40c3b2b34169d8d2919dce4894d8eac1a4Daniel Veillard	    if (rebuf == NULL) {
819bca22f40c3b2b34169d8d2919dce4894d8eac1a4Daniel Veillard		xmlBufMemoryError(buf, "growing buffer");
820bca22f40c3b2b34169d8d2919dce4894d8eac1a4Daniel Veillard		return 0;
821bca22f40c3b2b34169d8d2919dce4894d8eac1a4Daniel Veillard	    }
822bca22f40c3b2b34169d8d2919dce4894d8eac1a4Daniel Veillard	    buf->contentIO = rebuf;
823bca22f40c3b2b34169d8d2919dce4894d8eac1a4Daniel Veillard	    buf->content = rebuf + start_buf;
824bca22f40c3b2b34169d8d2919dce4894d8eac1a4Daniel Veillard	}
825bca22f40c3b2b34169d8d2919dce4894d8eac1a4Daniel Veillard    } else {
826bca22f40c3b2b34169d8d2919dce4894d8eac1a4Daniel Veillard	if (buf->content == NULL) {
827bca22f40c3b2b34169d8d2919dce4894d8eac1a4Daniel Veillard	    rebuf = (xmlChar *) xmlMallocAtomic(newSize);
828bca22f40c3b2b34169d8d2919dce4894d8eac1a4Daniel Veillard	} else if (buf->size - buf->use < 100) {
829bca22f40c3b2b34169d8d2919dce4894d8eac1a4Daniel Veillard	    rebuf = (xmlChar *) xmlRealloc(buf->content, newSize);
830bca22f40c3b2b34169d8d2919dce4894d8eac1a4Daniel Veillard        } else {
831bca22f40c3b2b34169d8d2919dce4894d8eac1a4Daniel Veillard	    /*
832bca22f40c3b2b34169d8d2919dce4894d8eac1a4Daniel Veillard	     * if we are reallocating a buffer far from being full, it's
833bca22f40c3b2b34169d8d2919dce4894d8eac1a4Daniel Veillard	     * better to make a new allocation and copy only the used range
834bca22f40c3b2b34169d8d2919dce4894d8eac1a4Daniel Veillard	     * and free the old one.
835bca22f40c3b2b34169d8d2919dce4894d8eac1a4Daniel Veillard	     */
836bca22f40c3b2b34169d8d2919dce4894d8eac1a4Daniel Veillard	    rebuf = (xmlChar *) xmlMallocAtomic(newSize);
837bca22f40c3b2b34169d8d2919dce4894d8eac1a4Daniel Veillard	    if (rebuf != NULL) {
838bca22f40c3b2b34169d8d2919dce4894d8eac1a4Daniel Veillard		memcpy(rebuf, buf->content, buf->use);
839bca22f40c3b2b34169d8d2919dce4894d8eac1a4Daniel Veillard		xmlFree(buf->content);
840bca22f40c3b2b34169d8d2919dce4894d8eac1a4Daniel Veillard		rebuf[buf->use] = 0;
841bca22f40c3b2b34169d8d2919dce4894d8eac1a4Daniel Veillard	    }
842bca22f40c3b2b34169d8d2919dce4894d8eac1a4Daniel Veillard	}
843bca22f40c3b2b34169d8d2919dce4894d8eac1a4Daniel Veillard	if (rebuf == NULL) {
844bca22f40c3b2b34169d8d2919dce4894d8eac1a4Daniel Veillard	    xmlBufMemoryError(buf, "growing buffer");
845bca22f40c3b2b34169d8d2919dce4894d8eac1a4Daniel Veillard	    return 0;
846bca22f40c3b2b34169d8d2919dce4894d8eac1a4Daniel Veillard	}
847bca22f40c3b2b34169d8d2919dce4894d8eac1a4Daniel Veillard	buf->content = rebuf;
848bca22f40c3b2b34169d8d2919dce4894d8eac1a4Daniel Veillard    }
849bca22f40c3b2b34169d8d2919dce4894d8eac1a4Daniel Veillard    buf->size = newSize;
85018e1f1f1180c4d48ed52bf995b3c700c2cefb492Daniel Veillard    UPDATE_COMPAT(buf)
851bca22f40c3b2b34169d8d2919dce4894d8eac1a4Daniel Veillard
852bca22f40c3b2b34169d8d2919dce4894d8eac1a4Daniel Veillard    return 1;
853bca22f40c3b2b34169d8d2919dce4894d8eac1a4Daniel Veillard}
854bca22f40c3b2b34169d8d2919dce4894d8eac1a4Daniel Veillard
855bca22f40c3b2b34169d8d2919dce4894d8eac1a4Daniel Veillard/**
856bca22f40c3b2b34169d8d2919dce4894d8eac1a4Daniel Veillard * xmlBufAdd:
857bca22f40c3b2b34169d8d2919dce4894d8eac1a4Daniel Veillard * @buf:  the buffer to dump
858bca22f40c3b2b34169d8d2919dce4894d8eac1a4Daniel Veillard * @str:  the #xmlChar string
859bca22f40c3b2b34169d8d2919dce4894d8eac1a4Daniel Veillard * @len:  the number of #xmlChar to add
860bca22f40c3b2b34169d8d2919dce4894d8eac1a4Daniel Veillard *
861bca22f40c3b2b34169d8d2919dce4894d8eac1a4Daniel Veillard * Add a string range to an XML buffer. if len == -1, the length of
862bca22f40c3b2b34169d8d2919dce4894d8eac1a4Daniel Veillard * str is recomputed.
863bca22f40c3b2b34169d8d2919dce4894d8eac1a4Daniel Veillard *
864bca22f40c3b2b34169d8d2919dce4894d8eac1a4Daniel Veillard * Returns 0 successful, a positive error code number otherwise
865bca22f40c3b2b34169d8d2919dce4894d8eac1a4Daniel Veillard *         and -1 in case of internal or API error.
866bca22f40c3b2b34169d8d2919dce4894d8eac1a4Daniel Veillard */
867bca22f40c3b2b34169d8d2919dce4894d8eac1a4Daniel Veillardint
868bca22f40c3b2b34169d8d2919dce4894d8eac1a4Daniel VeillardxmlBufAdd(xmlBufPtr buf, const xmlChar *str, int len) {
869bca22f40c3b2b34169d8d2919dce4894d8eac1a4Daniel Veillard    unsigned int needSize;
870bca22f40c3b2b34169d8d2919dce4894d8eac1a4Daniel Veillard
8717f713494adbc1f2be3e043a737ba31b616499bc0Daniel Veillard    if ((str == NULL) || (buf == NULL) || (buf->error))
872bca22f40c3b2b34169d8d2919dce4894d8eac1a4Daniel Veillard	return -1;
8737f713494adbc1f2be3e043a737ba31b616499bc0Daniel Veillard    CHECK_COMPAT(buf)
8747f713494adbc1f2be3e043a737ba31b616499bc0Daniel Veillard
875bca22f40c3b2b34169d8d2919dce4894d8eac1a4Daniel Veillard    if (buf->alloc == XML_BUFFER_ALLOC_IMMUTABLE) return -1;
876bca22f40c3b2b34169d8d2919dce4894d8eac1a4Daniel Veillard    if (len < -1) {
877bca22f40c3b2b34169d8d2919dce4894d8eac1a4Daniel Veillard#ifdef DEBUG_BUFFER
878bca22f40c3b2b34169d8d2919dce4894d8eac1a4Daniel Veillard        xmlGenericError(xmlGenericErrorContext,
879bca22f40c3b2b34169d8d2919dce4894d8eac1a4Daniel Veillard		"xmlBufAdd: len < 0\n");
880bca22f40c3b2b34169d8d2919dce4894d8eac1a4Daniel Veillard#endif
881bca22f40c3b2b34169d8d2919dce4894d8eac1a4Daniel Veillard	return -1;
882bca22f40c3b2b34169d8d2919dce4894d8eac1a4Daniel Veillard    }
883bca22f40c3b2b34169d8d2919dce4894d8eac1a4Daniel Veillard    if (len == 0) return 0;
884bca22f40c3b2b34169d8d2919dce4894d8eac1a4Daniel Veillard
885bca22f40c3b2b34169d8d2919dce4894d8eac1a4Daniel Veillard    if (len < 0)
886bca22f40c3b2b34169d8d2919dce4894d8eac1a4Daniel Veillard        len = xmlStrlen(str);
887bca22f40c3b2b34169d8d2919dce4894d8eac1a4Daniel Veillard
888bca22f40c3b2b34169d8d2919dce4894d8eac1a4Daniel Veillard    if (len < 0) return -1;
889bca22f40c3b2b34169d8d2919dce4894d8eac1a4Daniel Veillard    if (len == 0) return 0;
890bca22f40c3b2b34169d8d2919dce4894d8eac1a4Daniel Veillard
891bca22f40c3b2b34169d8d2919dce4894d8eac1a4Daniel Veillard    needSize = buf->use + len + 2;
892bca22f40c3b2b34169d8d2919dce4894d8eac1a4Daniel Veillard    if (needSize > buf->size){
893213f1fe0d76d30eaed6e5853057defc43e6df2c9Daniel Veillard	if (buf->alloc == XML_BUFFER_ALLOC_BOUNDED) {
894213f1fe0d76d30eaed6e5853057defc43e6df2c9Daniel Veillard	    /*
895213f1fe0d76d30eaed6e5853057defc43e6df2c9Daniel Veillard	     * Used to provide parsing limits
896213f1fe0d76d30eaed6e5853057defc43e6df2c9Daniel Veillard	     */
897213f1fe0d76d30eaed6e5853057defc43e6df2c9Daniel Veillard	    if (needSize >= XML_MAX_TEXT_LENGTH) {
898213f1fe0d76d30eaed6e5853057defc43e6df2c9Daniel Veillard		xmlBufMemoryError(buf, "buffer error: text too long\n");
899213f1fe0d76d30eaed6e5853057defc43e6df2c9Daniel Veillard		return(-1);
900213f1fe0d76d30eaed6e5853057defc43e6df2c9Daniel Veillard	    }
901213f1fe0d76d30eaed6e5853057defc43e6df2c9Daniel Veillard	}
902bca22f40c3b2b34169d8d2919dce4894d8eac1a4Daniel Veillard        if (!xmlBufResize(buf, needSize)){
903bca22f40c3b2b34169d8d2919dce4894d8eac1a4Daniel Veillard	    xmlBufMemoryError(buf, "growing buffer");
904bca22f40c3b2b34169d8d2919dce4894d8eac1a4Daniel Veillard            return XML_ERR_NO_MEMORY;
905bca22f40c3b2b34169d8d2919dce4894d8eac1a4Daniel Veillard        }
906bca22f40c3b2b34169d8d2919dce4894d8eac1a4Daniel Veillard    }
907bca22f40c3b2b34169d8d2919dce4894d8eac1a4Daniel Veillard
908bca22f40c3b2b34169d8d2919dce4894d8eac1a4Daniel Veillard    memmove(&buf->content[buf->use], str, len*sizeof(xmlChar));
909bca22f40c3b2b34169d8d2919dce4894d8eac1a4Daniel Veillard    buf->use += len;
910bca22f40c3b2b34169d8d2919dce4894d8eac1a4Daniel Veillard    buf->content[buf->use] = 0;
91118e1f1f1180c4d48ed52bf995b3c700c2cefb492Daniel Veillard    UPDATE_COMPAT(buf)
912bca22f40c3b2b34169d8d2919dce4894d8eac1a4Daniel Veillard    return 0;
913bca22f40c3b2b34169d8d2919dce4894d8eac1a4Daniel Veillard}
914bca22f40c3b2b34169d8d2919dce4894d8eac1a4Daniel Veillard
915bca22f40c3b2b34169d8d2919dce4894d8eac1a4Daniel Veillard/**
916bca22f40c3b2b34169d8d2919dce4894d8eac1a4Daniel Veillard * xmlBufAddHead:
917bca22f40c3b2b34169d8d2919dce4894d8eac1a4Daniel Veillard * @buf:  the buffer
918bca22f40c3b2b34169d8d2919dce4894d8eac1a4Daniel Veillard * @str:  the #xmlChar string
919bca22f40c3b2b34169d8d2919dce4894d8eac1a4Daniel Veillard * @len:  the number of #xmlChar to add
920bca22f40c3b2b34169d8d2919dce4894d8eac1a4Daniel Veillard *
921bca22f40c3b2b34169d8d2919dce4894d8eac1a4Daniel Veillard * Add a string range to the beginning of an XML buffer.
922bca22f40c3b2b34169d8d2919dce4894d8eac1a4Daniel Veillard * if len == -1, the length of @str is recomputed.
923bca22f40c3b2b34169d8d2919dce4894d8eac1a4Daniel Veillard *
924bca22f40c3b2b34169d8d2919dce4894d8eac1a4Daniel Veillard * Returns 0 successful, a positive error code number otherwise
925bca22f40c3b2b34169d8d2919dce4894d8eac1a4Daniel Veillard *         and -1 in case of internal or API error.
926bca22f40c3b2b34169d8d2919dce4894d8eac1a4Daniel Veillard */
927bca22f40c3b2b34169d8d2919dce4894d8eac1a4Daniel Veillardint
928bca22f40c3b2b34169d8d2919dce4894d8eac1a4Daniel VeillardxmlBufAddHead(xmlBufPtr buf, const xmlChar *str, int len) {
929bca22f40c3b2b34169d8d2919dce4894d8eac1a4Daniel Veillard    unsigned int needSize;
930bca22f40c3b2b34169d8d2919dce4894d8eac1a4Daniel Veillard
9319ee02f80a4d674bac96f88b5a241825aad453a7aDaniel Veillard    if ((buf == NULL) || (buf->error))
932bca22f40c3b2b34169d8d2919dce4894d8eac1a4Daniel Veillard        return(-1);
9337f713494adbc1f2be3e043a737ba31b616499bc0Daniel Veillard    CHECK_COMPAT(buf)
934bca22f40c3b2b34169d8d2919dce4894d8eac1a4Daniel Veillard    if (buf->alloc == XML_BUFFER_ALLOC_IMMUTABLE) return -1;
935bca22f40c3b2b34169d8d2919dce4894d8eac1a4Daniel Veillard    if (str == NULL) {
936bca22f40c3b2b34169d8d2919dce4894d8eac1a4Daniel Veillard#ifdef DEBUG_BUFFER
937bca22f40c3b2b34169d8d2919dce4894d8eac1a4Daniel Veillard        xmlGenericError(xmlGenericErrorContext,
938bca22f40c3b2b34169d8d2919dce4894d8eac1a4Daniel Veillard		"xmlBufAddHead: str == NULL\n");
939bca22f40c3b2b34169d8d2919dce4894d8eac1a4Daniel Veillard#endif
940bca22f40c3b2b34169d8d2919dce4894d8eac1a4Daniel Veillard	return -1;
941bca22f40c3b2b34169d8d2919dce4894d8eac1a4Daniel Veillard    }
942bca22f40c3b2b34169d8d2919dce4894d8eac1a4Daniel Veillard    if (len < -1) {
943bca22f40c3b2b34169d8d2919dce4894d8eac1a4Daniel Veillard#ifdef DEBUG_BUFFER
944bca22f40c3b2b34169d8d2919dce4894d8eac1a4Daniel Veillard        xmlGenericError(xmlGenericErrorContext,
945bca22f40c3b2b34169d8d2919dce4894d8eac1a4Daniel Veillard		"xmlBufAddHead: len < 0\n");
946bca22f40c3b2b34169d8d2919dce4894d8eac1a4Daniel Veillard#endif
947bca22f40c3b2b34169d8d2919dce4894d8eac1a4Daniel Veillard	return -1;
948bca22f40c3b2b34169d8d2919dce4894d8eac1a4Daniel Veillard    }
949bca22f40c3b2b34169d8d2919dce4894d8eac1a4Daniel Veillard    if (len == 0) return 0;
950bca22f40c3b2b34169d8d2919dce4894d8eac1a4Daniel Veillard
951bca22f40c3b2b34169d8d2919dce4894d8eac1a4Daniel Veillard    if (len < 0)
952bca22f40c3b2b34169d8d2919dce4894d8eac1a4Daniel Veillard        len = xmlStrlen(str);
953bca22f40c3b2b34169d8d2919dce4894d8eac1a4Daniel Veillard
954bca22f40c3b2b34169d8d2919dce4894d8eac1a4Daniel Veillard    if (len <= 0) return -1;
955bca22f40c3b2b34169d8d2919dce4894d8eac1a4Daniel Veillard
956bca22f40c3b2b34169d8d2919dce4894d8eac1a4Daniel Veillard    if ((buf->alloc == XML_BUFFER_ALLOC_IO) && (buf->contentIO != NULL)) {
957bca22f40c3b2b34169d8d2919dce4894d8eac1a4Daniel Veillard        size_t start_buf = buf->content - buf->contentIO;
958bca22f40c3b2b34169d8d2919dce4894d8eac1a4Daniel Veillard
959bca22f40c3b2b34169d8d2919dce4894d8eac1a4Daniel Veillard	if (start_buf > (unsigned int) len) {
960bca22f40c3b2b34169d8d2919dce4894d8eac1a4Daniel Veillard	    /*
961bca22f40c3b2b34169d8d2919dce4894d8eac1a4Daniel Veillard	     * We can add it in the space previously shrinked
962bca22f40c3b2b34169d8d2919dce4894d8eac1a4Daniel Veillard	     */
963bca22f40c3b2b34169d8d2919dce4894d8eac1a4Daniel Veillard	    buf->content -= len;
964bca22f40c3b2b34169d8d2919dce4894d8eac1a4Daniel Veillard            memmove(&buf->content[0], str, len);
965bca22f40c3b2b34169d8d2919dce4894d8eac1a4Daniel Veillard	    buf->use += len;
966bca22f40c3b2b34169d8d2919dce4894d8eac1a4Daniel Veillard	    buf->size += len;
9677f713494adbc1f2be3e043a737ba31b616499bc0Daniel Veillard	    UPDATE_COMPAT(buf)
968bca22f40c3b2b34169d8d2919dce4894d8eac1a4Daniel Veillard	    return(0);
969bca22f40c3b2b34169d8d2919dce4894d8eac1a4Daniel Veillard	}
970bca22f40c3b2b34169d8d2919dce4894d8eac1a4Daniel Veillard    }
971bca22f40c3b2b34169d8d2919dce4894d8eac1a4Daniel Veillard    needSize = buf->use + len + 2;
972bca22f40c3b2b34169d8d2919dce4894d8eac1a4Daniel Veillard    if (needSize > buf->size){
973213f1fe0d76d30eaed6e5853057defc43e6df2c9Daniel Veillard	if (buf->alloc == XML_BUFFER_ALLOC_BOUNDED) {
974213f1fe0d76d30eaed6e5853057defc43e6df2c9Daniel Veillard	    /*
975213f1fe0d76d30eaed6e5853057defc43e6df2c9Daniel Veillard	     * Used to provide parsing limits
976213f1fe0d76d30eaed6e5853057defc43e6df2c9Daniel Veillard	     */
977213f1fe0d76d30eaed6e5853057defc43e6df2c9Daniel Veillard	    if (needSize >= XML_MAX_TEXT_LENGTH) {
978213f1fe0d76d30eaed6e5853057defc43e6df2c9Daniel Veillard		xmlBufMemoryError(buf, "buffer error: text too long\n");
979213f1fe0d76d30eaed6e5853057defc43e6df2c9Daniel Veillard		return(-1);
980213f1fe0d76d30eaed6e5853057defc43e6df2c9Daniel Veillard	    }
981213f1fe0d76d30eaed6e5853057defc43e6df2c9Daniel Veillard	}
982bca22f40c3b2b34169d8d2919dce4894d8eac1a4Daniel Veillard        if (!xmlBufResize(buf, needSize)){
983bca22f40c3b2b34169d8d2919dce4894d8eac1a4Daniel Veillard	    xmlBufMemoryError(buf, "growing buffer");
984bca22f40c3b2b34169d8d2919dce4894d8eac1a4Daniel Veillard            return XML_ERR_NO_MEMORY;
985bca22f40c3b2b34169d8d2919dce4894d8eac1a4Daniel Veillard        }
986bca22f40c3b2b34169d8d2919dce4894d8eac1a4Daniel Veillard    }
987bca22f40c3b2b34169d8d2919dce4894d8eac1a4Daniel Veillard
988bca22f40c3b2b34169d8d2919dce4894d8eac1a4Daniel Veillard    memmove(&buf->content[len], &buf->content[0], buf->use);
989bca22f40c3b2b34169d8d2919dce4894d8eac1a4Daniel Veillard    memmove(&buf->content[0], str, len);
990bca22f40c3b2b34169d8d2919dce4894d8eac1a4Daniel Veillard    buf->use += len;
991bca22f40c3b2b34169d8d2919dce4894d8eac1a4Daniel Veillard    buf->content[buf->use] = 0;
99218e1f1f1180c4d48ed52bf995b3c700c2cefb492Daniel Veillard    UPDATE_COMPAT(buf)
993bca22f40c3b2b34169d8d2919dce4894d8eac1a4Daniel Veillard    return 0;
994bca22f40c3b2b34169d8d2919dce4894d8eac1a4Daniel Veillard}
995bca22f40c3b2b34169d8d2919dce4894d8eac1a4Daniel Veillard
996bca22f40c3b2b34169d8d2919dce4894d8eac1a4Daniel Veillard/**
997bca22f40c3b2b34169d8d2919dce4894d8eac1a4Daniel Veillard * xmlBufCat:
998bca22f40c3b2b34169d8d2919dce4894d8eac1a4Daniel Veillard * @buf:  the buffer to add to
999bca22f40c3b2b34169d8d2919dce4894d8eac1a4Daniel Veillard * @str:  the #xmlChar string
1000bca22f40c3b2b34169d8d2919dce4894d8eac1a4Daniel Veillard *
1001bca22f40c3b2b34169d8d2919dce4894d8eac1a4Daniel Veillard * Append a zero terminated string to an XML buffer.
1002bca22f40c3b2b34169d8d2919dce4894d8eac1a4Daniel Veillard *
1003bca22f40c3b2b34169d8d2919dce4894d8eac1a4Daniel Veillard * Returns 0 successful, a positive error code number otherwise
1004bca22f40c3b2b34169d8d2919dce4894d8eac1a4Daniel Veillard *         and -1 in case of internal or API error.
1005bca22f40c3b2b34169d8d2919dce4894d8eac1a4Daniel Veillard */
1006bca22f40c3b2b34169d8d2919dce4894d8eac1a4Daniel Veillardint
1007bca22f40c3b2b34169d8d2919dce4894d8eac1a4Daniel VeillardxmlBufCat(xmlBufPtr buf, const xmlChar *str) {
10089ee02f80a4d674bac96f88b5a241825aad453a7aDaniel Veillard    if ((buf == NULL) || (buf->error))
1009bca22f40c3b2b34169d8d2919dce4894d8eac1a4Daniel Veillard        return(-1);
10107f713494adbc1f2be3e043a737ba31b616499bc0Daniel Veillard    CHECK_COMPAT(buf)
1011bca22f40c3b2b34169d8d2919dce4894d8eac1a4Daniel Veillard    if (buf->alloc == XML_BUFFER_ALLOC_IMMUTABLE) return -1;
1012bca22f40c3b2b34169d8d2919dce4894d8eac1a4Daniel Veillard    if (str == NULL) return -1;
1013bca22f40c3b2b34169d8d2919dce4894d8eac1a4Daniel Veillard    return xmlBufAdd(buf, str, -1);
1014bca22f40c3b2b34169d8d2919dce4894d8eac1a4Daniel Veillard}
1015bca22f40c3b2b34169d8d2919dce4894d8eac1a4Daniel Veillard
1016bca22f40c3b2b34169d8d2919dce4894d8eac1a4Daniel Veillard/**
1017bca22f40c3b2b34169d8d2919dce4894d8eac1a4Daniel Veillard * xmlBufCCat:
1018bca22f40c3b2b34169d8d2919dce4894d8eac1a4Daniel Veillard * @buf:  the buffer to dump
1019bca22f40c3b2b34169d8d2919dce4894d8eac1a4Daniel Veillard * @str:  the C char string
1020bca22f40c3b2b34169d8d2919dce4894d8eac1a4Daniel Veillard *
1021bca22f40c3b2b34169d8d2919dce4894d8eac1a4Daniel Veillard * Append a zero terminated C string to an XML buffer.
1022bca22f40c3b2b34169d8d2919dce4894d8eac1a4Daniel Veillard *
1023bca22f40c3b2b34169d8d2919dce4894d8eac1a4Daniel Veillard * Returns 0 successful, a positive error code number otherwise
1024bca22f40c3b2b34169d8d2919dce4894d8eac1a4Daniel Veillard *         and -1 in case of internal or API error.
1025bca22f40c3b2b34169d8d2919dce4894d8eac1a4Daniel Veillard */
1026bca22f40c3b2b34169d8d2919dce4894d8eac1a4Daniel Veillardint
1027bca22f40c3b2b34169d8d2919dce4894d8eac1a4Daniel VeillardxmlBufCCat(xmlBufPtr buf, const char *str) {
1028bca22f40c3b2b34169d8d2919dce4894d8eac1a4Daniel Veillard    const char *cur;
1029bca22f40c3b2b34169d8d2919dce4894d8eac1a4Daniel Veillard
10309ee02f80a4d674bac96f88b5a241825aad453a7aDaniel Veillard    if ((buf == NULL) || (buf->error))
1031bca22f40c3b2b34169d8d2919dce4894d8eac1a4Daniel Veillard        return(-1);
10327f713494adbc1f2be3e043a737ba31b616499bc0Daniel Veillard    CHECK_COMPAT(buf)
1033bca22f40c3b2b34169d8d2919dce4894d8eac1a4Daniel Veillard    if (buf->alloc == XML_BUFFER_ALLOC_IMMUTABLE) return -1;
1034bca22f40c3b2b34169d8d2919dce4894d8eac1a4Daniel Veillard    if (str == NULL) {
1035bca22f40c3b2b34169d8d2919dce4894d8eac1a4Daniel Veillard#ifdef DEBUG_BUFFER
1036bca22f40c3b2b34169d8d2919dce4894d8eac1a4Daniel Veillard        xmlGenericError(xmlGenericErrorContext,
1037bca22f40c3b2b34169d8d2919dce4894d8eac1a4Daniel Veillard		"xmlBufCCat: str == NULL\n");
1038bca22f40c3b2b34169d8d2919dce4894d8eac1a4Daniel Veillard#endif
1039bca22f40c3b2b34169d8d2919dce4894d8eac1a4Daniel Veillard	return -1;
1040bca22f40c3b2b34169d8d2919dce4894d8eac1a4Daniel Veillard    }
1041bca22f40c3b2b34169d8d2919dce4894d8eac1a4Daniel Veillard    for (cur = str;*cur != 0;cur++) {
1042bca22f40c3b2b34169d8d2919dce4894d8eac1a4Daniel Veillard        if (buf->use  + 10 >= buf->size) {
1043bca22f40c3b2b34169d8d2919dce4894d8eac1a4Daniel Veillard            if (!xmlBufResize(buf, buf->use+10)){
1044bca22f40c3b2b34169d8d2919dce4894d8eac1a4Daniel Veillard		xmlBufMemoryError(buf, "growing buffer");
1045bca22f40c3b2b34169d8d2919dce4894d8eac1a4Daniel Veillard                return XML_ERR_NO_MEMORY;
1046bca22f40c3b2b34169d8d2919dce4894d8eac1a4Daniel Veillard            }
1047bca22f40c3b2b34169d8d2919dce4894d8eac1a4Daniel Veillard        }
1048bca22f40c3b2b34169d8d2919dce4894d8eac1a4Daniel Veillard        buf->content[buf->use++] = *cur;
1049bca22f40c3b2b34169d8d2919dce4894d8eac1a4Daniel Veillard    }
1050bca22f40c3b2b34169d8d2919dce4894d8eac1a4Daniel Veillard    buf->content[buf->use] = 0;
105118e1f1f1180c4d48ed52bf995b3c700c2cefb492Daniel Veillard    UPDATE_COMPAT(buf)
1052bca22f40c3b2b34169d8d2919dce4894d8eac1a4Daniel Veillard    return 0;
1053bca22f40c3b2b34169d8d2919dce4894d8eac1a4Daniel Veillard}
1054bca22f40c3b2b34169d8d2919dce4894d8eac1a4Daniel Veillard
1055bca22f40c3b2b34169d8d2919dce4894d8eac1a4Daniel Veillard/**
1056bca22f40c3b2b34169d8d2919dce4894d8eac1a4Daniel Veillard * xmlBufWriteCHAR:
1057bca22f40c3b2b34169d8d2919dce4894d8eac1a4Daniel Veillard * @buf:  the XML buffer
1058bca22f40c3b2b34169d8d2919dce4894d8eac1a4Daniel Veillard * @string:  the string to add
1059bca22f40c3b2b34169d8d2919dce4894d8eac1a4Daniel Veillard *
1060bca22f40c3b2b34169d8d2919dce4894d8eac1a4Daniel Veillard * routine which manages and grows an output buffer. This one adds
1061bca22f40c3b2b34169d8d2919dce4894d8eac1a4Daniel Veillard * xmlChars at the end of the buffer.
1062bca22f40c3b2b34169d8d2919dce4894d8eac1a4Daniel Veillard *
1063bca22f40c3b2b34169d8d2919dce4894d8eac1a4Daniel Veillard * Returns 0 if successful, a positive error code number otherwise
1064bca22f40c3b2b34169d8d2919dce4894d8eac1a4Daniel Veillard *         and -1 in case of internal or API error.
1065bca22f40c3b2b34169d8d2919dce4894d8eac1a4Daniel Veillard */
1066bca22f40c3b2b34169d8d2919dce4894d8eac1a4Daniel Veillardint
1067bca22f40c3b2b34169d8d2919dce4894d8eac1a4Daniel VeillardxmlBufWriteCHAR(xmlBufPtr buf, const xmlChar *string) {
10689ee02f80a4d674bac96f88b5a241825aad453a7aDaniel Veillard    if ((buf == NULL) || (buf->error))
1069bca22f40c3b2b34169d8d2919dce4894d8eac1a4Daniel Veillard        return(-1);
10707f713494adbc1f2be3e043a737ba31b616499bc0Daniel Veillard    CHECK_COMPAT(buf)
1071bca22f40c3b2b34169d8d2919dce4894d8eac1a4Daniel Veillard    if (buf->alloc == XML_BUFFER_ALLOC_IMMUTABLE)
1072bca22f40c3b2b34169d8d2919dce4894d8eac1a4Daniel Veillard        return(-1);
1073bca22f40c3b2b34169d8d2919dce4894d8eac1a4Daniel Veillard    return(xmlBufCat(buf, string));
1074bca22f40c3b2b34169d8d2919dce4894d8eac1a4Daniel Veillard}
1075bca22f40c3b2b34169d8d2919dce4894d8eac1a4Daniel Veillard
1076bca22f40c3b2b34169d8d2919dce4894d8eac1a4Daniel Veillard/**
1077bca22f40c3b2b34169d8d2919dce4894d8eac1a4Daniel Veillard * xmlBufWriteChar:
1078bca22f40c3b2b34169d8d2919dce4894d8eac1a4Daniel Veillard * @buf:  the XML buffer output
1079bca22f40c3b2b34169d8d2919dce4894d8eac1a4Daniel Veillard * @string:  the string to add
1080bca22f40c3b2b34169d8d2919dce4894d8eac1a4Daniel Veillard *
1081bca22f40c3b2b34169d8d2919dce4894d8eac1a4Daniel Veillard * routine which manage and grows an output buffer. This one add
1082bca22f40c3b2b34169d8d2919dce4894d8eac1a4Daniel Veillard * C chars at the end of the array.
1083bca22f40c3b2b34169d8d2919dce4894d8eac1a4Daniel Veillard *
1084bca22f40c3b2b34169d8d2919dce4894d8eac1a4Daniel Veillard * Returns 0 if successful, a positive error code number otherwise
1085bca22f40c3b2b34169d8d2919dce4894d8eac1a4Daniel Veillard *         and -1 in case of internal or API error.
1086bca22f40c3b2b34169d8d2919dce4894d8eac1a4Daniel Veillard */
1087bca22f40c3b2b34169d8d2919dce4894d8eac1a4Daniel Veillardint
1088bca22f40c3b2b34169d8d2919dce4894d8eac1a4Daniel VeillardxmlBufWriteChar(xmlBufPtr buf, const char *string) {
10899ee02f80a4d674bac96f88b5a241825aad453a7aDaniel Veillard    if ((buf == NULL) || (buf->error))
1090bca22f40c3b2b34169d8d2919dce4894d8eac1a4Daniel Veillard        return(-1);
10917f713494adbc1f2be3e043a737ba31b616499bc0Daniel Veillard    CHECK_COMPAT(buf)
1092bca22f40c3b2b34169d8d2919dce4894d8eac1a4Daniel Veillard    if (buf->alloc == XML_BUFFER_ALLOC_IMMUTABLE)
1093bca22f40c3b2b34169d8d2919dce4894d8eac1a4Daniel Veillard        return(-1);
1094bca22f40c3b2b34169d8d2919dce4894d8eac1a4Daniel Veillard    return(xmlBufCCat(buf, string));
1095bca22f40c3b2b34169d8d2919dce4894d8eac1a4Daniel Veillard}
1096bca22f40c3b2b34169d8d2919dce4894d8eac1a4Daniel Veillard
1097bca22f40c3b2b34169d8d2919dce4894d8eac1a4Daniel Veillard
1098bca22f40c3b2b34169d8d2919dce4894d8eac1a4Daniel Veillard/**
1099bca22f40c3b2b34169d8d2919dce4894d8eac1a4Daniel Veillard * xmlBufWriteQuotedString:
1100bca22f40c3b2b34169d8d2919dce4894d8eac1a4Daniel Veillard * @buf:  the XML buffer output
1101bca22f40c3b2b34169d8d2919dce4894d8eac1a4Daniel Veillard * @string:  the string to add
1102bca22f40c3b2b34169d8d2919dce4894d8eac1a4Daniel Veillard *
1103bca22f40c3b2b34169d8d2919dce4894d8eac1a4Daniel Veillard * routine which manage and grows an output buffer. This one writes
1104bca22f40c3b2b34169d8d2919dce4894d8eac1a4Daniel Veillard * a quoted or double quoted #xmlChar string, checking first if it holds
1105bca22f40c3b2b34169d8d2919dce4894d8eac1a4Daniel Veillard * quote or double-quotes internally
1106bca22f40c3b2b34169d8d2919dce4894d8eac1a4Daniel Veillard *
1107bca22f40c3b2b34169d8d2919dce4894d8eac1a4Daniel Veillard * Returns 0 if successful, a positive error code number otherwise
1108bca22f40c3b2b34169d8d2919dce4894d8eac1a4Daniel Veillard *         and -1 in case of internal or API error.
1109bca22f40c3b2b34169d8d2919dce4894d8eac1a4Daniel Veillard */
1110bca22f40c3b2b34169d8d2919dce4894d8eac1a4Daniel Veillardint
1111bca22f40c3b2b34169d8d2919dce4894d8eac1a4Daniel VeillardxmlBufWriteQuotedString(xmlBufPtr buf, const xmlChar *string) {
1112bca22f40c3b2b34169d8d2919dce4894d8eac1a4Daniel Veillard    const xmlChar *cur, *base;
11139ee02f80a4d674bac96f88b5a241825aad453a7aDaniel Veillard    if ((buf == NULL) || (buf->error))
1114bca22f40c3b2b34169d8d2919dce4894d8eac1a4Daniel Veillard        return(-1);
11157f713494adbc1f2be3e043a737ba31b616499bc0Daniel Veillard    CHECK_COMPAT(buf)
1116bca22f40c3b2b34169d8d2919dce4894d8eac1a4Daniel Veillard    if (buf->alloc == XML_BUFFER_ALLOC_IMMUTABLE)
1117bca22f40c3b2b34169d8d2919dce4894d8eac1a4Daniel Veillard        return(-1);
1118bca22f40c3b2b34169d8d2919dce4894d8eac1a4Daniel Veillard    if (xmlStrchr(string, '\"')) {
1119bca22f40c3b2b34169d8d2919dce4894d8eac1a4Daniel Veillard        if (xmlStrchr(string, '\'')) {
1120bca22f40c3b2b34169d8d2919dce4894d8eac1a4Daniel Veillard#ifdef DEBUG_BUFFER
1121bca22f40c3b2b34169d8d2919dce4894d8eac1a4Daniel Veillard	    xmlGenericError(xmlGenericErrorContext,
1122bca22f40c3b2b34169d8d2919dce4894d8eac1a4Daniel Veillard "xmlBufWriteQuotedString: string contains quote and double-quotes !\n");
1123bca22f40c3b2b34169d8d2919dce4894d8eac1a4Daniel Veillard#endif
1124bca22f40c3b2b34169d8d2919dce4894d8eac1a4Daniel Veillard	    xmlBufCCat(buf, "\"");
1125bca22f40c3b2b34169d8d2919dce4894d8eac1a4Daniel Veillard            base = cur = string;
1126bca22f40c3b2b34169d8d2919dce4894d8eac1a4Daniel Veillard            while(*cur != 0){
1127bca22f40c3b2b34169d8d2919dce4894d8eac1a4Daniel Veillard                if(*cur == '"'){
1128bca22f40c3b2b34169d8d2919dce4894d8eac1a4Daniel Veillard                    if (base != cur)
1129bca22f40c3b2b34169d8d2919dce4894d8eac1a4Daniel Veillard                        xmlBufAdd(buf, base, cur - base);
1130bca22f40c3b2b34169d8d2919dce4894d8eac1a4Daniel Veillard                    xmlBufAdd(buf, BAD_CAST "&quot;", 6);
1131bca22f40c3b2b34169d8d2919dce4894d8eac1a4Daniel Veillard                    cur++;
1132bca22f40c3b2b34169d8d2919dce4894d8eac1a4Daniel Veillard                    base = cur;
1133bca22f40c3b2b34169d8d2919dce4894d8eac1a4Daniel Veillard                }
1134bca22f40c3b2b34169d8d2919dce4894d8eac1a4Daniel Veillard                else {
1135bca22f40c3b2b34169d8d2919dce4894d8eac1a4Daniel Veillard                    cur++;
1136bca22f40c3b2b34169d8d2919dce4894d8eac1a4Daniel Veillard                }
1137bca22f40c3b2b34169d8d2919dce4894d8eac1a4Daniel Veillard            }
1138bca22f40c3b2b34169d8d2919dce4894d8eac1a4Daniel Veillard            if (base != cur)
1139bca22f40c3b2b34169d8d2919dce4894d8eac1a4Daniel Veillard                xmlBufAdd(buf, base, cur - base);
1140bca22f40c3b2b34169d8d2919dce4894d8eac1a4Daniel Veillard	    xmlBufCCat(buf, "\"");
1141bca22f40c3b2b34169d8d2919dce4894d8eac1a4Daniel Veillard	}
1142bca22f40c3b2b34169d8d2919dce4894d8eac1a4Daniel Veillard        else{
1143bca22f40c3b2b34169d8d2919dce4894d8eac1a4Daniel Veillard	    xmlBufCCat(buf, "\'");
1144bca22f40c3b2b34169d8d2919dce4894d8eac1a4Daniel Veillard            xmlBufCat(buf, string);
1145bca22f40c3b2b34169d8d2919dce4894d8eac1a4Daniel Veillard	    xmlBufCCat(buf, "\'");
1146bca22f40c3b2b34169d8d2919dce4894d8eac1a4Daniel Veillard        }
1147bca22f40c3b2b34169d8d2919dce4894d8eac1a4Daniel Veillard    } else {
1148bca22f40c3b2b34169d8d2919dce4894d8eac1a4Daniel Veillard        xmlBufCCat(buf, "\"");
1149bca22f40c3b2b34169d8d2919dce4894d8eac1a4Daniel Veillard        xmlBufCat(buf, string);
1150bca22f40c3b2b34169d8d2919dce4894d8eac1a4Daniel Veillard        xmlBufCCat(buf, "\"");
1151bca22f40c3b2b34169d8d2919dce4894d8eac1a4Daniel Veillard    }
1152bca22f40c3b2b34169d8d2919dce4894d8eac1a4Daniel Veillard    return(0);
1153bca22f40c3b2b34169d8d2919dce4894d8eac1a4Daniel Veillard}
1154bca22f40c3b2b34169d8d2919dce4894d8eac1a4Daniel Veillard
1155bca22f40c3b2b34169d8d2919dce4894d8eac1a4Daniel Veillard/**
1156bca22f40c3b2b34169d8d2919dce4894d8eac1a4Daniel Veillard * xmlBufFromBuffer:
1157bca22f40c3b2b34169d8d2919dce4894d8eac1a4Daniel Veillard * @buffer: incoming old buffer to convert to a new one
1158bca22f40c3b2b34169d8d2919dce4894d8eac1a4Daniel Veillard *
1159bca22f40c3b2b34169d8d2919dce4894d8eac1a4Daniel Veillard * Helper routine to switch from the old buffer structures in use
1160bca22f40c3b2b34169d8d2919dce4894d8eac1a4Daniel Veillard * in various APIs. It creates a wrapper xmlBufPtr which will be
1161bca22f40c3b2b34169d8d2919dce4894d8eac1a4Daniel Veillard * used for internal processing until the xmlBufBackToBuffer() is
1162bca22f40c3b2b34169d8d2919dce4894d8eac1a4Daniel Veillard * issued.
1163bca22f40c3b2b34169d8d2919dce4894d8eac1a4Daniel Veillard *
1164bca22f40c3b2b34169d8d2919dce4894d8eac1a4Daniel Veillard * Returns a new xmlBufPtr unless the call failed and NULL is returned
1165bca22f40c3b2b34169d8d2919dce4894d8eac1a4Daniel Veillard */
1166bca22f40c3b2b34169d8d2919dce4894d8eac1a4Daniel VeillardxmlBufPtr
1167bca22f40c3b2b34169d8d2919dce4894d8eac1a4Daniel VeillardxmlBufFromBuffer(xmlBufferPtr buffer) {
1168bca22f40c3b2b34169d8d2919dce4894d8eac1a4Daniel Veillard    xmlBufPtr ret;
1169bca22f40c3b2b34169d8d2919dce4894d8eac1a4Daniel Veillard
1170bca22f40c3b2b34169d8d2919dce4894d8eac1a4Daniel Veillard    if (buffer == NULL)
1171bca22f40c3b2b34169d8d2919dce4894d8eac1a4Daniel Veillard        return(NULL);
1172bca22f40c3b2b34169d8d2919dce4894d8eac1a4Daniel Veillard
1173bca22f40c3b2b34169d8d2919dce4894d8eac1a4Daniel Veillard    ret = (xmlBufPtr) xmlMalloc(sizeof(xmlBuf));
1174bca22f40c3b2b34169d8d2919dce4894d8eac1a4Daniel Veillard    if (ret == NULL) {
1175bca22f40c3b2b34169d8d2919dce4894d8eac1a4Daniel Veillard	xmlBufMemoryError(NULL, "creating buffer");
1176bca22f40c3b2b34169d8d2919dce4894d8eac1a4Daniel Veillard        return(NULL);
1177bca22f40c3b2b34169d8d2919dce4894d8eac1a4Daniel Veillard    }
1178bca22f40c3b2b34169d8d2919dce4894d8eac1a4Daniel Veillard    ret->use = buffer->use;
1179bca22f40c3b2b34169d8d2919dce4894d8eac1a4Daniel Veillard    ret->size = buffer->size;
11807f713494adbc1f2be3e043a737ba31b616499bc0Daniel Veillard    ret->compat_use = buffer->use;
11817f713494adbc1f2be3e043a737ba31b616499bc0Daniel Veillard    ret->compat_size = buffer->size;
1182bca22f40c3b2b34169d8d2919dce4894d8eac1a4Daniel Veillard    ret->error = 0;
1183bca22f40c3b2b34169d8d2919dce4894d8eac1a4Daniel Veillard    ret->buffer = buffer;
1184bca22f40c3b2b34169d8d2919dce4894d8eac1a4Daniel Veillard    ret->alloc = buffer->alloc;
1185bca22f40c3b2b34169d8d2919dce4894d8eac1a4Daniel Veillard    ret->content = buffer->content;
1186bca22f40c3b2b34169d8d2919dce4894d8eac1a4Daniel Veillard    ret->contentIO = buffer->contentIO;
1187bca22f40c3b2b34169d8d2919dce4894d8eac1a4Daniel Veillard
1188bca22f40c3b2b34169d8d2919dce4894d8eac1a4Daniel Veillard    return(ret);
1189bca22f40c3b2b34169d8d2919dce4894d8eac1a4Daniel Veillard}
1190bca22f40c3b2b34169d8d2919dce4894d8eac1a4Daniel Veillard
1191bca22f40c3b2b34169d8d2919dce4894d8eac1a4Daniel Veillard/**
1192bca22f40c3b2b34169d8d2919dce4894d8eac1a4Daniel Veillard * xmlBufBackToBuffer:
1193bca22f40c3b2b34169d8d2919dce4894d8eac1a4Daniel Veillard * @buf: new buffer wrapping the old one
1194bca22f40c3b2b34169d8d2919dce4894d8eac1a4Daniel Veillard *
1195bca22f40c3b2b34169d8d2919dce4894d8eac1a4Daniel Veillard * Function to be called once internal processing had been done to
1196bca22f40c3b2b34169d8d2919dce4894d8eac1a4Daniel Veillard * update back the buffer provided by the user. This can lead to
1197bca22f40c3b2b34169d8d2919dce4894d8eac1a4Daniel Veillard * a failure in case the size accumulated in the xmlBuf is larger
1198bca22f40c3b2b34169d8d2919dce4894d8eac1a4Daniel Veillard * than what an xmlBuffer can support on 64 bits (INT_MAX)
1199bca22f40c3b2b34169d8d2919dce4894d8eac1a4Daniel Veillard * The xmlBufPtr @buf wrapper is deallocated by this call in any case.
1200bca22f40c3b2b34169d8d2919dce4894d8eac1a4Daniel Veillard *
1201bca22f40c3b2b34169d8d2919dce4894d8eac1a4Daniel Veillard * Returns the old xmlBufferPtr unless the call failed and NULL is returned
1202bca22f40c3b2b34169d8d2919dce4894d8eac1a4Daniel Veillard */
1203bca22f40c3b2b34169d8d2919dce4894d8eac1a4Daniel VeillardxmlBufferPtr
1204bca22f40c3b2b34169d8d2919dce4894d8eac1a4Daniel VeillardxmlBufBackToBuffer(xmlBufPtr buf) {
1205bca22f40c3b2b34169d8d2919dce4894d8eac1a4Daniel Veillard    xmlBufferPtr ret;
1206bca22f40c3b2b34169d8d2919dce4894d8eac1a4Daniel Veillard
12079ee02f80a4d674bac96f88b5a241825aad453a7aDaniel Veillard    if ((buf == NULL) || (buf->error))
1208bca22f40c3b2b34169d8d2919dce4894d8eac1a4Daniel Veillard        return(NULL);
12097f713494adbc1f2be3e043a737ba31b616499bc0Daniel Veillard    CHECK_COMPAT(buf)
1210bca22f40c3b2b34169d8d2919dce4894d8eac1a4Daniel Veillard    if (buf->buffer == NULL) {
1211bca22f40c3b2b34169d8d2919dce4894d8eac1a4Daniel Veillard        xmlBufFree(buf);
1212bca22f40c3b2b34169d8d2919dce4894d8eac1a4Daniel Veillard        return(NULL);
1213bca22f40c3b2b34169d8d2919dce4894d8eac1a4Daniel Veillard    }
1214bca22f40c3b2b34169d8d2919dce4894d8eac1a4Daniel Veillard
1215bca22f40c3b2b34169d8d2919dce4894d8eac1a4Daniel Veillard    ret = buf->buffer;
1216bca22f40c3b2b34169d8d2919dce4894d8eac1a4Daniel Veillard    /*
1217bca22f40c3b2b34169d8d2919dce4894d8eac1a4Daniel Veillard     * What to do in case of error in the buffer ???
1218bca22f40c3b2b34169d8d2919dce4894d8eac1a4Daniel Veillard     */
1219bca22f40c3b2b34169d8d2919dce4894d8eac1a4Daniel Veillard    if (buf->use > INT_MAX) {
1220bca22f40c3b2b34169d8d2919dce4894d8eac1a4Daniel Veillard        /*
1221bca22f40c3b2b34169d8d2919dce4894d8eac1a4Daniel Veillard         * Worse case, we really allocated and used more than the
1222bca22f40c3b2b34169d8d2919dce4894d8eac1a4Daniel Veillard         * maximum allowed memory for an xmlBuffer on this architecture.
1223bca22f40c3b2b34169d8d2919dce4894d8eac1a4Daniel Veillard         * Keep the buffer but provide a truncated size value.
1224bca22f40c3b2b34169d8d2919dce4894d8eac1a4Daniel Veillard         */
1225bca22f40c3b2b34169d8d2919dce4894d8eac1a4Daniel Veillard        xmlBufOverflowError(buf, "Used size too big for xmlBuffer");
1226bca22f40c3b2b34169d8d2919dce4894d8eac1a4Daniel Veillard        ret->use = INT_MAX;
1227bca22f40c3b2b34169d8d2919dce4894d8eac1a4Daniel Veillard        ret->size = INT_MAX;
1228bca22f40c3b2b34169d8d2919dce4894d8eac1a4Daniel Veillard    } else if (buf->size > INT_MAX) {
1229bca22f40c3b2b34169d8d2919dce4894d8eac1a4Daniel Veillard        /*
1230bca22f40c3b2b34169d8d2919dce4894d8eac1a4Daniel Veillard         * milder case, we allocated more than the maximum allowed memory
1231bca22f40c3b2b34169d8d2919dce4894d8eac1a4Daniel Veillard         * for an xmlBuffer on this architecture, but used less than the
1232bca22f40c3b2b34169d8d2919dce4894d8eac1a4Daniel Veillard         * limit.
1233bca22f40c3b2b34169d8d2919dce4894d8eac1a4Daniel Veillard         * Keep the buffer but provide a truncated size value.
1234bca22f40c3b2b34169d8d2919dce4894d8eac1a4Daniel Veillard         */
1235bca22f40c3b2b34169d8d2919dce4894d8eac1a4Daniel Veillard        xmlBufOverflowError(buf, "Allocated size too big for xmlBuffer");
1236bca22f40c3b2b34169d8d2919dce4894d8eac1a4Daniel Veillard        ret->size = INT_MAX;
1237bca22f40c3b2b34169d8d2919dce4894d8eac1a4Daniel Veillard    }
1238bca22f40c3b2b34169d8d2919dce4894d8eac1a4Daniel Veillard    ret->use = (int) buf->use;
1239bca22f40c3b2b34169d8d2919dce4894d8eac1a4Daniel Veillard    ret->size = (int) buf->size;
1240bca22f40c3b2b34169d8d2919dce4894d8eac1a4Daniel Veillard    ret->alloc = buf->alloc;
1241bca22f40c3b2b34169d8d2919dce4894d8eac1a4Daniel Veillard    ret->content = buf->content;
1242bca22f40c3b2b34169d8d2919dce4894d8eac1a4Daniel Veillard    ret->contentIO = buf->contentIO;
1243bca22f40c3b2b34169d8d2919dce4894d8eac1a4Daniel Veillard    xmlFree(buf);
1244bca22f40c3b2b34169d8d2919dce4894d8eac1a4Daniel Veillard    return(ret);
1245bca22f40c3b2b34169d8d2919dce4894d8eac1a4Daniel Veillard}
1246bca22f40c3b2b34169d8d2919dce4894d8eac1a4Daniel Veillard
1247bca22f40c3b2b34169d8d2919dce4894d8eac1a4Daniel Veillard/**
1248bca22f40c3b2b34169d8d2919dce4894d8eac1a4Daniel Veillard * xmlBufMergeBuffer:
1249bca22f40c3b2b34169d8d2919dce4894d8eac1a4Daniel Veillard * @buf: an xmlBufPtr
1250bca22f40c3b2b34169d8d2919dce4894d8eac1a4Daniel Veillard * @buffer: the buffer to consume into @buf
1251bca22f40c3b2b34169d8d2919dce4894d8eac1a4Daniel Veillard *
1252bca22f40c3b2b34169d8d2919dce4894d8eac1a4Daniel Veillard * The content of @buffer is appended to @buf and @buffer is freed
1253bca22f40c3b2b34169d8d2919dce4894d8eac1a4Daniel Veillard *
1254bca22f40c3b2b34169d8d2919dce4894d8eac1a4Daniel Veillard * Returns -1 in case of error, 0 otherwise, in any case @buffer is freed
1255bca22f40c3b2b34169d8d2919dce4894d8eac1a4Daniel Veillard */
1256bca22f40c3b2b34169d8d2919dce4894d8eac1a4Daniel Veillardint
1257bca22f40c3b2b34169d8d2919dce4894d8eac1a4Daniel VeillardxmlBufMergeBuffer(xmlBufPtr buf, xmlBufferPtr buffer) {
12586f6feba876eeff3a75fc10cdc2f414cc66204ddeDaniel Veillard    int ret = 0;
1259bca22f40c3b2b34169d8d2919dce4894d8eac1a4Daniel Veillard
12607f713494adbc1f2be3e043a737ba31b616499bc0Daniel Veillard    if ((buf == NULL) || (buf->error)) {
12617f713494adbc1f2be3e043a737ba31b616499bc0Daniel Veillard	xmlBufferFree(buffer);
12627f713494adbc1f2be3e043a737ba31b616499bc0Daniel Veillard        return(-1);
12637f713494adbc1f2be3e043a737ba31b616499bc0Daniel Veillard    }
12647f713494adbc1f2be3e043a737ba31b616499bc0Daniel Veillard    CHECK_COMPAT(buf)
12657f713494adbc1f2be3e043a737ba31b616499bc0Daniel Veillard    if ((buffer != NULL) && (buffer->content != NULL) &&
12666f6feba876eeff3a75fc10cdc2f414cc66204ddeDaniel Veillard             (buffer->use > 0)) {
1267bca22f40c3b2b34169d8d2919dce4894d8eac1a4Daniel Veillard        ret = xmlBufAdd(buf, buffer->content, buffer->use);
1268bca22f40c3b2b34169d8d2919dce4894d8eac1a4Daniel Veillard    }
1269bca22f40c3b2b34169d8d2919dce4894d8eac1a4Daniel Veillard    xmlBufferFree(buffer);
1270bca22f40c3b2b34169d8d2919dce4894d8eac1a4Daniel Veillard    return(ret);
1271bca22f40c3b2b34169d8d2919dce4894d8eac1a4Daniel Veillard}
127261551a1eb75bacb32e5209635c0f3459595af54aDaniel Veillard
127361551a1eb75bacb32e5209635c0f3459595af54aDaniel Veillard/**
127461551a1eb75bacb32e5209635c0f3459595af54aDaniel Veillard * xmlBufResetInput:
127561551a1eb75bacb32e5209635c0f3459595af54aDaniel Veillard * @buf: an xmlBufPtr
127661551a1eb75bacb32e5209635c0f3459595af54aDaniel Veillard * @input: an xmlParserInputPtr
127761551a1eb75bacb32e5209635c0f3459595af54aDaniel Veillard *
127861551a1eb75bacb32e5209635c0f3459595af54aDaniel Veillard * Update the input to use the current set of pointers from the buffer.
127961551a1eb75bacb32e5209635c0f3459595af54aDaniel Veillard *
128000ac0d3b96459865684fc9378e420e93418f9ef9Daniel Veillard * Returns -1 in case of error, 0 otherwise
128161551a1eb75bacb32e5209635c0f3459595af54aDaniel Veillard */
128261551a1eb75bacb32e5209635c0f3459595af54aDaniel Veillardint
128361551a1eb75bacb32e5209635c0f3459595af54aDaniel VeillardxmlBufResetInput(xmlBufPtr buf, xmlParserInputPtr input) {
12849ee02f80a4d674bac96f88b5a241825aad453a7aDaniel Veillard    if ((input == NULL) || (buf == NULL) || (buf->error))
128561551a1eb75bacb32e5209635c0f3459595af54aDaniel Veillard        return(-1);
12867f713494adbc1f2be3e043a737ba31b616499bc0Daniel Veillard    CHECK_COMPAT(buf)
128761551a1eb75bacb32e5209635c0f3459595af54aDaniel Veillard    input->base = input->cur = buf->content;
128861551a1eb75bacb32e5209635c0f3459595af54aDaniel Veillard    input->end = &buf->content[buf->use];
128961551a1eb75bacb32e5209635c0f3459595af54aDaniel Veillard    return(0);
129061551a1eb75bacb32e5209635c0f3459595af54aDaniel Veillard}
129100ac0d3b96459865684fc9378e420e93418f9ef9Daniel Veillard
129200ac0d3b96459865684fc9378e420e93418f9ef9Daniel Veillard/**
129300ac0d3b96459865684fc9378e420e93418f9ef9Daniel Veillard * xmlBufGetInputBase:
129400ac0d3b96459865684fc9378e420e93418f9ef9Daniel Veillard * @buf: an xmlBufPtr
129500ac0d3b96459865684fc9378e420e93418f9ef9Daniel Veillard * @input: an xmlParserInputPtr
129600ac0d3b96459865684fc9378e420e93418f9ef9Daniel Veillard *
129700ac0d3b96459865684fc9378e420e93418f9ef9Daniel Veillard * Get the base of the @input relative to the beginning of the buffer
129800ac0d3b96459865684fc9378e420e93418f9ef9Daniel Veillard *
129900ac0d3b96459865684fc9378e420e93418f9ef9Daniel Veillard * Returns the size_t corresponding to the displacement
130000ac0d3b96459865684fc9378e420e93418f9ef9Daniel Veillard */
130100ac0d3b96459865684fc9378e420e93418f9ef9Daniel Veillardsize_t
130200ac0d3b96459865684fc9378e420e93418f9ef9Daniel VeillardxmlBufGetInputBase(xmlBufPtr buf, xmlParserInputPtr input) {
130300ac0d3b96459865684fc9378e420e93418f9ef9Daniel Veillard    size_t base;
130400ac0d3b96459865684fc9378e420e93418f9ef9Daniel Veillard
13059ee02f80a4d674bac96f88b5a241825aad453a7aDaniel Veillard    if ((input == NULL) || (buf == NULL) || (buf->error))
13069ee02f80a4d674bac96f88b5a241825aad453a7aDaniel Veillard        return(-1);
13077f713494adbc1f2be3e043a737ba31b616499bc0Daniel Veillard    CHECK_COMPAT(buf)
130800ac0d3b96459865684fc9378e420e93418f9ef9Daniel Veillard    base = input->base - buf->content;
130900ac0d3b96459865684fc9378e420e93418f9ef9Daniel Veillard    /*
131000ac0d3b96459865684fc9378e420e93418f9ef9Daniel Veillard     * We could do some pointer arythmetic checks but that's probably
131100ac0d3b96459865684fc9378e420e93418f9ef9Daniel Veillard     * sufficient.
131200ac0d3b96459865684fc9378e420e93418f9ef9Daniel Veillard     */
131300ac0d3b96459865684fc9378e420e93418f9ef9Daniel Veillard    if (base > buf->size) {
131400ac0d3b96459865684fc9378e420e93418f9ef9Daniel Veillard        xmlBufOverflowError(buf, "Input reference outside of the buffer");
131500ac0d3b96459865684fc9378e420e93418f9ef9Daniel Veillard        base = 0;
131600ac0d3b96459865684fc9378e420e93418f9ef9Daniel Veillard    }
131700ac0d3b96459865684fc9378e420e93418f9ef9Daniel Veillard    return(base);
131800ac0d3b96459865684fc9378e420e93418f9ef9Daniel Veillard}
131900ac0d3b96459865684fc9378e420e93418f9ef9Daniel Veillard
132000ac0d3b96459865684fc9378e420e93418f9ef9Daniel Veillard/**
132100ac0d3b96459865684fc9378e420e93418f9ef9Daniel Veillard * xmlBufSetInputBaseCur:
132200ac0d3b96459865684fc9378e420e93418f9ef9Daniel Veillard * @buf: an xmlBufPtr
132300ac0d3b96459865684fc9378e420e93418f9ef9Daniel Veillard * @input: an xmlParserInputPtr
132428cc42d06867f46f921ec137b725a124e43936fdDaniel Veillard * @base: the base value relative to the beginning of the buffer
132528cc42d06867f46f921ec137b725a124e43936fdDaniel Veillard * @cur: the cur value relative to the beginning of the buffer
132600ac0d3b96459865684fc9378e420e93418f9ef9Daniel Veillard *
132700ac0d3b96459865684fc9378e420e93418f9ef9Daniel Veillard * Update the input to use the base and cur relative to the buffer
132800ac0d3b96459865684fc9378e420e93418f9ef9Daniel Veillard * after a possible reallocation of its content
132900ac0d3b96459865684fc9378e420e93418f9ef9Daniel Veillard *
133000ac0d3b96459865684fc9378e420e93418f9ef9Daniel Veillard * Returns -1 in case of error, 0 otherwise
133100ac0d3b96459865684fc9378e420e93418f9ef9Daniel Veillard */
133200ac0d3b96459865684fc9378e420e93418f9ef9Daniel Veillardint
133300ac0d3b96459865684fc9378e420e93418f9ef9Daniel VeillardxmlBufSetInputBaseCur(xmlBufPtr buf, xmlParserInputPtr input,
133400ac0d3b96459865684fc9378e420e93418f9ef9Daniel Veillard                      size_t base, size_t cur) {
13359ee02f80a4d674bac96f88b5a241825aad453a7aDaniel Veillard    if ((input == NULL) || (buf == NULL) || (buf->error))
133600ac0d3b96459865684fc9378e420e93418f9ef9Daniel Veillard        return(-1);
13377f713494adbc1f2be3e043a737ba31b616499bc0Daniel Veillard    CHECK_COMPAT(buf)
133800ac0d3b96459865684fc9378e420e93418f9ef9Daniel Veillard    input->base = &buf->content[base];
133900ac0d3b96459865684fc9378e420e93418f9ef9Daniel Veillard    input->cur = input->base + cur;
134000ac0d3b96459865684fc9378e420e93418f9ef9Daniel Veillard    input->end = &buf->content[buf->use];
134100ac0d3b96459865684fc9378e420e93418f9ef9Daniel Veillard    return(0);
134200ac0d3b96459865684fc9378e420e93418f9ef9Daniel Veillard}
13432ff9284325d64d01ac0245ae266ef170c05f0e50Roumen Petrov
13442ff9284325d64d01ac0245ae266ef170c05f0e50Roumen Petrov#define bottom_buf
13452ff9284325d64d01ac0245ae266ef170c05f0e50Roumen Petrov#include "elfgcchack.h"
1346