xref: /aosp_15_r20/external/cronet/third_party/libxml/src/buf.c (revision 6777b5387eb2ff775bb5750e3f5d96f37fb7352b)
1*6777b538SAndroid Build Coastguard Worker /*
2*6777b538SAndroid Build Coastguard Worker  * buf.c: memory buffers for libxml2
3*6777b538SAndroid Build Coastguard Worker  *
4*6777b538SAndroid Build Coastguard Worker  * new buffer structures and entry points to simplify the maintenance
5*6777b538SAndroid Build Coastguard Worker  * of libxml2 and ensure we keep good control over memory allocations
6*6777b538SAndroid Build Coastguard Worker  * and stay 64 bits clean.
7*6777b538SAndroid Build Coastguard Worker  * The new entry point use the xmlBufPtr opaque structure and
8*6777b538SAndroid Build Coastguard Worker  * xmlBuf...() counterparts to the old xmlBuf...() functions
9*6777b538SAndroid Build Coastguard Worker  *
10*6777b538SAndroid Build Coastguard Worker  * See Copyright for the status of this software.
11*6777b538SAndroid Build Coastguard Worker  *
12*6777b538SAndroid Build Coastguard Worker  * [email protected]
13*6777b538SAndroid Build Coastguard Worker  */
14*6777b538SAndroid Build Coastguard Worker 
15*6777b538SAndroid Build Coastguard Worker #define IN_LIBXML
16*6777b538SAndroid Build Coastguard Worker #include "libxml.h"
17*6777b538SAndroid Build Coastguard Worker 
18*6777b538SAndroid Build Coastguard Worker #include <string.h> /* for memset() only ! */
19*6777b538SAndroid Build Coastguard Worker #include <limits.h>
20*6777b538SAndroid Build Coastguard Worker #include <ctype.h>
21*6777b538SAndroid Build Coastguard Worker #include <stdlib.h>
22*6777b538SAndroid Build Coastguard Worker 
23*6777b538SAndroid Build Coastguard Worker #include <libxml/tree.h>
24*6777b538SAndroid Build Coastguard Worker #include <libxml/parserInternals.h> /* for XML_MAX_TEXT_LENGTH */
25*6777b538SAndroid Build Coastguard Worker 
26*6777b538SAndroid Build Coastguard Worker #include "private/buf.h"
27*6777b538SAndroid Build Coastguard Worker #include "private/error.h"
28*6777b538SAndroid Build Coastguard Worker 
29*6777b538SAndroid Build Coastguard Worker #ifndef SIZE_MAX
30*6777b538SAndroid Build Coastguard Worker #define SIZE_MAX ((size_t) -1)
31*6777b538SAndroid Build Coastguard Worker #endif
32*6777b538SAndroid Build Coastguard Worker 
33*6777b538SAndroid Build Coastguard Worker #define WITH_BUFFER_COMPAT
34*6777b538SAndroid Build Coastguard Worker 
35*6777b538SAndroid Build Coastguard Worker /**
36*6777b538SAndroid Build Coastguard Worker  * xmlBuf:
37*6777b538SAndroid Build Coastguard Worker  *
38*6777b538SAndroid Build Coastguard Worker  * A buffer structure. The base of the structure is somehow compatible
39*6777b538SAndroid Build Coastguard Worker  * with struct _xmlBuffer to limit risks on application which accessed
40*6777b538SAndroid Build Coastguard Worker  * directly the input->buf->buffer structures.
41*6777b538SAndroid Build Coastguard Worker  */
42*6777b538SAndroid Build Coastguard Worker 
43*6777b538SAndroid Build Coastguard Worker struct _xmlBuf {
44*6777b538SAndroid Build Coastguard Worker     xmlChar *content;		/* The buffer content UTF8 */
45*6777b538SAndroid Build Coastguard Worker     unsigned int compat_use;    /* for binary compatibility */
46*6777b538SAndroid Build Coastguard Worker     unsigned int compat_size;   /* for binary compatibility */
47*6777b538SAndroid Build Coastguard Worker     xmlBufferAllocationScheme alloc; /* The realloc method */
48*6777b538SAndroid Build Coastguard Worker     xmlChar *contentIO;		/* in IO mode we may have a different base */
49*6777b538SAndroid Build Coastguard Worker     size_t use;		        /* The buffer size used */
50*6777b538SAndroid Build Coastguard Worker     size_t size;		/* The buffer size */
51*6777b538SAndroid Build Coastguard Worker     xmlBufferPtr buffer;        /* wrapper for an old buffer */
52*6777b538SAndroid Build Coastguard Worker     int error;                  /* an error code if a failure occurred */
53*6777b538SAndroid Build Coastguard Worker };
54*6777b538SAndroid Build Coastguard Worker 
55*6777b538SAndroid Build Coastguard Worker #ifdef WITH_BUFFER_COMPAT
56*6777b538SAndroid Build Coastguard Worker /*
57*6777b538SAndroid Build Coastguard Worker  * Macro for compatibility with xmlBuffer to be used after an xmlBuf
58*6777b538SAndroid Build Coastguard Worker  * is updated. This makes sure the compat fields are updated too.
59*6777b538SAndroid Build Coastguard Worker  */
60*6777b538SAndroid Build Coastguard Worker #define UPDATE_COMPAT(buf)				    \
61*6777b538SAndroid Build Coastguard Worker      if (buf->size < INT_MAX) buf->compat_size = buf->size; \
62*6777b538SAndroid Build Coastguard Worker      else buf->compat_size = INT_MAX;			    \
63*6777b538SAndroid Build Coastguard Worker      if (buf->use < INT_MAX) buf->compat_use = buf->use; \
64*6777b538SAndroid Build Coastguard Worker      else buf->compat_use = INT_MAX;
65*6777b538SAndroid Build Coastguard Worker 
66*6777b538SAndroid Build Coastguard Worker /*
67*6777b538SAndroid Build Coastguard Worker  * Macro for compatibility with xmlBuffer to be used in all the xmlBuf
68*6777b538SAndroid Build Coastguard Worker  * entry points, it checks that the compat fields have not been modified
69*6777b538SAndroid Build Coastguard Worker  * by direct call to xmlBuffer function from code compiled before 2.9.0 .
70*6777b538SAndroid Build Coastguard Worker  */
71*6777b538SAndroid Build Coastguard Worker #define CHECK_COMPAT(buf)				    \
72*6777b538SAndroid Build Coastguard Worker      if (buf->size != (size_t) buf->compat_size)	    \
73*6777b538SAndroid Build Coastguard Worker          if (buf->compat_size < INT_MAX)		    \
74*6777b538SAndroid Build Coastguard Worker 	     buf->size = buf->compat_size;		    \
75*6777b538SAndroid Build Coastguard Worker      if (buf->use != (size_t) buf->compat_use)		    \
76*6777b538SAndroid Build Coastguard Worker          if (buf->compat_use < INT_MAX)			    \
77*6777b538SAndroid Build Coastguard Worker 	     buf->use = buf->compat_use;
78*6777b538SAndroid Build Coastguard Worker 
79*6777b538SAndroid Build Coastguard Worker #else /* ! WITH_BUFFER_COMPAT */
80*6777b538SAndroid Build Coastguard Worker #define UPDATE_COMPAT(buf)
81*6777b538SAndroid Build Coastguard Worker #define CHECK_COMPAT(buf)
82*6777b538SAndroid Build Coastguard Worker #endif /* WITH_BUFFER_COMPAT */
83*6777b538SAndroid Build Coastguard Worker 
84*6777b538SAndroid Build Coastguard Worker /**
85*6777b538SAndroid Build Coastguard Worker  * xmlBufMemoryError:
86*6777b538SAndroid Build Coastguard Worker  * @extra:  extra information
87*6777b538SAndroid Build Coastguard Worker  *
88*6777b538SAndroid Build Coastguard Worker  * Handle an out of memory condition
89*6777b538SAndroid Build Coastguard Worker  * To be improved...
90*6777b538SAndroid Build Coastguard Worker  */
91*6777b538SAndroid Build Coastguard Worker static void
xmlBufMemoryError(xmlBufPtr buf)92*6777b538SAndroid Build Coastguard Worker xmlBufMemoryError(xmlBufPtr buf)
93*6777b538SAndroid Build Coastguard Worker {
94*6777b538SAndroid Build Coastguard Worker     if (buf->error == 0)
95*6777b538SAndroid Build Coastguard Worker         buf->error = XML_ERR_NO_MEMORY;
96*6777b538SAndroid Build Coastguard Worker }
97*6777b538SAndroid Build Coastguard Worker 
98*6777b538SAndroid Build Coastguard Worker /**
99*6777b538SAndroid Build Coastguard Worker  * xmlBufOverflowError:
100*6777b538SAndroid Build Coastguard Worker  * @extra:  extra information
101*6777b538SAndroid Build Coastguard Worker  *
102*6777b538SAndroid Build Coastguard Worker  * Handle a buffer overflow error
103*6777b538SAndroid Build Coastguard Worker  * To be improved...
104*6777b538SAndroid Build Coastguard Worker  */
105*6777b538SAndroid Build Coastguard Worker static void
xmlBufOverflowError(xmlBufPtr buf)106*6777b538SAndroid Build Coastguard Worker xmlBufOverflowError(xmlBufPtr buf)
107*6777b538SAndroid Build Coastguard Worker {
108*6777b538SAndroid Build Coastguard Worker     if (buf->error == 0)
109*6777b538SAndroid Build Coastguard Worker         buf->error = XML_BUF_OVERFLOW;
110*6777b538SAndroid Build Coastguard Worker }
111*6777b538SAndroid Build Coastguard Worker 
112*6777b538SAndroid Build Coastguard Worker 
113*6777b538SAndroid Build Coastguard Worker /**
114*6777b538SAndroid Build Coastguard Worker  * xmlBufCreate:
115*6777b538SAndroid Build Coastguard Worker  *
116*6777b538SAndroid Build Coastguard Worker  * routine to create an XML buffer.
117*6777b538SAndroid Build Coastguard Worker  * returns the new structure.
118*6777b538SAndroid Build Coastguard Worker  */
119*6777b538SAndroid Build Coastguard Worker xmlBufPtr
xmlBufCreate(void)120*6777b538SAndroid Build Coastguard Worker xmlBufCreate(void) {
121*6777b538SAndroid Build Coastguard Worker     xmlBufPtr ret;
122*6777b538SAndroid Build Coastguard Worker 
123*6777b538SAndroid Build Coastguard Worker     ret = (xmlBufPtr) xmlMalloc(sizeof(xmlBuf));
124*6777b538SAndroid Build Coastguard Worker     if (ret == NULL)
125*6777b538SAndroid Build Coastguard Worker         return(NULL);
126*6777b538SAndroid Build Coastguard Worker     ret->use = 0;
127*6777b538SAndroid Build Coastguard Worker     ret->error = 0;
128*6777b538SAndroid Build Coastguard Worker     ret->buffer = NULL;
129*6777b538SAndroid Build Coastguard Worker     ret->size = xmlDefaultBufferSize;
130*6777b538SAndroid Build Coastguard Worker     UPDATE_COMPAT(ret);
131*6777b538SAndroid Build Coastguard Worker     ret->alloc = xmlBufferAllocScheme;
132*6777b538SAndroid Build Coastguard Worker     ret->content = (xmlChar *) xmlMallocAtomic(ret->size);
133*6777b538SAndroid Build Coastguard Worker     if (ret->content == NULL) {
134*6777b538SAndroid Build Coastguard Worker 	xmlFree(ret);
135*6777b538SAndroid Build Coastguard Worker         return(NULL);
136*6777b538SAndroid Build Coastguard Worker     }
137*6777b538SAndroid Build Coastguard Worker     ret->content[0] = 0;
138*6777b538SAndroid Build Coastguard Worker     ret->contentIO = NULL;
139*6777b538SAndroid Build Coastguard Worker     return(ret);
140*6777b538SAndroid Build Coastguard Worker }
141*6777b538SAndroid Build Coastguard Worker 
142*6777b538SAndroid Build Coastguard Worker /**
143*6777b538SAndroid Build Coastguard Worker  * xmlBufCreateSize:
144*6777b538SAndroid Build Coastguard Worker  * @size: initial size of buffer
145*6777b538SAndroid Build Coastguard Worker  *
146*6777b538SAndroid Build Coastguard Worker  * routine to create an XML buffer.
147*6777b538SAndroid Build Coastguard Worker  * returns the new structure.
148*6777b538SAndroid Build Coastguard Worker  */
149*6777b538SAndroid Build Coastguard Worker xmlBufPtr
xmlBufCreateSize(size_t size)150*6777b538SAndroid Build Coastguard Worker xmlBufCreateSize(size_t size) {
151*6777b538SAndroid Build Coastguard Worker     xmlBufPtr ret;
152*6777b538SAndroid Build Coastguard Worker 
153*6777b538SAndroid Build Coastguard Worker     if (size == SIZE_MAX)
154*6777b538SAndroid Build Coastguard Worker         return(NULL);
155*6777b538SAndroid Build Coastguard Worker     ret = (xmlBufPtr) xmlMalloc(sizeof(xmlBuf));
156*6777b538SAndroid Build Coastguard Worker     if (ret == NULL)
157*6777b538SAndroid Build Coastguard Worker         return(NULL);
158*6777b538SAndroid Build Coastguard Worker     ret->use = 0;
159*6777b538SAndroid Build Coastguard Worker     ret->error = 0;
160*6777b538SAndroid Build Coastguard Worker     ret->buffer = NULL;
161*6777b538SAndroid Build Coastguard Worker     ret->alloc = xmlBufferAllocScheme;
162*6777b538SAndroid Build Coastguard Worker     ret->size = (size ? size + 1 : 0);         /* +1 for ending null */
163*6777b538SAndroid Build Coastguard Worker     UPDATE_COMPAT(ret);
164*6777b538SAndroid Build Coastguard Worker     if (ret->size){
165*6777b538SAndroid Build Coastguard Worker         ret->content = (xmlChar *) xmlMallocAtomic(ret->size);
166*6777b538SAndroid Build Coastguard Worker         if (ret->content == NULL) {
167*6777b538SAndroid Build Coastguard Worker             xmlFree(ret);
168*6777b538SAndroid Build Coastguard Worker             return(NULL);
169*6777b538SAndroid Build Coastguard Worker         }
170*6777b538SAndroid Build Coastguard Worker         ret->content[0] = 0;
171*6777b538SAndroid Build Coastguard Worker     } else
172*6777b538SAndroid Build Coastguard Worker 	ret->content = NULL;
173*6777b538SAndroid Build Coastguard Worker     ret->contentIO = NULL;
174*6777b538SAndroid Build Coastguard Worker     return(ret);
175*6777b538SAndroid Build Coastguard Worker }
176*6777b538SAndroid Build Coastguard Worker 
177*6777b538SAndroid Build Coastguard Worker /**
178*6777b538SAndroid Build Coastguard Worker  * xmlBufDetach:
179*6777b538SAndroid Build Coastguard Worker  * @buf:  the buffer
180*6777b538SAndroid Build Coastguard Worker  *
181*6777b538SAndroid Build Coastguard Worker  * Remove the string contained in a buffer and give it back to the
182*6777b538SAndroid Build Coastguard Worker  * caller. The buffer is reset to an empty content.
183*6777b538SAndroid Build Coastguard Worker  * This doesn't work with immutable buffers as they can't be reset.
184*6777b538SAndroid Build Coastguard Worker  *
185*6777b538SAndroid Build Coastguard Worker  * Returns the previous string contained by the buffer.
186*6777b538SAndroid Build Coastguard Worker  */
187*6777b538SAndroid Build Coastguard Worker xmlChar *
xmlBufDetach(xmlBufPtr buf)188*6777b538SAndroid Build Coastguard Worker xmlBufDetach(xmlBufPtr buf) {
189*6777b538SAndroid Build Coastguard Worker     xmlChar *ret;
190*6777b538SAndroid Build Coastguard Worker 
191*6777b538SAndroid Build Coastguard Worker     if (buf == NULL)
192*6777b538SAndroid Build Coastguard Worker         return(NULL);
193*6777b538SAndroid Build Coastguard Worker     if (buf->buffer != NULL)
194*6777b538SAndroid Build Coastguard Worker         return(NULL);
195*6777b538SAndroid Build Coastguard Worker     if (buf->error)
196*6777b538SAndroid Build Coastguard Worker         return(NULL);
197*6777b538SAndroid Build Coastguard Worker 
198*6777b538SAndroid Build Coastguard Worker     ret = buf->content;
199*6777b538SAndroid Build Coastguard Worker     buf->content = NULL;
200*6777b538SAndroid Build Coastguard Worker     buf->size = 0;
201*6777b538SAndroid Build Coastguard Worker     buf->use = 0;
202*6777b538SAndroid Build Coastguard Worker     UPDATE_COMPAT(buf);
203*6777b538SAndroid Build Coastguard Worker 
204*6777b538SAndroid Build Coastguard Worker     return ret;
205*6777b538SAndroid Build Coastguard Worker }
206*6777b538SAndroid Build Coastguard Worker 
207*6777b538SAndroid Build Coastguard Worker /**
208*6777b538SAndroid Build Coastguard Worker  * xmlBufGetAllocationScheme:
209*6777b538SAndroid Build Coastguard Worker  * @buf:  the buffer
210*6777b538SAndroid Build Coastguard Worker  *
211*6777b538SAndroid Build Coastguard Worker  * Get the buffer allocation scheme
212*6777b538SAndroid Build Coastguard Worker  *
213*6777b538SAndroid Build Coastguard Worker  * Returns the scheme or -1 in case of error
214*6777b538SAndroid Build Coastguard Worker  */
215*6777b538SAndroid Build Coastguard Worker int
xmlBufGetAllocationScheme(xmlBufPtr buf)216*6777b538SAndroid Build Coastguard Worker xmlBufGetAllocationScheme(xmlBufPtr buf) {
217*6777b538SAndroid Build Coastguard Worker     if (buf == NULL) {
218*6777b538SAndroid Build Coastguard Worker         return(-1);
219*6777b538SAndroid Build Coastguard Worker     }
220*6777b538SAndroid Build Coastguard Worker     return(buf->alloc);
221*6777b538SAndroid Build Coastguard Worker }
222*6777b538SAndroid Build Coastguard Worker 
223*6777b538SAndroid Build Coastguard Worker /**
224*6777b538SAndroid Build Coastguard Worker  * xmlBufSetAllocationScheme:
225*6777b538SAndroid Build Coastguard Worker  * @buf:  the buffer to tune
226*6777b538SAndroid Build Coastguard Worker  * @scheme:  allocation scheme to use
227*6777b538SAndroid Build Coastguard Worker  *
228*6777b538SAndroid Build Coastguard Worker  * Sets the allocation scheme for this buffer
229*6777b538SAndroid Build Coastguard Worker  *
230*6777b538SAndroid Build Coastguard Worker  * returns 0 in case of success and -1 in case of failure
231*6777b538SAndroid Build Coastguard Worker  */
232*6777b538SAndroid Build Coastguard Worker int
xmlBufSetAllocationScheme(xmlBufPtr buf,xmlBufferAllocationScheme scheme)233*6777b538SAndroid Build Coastguard Worker xmlBufSetAllocationScheme(xmlBufPtr buf,
234*6777b538SAndroid Build Coastguard Worker                           xmlBufferAllocationScheme scheme) {
235*6777b538SAndroid Build Coastguard Worker     if ((buf == NULL) || (buf->error != 0)) {
236*6777b538SAndroid Build Coastguard Worker         return(-1);
237*6777b538SAndroid Build Coastguard Worker     }
238*6777b538SAndroid Build Coastguard Worker     if (buf->alloc == XML_BUFFER_ALLOC_IO)
239*6777b538SAndroid Build Coastguard Worker         return(-1);
240*6777b538SAndroid Build Coastguard Worker     if ((scheme == XML_BUFFER_ALLOC_DOUBLEIT) ||
241*6777b538SAndroid Build Coastguard Worker         (scheme == XML_BUFFER_ALLOC_EXACT) ||
242*6777b538SAndroid Build Coastguard Worker         (scheme == XML_BUFFER_ALLOC_HYBRID) ||
243*6777b538SAndroid Build Coastguard Worker 	(scheme == XML_BUFFER_ALLOC_BOUNDED)) {
244*6777b538SAndroid Build Coastguard Worker 	buf->alloc = scheme;
245*6777b538SAndroid Build Coastguard Worker         if (buf->buffer)
246*6777b538SAndroid Build Coastguard Worker             buf->buffer->alloc = scheme;
247*6777b538SAndroid Build Coastguard Worker         return(0);
248*6777b538SAndroid Build Coastguard Worker     }
249*6777b538SAndroid Build Coastguard Worker     /*
250*6777b538SAndroid Build Coastguard Worker      * Switching a buffer ALLOC_IO has the side effect of initializing
251*6777b538SAndroid Build Coastguard Worker      * the contentIO field with the current content
252*6777b538SAndroid Build Coastguard Worker      */
253*6777b538SAndroid Build Coastguard Worker     if (scheme == XML_BUFFER_ALLOC_IO) {
254*6777b538SAndroid Build Coastguard Worker         buf->alloc = XML_BUFFER_ALLOC_IO;
255*6777b538SAndroid Build Coastguard Worker         buf->contentIO = buf->content;
256*6777b538SAndroid Build Coastguard Worker     }
257*6777b538SAndroid Build Coastguard Worker     return(-1);
258*6777b538SAndroid Build Coastguard Worker }
259*6777b538SAndroid Build Coastguard Worker 
260*6777b538SAndroid Build Coastguard Worker /**
261*6777b538SAndroid Build Coastguard Worker  * xmlBufFree:
262*6777b538SAndroid Build Coastguard Worker  * @buf:  the buffer to free
263*6777b538SAndroid Build Coastguard Worker  *
264*6777b538SAndroid Build Coastguard Worker  * Frees an XML buffer. It frees both the content and the structure which
265*6777b538SAndroid Build Coastguard Worker  * encapsulate it.
266*6777b538SAndroid Build Coastguard Worker  */
267*6777b538SAndroid Build Coastguard Worker void
xmlBufFree(xmlBufPtr buf)268*6777b538SAndroid Build Coastguard Worker xmlBufFree(xmlBufPtr buf) {
269*6777b538SAndroid Build Coastguard Worker     if (buf == NULL) {
270*6777b538SAndroid Build Coastguard Worker 	return;
271*6777b538SAndroid Build Coastguard Worker     }
272*6777b538SAndroid Build Coastguard Worker 
273*6777b538SAndroid Build Coastguard Worker     if ((buf->alloc == XML_BUFFER_ALLOC_IO) &&
274*6777b538SAndroid Build Coastguard Worker         (buf->contentIO != NULL)) {
275*6777b538SAndroid Build Coastguard Worker         xmlFree(buf->contentIO);
276*6777b538SAndroid Build Coastguard Worker     } else if (buf->content != NULL) {
277*6777b538SAndroid Build Coastguard Worker         xmlFree(buf->content);
278*6777b538SAndroid Build Coastguard Worker     }
279*6777b538SAndroid Build Coastguard Worker     xmlFree(buf);
280*6777b538SAndroid Build Coastguard Worker }
281*6777b538SAndroid Build Coastguard Worker 
282*6777b538SAndroid Build Coastguard Worker /**
283*6777b538SAndroid Build Coastguard Worker  * xmlBufEmpty:
284*6777b538SAndroid Build Coastguard Worker  * @buf:  the buffer
285*6777b538SAndroid Build Coastguard Worker  *
286*6777b538SAndroid Build Coastguard Worker  * empty a buffer.
287*6777b538SAndroid Build Coastguard Worker  */
288*6777b538SAndroid Build Coastguard Worker void
xmlBufEmpty(xmlBufPtr buf)289*6777b538SAndroid Build Coastguard Worker xmlBufEmpty(xmlBufPtr buf) {
290*6777b538SAndroid Build Coastguard Worker     if ((buf == NULL) || (buf->error != 0)) return;
291*6777b538SAndroid Build Coastguard Worker     if (buf->content == NULL) return;
292*6777b538SAndroid Build Coastguard Worker     CHECK_COMPAT(buf)
293*6777b538SAndroid Build Coastguard Worker     buf->use = 0;
294*6777b538SAndroid Build Coastguard Worker     if ((buf->alloc == XML_BUFFER_ALLOC_IO) &&
295*6777b538SAndroid Build Coastguard Worker                (buf->contentIO != NULL)) {
296*6777b538SAndroid Build Coastguard Worker         size_t start_buf = buf->content - buf->contentIO;
297*6777b538SAndroid Build Coastguard Worker 
298*6777b538SAndroid Build Coastguard Worker 	buf->size += start_buf;
299*6777b538SAndroid Build Coastguard Worker         buf->content = buf->contentIO;
300*6777b538SAndroid Build Coastguard Worker         buf->content[0] = 0;
301*6777b538SAndroid Build Coastguard Worker     } else {
302*6777b538SAndroid Build Coastguard Worker         buf->content[0] = 0;
303*6777b538SAndroid Build Coastguard Worker     }
304*6777b538SAndroid Build Coastguard Worker     UPDATE_COMPAT(buf)
305*6777b538SAndroid Build Coastguard Worker }
306*6777b538SAndroid Build Coastguard Worker 
307*6777b538SAndroid Build Coastguard Worker /**
308*6777b538SAndroid Build Coastguard Worker  * xmlBufShrink:
309*6777b538SAndroid Build Coastguard Worker  * @buf:  the buffer to dump
310*6777b538SAndroid Build Coastguard Worker  * @len:  the number of xmlChar to remove
311*6777b538SAndroid Build Coastguard Worker  *
312*6777b538SAndroid Build Coastguard Worker  * Remove the beginning of an XML buffer.
313*6777b538SAndroid Build Coastguard Worker  * NOTE that this routine behaviour differs from xmlBufferShrink()
314*6777b538SAndroid Build Coastguard Worker  * as it will return 0 on error instead of -1 due to size_t being
315*6777b538SAndroid Build Coastguard Worker  * used as the return type.
316*6777b538SAndroid Build Coastguard Worker  *
317*6777b538SAndroid Build Coastguard Worker  * Returns the number of byte removed or 0 in case of failure
318*6777b538SAndroid Build Coastguard Worker  */
319*6777b538SAndroid Build Coastguard Worker size_t
xmlBufShrink(xmlBufPtr buf,size_t len)320*6777b538SAndroid Build Coastguard Worker xmlBufShrink(xmlBufPtr buf, size_t len) {
321*6777b538SAndroid Build Coastguard Worker     if ((buf == NULL) || (buf->error != 0)) return(0);
322*6777b538SAndroid Build Coastguard Worker     CHECK_COMPAT(buf)
323*6777b538SAndroid Build Coastguard Worker     if (len == 0) return(0);
324*6777b538SAndroid Build Coastguard Worker     if (len > buf->use) return(0);
325*6777b538SAndroid Build Coastguard Worker 
326*6777b538SAndroid Build Coastguard Worker     buf->use -= len;
327*6777b538SAndroid Build Coastguard Worker     if ((buf->alloc == XML_BUFFER_ALLOC_IO) && (buf->contentIO != NULL)) {
328*6777b538SAndroid Build Coastguard Worker 	/*
329*6777b538SAndroid Build Coastguard Worker 	 * we just move the content pointer, but also make sure
330*6777b538SAndroid Build Coastguard Worker 	 * the perceived buffer size has shrunk accordingly
331*6777b538SAndroid Build Coastguard Worker 	 */
332*6777b538SAndroid Build Coastguard Worker         buf->content += len;
333*6777b538SAndroid Build Coastguard Worker 	buf->size -= len;
334*6777b538SAndroid Build Coastguard Worker 
335*6777b538SAndroid Build Coastguard Worker         /*
336*6777b538SAndroid Build Coastguard Worker 	 * sometimes though it maybe be better to really shrink
337*6777b538SAndroid Build Coastguard Worker 	 * on IO buffers
338*6777b538SAndroid Build Coastguard Worker 	 */
339*6777b538SAndroid Build Coastguard Worker 	if ((buf->alloc == XML_BUFFER_ALLOC_IO) && (buf->contentIO != NULL)) {
340*6777b538SAndroid Build Coastguard Worker 	    size_t start_buf = buf->content - buf->contentIO;
341*6777b538SAndroid Build Coastguard Worker 	    if (start_buf >= buf->size) {
342*6777b538SAndroid Build Coastguard Worker 		memmove(buf->contentIO, &buf->content[0], buf->use);
343*6777b538SAndroid Build Coastguard Worker 		buf->content = buf->contentIO;
344*6777b538SAndroid Build Coastguard Worker 		buf->content[buf->use] = 0;
345*6777b538SAndroid Build Coastguard Worker 		buf->size += start_buf;
346*6777b538SAndroid Build Coastguard Worker 	    }
347*6777b538SAndroid Build Coastguard Worker 	}
348*6777b538SAndroid Build Coastguard Worker     } else {
349*6777b538SAndroid Build Coastguard Worker 	memmove(buf->content, &buf->content[len], buf->use);
350*6777b538SAndroid Build Coastguard Worker 	buf->content[buf->use] = 0;
351*6777b538SAndroid Build Coastguard Worker     }
352*6777b538SAndroid Build Coastguard Worker     UPDATE_COMPAT(buf)
353*6777b538SAndroid Build Coastguard Worker     return(len);
354*6777b538SAndroid Build Coastguard Worker }
355*6777b538SAndroid Build Coastguard Worker 
356*6777b538SAndroid Build Coastguard Worker /**
357*6777b538SAndroid Build Coastguard Worker  * xmlBufGrowInternal:
358*6777b538SAndroid Build Coastguard Worker  * @buf:  the buffer
359*6777b538SAndroid Build Coastguard Worker  * @len:  the minimum free size to allocate
360*6777b538SAndroid Build Coastguard Worker  *
361*6777b538SAndroid Build Coastguard Worker  * Grow the available space of an XML buffer, @len is the target value
362*6777b538SAndroid Build Coastguard Worker  * Error checking should be done on buf->error since using the return
363*6777b538SAndroid Build Coastguard Worker  * value doesn't work that well
364*6777b538SAndroid Build Coastguard Worker  *
365*6777b538SAndroid Build Coastguard Worker  * Returns 0 in case of error or the length made available otherwise
366*6777b538SAndroid Build Coastguard Worker  */
367*6777b538SAndroid Build Coastguard Worker static size_t
xmlBufGrowInternal(xmlBufPtr buf,size_t len)368*6777b538SAndroid Build Coastguard Worker xmlBufGrowInternal(xmlBufPtr buf, size_t len) {
369*6777b538SAndroid Build Coastguard Worker     size_t size;
370*6777b538SAndroid Build Coastguard Worker     xmlChar *newbuf;
371*6777b538SAndroid Build Coastguard Worker 
372*6777b538SAndroid Build Coastguard Worker     if ((buf == NULL) || (buf->error != 0)) return(0);
373*6777b538SAndroid Build Coastguard Worker     CHECK_COMPAT(buf)
374*6777b538SAndroid Build Coastguard Worker 
375*6777b538SAndroid Build Coastguard Worker     if (len < buf->size - buf->use)
376*6777b538SAndroid Build Coastguard Worker         return(buf->size - buf->use - 1);
377*6777b538SAndroid Build Coastguard Worker     if (len >= SIZE_MAX - buf->use) {
378*6777b538SAndroid Build Coastguard Worker         xmlBufMemoryError(buf);
379*6777b538SAndroid Build Coastguard Worker         return(0);
380*6777b538SAndroid Build Coastguard Worker     }
381*6777b538SAndroid Build Coastguard Worker 
382*6777b538SAndroid Build Coastguard Worker     if (buf->size > (size_t) len) {
383*6777b538SAndroid Build Coastguard Worker         size = buf->size > SIZE_MAX / 2 ? SIZE_MAX : buf->size * 2;
384*6777b538SAndroid Build Coastguard Worker     } else {
385*6777b538SAndroid Build Coastguard Worker         size = buf->use + len;
386*6777b538SAndroid Build Coastguard Worker         size = size > SIZE_MAX - 100 ? SIZE_MAX : size + 100;
387*6777b538SAndroid Build Coastguard Worker     }
388*6777b538SAndroid Build Coastguard Worker 
389*6777b538SAndroid Build Coastguard Worker     if (buf->alloc == XML_BUFFER_ALLOC_BOUNDED) {
390*6777b538SAndroid Build Coastguard Worker         /*
391*6777b538SAndroid Build Coastguard Worker 	 * Used to provide parsing limits
392*6777b538SAndroid Build Coastguard Worker 	 */
393*6777b538SAndroid Build Coastguard Worker         if ((buf->use + len + 1 >= XML_MAX_TEXT_LENGTH) ||
394*6777b538SAndroid Build Coastguard Worker 	    (buf->size >= XML_MAX_TEXT_LENGTH)) {
395*6777b538SAndroid Build Coastguard Worker 	    xmlBufMemoryError(buf);
396*6777b538SAndroid Build Coastguard Worker 	    return(0);
397*6777b538SAndroid Build Coastguard Worker 	}
398*6777b538SAndroid Build Coastguard Worker 	if (size >= XML_MAX_TEXT_LENGTH)
399*6777b538SAndroid Build Coastguard Worker 	    size = XML_MAX_TEXT_LENGTH;
400*6777b538SAndroid Build Coastguard Worker     }
401*6777b538SAndroid Build Coastguard Worker     if ((buf->alloc == XML_BUFFER_ALLOC_IO) && (buf->contentIO != NULL)) {
402*6777b538SAndroid Build Coastguard Worker         size_t start_buf = buf->content - buf->contentIO;
403*6777b538SAndroid Build Coastguard Worker 
404*6777b538SAndroid Build Coastguard Worker 	newbuf = (xmlChar *) xmlRealloc(buf->contentIO, start_buf + size);
405*6777b538SAndroid Build Coastguard Worker 	if (newbuf == NULL) {
406*6777b538SAndroid Build Coastguard Worker 	    xmlBufMemoryError(buf);
407*6777b538SAndroid Build Coastguard Worker 	    return(0);
408*6777b538SAndroid Build Coastguard Worker 	}
409*6777b538SAndroid Build Coastguard Worker 	buf->contentIO = newbuf;
410*6777b538SAndroid Build Coastguard Worker 	buf->content = newbuf + start_buf;
411*6777b538SAndroid Build Coastguard Worker     } else {
412*6777b538SAndroid Build Coastguard Worker 	newbuf = (xmlChar *) xmlRealloc(buf->content, size);
413*6777b538SAndroid Build Coastguard Worker 	if (newbuf == NULL) {
414*6777b538SAndroid Build Coastguard Worker 	    xmlBufMemoryError(buf);
415*6777b538SAndroid Build Coastguard Worker 	    return(0);
416*6777b538SAndroid Build Coastguard Worker 	}
417*6777b538SAndroid Build Coastguard Worker 	buf->content = newbuf;
418*6777b538SAndroid Build Coastguard Worker     }
419*6777b538SAndroid Build Coastguard Worker     buf->size = size;
420*6777b538SAndroid Build Coastguard Worker     UPDATE_COMPAT(buf)
421*6777b538SAndroid Build Coastguard Worker     return(buf->size - buf->use - 1);
422*6777b538SAndroid Build Coastguard Worker }
423*6777b538SAndroid Build Coastguard Worker 
424*6777b538SAndroid Build Coastguard Worker /**
425*6777b538SAndroid Build Coastguard Worker  * xmlBufGrow:
426*6777b538SAndroid Build Coastguard Worker  * @buf:  the buffer
427*6777b538SAndroid Build Coastguard Worker  * @len:  the minimum free size to allocate
428*6777b538SAndroid Build Coastguard Worker  *
429*6777b538SAndroid Build Coastguard Worker  * Grow the available space of an XML buffer, @len is the target value
430*6777b538SAndroid Build Coastguard Worker  * This is been kept compatible with xmlBufferGrow() as much as possible
431*6777b538SAndroid Build Coastguard Worker  *
432*6777b538SAndroid Build Coastguard Worker  * Returns -1 in case of error or the length made available otherwise
433*6777b538SAndroid Build Coastguard Worker  */
434*6777b538SAndroid Build Coastguard Worker int
xmlBufGrow(xmlBufPtr buf,int len)435*6777b538SAndroid Build Coastguard Worker xmlBufGrow(xmlBufPtr buf, int len) {
436*6777b538SAndroid Build Coastguard Worker     size_t ret;
437*6777b538SAndroid Build Coastguard Worker 
438*6777b538SAndroid Build Coastguard Worker     if ((buf == NULL) || (len < 0)) return(-1);
439*6777b538SAndroid Build Coastguard Worker     if (len == 0)
440*6777b538SAndroid Build Coastguard Worker         return(0);
441*6777b538SAndroid Build Coastguard Worker     ret = xmlBufGrowInternal(buf, len);
442*6777b538SAndroid Build Coastguard Worker     if (buf->error != 0)
443*6777b538SAndroid Build Coastguard Worker         return(-1);
444*6777b538SAndroid Build Coastguard Worker     return(ret > INT_MAX ? INT_MAX : ret);
445*6777b538SAndroid Build Coastguard Worker }
446*6777b538SAndroid Build Coastguard Worker 
447*6777b538SAndroid Build Coastguard Worker /**
448*6777b538SAndroid Build Coastguard Worker  * xmlBufDump:
449*6777b538SAndroid Build Coastguard Worker  * @file:  the file output
450*6777b538SAndroid Build Coastguard Worker  * @buf:  the buffer to dump
451*6777b538SAndroid Build Coastguard Worker  *
452*6777b538SAndroid Build Coastguard Worker  * Dumps an XML buffer to  a FILE *.
453*6777b538SAndroid Build Coastguard Worker  * Returns the number of #xmlChar written
454*6777b538SAndroid Build Coastguard Worker  */
455*6777b538SAndroid Build Coastguard Worker size_t
xmlBufDump(FILE * file,xmlBufPtr buf)456*6777b538SAndroid Build Coastguard Worker xmlBufDump(FILE *file, xmlBufPtr buf) {
457*6777b538SAndroid Build Coastguard Worker     size_t ret;
458*6777b538SAndroid Build Coastguard Worker 
459*6777b538SAndroid Build Coastguard Worker     if ((buf == NULL) || (buf->error != 0)) {
460*6777b538SAndroid Build Coastguard Worker 	return(0);
461*6777b538SAndroid Build Coastguard Worker     }
462*6777b538SAndroid Build Coastguard Worker     if (buf->content == NULL) {
463*6777b538SAndroid Build Coastguard Worker 	return(0);
464*6777b538SAndroid Build Coastguard Worker     }
465*6777b538SAndroid Build Coastguard Worker     CHECK_COMPAT(buf)
466*6777b538SAndroid Build Coastguard Worker     if (file == NULL)
467*6777b538SAndroid Build Coastguard Worker 	file = stdout;
468*6777b538SAndroid Build Coastguard Worker     ret = fwrite(buf->content, 1, buf->use, file);
469*6777b538SAndroid Build Coastguard Worker     return(ret);
470*6777b538SAndroid Build Coastguard Worker }
471*6777b538SAndroid Build Coastguard Worker 
472*6777b538SAndroid Build Coastguard Worker /**
473*6777b538SAndroid Build Coastguard Worker  * xmlBufContent:
474*6777b538SAndroid Build Coastguard Worker  * @buf:  the buffer
475*6777b538SAndroid Build Coastguard Worker  *
476*6777b538SAndroid Build Coastguard Worker  * Function to extract the content of a buffer
477*6777b538SAndroid Build Coastguard Worker  *
478*6777b538SAndroid Build Coastguard Worker  * Returns the internal content
479*6777b538SAndroid Build Coastguard Worker  */
480*6777b538SAndroid Build Coastguard Worker 
481*6777b538SAndroid Build Coastguard Worker xmlChar *
xmlBufContent(const xmlBuf * buf)482*6777b538SAndroid Build Coastguard Worker xmlBufContent(const xmlBuf *buf)
483*6777b538SAndroid Build Coastguard Worker {
484*6777b538SAndroid Build Coastguard Worker     if ((!buf) || (buf->error))
485*6777b538SAndroid Build Coastguard Worker         return NULL;
486*6777b538SAndroid Build Coastguard Worker 
487*6777b538SAndroid Build Coastguard Worker     return(buf->content);
488*6777b538SAndroid Build Coastguard Worker }
489*6777b538SAndroid Build Coastguard Worker 
490*6777b538SAndroid Build Coastguard Worker /**
491*6777b538SAndroid Build Coastguard Worker  * xmlBufEnd:
492*6777b538SAndroid Build Coastguard Worker  * @buf:  the buffer
493*6777b538SAndroid Build Coastguard Worker  *
494*6777b538SAndroid Build Coastguard Worker  * Function to extract the end of the content of a buffer
495*6777b538SAndroid Build Coastguard Worker  *
496*6777b538SAndroid Build Coastguard Worker  * Returns the end of the internal content or NULL in case of error
497*6777b538SAndroid Build Coastguard Worker  */
498*6777b538SAndroid Build Coastguard Worker 
499*6777b538SAndroid Build Coastguard Worker xmlChar *
xmlBufEnd(xmlBufPtr buf)500*6777b538SAndroid Build Coastguard Worker xmlBufEnd(xmlBufPtr buf)
501*6777b538SAndroid Build Coastguard Worker {
502*6777b538SAndroid Build Coastguard Worker     if ((!buf) || (buf->error))
503*6777b538SAndroid Build Coastguard Worker         return NULL;
504*6777b538SAndroid Build Coastguard Worker     CHECK_COMPAT(buf)
505*6777b538SAndroid Build Coastguard Worker 
506*6777b538SAndroid Build Coastguard Worker     return(&buf->content[buf->use]);
507*6777b538SAndroid Build Coastguard Worker }
508*6777b538SAndroid Build Coastguard Worker 
509*6777b538SAndroid Build Coastguard Worker /**
510*6777b538SAndroid Build Coastguard Worker  * xmlBufAddLen:
511*6777b538SAndroid Build Coastguard Worker  * @buf:  the buffer
512*6777b538SAndroid Build Coastguard Worker  * @len:  the size which were added at the end
513*6777b538SAndroid Build Coastguard Worker  *
514*6777b538SAndroid Build Coastguard Worker  * Sometime data may be added at the end of the buffer without
515*6777b538SAndroid Build Coastguard Worker  * using the xmlBuf APIs that is used to expand the used space
516*6777b538SAndroid Build Coastguard Worker  * and set the zero terminating at the end of the buffer
517*6777b538SAndroid Build Coastguard Worker  *
518*6777b538SAndroid Build Coastguard Worker  * Returns -1 in case of error and 0 otherwise
519*6777b538SAndroid Build Coastguard Worker  */
520*6777b538SAndroid Build Coastguard Worker int
xmlBufAddLen(xmlBufPtr buf,size_t len)521*6777b538SAndroid Build Coastguard Worker xmlBufAddLen(xmlBufPtr buf, size_t len) {
522*6777b538SAndroid Build Coastguard Worker     if ((buf == NULL) || (buf->error))
523*6777b538SAndroid Build Coastguard Worker         return(-1);
524*6777b538SAndroid Build Coastguard Worker     CHECK_COMPAT(buf)
525*6777b538SAndroid Build Coastguard Worker     if (len >= (buf->size - buf->use))
526*6777b538SAndroid Build Coastguard Worker         return(-1);
527*6777b538SAndroid Build Coastguard Worker     buf->use += len;
528*6777b538SAndroid Build Coastguard Worker     buf->content[buf->use] = 0;
529*6777b538SAndroid Build Coastguard Worker     UPDATE_COMPAT(buf)
530*6777b538SAndroid Build Coastguard Worker     return(0);
531*6777b538SAndroid Build Coastguard Worker }
532*6777b538SAndroid Build Coastguard Worker 
533*6777b538SAndroid Build Coastguard Worker /**
534*6777b538SAndroid Build Coastguard Worker  * xmlBufLength:
535*6777b538SAndroid Build Coastguard Worker  * @buf:  the buffer
536*6777b538SAndroid Build Coastguard Worker  *
537*6777b538SAndroid Build Coastguard Worker  * Function to get the length of a buffer
538*6777b538SAndroid Build Coastguard Worker  *
539*6777b538SAndroid Build Coastguard Worker  * Returns the length of data in the internal content
540*6777b538SAndroid Build Coastguard Worker  */
541*6777b538SAndroid Build Coastguard Worker 
542*6777b538SAndroid Build Coastguard Worker size_t
xmlBufLength(const xmlBufPtr buf)543*6777b538SAndroid Build Coastguard Worker xmlBufLength(const xmlBufPtr buf)
544*6777b538SAndroid Build Coastguard Worker {
545*6777b538SAndroid Build Coastguard Worker     if ((!buf) || (buf->error))
546*6777b538SAndroid Build Coastguard Worker         return 0;
547*6777b538SAndroid Build Coastguard Worker     CHECK_COMPAT(buf)
548*6777b538SAndroid Build Coastguard Worker 
549*6777b538SAndroid Build Coastguard Worker     return(buf->use);
550*6777b538SAndroid Build Coastguard Worker }
551*6777b538SAndroid Build Coastguard Worker 
552*6777b538SAndroid Build Coastguard Worker /**
553*6777b538SAndroid Build Coastguard Worker  * xmlBufUse:
554*6777b538SAndroid Build Coastguard Worker  * @buf:  the buffer
555*6777b538SAndroid Build Coastguard Worker  *
556*6777b538SAndroid Build Coastguard Worker  * Function to get the length of a buffer
557*6777b538SAndroid Build Coastguard Worker  *
558*6777b538SAndroid Build Coastguard Worker  * Returns the length of data in the internal content
559*6777b538SAndroid Build Coastguard Worker  */
560*6777b538SAndroid Build Coastguard Worker 
561*6777b538SAndroid Build Coastguard Worker size_t
xmlBufUse(const xmlBufPtr buf)562*6777b538SAndroid Build Coastguard Worker xmlBufUse(const xmlBufPtr buf)
563*6777b538SAndroid Build Coastguard Worker {
564*6777b538SAndroid Build Coastguard Worker     if ((!buf) || (buf->error))
565*6777b538SAndroid Build Coastguard Worker         return 0;
566*6777b538SAndroid Build Coastguard Worker     CHECK_COMPAT(buf)
567*6777b538SAndroid Build Coastguard Worker 
568*6777b538SAndroid Build Coastguard Worker     return(buf->use);
569*6777b538SAndroid Build Coastguard Worker }
570*6777b538SAndroid Build Coastguard Worker 
571*6777b538SAndroid Build Coastguard Worker /**
572*6777b538SAndroid Build Coastguard Worker  * xmlBufAvail:
573*6777b538SAndroid Build Coastguard Worker  * @buf:  the buffer
574*6777b538SAndroid Build Coastguard Worker  *
575*6777b538SAndroid Build Coastguard Worker  * Function to find how much free space is allocated but not
576*6777b538SAndroid Build Coastguard Worker  * used in the buffer. It reserves one byte for the NUL
577*6777b538SAndroid Build Coastguard Worker  * terminator character that is usually needed, so there is
578*6777b538SAndroid Build Coastguard Worker  * no need to subtract 1 from the result anymore.
579*6777b538SAndroid Build Coastguard Worker  *
580*6777b538SAndroid Build Coastguard Worker  * Returns the amount, or 0 if none or if an error occurred.
581*6777b538SAndroid Build Coastguard Worker  */
582*6777b538SAndroid Build Coastguard Worker 
583*6777b538SAndroid Build Coastguard Worker size_t
xmlBufAvail(const xmlBufPtr buf)584*6777b538SAndroid Build Coastguard Worker xmlBufAvail(const xmlBufPtr buf)
585*6777b538SAndroid Build Coastguard Worker {
586*6777b538SAndroid Build Coastguard Worker     if ((!buf) || (buf->error))
587*6777b538SAndroid Build Coastguard Worker         return 0;
588*6777b538SAndroid Build Coastguard Worker     CHECK_COMPAT(buf)
589*6777b538SAndroid Build Coastguard Worker 
590*6777b538SAndroid Build Coastguard Worker     return((buf->size > buf->use) ? (buf->size - buf->use - 1) : 0);
591*6777b538SAndroid Build Coastguard Worker }
592*6777b538SAndroid Build Coastguard Worker 
593*6777b538SAndroid Build Coastguard Worker /**
594*6777b538SAndroid Build Coastguard Worker  * xmlBufIsEmpty:
595*6777b538SAndroid Build Coastguard Worker  * @buf:  the buffer
596*6777b538SAndroid Build Coastguard Worker  *
597*6777b538SAndroid Build Coastguard Worker  * Tell if a buffer is empty
598*6777b538SAndroid Build Coastguard Worker  *
599*6777b538SAndroid Build Coastguard Worker  * Returns 0 if no, 1 if yes and -1 in case of error
600*6777b538SAndroid Build Coastguard Worker  */
601*6777b538SAndroid Build Coastguard Worker int
xmlBufIsEmpty(const xmlBufPtr buf)602*6777b538SAndroid Build Coastguard Worker xmlBufIsEmpty(const xmlBufPtr buf)
603*6777b538SAndroid Build Coastguard Worker {
604*6777b538SAndroid Build Coastguard Worker     if ((!buf) || (buf->error))
605*6777b538SAndroid Build Coastguard Worker         return(-1);
606*6777b538SAndroid Build Coastguard Worker     CHECK_COMPAT(buf)
607*6777b538SAndroid Build Coastguard Worker 
608*6777b538SAndroid Build Coastguard Worker     return(buf->use == 0);
609*6777b538SAndroid Build Coastguard Worker }
610*6777b538SAndroid Build Coastguard Worker 
611*6777b538SAndroid Build Coastguard Worker /**
612*6777b538SAndroid Build Coastguard Worker  * xmlBufResize:
613*6777b538SAndroid Build Coastguard Worker  * @buf:  the buffer to resize
614*6777b538SAndroid Build Coastguard Worker  * @size:  the desired size
615*6777b538SAndroid Build Coastguard Worker  *
616*6777b538SAndroid Build Coastguard Worker  * Resize a buffer to accommodate minimum size of @size.
617*6777b538SAndroid Build Coastguard Worker  *
618*6777b538SAndroid Build Coastguard Worker  * Returns  0 in case of problems, 1 otherwise
619*6777b538SAndroid Build Coastguard Worker  */
620*6777b538SAndroid Build Coastguard Worker int
xmlBufResize(xmlBufPtr buf,size_t size)621*6777b538SAndroid Build Coastguard Worker xmlBufResize(xmlBufPtr buf, size_t size)
622*6777b538SAndroid Build Coastguard Worker {
623*6777b538SAndroid Build Coastguard Worker     size_t newSize;
624*6777b538SAndroid Build Coastguard Worker     xmlChar* rebuf = NULL;
625*6777b538SAndroid Build Coastguard Worker     size_t start_buf;
626*6777b538SAndroid Build Coastguard Worker 
627*6777b538SAndroid Build Coastguard Worker     if ((buf == NULL) || (buf->error))
628*6777b538SAndroid Build Coastguard Worker         return(0);
629*6777b538SAndroid Build Coastguard Worker     CHECK_COMPAT(buf)
630*6777b538SAndroid Build Coastguard Worker 
631*6777b538SAndroid Build Coastguard Worker     if (buf->alloc == XML_BUFFER_ALLOC_BOUNDED) {
632*6777b538SAndroid Build Coastguard Worker         /*
633*6777b538SAndroid Build Coastguard Worker 	 * Used to provide parsing limits
634*6777b538SAndroid Build Coastguard Worker 	 */
635*6777b538SAndroid Build Coastguard Worker         if (size >= XML_MAX_TEXT_LENGTH) {
636*6777b538SAndroid Build Coastguard Worker 	    xmlBufMemoryError(buf);
637*6777b538SAndroid Build Coastguard Worker 	    return(0);
638*6777b538SAndroid Build Coastguard Worker 	}
639*6777b538SAndroid Build Coastguard Worker     }
640*6777b538SAndroid Build Coastguard Worker 
641*6777b538SAndroid Build Coastguard Worker     /* Don't resize if we don't have to */
642*6777b538SAndroid Build Coastguard Worker     if (size < buf->size)
643*6777b538SAndroid Build Coastguard Worker         return 1;
644*6777b538SAndroid Build Coastguard Worker 
645*6777b538SAndroid Build Coastguard Worker     /* figure out new size */
646*6777b538SAndroid Build Coastguard Worker     switch (buf->alloc){
647*6777b538SAndroid Build Coastguard Worker 	case XML_BUFFER_ALLOC_IO:
648*6777b538SAndroid Build Coastguard Worker 	case XML_BUFFER_ALLOC_DOUBLEIT:
649*6777b538SAndroid Build Coastguard Worker 	    /*take care of empty case*/
650*6777b538SAndroid Build Coastguard Worker             if (buf->size == 0) {
651*6777b538SAndroid Build Coastguard Worker                 newSize = (size > SIZE_MAX - 10 ? SIZE_MAX : size + 10);
652*6777b538SAndroid Build Coastguard Worker             } else {
653*6777b538SAndroid Build Coastguard Worker                 newSize = buf->size;
654*6777b538SAndroid Build Coastguard Worker             }
655*6777b538SAndroid Build Coastguard Worker 	    while (size > newSize) {
656*6777b538SAndroid Build Coastguard Worker 	        if (newSize > SIZE_MAX / 2) {
657*6777b538SAndroid Build Coastguard Worker 	            xmlBufMemoryError(buf);
658*6777b538SAndroid Build Coastguard Worker 	            return 0;
659*6777b538SAndroid Build Coastguard Worker 	        }
660*6777b538SAndroid Build Coastguard Worker 	        newSize *= 2;
661*6777b538SAndroid Build Coastguard Worker 	    }
662*6777b538SAndroid Build Coastguard Worker 	    break;
663*6777b538SAndroid Build Coastguard Worker 	case XML_BUFFER_ALLOC_EXACT:
664*6777b538SAndroid Build Coastguard Worker             newSize = (size > SIZE_MAX - 10 ? SIZE_MAX : size + 10);
665*6777b538SAndroid Build Coastguard Worker 	    break;
666*6777b538SAndroid Build Coastguard Worker         case XML_BUFFER_ALLOC_HYBRID:
667*6777b538SAndroid Build Coastguard Worker             if (buf->use < BASE_BUFFER_SIZE)
668*6777b538SAndroid Build Coastguard Worker                 newSize = size;
669*6777b538SAndroid Build Coastguard Worker             else {
670*6777b538SAndroid Build Coastguard Worker                 newSize = buf->size;
671*6777b538SAndroid Build Coastguard Worker                 while (size > newSize) {
672*6777b538SAndroid Build Coastguard Worker                     if (newSize > SIZE_MAX / 2) {
673*6777b538SAndroid Build Coastguard Worker                         xmlBufMemoryError(buf);
674*6777b538SAndroid Build Coastguard Worker                         return 0;
675*6777b538SAndroid Build Coastguard Worker                     }
676*6777b538SAndroid Build Coastguard Worker                     newSize *= 2;
677*6777b538SAndroid Build Coastguard Worker                 }
678*6777b538SAndroid Build Coastguard Worker             }
679*6777b538SAndroid Build Coastguard Worker             break;
680*6777b538SAndroid Build Coastguard Worker 
681*6777b538SAndroid Build Coastguard Worker 	default:
682*6777b538SAndroid Build Coastguard Worker             newSize = (size > SIZE_MAX - 10 ? SIZE_MAX : size + 10);
683*6777b538SAndroid Build Coastguard Worker 	    break;
684*6777b538SAndroid Build Coastguard Worker     }
685*6777b538SAndroid Build Coastguard Worker 
686*6777b538SAndroid Build Coastguard Worker     if ((buf->alloc == XML_BUFFER_ALLOC_IO) && (buf->contentIO != NULL)) {
687*6777b538SAndroid Build Coastguard Worker         start_buf = buf->content - buf->contentIO;
688*6777b538SAndroid Build Coastguard Worker 
689*6777b538SAndroid Build Coastguard Worker         if (start_buf > newSize) {
690*6777b538SAndroid Build Coastguard Worker 	    /* move data back to start */
691*6777b538SAndroid Build Coastguard Worker 	    memmove(buf->contentIO, buf->content, buf->use);
692*6777b538SAndroid Build Coastguard Worker 	    buf->content = buf->contentIO;
693*6777b538SAndroid Build Coastguard Worker 	    buf->content[buf->use] = 0;
694*6777b538SAndroid Build Coastguard Worker 	    buf->size += start_buf;
695*6777b538SAndroid Build Coastguard Worker 	} else {
696*6777b538SAndroid Build Coastguard Worker 	    rebuf = (xmlChar *) xmlRealloc(buf->contentIO, start_buf + newSize);
697*6777b538SAndroid Build Coastguard Worker 	    if (rebuf == NULL) {
698*6777b538SAndroid Build Coastguard Worker 		xmlBufMemoryError(buf);
699*6777b538SAndroid Build Coastguard Worker 		return 0;
700*6777b538SAndroid Build Coastguard Worker 	    }
701*6777b538SAndroid Build Coastguard Worker 	    buf->contentIO = rebuf;
702*6777b538SAndroid Build Coastguard Worker 	    buf->content = rebuf + start_buf;
703*6777b538SAndroid Build Coastguard Worker 	}
704*6777b538SAndroid Build Coastguard Worker     } else {
705*6777b538SAndroid Build Coastguard Worker 	if (buf->content == NULL) {
706*6777b538SAndroid Build Coastguard Worker 	    rebuf = (xmlChar *) xmlMallocAtomic(newSize);
707*6777b538SAndroid Build Coastguard Worker 	    buf->use = 0;
708*6777b538SAndroid Build Coastguard Worker             if (rebuf != NULL)
709*6777b538SAndroid Build Coastguard Worker 	        rebuf[buf->use] = 0;
710*6777b538SAndroid Build Coastguard Worker 	} else if (buf->size - buf->use < 100) {
711*6777b538SAndroid Build Coastguard Worker 	    rebuf = (xmlChar *) xmlRealloc(buf->content, newSize);
712*6777b538SAndroid Build Coastguard Worker         } else {
713*6777b538SAndroid Build Coastguard Worker 	    /*
714*6777b538SAndroid Build Coastguard Worker 	     * if we are reallocating a buffer far from being full, it's
715*6777b538SAndroid Build Coastguard Worker 	     * better to make a new allocation and copy only the used range
716*6777b538SAndroid Build Coastguard Worker 	     * and free the old one.
717*6777b538SAndroid Build Coastguard Worker 	     */
718*6777b538SAndroid Build Coastguard Worker 	    rebuf = (xmlChar *) xmlMallocAtomic(newSize);
719*6777b538SAndroid Build Coastguard Worker 	    if (rebuf != NULL) {
720*6777b538SAndroid Build Coastguard Worker 		memcpy(rebuf, buf->content, buf->use);
721*6777b538SAndroid Build Coastguard Worker 		xmlFree(buf->content);
722*6777b538SAndroid Build Coastguard Worker 		rebuf[buf->use] = 0;
723*6777b538SAndroid Build Coastguard Worker 	    }
724*6777b538SAndroid Build Coastguard Worker 	}
725*6777b538SAndroid Build Coastguard Worker 	if (rebuf == NULL) {
726*6777b538SAndroid Build Coastguard Worker 	    xmlBufMemoryError(buf);
727*6777b538SAndroid Build Coastguard Worker 	    return 0;
728*6777b538SAndroid Build Coastguard Worker 	}
729*6777b538SAndroid Build Coastguard Worker 	buf->content = rebuf;
730*6777b538SAndroid Build Coastguard Worker     }
731*6777b538SAndroid Build Coastguard Worker     buf->size = newSize;
732*6777b538SAndroid Build Coastguard Worker     UPDATE_COMPAT(buf)
733*6777b538SAndroid Build Coastguard Worker 
734*6777b538SAndroid Build Coastguard Worker     return 1;
735*6777b538SAndroid Build Coastguard Worker }
736*6777b538SAndroid Build Coastguard Worker 
737*6777b538SAndroid Build Coastguard Worker /**
738*6777b538SAndroid Build Coastguard Worker  * xmlBufAdd:
739*6777b538SAndroid Build Coastguard Worker  * @buf:  the buffer to dump
740*6777b538SAndroid Build Coastguard Worker  * @str:  the #xmlChar string
741*6777b538SAndroid Build Coastguard Worker  * @len:  the number of #xmlChar to add
742*6777b538SAndroid Build Coastguard Worker  *
743*6777b538SAndroid Build Coastguard Worker  * Add a string range to an XML buffer. if len == -1, the length of
744*6777b538SAndroid Build Coastguard Worker  * str is recomputed.
745*6777b538SAndroid Build Coastguard Worker  *
746*6777b538SAndroid Build Coastguard Worker  * Returns 0 successful, a positive error code number otherwise
747*6777b538SAndroid Build Coastguard Worker  *         and -1 in case of internal or API error.
748*6777b538SAndroid Build Coastguard Worker  */
749*6777b538SAndroid Build Coastguard Worker int
xmlBufAdd(xmlBufPtr buf,const xmlChar * str,int len)750*6777b538SAndroid Build Coastguard Worker xmlBufAdd(xmlBufPtr buf, const xmlChar *str, int len) {
751*6777b538SAndroid Build Coastguard Worker     size_t needSize;
752*6777b538SAndroid Build Coastguard Worker 
753*6777b538SAndroid Build Coastguard Worker     if ((str == NULL) || (buf == NULL) || (buf->error))
754*6777b538SAndroid Build Coastguard Worker 	return -1;
755*6777b538SAndroid Build Coastguard Worker     CHECK_COMPAT(buf)
756*6777b538SAndroid Build Coastguard Worker 
757*6777b538SAndroid Build Coastguard Worker     if (len < -1) {
758*6777b538SAndroid Build Coastguard Worker 	return -1;
759*6777b538SAndroid Build Coastguard Worker     }
760*6777b538SAndroid Build Coastguard Worker     if (len == 0) return 0;
761*6777b538SAndroid Build Coastguard Worker 
762*6777b538SAndroid Build Coastguard Worker     if (len < 0)
763*6777b538SAndroid Build Coastguard Worker         len = xmlStrlen(str);
764*6777b538SAndroid Build Coastguard Worker 
765*6777b538SAndroid Build Coastguard Worker     if (len < 0) return -1;
766*6777b538SAndroid Build Coastguard Worker     if (len == 0) return 0;
767*6777b538SAndroid Build Coastguard Worker 
768*6777b538SAndroid Build Coastguard Worker     /* Note that both buf->size and buf->use can be zero here. */
769*6777b538SAndroid Build Coastguard Worker     if ((size_t) len >= buf->size - buf->use) {
770*6777b538SAndroid Build Coastguard Worker         if ((size_t) len >= SIZE_MAX - buf->use) {
771*6777b538SAndroid Build Coastguard Worker             xmlBufMemoryError(buf);
772*6777b538SAndroid Build Coastguard Worker             return(-1);
773*6777b538SAndroid Build Coastguard Worker         }
774*6777b538SAndroid Build Coastguard Worker         needSize = buf->use + len + 1;
775*6777b538SAndroid Build Coastguard Worker 	if (buf->alloc == XML_BUFFER_ALLOC_BOUNDED) {
776*6777b538SAndroid Build Coastguard Worker 	    /*
777*6777b538SAndroid Build Coastguard Worker 	     * Used to provide parsing limits
778*6777b538SAndroid Build Coastguard Worker 	     */
779*6777b538SAndroid Build Coastguard Worker 	    if (needSize >= XML_MAX_TEXT_LENGTH) {
780*6777b538SAndroid Build Coastguard Worker 		xmlBufMemoryError(buf);
781*6777b538SAndroid Build Coastguard Worker 		return(-1);
782*6777b538SAndroid Build Coastguard Worker 	    }
783*6777b538SAndroid Build Coastguard Worker 	}
784*6777b538SAndroid Build Coastguard Worker         if (!xmlBufResize(buf, needSize)){
785*6777b538SAndroid Build Coastguard Worker 	    xmlBufMemoryError(buf);
786*6777b538SAndroid Build Coastguard Worker             return XML_ERR_NO_MEMORY;
787*6777b538SAndroid Build Coastguard Worker         }
788*6777b538SAndroid Build Coastguard Worker     }
789*6777b538SAndroid Build Coastguard Worker 
790*6777b538SAndroid Build Coastguard Worker     memmove(&buf->content[buf->use], str, len);
791*6777b538SAndroid Build Coastguard Worker     buf->use += len;
792*6777b538SAndroid Build Coastguard Worker     buf->content[buf->use] = 0;
793*6777b538SAndroid Build Coastguard Worker     UPDATE_COMPAT(buf)
794*6777b538SAndroid Build Coastguard Worker     return 0;
795*6777b538SAndroid Build Coastguard Worker }
796*6777b538SAndroid Build Coastguard Worker 
797*6777b538SAndroid Build Coastguard Worker /**
798*6777b538SAndroid Build Coastguard Worker  * xmlBufCat:
799*6777b538SAndroid Build Coastguard Worker  * @buf:  the buffer to add to
800*6777b538SAndroid Build Coastguard Worker  * @str:  the #xmlChar string
801*6777b538SAndroid Build Coastguard Worker  *
802*6777b538SAndroid Build Coastguard Worker  * Append a zero terminated string to an XML buffer.
803*6777b538SAndroid Build Coastguard Worker  *
804*6777b538SAndroid Build Coastguard Worker  * Returns 0 successful, a positive error code number otherwise
805*6777b538SAndroid Build Coastguard Worker  *         and -1 in case of internal or API error.
806*6777b538SAndroid Build Coastguard Worker  */
807*6777b538SAndroid Build Coastguard Worker int
xmlBufCat(xmlBufPtr buf,const xmlChar * str)808*6777b538SAndroid Build Coastguard Worker xmlBufCat(xmlBufPtr buf, const xmlChar *str) {
809*6777b538SAndroid Build Coastguard Worker     if ((buf == NULL) || (buf->error))
810*6777b538SAndroid Build Coastguard Worker         return(-1);
811*6777b538SAndroid Build Coastguard Worker     CHECK_COMPAT(buf)
812*6777b538SAndroid Build Coastguard Worker     if (str == NULL) return -1;
813*6777b538SAndroid Build Coastguard Worker     return xmlBufAdd(buf, str, -1);
814*6777b538SAndroid Build Coastguard Worker }
815*6777b538SAndroid Build Coastguard Worker 
816*6777b538SAndroid Build Coastguard Worker /**
817*6777b538SAndroid Build Coastguard Worker  * xmlBufCCat:
818*6777b538SAndroid Build Coastguard Worker  * @buf:  the buffer to dump
819*6777b538SAndroid Build Coastguard Worker  * @str:  the C char string
820*6777b538SAndroid Build Coastguard Worker  *
821*6777b538SAndroid Build Coastguard Worker  * Append a zero terminated C string to an XML buffer.
822*6777b538SAndroid Build Coastguard Worker  *
823*6777b538SAndroid Build Coastguard Worker  * Returns 0 successful, a positive error code number otherwise
824*6777b538SAndroid Build Coastguard Worker  *         and -1 in case of internal or API error.
825*6777b538SAndroid Build Coastguard Worker  */
826*6777b538SAndroid Build Coastguard Worker int
xmlBufCCat(xmlBufPtr buf,const char * str)827*6777b538SAndroid Build Coastguard Worker xmlBufCCat(xmlBufPtr buf, const char *str) {
828*6777b538SAndroid Build Coastguard Worker     return xmlBufCat(buf, (const xmlChar *) str);
829*6777b538SAndroid Build Coastguard Worker }
830*6777b538SAndroid Build Coastguard Worker 
831*6777b538SAndroid Build Coastguard Worker /**
832*6777b538SAndroid Build Coastguard Worker  * xmlBufWriteQuotedString:
833*6777b538SAndroid Build Coastguard Worker  * @buf:  the XML buffer output
834*6777b538SAndroid Build Coastguard Worker  * @string:  the string to add
835*6777b538SAndroid Build Coastguard Worker  *
836*6777b538SAndroid Build Coastguard Worker  * routine which manage and grows an output buffer. This one writes
837*6777b538SAndroid Build Coastguard Worker  * a quoted or double quoted #xmlChar string, checking first if it holds
838*6777b538SAndroid Build Coastguard Worker  * quote or double-quotes internally
839*6777b538SAndroid Build Coastguard Worker  *
840*6777b538SAndroid Build Coastguard Worker  * Returns 0 if successful, a positive error code number otherwise
841*6777b538SAndroid Build Coastguard Worker  *         and -1 in case of internal or API error.
842*6777b538SAndroid Build Coastguard Worker  */
843*6777b538SAndroid Build Coastguard Worker int
xmlBufWriteQuotedString(xmlBufPtr buf,const xmlChar * string)844*6777b538SAndroid Build Coastguard Worker xmlBufWriteQuotedString(xmlBufPtr buf, const xmlChar *string) {
845*6777b538SAndroid Build Coastguard Worker     const xmlChar *cur, *base;
846*6777b538SAndroid Build Coastguard Worker     if ((buf == NULL) || (buf->error))
847*6777b538SAndroid Build Coastguard Worker         return(-1);
848*6777b538SAndroid Build Coastguard Worker     CHECK_COMPAT(buf)
849*6777b538SAndroid Build Coastguard Worker     if (xmlStrchr(string, '\"')) {
850*6777b538SAndroid Build Coastguard Worker         if (xmlStrchr(string, '\'')) {
851*6777b538SAndroid Build Coastguard Worker 	    xmlBufCCat(buf, "\"");
852*6777b538SAndroid Build Coastguard Worker             base = cur = string;
853*6777b538SAndroid Build Coastguard Worker             while(*cur != 0){
854*6777b538SAndroid Build Coastguard Worker                 if(*cur == '"'){
855*6777b538SAndroid Build Coastguard Worker                     if (base != cur)
856*6777b538SAndroid Build Coastguard Worker                         xmlBufAdd(buf, base, cur - base);
857*6777b538SAndroid Build Coastguard Worker                     xmlBufAdd(buf, BAD_CAST "&quot;", 6);
858*6777b538SAndroid Build Coastguard Worker                     cur++;
859*6777b538SAndroid Build Coastguard Worker                     base = cur;
860*6777b538SAndroid Build Coastguard Worker                 }
861*6777b538SAndroid Build Coastguard Worker                 else {
862*6777b538SAndroid Build Coastguard Worker                     cur++;
863*6777b538SAndroid Build Coastguard Worker                 }
864*6777b538SAndroid Build Coastguard Worker             }
865*6777b538SAndroid Build Coastguard Worker             if (base != cur)
866*6777b538SAndroid Build Coastguard Worker                 xmlBufAdd(buf, base, cur - base);
867*6777b538SAndroid Build Coastguard Worker 	    xmlBufCCat(buf, "\"");
868*6777b538SAndroid Build Coastguard Worker 	}
869*6777b538SAndroid Build Coastguard Worker         else{
870*6777b538SAndroid Build Coastguard Worker 	    xmlBufCCat(buf, "\'");
871*6777b538SAndroid Build Coastguard Worker             xmlBufCat(buf, string);
872*6777b538SAndroid Build Coastguard Worker 	    xmlBufCCat(buf, "\'");
873*6777b538SAndroid Build Coastguard Worker         }
874*6777b538SAndroid Build Coastguard Worker     } else {
875*6777b538SAndroid Build Coastguard Worker         xmlBufCCat(buf, "\"");
876*6777b538SAndroid Build Coastguard Worker         xmlBufCat(buf, string);
877*6777b538SAndroid Build Coastguard Worker         xmlBufCCat(buf, "\"");
878*6777b538SAndroid Build Coastguard Worker     }
879*6777b538SAndroid Build Coastguard Worker     return(0);
880*6777b538SAndroid Build Coastguard Worker }
881*6777b538SAndroid Build Coastguard Worker 
882*6777b538SAndroid Build Coastguard Worker /**
883*6777b538SAndroid Build Coastguard Worker  * xmlBufFromBuffer:
884*6777b538SAndroid Build Coastguard Worker  * @buffer: incoming old buffer to convert to a new one
885*6777b538SAndroid Build Coastguard Worker  *
886*6777b538SAndroid Build Coastguard Worker  * Helper routine to switch from the old buffer structures in use
887*6777b538SAndroid Build Coastguard Worker  * in various APIs. It creates a wrapper xmlBufPtr which will be
888*6777b538SAndroid Build Coastguard Worker  * used for internal processing until the xmlBufBackToBuffer() is
889*6777b538SAndroid Build Coastguard Worker  * issued.
890*6777b538SAndroid Build Coastguard Worker  *
891*6777b538SAndroid Build Coastguard Worker  * Returns a new xmlBufPtr unless the call failed and NULL is returned
892*6777b538SAndroid Build Coastguard Worker  */
893*6777b538SAndroid Build Coastguard Worker xmlBufPtr
xmlBufFromBuffer(xmlBufferPtr buffer)894*6777b538SAndroid Build Coastguard Worker xmlBufFromBuffer(xmlBufferPtr buffer) {
895*6777b538SAndroid Build Coastguard Worker     xmlBufPtr ret;
896*6777b538SAndroid Build Coastguard Worker 
897*6777b538SAndroid Build Coastguard Worker     if (buffer == NULL)
898*6777b538SAndroid Build Coastguard Worker         return(NULL);
899*6777b538SAndroid Build Coastguard Worker 
900*6777b538SAndroid Build Coastguard Worker     ret = (xmlBufPtr) xmlMalloc(sizeof(xmlBuf));
901*6777b538SAndroid Build Coastguard Worker     if (ret == NULL) {
902*6777b538SAndroid Build Coastguard Worker         return(NULL);
903*6777b538SAndroid Build Coastguard Worker     }
904*6777b538SAndroid Build Coastguard Worker     ret->use = buffer->use;
905*6777b538SAndroid Build Coastguard Worker     ret->size = buffer->size;
906*6777b538SAndroid Build Coastguard Worker     UPDATE_COMPAT(ret);
907*6777b538SAndroid Build Coastguard Worker     ret->error = 0;
908*6777b538SAndroid Build Coastguard Worker     ret->buffer = buffer;
909*6777b538SAndroid Build Coastguard Worker     ret->alloc = buffer->alloc;
910*6777b538SAndroid Build Coastguard Worker     ret->content = buffer->content;
911*6777b538SAndroid Build Coastguard Worker     ret->contentIO = buffer->contentIO;
912*6777b538SAndroid Build Coastguard Worker 
913*6777b538SAndroid Build Coastguard Worker     return(ret);
914*6777b538SAndroid Build Coastguard Worker }
915*6777b538SAndroid Build Coastguard Worker 
916*6777b538SAndroid Build Coastguard Worker /**
917*6777b538SAndroid Build Coastguard Worker  * xmlBufBackToBuffer:
918*6777b538SAndroid Build Coastguard Worker  * @buf: new buffer wrapping the old one
919*6777b538SAndroid Build Coastguard Worker  *
920*6777b538SAndroid Build Coastguard Worker  * Function to be called once internal processing had been done to
921*6777b538SAndroid Build Coastguard Worker  * update back the buffer provided by the user. This can lead to
922*6777b538SAndroid Build Coastguard Worker  * a failure in case the size accumulated in the xmlBuf is larger
923*6777b538SAndroid Build Coastguard Worker  * than what an xmlBuffer can support on 64 bits (INT_MAX)
924*6777b538SAndroid Build Coastguard Worker  * The xmlBufPtr @buf wrapper is deallocated by this call in any case.
925*6777b538SAndroid Build Coastguard Worker  *
926*6777b538SAndroid Build Coastguard Worker  * Returns the old xmlBufferPtr unless the call failed and NULL is returned
927*6777b538SAndroid Build Coastguard Worker  */
928*6777b538SAndroid Build Coastguard Worker xmlBufferPtr
xmlBufBackToBuffer(xmlBufPtr buf)929*6777b538SAndroid Build Coastguard Worker xmlBufBackToBuffer(xmlBufPtr buf) {
930*6777b538SAndroid Build Coastguard Worker     xmlBufferPtr ret;
931*6777b538SAndroid Build Coastguard Worker 
932*6777b538SAndroid Build Coastguard Worker     if (buf == NULL)
933*6777b538SAndroid Build Coastguard Worker         return(NULL);
934*6777b538SAndroid Build Coastguard Worker     CHECK_COMPAT(buf)
935*6777b538SAndroid Build Coastguard Worker     if ((buf->error) || (buf->buffer == NULL)) {
936*6777b538SAndroid Build Coastguard Worker         xmlBufFree(buf);
937*6777b538SAndroid Build Coastguard Worker         return(NULL);
938*6777b538SAndroid Build Coastguard Worker     }
939*6777b538SAndroid Build Coastguard Worker 
940*6777b538SAndroid Build Coastguard Worker     ret = buf->buffer;
941*6777b538SAndroid Build Coastguard Worker     /*
942*6777b538SAndroid Build Coastguard Worker      * What to do in case of error in the buffer ???
943*6777b538SAndroid Build Coastguard Worker      */
944*6777b538SAndroid Build Coastguard Worker     if (buf->use > INT_MAX) {
945*6777b538SAndroid Build Coastguard Worker         /*
946*6777b538SAndroid Build Coastguard Worker          * Worse case, we really allocated and used more than the
947*6777b538SAndroid Build Coastguard Worker          * maximum allowed memory for an xmlBuffer on this architecture.
948*6777b538SAndroid Build Coastguard Worker          * Keep the buffer but provide a truncated size value.
949*6777b538SAndroid Build Coastguard Worker          */
950*6777b538SAndroid Build Coastguard Worker         xmlBufOverflowError(buf);
951*6777b538SAndroid Build Coastguard Worker         ret->use = INT_MAX;
952*6777b538SAndroid Build Coastguard Worker         ret->size = INT_MAX;
953*6777b538SAndroid Build Coastguard Worker     } else if (buf->size > INT_MAX) {
954*6777b538SAndroid Build Coastguard Worker         /*
955*6777b538SAndroid Build Coastguard Worker          * milder case, we allocated more than the maximum allowed memory
956*6777b538SAndroid Build Coastguard Worker          * for an xmlBuffer on this architecture, but used less than the
957*6777b538SAndroid Build Coastguard Worker          * limit.
958*6777b538SAndroid Build Coastguard Worker          * Keep the buffer but provide a truncated size value.
959*6777b538SAndroid Build Coastguard Worker          */
960*6777b538SAndroid Build Coastguard Worker         xmlBufOverflowError(buf);
961*6777b538SAndroid Build Coastguard Worker         ret->use = buf->use;
962*6777b538SAndroid Build Coastguard Worker         ret->size = INT_MAX;
963*6777b538SAndroid Build Coastguard Worker     } else {
964*6777b538SAndroid Build Coastguard Worker         ret->use = buf->use;
965*6777b538SAndroid Build Coastguard Worker         ret->size = buf->size;
966*6777b538SAndroid Build Coastguard Worker     }
967*6777b538SAndroid Build Coastguard Worker     ret->alloc = buf->alloc;
968*6777b538SAndroid Build Coastguard Worker     ret->content = buf->content;
969*6777b538SAndroid Build Coastguard Worker     ret->contentIO = buf->contentIO;
970*6777b538SAndroid Build Coastguard Worker     xmlFree(buf);
971*6777b538SAndroid Build Coastguard Worker     return(ret);
972*6777b538SAndroid Build Coastguard Worker }
973*6777b538SAndroid Build Coastguard Worker 
974*6777b538SAndroid Build Coastguard Worker /**
975*6777b538SAndroid Build Coastguard Worker  * xmlBufResetInput:
976*6777b538SAndroid Build Coastguard Worker  * @buf: an xmlBufPtr
977*6777b538SAndroid Build Coastguard Worker  * @input: an xmlParserInputPtr
978*6777b538SAndroid Build Coastguard Worker  *
979*6777b538SAndroid Build Coastguard Worker  * Update the input to use the current set of pointers from the buffer.
980*6777b538SAndroid Build Coastguard Worker  *
981*6777b538SAndroid Build Coastguard Worker  * Returns -1 in case of error, 0 otherwise
982*6777b538SAndroid Build Coastguard Worker  */
983*6777b538SAndroid Build Coastguard Worker int
xmlBufResetInput(xmlBufPtr buf,xmlParserInputPtr input)984*6777b538SAndroid Build Coastguard Worker xmlBufResetInput(xmlBufPtr buf, xmlParserInputPtr input) {
985*6777b538SAndroid Build Coastguard Worker     return(xmlBufUpdateInput(buf, input, 0));
986*6777b538SAndroid Build Coastguard Worker }
987*6777b538SAndroid Build Coastguard Worker 
988*6777b538SAndroid Build Coastguard Worker /**
989*6777b538SAndroid Build Coastguard Worker  * xmlBufUpdateInput:
990*6777b538SAndroid Build Coastguard Worker  * @buf: an xmlBufPtr
991*6777b538SAndroid Build Coastguard Worker  * @input: an xmlParserInputPtr
992*6777b538SAndroid Build Coastguard Worker  * @pos: the cur value relative to the beginning of the buffer
993*6777b538SAndroid Build Coastguard Worker  *
994*6777b538SAndroid Build Coastguard Worker  * Update the input to use the base and cur relative to the buffer
995*6777b538SAndroid Build Coastguard Worker  * after a possible reallocation of its content
996*6777b538SAndroid Build Coastguard Worker  *
997*6777b538SAndroid Build Coastguard Worker  * Returns -1 in case of error, 0 otherwise
998*6777b538SAndroid Build Coastguard Worker  */
999*6777b538SAndroid Build Coastguard Worker int
xmlBufUpdateInput(xmlBufPtr buf,xmlParserInputPtr input,size_t pos)1000*6777b538SAndroid Build Coastguard Worker xmlBufUpdateInput(xmlBufPtr buf, xmlParserInputPtr input, size_t pos) {
1001*6777b538SAndroid Build Coastguard Worker     if ((buf == NULL) || (input == NULL))
1002*6777b538SAndroid Build Coastguard Worker         return(-1);
1003*6777b538SAndroid Build Coastguard Worker     CHECK_COMPAT(buf)
1004*6777b538SAndroid Build Coastguard Worker     input->base = buf->content;
1005*6777b538SAndroid Build Coastguard Worker     input->cur = input->base + pos;
1006*6777b538SAndroid Build Coastguard Worker     input->end = &buf->content[buf->use];
1007*6777b538SAndroid Build Coastguard Worker     return(0);
1008*6777b538SAndroid Build Coastguard Worker }
1009*6777b538SAndroid Build Coastguard Worker 
1010