xref: /aosp_15_r20/external/libxml2/buf.c (revision 7c5688314b92172186c154356a6374bf7684c3ca)
1*7c568831SAndroid Build Coastguard Worker /*
2*7c568831SAndroid Build Coastguard Worker  * buf.c: memory buffers for libxml2
3*7c568831SAndroid Build Coastguard Worker  *
4*7c568831SAndroid Build Coastguard Worker  * new buffer structures and entry points to simplify the maintenance
5*7c568831SAndroid Build Coastguard Worker  * of libxml2 and ensure we keep good control over memory allocations
6*7c568831SAndroid Build Coastguard Worker  * and stay 64 bits clean.
7*7c568831SAndroid Build Coastguard Worker  * The new entry point use the xmlBufPtr opaque structure and
8*7c568831SAndroid Build Coastguard Worker  * xmlBuf...() counterparts to the old xmlBuf...() functions
9*7c568831SAndroid Build Coastguard Worker  *
10*7c568831SAndroid Build Coastguard Worker  * See Copyright for the status of this software.
11*7c568831SAndroid Build Coastguard Worker  *
12*7c568831SAndroid Build Coastguard Worker  * [email protected]
13*7c568831SAndroid Build Coastguard Worker  */
14*7c568831SAndroid Build Coastguard Worker 
15*7c568831SAndroid Build Coastguard Worker #define IN_LIBXML
16*7c568831SAndroid Build Coastguard Worker #include "libxml.h"
17*7c568831SAndroid Build Coastguard Worker 
18*7c568831SAndroid Build Coastguard Worker #include <string.h>
19*7c568831SAndroid Build Coastguard Worker #include <limits.h>
20*7c568831SAndroid Build Coastguard Worker 
21*7c568831SAndroid Build Coastguard Worker #include <libxml/parser.h>
22*7c568831SAndroid Build Coastguard Worker #include <libxml/tree.h>
23*7c568831SAndroid Build Coastguard Worker 
24*7c568831SAndroid Build Coastguard Worker #include "private/buf.h"
25*7c568831SAndroid Build Coastguard Worker 
26*7c568831SAndroid Build Coastguard Worker #ifndef SIZE_MAX
27*7c568831SAndroid Build Coastguard Worker #define SIZE_MAX ((size_t) -1)
28*7c568831SAndroid Build Coastguard Worker #endif
29*7c568831SAndroid Build Coastguard Worker 
30*7c568831SAndroid Build Coastguard Worker #define WITH_BUFFER_COMPAT
31*7c568831SAndroid Build Coastguard Worker 
32*7c568831SAndroid Build Coastguard Worker #define BUF_FLAG_OOM        (1u << 0)
33*7c568831SAndroid Build Coastguard Worker #define BUF_FLAG_OVERFLOW   (1u << 1)
34*7c568831SAndroid Build Coastguard Worker #define BUF_FLAG_STATIC     (1u << 2)
35*7c568831SAndroid Build Coastguard Worker 
36*7c568831SAndroid Build Coastguard Worker #define BUF_ERROR(buf) ((buf)->flags & (BUF_FLAG_OOM | BUF_FLAG_OVERFLOW))
37*7c568831SAndroid Build Coastguard Worker #define BUF_STATIC(buf) ((buf)->flags & BUF_FLAG_STATIC)
38*7c568831SAndroid Build Coastguard Worker 
39*7c568831SAndroid Build Coastguard Worker /**
40*7c568831SAndroid Build Coastguard Worker  * xmlBuf:
41*7c568831SAndroid Build Coastguard Worker  *
42*7c568831SAndroid Build Coastguard Worker  * A buffer structure. The base of the structure is somehow compatible
43*7c568831SAndroid Build Coastguard Worker  * with struct _xmlBuffer to limit risks on application which accessed
44*7c568831SAndroid Build Coastguard Worker  * directly the input->buf->buffer structures.
45*7c568831SAndroid Build Coastguard Worker  */
46*7c568831SAndroid Build Coastguard Worker 
47*7c568831SAndroid Build Coastguard Worker struct _xmlBuf {
48*7c568831SAndroid Build Coastguard Worker     xmlChar *content;		/* The buffer content UTF8 */
49*7c568831SAndroid Build Coastguard Worker #ifdef WITH_BUFFER_COMPAT
50*7c568831SAndroid Build Coastguard Worker     unsigned int compat_use;    /* for binary compatibility */
51*7c568831SAndroid Build Coastguard Worker     unsigned int compat_size;   /* for binary compatibility */
52*7c568831SAndroid Build Coastguard Worker #endif
53*7c568831SAndroid Build Coastguard Worker     xmlChar *mem;		/* Start of the allocation */
54*7c568831SAndroid Build Coastguard Worker     size_t use;		        /* The buffer size used */
55*7c568831SAndroid Build Coastguard Worker     size_t size;		/* The buffer size, excluding terminating 0 */
56*7c568831SAndroid Build Coastguard Worker     size_t maxSize;             /* The maximum buffer size */
57*7c568831SAndroid Build Coastguard Worker     unsigned flags;             /* flags */
58*7c568831SAndroid Build Coastguard Worker };
59*7c568831SAndroid Build Coastguard Worker 
60*7c568831SAndroid Build Coastguard Worker #ifdef WITH_BUFFER_COMPAT
61*7c568831SAndroid Build Coastguard Worker /*
62*7c568831SAndroid Build Coastguard Worker  * Macro for compatibility with xmlBuffer to be used after an xmlBuf
63*7c568831SAndroid Build Coastguard Worker  * is updated. This makes sure the compat fields are updated too.
64*7c568831SAndroid Build Coastguard Worker  */
65*7c568831SAndroid Build Coastguard Worker #define UPDATE_COMPAT(buf)				    \
66*7c568831SAndroid Build Coastguard Worker      if (buf->size < INT_MAX) buf->compat_size = buf->size; \
67*7c568831SAndroid Build Coastguard Worker      else buf->compat_size = INT_MAX;			    \
68*7c568831SAndroid Build Coastguard Worker      if (buf->use < INT_MAX) buf->compat_use = buf->use; \
69*7c568831SAndroid Build Coastguard Worker      else buf->compat_use = INT_MAX;
70*7c568831SAndroid Build Coastguard Worker 
71*7c568831SAndroid Build Coastguard Worker /*
72*7c568831SAndroid Build Coastguard Worker  * Macro for compatibility with xmlBuffer to be used in all the xmlBuf
73*7c568831SAndroid Build Coastguard Worker  * entry points, it checks that the compat fields have not been modified
74*7c568831SAndroid Build Coastguard Worker  * by direct call to xmlBuffer function from code compiled before 2.9.0 .
75*7c568831SAndroid Build Coastguard Worker  */
76*7c568831SAndroid Build Coastguard Worker #define CHECK_COMPAT(buf)				    \
77*7c568831SAndroid Build Coastguard Worker      if (buf->size != (size_t) buf->compat_size)	    \
78*7c568831SAndroid Build Coastguard Worker          if (buf->compat_size < INT_MAX)		    \
79*7c568831SAndroid Build Coastguard Worker 	     buf->size = buf->compat_size;		    \
80*7c568831SAndroid Build Coastguard Worker      if (buf->use != (size_t) buf->compat_use)		    \
81*7c568831SAndroid Build Coastguard Worker          if (buf->compat_use < INT_MAX)			    \
82*7c568831SAndroid Build Coastguard Worker 	     buf->use = buf->compat_use;
83*7c568831SAndroid Build Coastguard Worker 
84*7c568831SAndroid Build Coastguard Worker #else /* ! WITH_BUFFER_COMPAT */
85*7c568831SAndroid Build Coastguard Worker #define UPDATE_COMPAT(buf)
86*7c568831SAndroid Build Coastguard Worker #define CHECK_COMPAT(buf)
87*7c568831SAndroid Build Coastguard Worker #endif /* WITH_BUFFER_COMPAT */
88*7c568831SAndroid Build Coastguard Worker 
89*7c568831SAndroid Build Coastguard Worker /**
90*7c568831SAndroid Build Coastguard Worker  * xmlBufMemoryError:
91*7c568831SAndroid Build Coastguard Worker  * @extra:  extra information
92*7c568831SAndroid Build Coastguard Worker  *
93*7c568831SAndroid Build Coastguard Worker  * Handle an out of memory condition
94*7c568831SAndroid Build Coastguard Worker  * To be improved...
95*7c568831SAndroid Build Coastguard Worker  */
96*7c568831SAndroid Build Coastguard Worker static void
xmlBufMemoryError(xmlBufPtr buf)97*7c568831SAndroid Build Coastguard Worker xmlBufMemoryError(xmlBufPtr buf)
98*7c568831SAndroid Build Coastguard Worker {
99*7c568831SAndroid Build Coastguard Worker     if (!BUF_ERROR(buf))
100*7c568831SAndroid Build Coastguard Worker         buf->flags |= BUF_FLAG_OOM;
101*7c568831SAndroid Build Coastguard Worker }
102*7c568831SAndroid Build Coastguard Worker 
103*7c568831SAndroid Build Coastguard Worker /**
104*7c568831SAndroid Build Coastguard Worker  * xmlBufOverflowError:
105*7c568831SAndroid Build Coastguard Worker  * @extra:  extra information
106*7c568831SAndroid Build Coastguard Worker  *
107*7c568831SAndroid Build Coastguard Worker  * Handle a buffer overflow error
108*7c568831SAndroid Build Coastguard Worker  * To be improved...
109*7c568831SAndroid Build Coastguard Worker  */
110*7c568831SAndroid Build Coastguard Worker static void
xmlBufOverflowError(xmlBufPtr buf)111*7c568831SAndroid Build Coastguard Worker xmlBufOverflowError(xmlBufPtr buf)
112*7c568831SAndroid Build Coastguard Worker {
113*7c568831SAndroid Build Coastguard Worker     if (!BUF_ERROR(buf))
114*7c568831SAndroid Build Coastguard Worker         buf->flags |= BUF_FLAG_OVERFLOW;
115*7c568831SAndroid Build Coastguard Worker }
116*7c568831SAndroid Build Coastguard Worker 
117*7c568831SAndroid Build Coastguard Worker /**
118*7c568831SAndroid Build Coastguard Worker  * xmlBufCreate:
119*7c568831SAndroid Build Coastguard Worker  * @size: initial size of buffer
120*7c568831SAndroid Build Coastguard Worker  *
121*7c568831SAndroid Build Coastguard Worker  * routine to create an XML buffer.
122*7c568831SAndroid Build Coastguard Worker  * returns the new structure.
123*7c568831SAndroid Build Coastguard Worker  */
124*7c568831SAndroid Build Coastguard Worker xmlBufPtr
xmlBufCreate(size_t size)125*7c568831SAndroid Build Coastguard Worker xmlBufCreate(size_t size) {
126*7c568831SAndroid Build Coastguard Worker     xmlBufPtr ret;
127*7c568831SAndroid Build Coastguard Worker 
128*7c568831SAndroid Build Coastguard Worker     if (size == SIZE_MAX)
129*7c568831SAndroid Build Coastguard Worker         return(NULL);
130*7c568831SAndroid Build Coastguard Worker 
131*7c568831SAndroid Build Coastguard Worker     ret = xmlMalloc(sizeof(*ret));
132*7c568831SAndroid Build Coastguard Worker     if (ret == NULL)
133*7c568831SAndroid Build Coastguard Worker         return(NULL);
134*7c568831SAndroid Build Coastguard Worker 
135*7c568831SAndroid Build Coastguard Worker     ret->use = 0;
136*7c568831SAndroid Build Coastguard Worker     ret->flags = 0;
137*7c568831SAndroid Build Coastguard Worker     ret->size = size;
138*7c568831SAndroid Build Coastguard Worker     ret->maxSize = SIZE_MAX - 1;
139*7c568831SAndroid Build Coastguard Worker 
140*7c568831SAndroid Build Coastguard Worker     ret->mem = xmlMalloc(ret->size + 1);
141*7c568831SAndroid Build Coastguard Worker     if (ret->mem == NULL) {
142*7c568831SAndroid Build Coastguard Worker         xmlFree(ret);
143*7c568831SAndroid Build Coastguard Worker         return(NULL);
144*7c568831SAndroid Build Coastguard Worker     }
145*7c568831SAndroid Build Coastguard Worker     ret->content = ret->mem;
146*7c568831SAndroid Build Coastguard Worker     ret->content[0] = 0;
147*7c568831SAndroid Build Coastguard Worker 
148*7c568831SAndroid Build Coastguard Worker     UPDATE_COMPAT(ret);
149*7c568831SAndroid Build Coastguard Worker     return(ret);
150*7c568831SAndroid Build Coastguard Worker }
151*7c568831SAndroid Build Coastguard Worker 
152*7c568831SAndroid Build Coastguard Worker /**
153*7c568831SAndroid Build Coastguard Worker  * xmlBufCreateMem:
154*7c568831SAndroid Build Coastguard Worker  * @mem:  a memory area
155*7c568831SAndroid Build Coastguard Worker  * @size:  size of the buffer excluding terminator
156*7c568831SAndroid Build Coastguard Worker  * @isStatic:  whether the memory area is static
157*7c568831SAndroid Build Coastguard Worker  *
158*7c568831SAndroid Build Coastguard Worker  * Create a buffer initialized with memory.
159*7c568831SAndroid Build Coastguard Worker  *
160*7c568831SAndroid Build Coastguard Worker  * If @isStatic is set, uses the memory area directly as backing store.
161*7c568831SAndroid Build Coastguard Worker  * The memory must be zero-terminated and not be modified for the
162*7c568831SAndroid Build Coastguard Worker  * lifetime of the buffer. A static buffer can't be grown, modified or
163*7c568831SAndroid Build Coastguard Worker  * detached, but it can be shrunk.
164*7c568831SAndroid Build Coastguard Worker  *
165*7c568831SAndroid Build Coastguard Worker  * Returns a new buffer.
166*7c568831SAndroid Build Coastguard Worker  */
167*7c568831SAndroid Build Coastguard Worker xmlBufPtr
xmlBufCreateMem(const xmlChar * mem,size_t size,int isStatic)168*7c568831SAndroid Build Coastguard Worker xmlBufCreateMem(const xmlChar *mem, size_t size, int isStatic) {
169*7c568831SAndroid Build Coastguard Worker     xmlBufPtr ret;
170*7c568831SAndroid Build Coastguard Worker 
171*7c568831SAndroid Build Coastguard Worker     if (mem == NULL)
172*7c568831SAndroid Build Coastguard Worker         return(NULL);
173*7c568831SAndroid Build Coastguard Worker 
174*7c568831SAndroid Build Coastguard Worker     ret = xmlMalloc(sizeof(*ret));
175*7c568831SAndroid Build Coastguard Worker     if (ret == NULL)
176*7c568831SAndroid Build Coastguard Worker         return(NULL);
177*7c568831SAndroid Build Coastguard Worker 
178*7c568831SAndroid Build Coastguard Worker     if (isStatic) {
179*7c568831SAndroid Build Coastguard Worker         /* Check that memory is zero-terminated */
180*7c568831SAndroid Build Coastguard Worker         if (mem[size] != 0) {
181*7c568831SAndroid Build Coastguard Worker             xmlFree(ret);
182*7c568831SAndroid Build Coastguard Worker             return(NULL);
183*7c568831SAndroid Build Coastguard Worker         }
184*7c568831SAndroid Build Coastguard Worker         ret->flags = BUF_FLAG_STATIC;
185*7c568831SAndroid Build Coastguard Worker         ret->mem = (xmlChar *) mem;
186*7c568831SAndroid Build Coastguard Worker     } else {
187*7c568831SAndroid Build Coastguard Worker         ret->flags = 0;
188*7c568831SAndroid Build Coastguard Worker         ret->mem = xmlMalloc(size + 1);
189*7c568831SAndroid Build Coastguard Worker         if (ret->mem == NULL) {
190*7c568831SAndroid Build Coastguard Worker             xmlFree(ret);
191*7c568831SAndroid Build Coastguard Worker             return(NULL);
192*7c568831SAndroid Build Coastguard Worker         }
193*7c568831SAndroid Build Coastguard Worker         memcpy(ret->mem, mem, size);
194*7c568831SAndroid Build Coastguard Worker         ret->mem[size] = 0;
195*7c568831SAndroid Build Coastguard Worker     }
196*7c568831SAndroid Build Coastguard Worker 
197*7c568831SAndroid Build Coastguard Worker     ret->use = size;
198*7c568831SAndroid Build Coastguard Worker     ret->size = size;
199*7c568831SAndroid Build Coastguard Worker     ret->maxSize = SIZE_MAX - 1;
200*7c568831SAndroid Build Coastguard Worker     ret->content = ret->mem;
201*7c568831SAndroid Build Coastguard Worker 
202*7c568831SAndroid Build Coastguard Worker     UPDATE_COMPAT(ret);
203*7c568831SAndroid Build Coastguard Worker     return(ret);
204*7c568831SAndroid Build Coastguard Worker }
205*7c568831SAndroid Build Coastguard Worker 
206*7c568831SAndroid Build Coastguard Worker /**
207*7c568831SAndroid Build Coastguard Worker  * xmlBufDetach:
208*7c568831SAndroid Build Coastguard Worker  * @buf:  the buffer
209*7c568831SAndroid Build Coastguard Worker  *
210*7c568831SAndroid Build Coastguard Worker  * Remove the string contained in a buffer and give it back to the
211*7c568831SAndroid Build Coastguard Worker  * caller. The buffer is reset to an empty content.
212*7c568831SAndroid Build Coastguard Worker  * This doesn't work with immutable buffers as they can't be reset.
213*7c568831SAndroid Build Coastguard Worker  *
214*7c568831SAndroid Build Coastguard Worker  * Returns the previous string contained by the buffer.
215*7c568831SAndroid Build Coastguard Worker  */
216*7c568831SAndroid Build Coastguard Worker xmlChar *
xmlBufDetach(xmlBufPtr buf)217*7c568831SAndroid Build Coastguard Worker xmlBufDetach(xmlBufPtr buf) {
218*7c568831SAndroid Build Coastguard Worker     xmlChar *ret;
219*7c568831SAndroid Build Coastguard Worker 
220*7c568831SAndroid Build Coastguard Worker     if ((buf == NULL) || (BUF_ERROR(buf)) || (BUF_STATIC(buf)))
221*7c568831SAndroid Build Coastguard Worker         return(NULL);
222*7c568831SAndroid Build Coastguard Worker 
223*7c568831SAndroid Build Coastguard Worker     if (buf->content != buf->mem) {
224*7c568831SAndroid Build Coastguard Worker         ret = xmlStrndup(buf->content, buf->use);
225*7c568831SAndroid Build Coastguard Worker         xmlFree(buf->mem);
226*7c568831SAndroid Build Coastguard Worker     } else {
227*7c568831SAndroid Build Coastguard Worker         ret = buf->mem;
228*7c568831SAndroid Build Coastguard Worker     }
229*7c568831SAndroid Build Coastguard Worker 
230*7c568831SAndroid Build Coastguard Worker     buf->content = NULL;
231*7c568831SAndroid Build Coastguard Worker     buf->mem = NULL;
232*7c568831SAndroid Build Coastguard Worker     buf->size = 0;
233*7c568831SAndroid Build Coastguard Worker     buf->use = 0;
234*7c568831SAndroid Build Coastguard Worker 
235*7c568831SAndroid Build Coastguard Worker     UPDATE_COMPAT(buf);
236*7c568831SAndroid Build Coastguard Worker     return ret;
237*7c568831SAndroid Build Coastguard Worker }
238*7c568831SAndroid Build Coastguard Worker 
239*7c568831SAndroid Build Coastguard Worker /**
240*7c568831SAndroid Build Coastguard Worker  * xmlBufFree:
241*7c568831SAndroid Build Coastguard Worker  * @buf:  the buffer to free
242*7c568831SAndroid Build Coastguard Worker  *
243*7c568831SAndroid Build Coastguard Worker  * Frees an XML buffer. It frees both the content and the structure which
244*7c568831SAndroid Build Coastguard Worker  * encapsulate it.
245*7c568831SAndroid Build Coastguard Worker  */
246*7c568831SAndroid Build Coastguard Worker void
xmlBufFree(xmlBufPtr buf)247*7c568831SAndroid Build Coastguard Worker xmlBufFree(xmlBufPtr buf) {
248*7c568831SAndroid Build Coastguard Worker     if (buf == NULL)
249*7c568831SAndroid Build Coastguard Worker 	return;
250*7c568831SAndroid Build Coastguard Worker 
251*7c568831SAndroid Build Coastguard Worker     if (!BUF_STATIC(buf))
252*7c568831SAndroid Build Coastguard Worker         xmlFree(buf->mem);
253*7c568831SAndroid Build Coastguard Worker     xmlFree(buf);
254*7c568831SAndroid Build Coastguard Worker }
255*7c568831SAndroid Build Coastguard Worker 
256*7c568831SAndroid Build Coastguard Worker /**
257*7c568831SAndroid Build Coastguard Worker  * xmlBufEmpty:
258*7c568831SAndroid Build Coastguard Worker  * @buf:  the buffer
259*7c568831SAndroid Build Coastguard Worker  *
260*7c568831SAndroid Build Coastguard Worker  * empty a buffer.
261*7c568831SAndroid Build Coastguard Worker  */
262*7c568831SAndroid Build Coastguard Worker void
xmlBufEmpty(xmlBufPtr buf)263*7c568831SAndroid Build Coastguard Worker xmlBufEmpty(xmlBufPtr buf) {
264*7c568831SAndroid Build Coastguard Worker     if ((buf == NULL) || (BUF_ERROR(buf)) || (BUF_STATIC(buf)))
265*7c568831SAndroid Build Coastguard Worker         return;
266*7c568831SAndroid Build Coastguard Worker     if (buf->mem == NULL)
267*7c568831SAndroid Build Coastguard Worker         return;
268*7c568831SAndroid Build Coastguard Worker     CHECK_COMPAT(buf)
269*7c568831SAndroid Build Coastguard Worker 
270*7c568831SAndroid Build Coastguard Worker     buf->use = 0;
271*7c568831SAndroid Build Coastguard Worker     buf->size += buf->content - buf->mem;
272*7c568831SAndroid Build Coastguard Worker     buf->content = buf->mem;
273*7c568831SAndroid Build Coastguard Worker     buf->content[0] = 0;
274*7c568831SAndroid Build Coastguard Worker 
275*7c568831SAndroid Build Coastguard Worker     UPDATE_COMPAT(buf)
276*7c568831SAndroid Build Coastguard Worker }
277*7c568831SAndroid Build Coastguard Worker 
278*7c568831SAndroid Build Coastguard Worker /**
279*7c568831SAndroid Build Coastguard Worker  * xmlBufShrink:
280*7c568831SAndroid Build Coastguard Worker  * @buf:  the buffer to dump
281*7c568831SAndroid Build Coastguard Worker  * @len:  the number of xmlChar to remove
282*7c568831SAndroid Build Coastguard Worker  *
283*7c568831SAndroid Build Coastguard Worker  * DEPRECATED: Don't use.
284*7c568831SAndroid Build Coastguard Worker  *
285*7c568831SAndroid Build Coastguard Worker  * Remove the beginning of an XML buffer.
286*7c568831SAndroid Build Coastguard Worker  * NOTE that this routine behaviour differs from xmlBufferShrink()
287*7c568831SAndroid Build Coastguard Worker  * as it will return 0 on error instead of -1 due to size_t being
288*7c568831SAndroid Build Coastguard Worker  * used as the return type.
289*7c568831SAndroid Build Coastguard Worker  *
290*7c568831SAndroid Build Coastguard Worker  * Returns the number of byte removed or 0 in case of failure
291*7c568831SAndroid Build Coastguard Worker  */
292*7c568831SAndroid Build Coastguard Worker size_t
xmlBufShrink(xmlBufPtr buf,size_t len)293*7c568831SAndroid Build Coastguard Worker xmlBufShrink(xmlBufPtr buf, size_t len) {
294*7c568831SAndroid Build Coastguard Worker     if ((buf == NULL) || (BUF_ERROR(buf)))
295*7c568831SAndroid Build Coastguard Worker         return(0);
296*7c568831SAndroid Build Coastguard Worker     if (len == 0)
297*7c568831SAndroid Build Coastguard Worker         return(0);
298*7c568831SAndroid Build Coastguard Worker     CHECK_COMPAT(buf)
299*7c568831SAndroid Build Coastguard Worker 
300*7c568831SAndroid Build Coastguard Worker     if (len > buf->use)
301*7c568831SAndroid Build Coastguard Worker         return(0);
302*7c568831SAndroid Build Coastguard Worker 
303*7c568831SAndroid Build Coastguard Worker     buf->use -= len;
304*7c568831SAndroid Build Coastguard Worker     buf->content += len;
305*7c568831SAndroid Build Coastguard Worker     buf->size -= len;
306*7c568831SAndroid Build Coastguard Worker 
307*7c568831SAndroid Build Coastguard Worker     UPDATE_COMPAT(buf)
308*7c568831SAndroid Build Coastguard Worker     return(len);
309*7c568831SAndroid Build Coastguard Worker }
310*7c568831SAndroid Build Coastguard Worker 
311*7c568831SAndroid Build Coastguard Worker /**
312*7c568831SAndroid Build Coastguard Worker  * xmlBufGrowInternal:
313*7c568831SAndroid Build Coastguard Worker  * @buf:  the buffer
314*7c568831SAndroid Build Coastguard Worker  * @len:  the minimum free size to allocate
315*7c568831SAndroid Build Coastguard Worker  *
316*7c568831SAndroid Build Coastguard Worker  * Grow the available space of an XML buffer, @len is the target value
317*7c568831SAndroid Build Coastguard Worker  *
318*7c568831SAndroid Build Coastguard Worker  * Returns 0 on success, -1 in case of error
319*7c568831SAndroid Build Coastguard Worker  */
320*7c568831SAndroid Build Coastguard Worker static int
xmlBufGrowInternal(xmlBufPtr buf,size_t len)321*7c568831SAndroid Build Coastguard Worker xmlBufGrowInternal(xmlBufPtr buf, size_t len) {
322*7c568831SAndroid Build Coastguard Worker     size_t size;
323*7c568831SAndroid Build Coastguard Worker     size_t start;
324*7c568831SAndroid Build Coastguard Worker     xmlChar *newbuf;
325*7c568831SAndroid Build Coastguard Worker 
326*7c568831SAndroid Build Coastguard Worker     /*
327*7c568831SAndroid Build Coastguard Worker      * If there's enough space at the start of the buffer,
328*7c568831SAndroid Build Coastguard Worker      * move the contents.
329*7c568831SAndroid Build Coastguard Worker      */
330*7c568831SAndroid Build Coastguard Worker     start = buf->content - buf->mem;
331*7c568831SAndroid Build Coastguard Worker     if (len <= start + buf->size - buf->use) {
332*7c568831SAndroid Build Coastguard Worker         memmove(buf->mem, buf->content, buf->use + 1);
333*7c568831SAndroid Build Coastguard Worker         buf->size += start;
334*7c568831SAndroid Build Coastguard Worker         buf->content = buf->mem;
335*7c568831SAndroid Build Coastguard Worker         return(0);
336*7c568831SAndroid Build Coastguard Worker     }
337*7c568831SAndroid Build Coastguard Worker 
338*7c568831SAndroid Build Coastguard Worker     if (len > buf->maxSize - buf->use) {
339*7c568831SAndroid Build Coastguard Worker         xmlBufOverflowError(buf);
340*7c568831SAndroid Build Coastguard Worker         return(-1);
341*7c568831SAndroid Build Coastguard Worker     }
342*7c568831SAndroid Build Coastguard Worker 
343*7c568831SAndroid Build Coastguard Worker     if (buf->size > (size_t) len) {
344*7c568831SAndroid Build Coastguard Worker         if (buf->size <= buf->maxSize / 2)
345*7c568831SAndroid Build Coastguard Worker             size = buf->size * 2;
346*7c568831SAndroid Build Coastguard Worker         else
347*7c568831SAndroid Build Coastguard Worker             size = buf->maxSize;
348*7c568831SAndroid Build Coastguard Worker     } else {
349*7c568831SAndroid Build Coastguard Worker         size = buf->use + len;
350*7c568831SAndroid Build Coastguard Worker         if (size <= buf->maxSize - 100)
351*7c568831SAndroid Build Coastguard Worker             size += 100;
352*7c568831SAndroid Build Coastguard Worker     }
353*7c568831SAndroid Build Coastguard Worker 
354*7c568831SAndroid Build Coastguard Worker     if (buf->content == buf->mem) {
355*7c568831SAndroid Build Coastguard Worker         newbuf = xmlRealloc(buf->mem, size + 1);
356*7c568831SAndroid Build Coastguard Worker         if (newbuf == NULL) {
357*7c568831SAndroid Build Coastguard Worker             xmlBufMemoryError(buf);
358*7c568831SAndroid Build Coastguard Worker             return(-1);
359*7c568831SAndroid Build Coastguard Worker         }
360*7c568831SAndroid Build Coastguard Worker     } else {
361*7c568831SAndroid Build Coastguard Worker         newbuf = xmlMalloc(size + 1);
362*7c568831SAndroid Build Coastguard Worker         if (newbuf == NULL) {
363*7c568831SAndroid Build Coastguard Worker             xmlBufMemoryError(buf);
364*7c568831SAndroid Build Coastguard Worker             return(-1);
365*7c568831SAndroid Build Coastguard Worker         }
366*7c568831SAndroid Build Coastguard Worker         if (buf->content != NULL)
367*7c568831SAndroid Build Coastguard Worker             memcpy(newbuf, buf->content, buf->use + 1);
368*7c568831SAndroid Build Coastguard Worker         xmlFree(buf->mem);
369*7c568831SAndroid Build Coastguard Worker     }
370*7c568831SAndroid Build Coastguard Worker 
371*7c568831SAndroid Build Coastguard Worker     buf->mem = newbuf;
372*7c568831SAndroid Build Coastguard Worker     buf->content = newbuf;
373*7c568831SAndroid Build Coastguard Worker     buf->size = size;
374*7c568831SAndroid Build Coastguard Worker 
375*7c568831SAndroid Build Coastguard Worker     return(0);
376*7c568831SAndroid Build Coastguard Worker }
377*7c568831SAndroid Build Coastguard Worker 
378*7c568831SAndroid Build Coastguard Worker /**
379*7c568831SAndroid Build Coastguard Worker  * xmlBufGrow:
380*7c568831SAndroid Build Coastguard Worker  * @buf:  the buffer
381*7c568831SAndroid Build Coastguard Worker  * @len:  the minimum free size to allocate
382*7c568831SAndroid Build Coastguard Worker  *
383*7c568831SAndroid Build Coastguard Worker  * Grow the available space of an XML buffer, @len is the target value
384*7c568831SAndroid Build Coastguard Worker  * This is been kept compatible with xmlBufferGrow() as much as possible
385*7c568831SAndroid Build Coastguard Worker  *
386*7c568831SAndroid Build Coastguard Worker  * Returns 0 on succes, -1 in case of error
387*7c568831SAndroid Build Coastguard Worker  */
388*7c568831SAndroid Build Coastguard Worker int
xmlBufGrow(xmlBufPtr buf,size_t len)389*7c568831SAndroid Build Coastguard Worker xmlBufGrow(xmlBufPtr buf, size_t len) {
390*7c568831SAndroid Build Coastguard Worker     if ((buf == NULL) || (BUF_ERROR(buf)) || (BUF_STATIC(buf)))
391*7c568831SAndroid Build Coastguard Worker         return(-1);
392*7c568831SAndroid Build Coastguard Worker     CHECK_COMPAT(buf)
393*7c568831SAndroid Build Coastguard Worker 
394*7c568831SAndroid Build Coastguard Worker     if (len <= buf->size - buf->use)
395*7c568831SAndroid Build Coastguard Worker         return(0);
396*7c568831SAndroid Build Coastguard Worker 
397*7c568831SAndroid Build Coastguard Worker     if (xmlBufGrowInternal(buf, len) < 0)
398*7c568831SAndroid Build Coastguard Worker         return(-1);
399*7c568831SAndroid Build Coastguard Worker 
400*7c568831SAndroid Build Coastguard Worker     UPDATE_COMPAT(buf)
401*7c568831SAndroid Build Coastguard Worker     return(0);
402*7c568831SAndroid Build Coastguard Worker }
403*7c568831SAndroid Build Coastguard Worker 
404*7c568831SAndroid Build Coastguard Worker /**
405*7c568831SAndroid Build Coastguard Worker  * xmlBufContent:
406*7c568831SAndroid Build Coastguard Worker  * @buf:  the buffer
407*7c568831SAndroid Build Coastguard Worker  *
408*7c568831SAndroid Build Coastguard Worker  * Function to extract the content of a buffer
409*7c568831SAndroid Build Coastguard Worker  *
410*7c568831SAndroid Build Coastguard Worker  * Returns the internal content
411*7c568831SAndroid Build Coastguard Worker  */
412*7c568831SAndroid Build Coastguard Worker 
413*7c568831SAndroid Build Coastguard Worker xmlChar *
xmlBufContent(const xmlBuf * buf)414*7c568831SAndroid Build Coastguard Worker xmlBufContent(const xmlBuf *buf)
415*7c568831SAndroid Build Coastguard Worker {
416*7c568831SAndroid Build Coastguard Worker     if ((!buf) || (BUF_ERROR(buf)))
417*7c568831SAndroid Build Coastguard Worker         return NULL;
418*7c568831SAndroid Build Coastguard Worker 
419*7c568831SAndroid Build Coastguard Worker     return(buf->content);
420*7c568831SAndroid Build Coastguard Worker }
421*7c568831SAndroid Build Coastguard Worker 
422*7c568831SAndroid Build Coastguard Worker /**
423*7c568831SAndroid Build Coastguard Worker  * xmlBufEnd:
424*7c568831SAndroid Build Coastguard Worker  * @buf:  the buffer
425*7c568831SAndroid Build Coastguard Worker  *
426*7c568831SAndroid Build Coastguard Worker  * Function to extract the end of the content of a buffer
427*7c568831SAndroid Build Coastguard Worker  *
428*7c568831SAndroid Build Coastguard Worker  * Returns the end of the internal content or NULL in case of error
429*7c568831SAndroid Build Coastguard Worker  */
430*7c568831SAndroid Build Coastguard Worker 
431*7c568831SAndroid Build Coastguard Worker xmlChar *
xmlBufEnd(xmlBufPtr buf)432*7c568831SAndroid Build Coastguard Worker xmlBufEnd(xmlBufPtr buf)
433*7c568831SAndroid Build Coastguard Worker {
434*7c568831SAndroid Build Coastguard Worker     if ((!buf) || (BUF_ERROR(buf)))
435*7c568831SAndroid Build Coastguard Worker         return NULL;
436*7c568831SAndroid Build Coastguard Worker     CHECK_COMPAT(buf)
437*7c568831SAndroid Build Coastguard Worker 
438*7c568831SAndroid Build Coastguard Worker     return(&buf->content[buf->use]);
439*7c568831SAndroid Build Coastguard Worker }
440*7c568831SAndroid Build Coastguard Worker 
441*7c568831SAndroid Build Coastguard Worker /**
442*7c568831SAndroid Build Coastguard Worker  * xmlBufAddLen:
443*7c568831SAndroid Build Coastguard Worker  * @buf:  the buffer
444*7c568831SAndroid Build Coastguard Worker  * @len:  the size which were added at the end
445*7c568831SAndroid Build Coastguard Worker  *
446*7c568831SAndroid Build Coastguard Worker  * Sometime data may be added at the end of the buffer without
447*7c568831SAndroid Build Coastguard Worker  * using the xmlBuf APIs that is used to expand the used space
448*7c568831SAndroid Build Coastguard Worker  * and set the zero terminating at the end of the buffer
449*7c568831SAndroid Build Coastguard Worker  *
450*7c568831SAndroid Build Coastguard Worker  * Returns -1 in case of error and 0 otherwise
451*7c568831SAndroid Build Coastguard Worker  */
452*7c568831SAndroid Build Coastguard Worker int
xmlBufAddLen(xmlBufPtr buf,size_t len)453*7c568831SAndroid Build Coastguard Worker xmlBufAddLen(xmlBufPtr buf, size_t len) {
454*7c568831SAndroid Build Coastguard Worker     if ((buf == NULL) || (BUF_ERROR(buf)) || (BUF_STATIC(buf)))
455*7c568831SAndroid Build Coastguard Worker         return(-1);
456*7c568831SAndroid Build Coastguard Worker     CHECK_COMPAT(buf)
457*7c568831SAndroid Build Coastguard Worker     if (len > buf->size - buf->use)
458*7c568831SAndroid Build Coastguard Worker         return(-1);
459*7c568831SAndroid Build Coastguard Worker     buf->use += len;
460*7c568831SAndroid Build Coastguard Worker     buf->content[buf->use] = 0;
461*7c568831SAndroid Build Coastguard Worker     UPDATE_COMPAT(buf)
462*7c568831SAndroid Build Coastguard Worker     return(0);
463*7c568831SAndroid Build Coastguard Worker }
464*7c568831SAndroid Build Coastguard Worker 
465*7c568831SAndroid Build Coastguard Worker /**
466*7c568831SAndroid Build Coastguard Worker  * xmlBufUse:
467*7c568831SAndroid Build Coastguard Worker  * @buf:  the buffer
468*7c568831SAndroid Build Coastguard Worker  *
469*7c568831SAndroid Build Coastguard Worker  * Function to get the length of a buffer
470*7c568831SAndroid Build Coastguard Worker  *
471*7c568831SAndroid Build Coastguard Worker  * Returns the length of data in the internal content
472*7c568831SAndroid Build Coastguard Worker  */
473*7c568831SAndroid Build Coastguard Worker 
474*7c568831SAndroid Build Coastguard Worker size_t
xmlBufUse(const xmlBufPtr buf)475*7c568831SAndroid Build Coastguard Worker xmlBufUse(const xmlBufPtr buf)
476*7c568831SAndroid Build Coastguard Worker {
477*7c568831SAndroid Build Coastguard Worker     if ((!buf) || (BUF_ERROR(buf)))
478*7c568831SAndroid Build Coastguard Worker         return 0;
479*7c568831SAndroid Build Coastguard Worker     CHECK_COMPAT(buf)
480*7c568831SAndroid Build Coastguard Worker 
481*7c568831SAndroid Build Coastguard Worker     return(buf->use);
482*7c568831SAndroid Build Coastguard Worker }
483*7c568831SAndroid Build Coastguard Worker 
484*7c568831SAndroid Build Coastguard Worker /**
485*7c568831SAndroid Build Coastguard Worker  * xmlBufAvail:
486*7c568831SAndroid Build Coastguard Worker  * @buf:  the buffer
487*7c568831SAndroid Build Coastguard Worker  *
488*7c568831SAndroid Build Coastguard Worker  * Function to find how much free space is allocated but not
489*7c568831SAndroid Build Coastguard Worker  * used in the buffer. It reserves one byte for the NUL
490*7c568831SAndroid Build Coastguard Worker  * terminator character that is usually needed, so there is
491*7c568831SAndroid Build Coastguard Worker  * no need to subtract 1 from the result anymore.
492*7c568831SAndroid Build Coastguard Worker  *
493*7c568831SAndroid Build Coastguard Worker  * Returns the amount, or 0 if none or if an error occurred.
494*7c568831SAndroid Build Coastguard Worker  */
495*7c568831SAndroid Build Coastguard Worker 
496*7c568831SAndroid Build Coastguard Worker size_t
xmlBufAvail(const xmlBufPtr buf)497*7c568831SAndroid Build Coastguard Worker xmlBufAvail(const xmlBufPtr buf)
498*7c568831SAndroid Build Coastguard Worker {
499*7c568831SAndroid Build Coastguard Worker     if ((!buf) || (BUF_ERROR(buf)))
500*7c568831SAndroid Build Coastguard Worker         return 0;
501*7c568831SAndroid Build Coastguard Worker     CHECK_COMPAT(buf)
502*7c568831SAndroid Build Coastguard Worker 
503*7c568831SAndroid Build Coastguard Worker     return(buf->size - buf->use);
504*7c568831SAndroid Build Coastguard Worker }
505*7c568831SAndroid Build Coastguard Worker 
506*7c568831SAndroid Build Coastguard Worker /**
507*7c568831SAndroid Build Coastguard Worker  * xmlBufIsEmpty:
508*7c568831SAndroid Build Coastguard Worker  * @buf:  the buffer
509*7c568831SAndroid Build Coastguard Worker  *
510*7c568831SAndroid Build Coastguard Worker  * Tell if a buffer is empty
511*7c568831SAndroid Build Coastguard Worker  *
512*7c568831SAndroid Build Coastguard Worker  * Returns 0 if no, 1 if yes and -1 in case of error
513*7c568831SAndroid Build Coastguard Worker  */
514*7c568831SAndroid Build Coastguard Worker int
xmlBufIsEmpty(const xmlBufPtr buf)515*7c568831SAndroid Build Coastguard Worker xmlBufIsEmpty(const xmlBufPtr buf)
516*7c568831SAndroid Build Coastguard Worker {
517*7c568831SAndroid Build Coastguard Worker     if ((!buf) || (BUF_ERROR(buf)))
518*7c568831SAndroid Build Coastguard Worker         return(-1);
519*7c568831SAndroid Build Coastguard Worker     CHECK_COMPAT(buf)
520*7c568831SAndroid Build Coastguard Worker 
521*7c568831SAndroid Build Coastguard Worker     return(buf->use == 0);
522*7c568831SAndroid Build Coastguard Worker }
523*7c568831SAndroid Build Coastguard Worker 
524*7c568831SAndroid Build Coastguard Worker /**
525*7c568831SAndroid Build Coastguard Worker  * xmlBufAdd:
526*7c568831SAndroid Build Coastguard Worker  * @buf:  the buffer to dump
527*7c568831SAndroid Build Coastguard Worker  * @str:  the #xmlChar string
528*7c568831SAndroid Build Coastguard Worker  * @len:  the number of #xmlChar to add
529*7c568831SAndroid Build Coastguard Worker  *
530*7c568831SAndroid Build Coastguard Worker  * Add a string range to an XML buffer. if len == -1, the length of
531*7c568831SAndroid Build Coastguard Worker  * str is recomputed.
532*7c568831SAndroid Build Coastguard Worker  *
533*7c568831SAndroid Build Coastguard Worker  * Returns 0 if successful, -1 in case of error.
534*7c568831SAndroid Build Coastguard Worker  */
535*7c568831SAndroid Build Coastguard Worker int
xmlBufAdd(xmlBufPtr buf,const xmlChar * str,size_t len)536*7c568831SAndroid Build Coastguard Worker xmlBufAdd(xmlBufPtr buf, const xmlChar *str, size_t len) {
537*7c568831SAndroid Build Coastguard Worker     if ((buf == NULL) || (BUF_ERROR(buf)) || (BUF_STATIC(buf)))
538*7c568831SAndroid Build Coastguard Worker         return(-1);
539*7c568831SAndroid Build Coastguard Worker     if (len == 0)
540*7c568831SAndroid Build Coastguard Worker         return(0);
541*7c568831SAndroid Build Coastguard Worker     if (str == NULL)
542*7c568831SAndroid Build Coastguard Worker 	return(-1);
543*7c568831SAndroid Build Coastguard Worker     CHECK_COMPAT(buf)
544*7c568831SAndroid Build Coastguard Worker 
545*7c568831SAndroid Build Coastguard Worker     if (len > buf->size - buf->use) {
546*7c568831SAndroid Build Coastguard Worker         if (xmlBufGrowInternal(buf, len) < 0)
547*7c568831SAndroid Build Coastguard Worker             return(-1);
548*7c568831SAndroid Build Coastguard Worker     }
549*7c568831SAndroid Build Coastguard Worker 
550*7c568831SAndroid Build Coastguard Worker     memmove(&buf->content[buf->use], str, len);
551*7c568831SAndroid Build Coastguard Worker     buf->use += len;
552*7c568831SAndroid Build Coastguard Worker     buf->content[buf->use] = 0;
553*7c568831SAndroid Build Coastguard Worker 
554*7c568831SAndroid Build Coastguard Worker     UPDATE_COMPAT(buf)
555*7c568831SAndroid Build Coastguard Worker     return(0);
556*7c568831SAndroid Build Coastguard Worker }
557*7c568831SAndroid Build Coastguard Worker 
558*7c568831SAndroid Build Coastguard Worker /**
559*7c568831SAndroid Build Coastguard Worker  * xmlBufCat:
560*7c568831SAndroid Build Coastguard Worker  * @buf:  the buffer to add to
561*7c568831SAndroid Build Coastguard Worker  * @str:  the #xmlChar string (optional)
562*7c568831SAndroid Build Coastguard Worker  *
563*7c568831SAndroid Build Coastguard Worker  * Append a zero terminated string to an XML buffer.
564*7c568831SAndroid Build Coastguard Worker  *
565*7c568831SAndroid Build Coastguard Worker  * Returns 0 successful, a positive error code number otherwise
566*7c568831SAndroid Build Coastguard Worker  *         and -1 in case of internal or API error.
567*7c568831SAndroid Build Coastguard Worker  */
568*7c568831SAndroid Build Coastguard Worker int
xmlBufCat(xmlBufPtr buf,const xmlChar * str)569*7c568831SAndroid Build Coastguard Worker xmlBufCat(xmlBufPtr buf, const xmlChar *str) {
570*7c568831SAndroid Build Coastguard Worker     if (str == NULL)
571*7c568831SAndroid Build Coastguard Worker         return(0);
572*7c568831SAndroid Build Coastguard Worker     return(xmlBufAdd(buf, str, strlen((const char *) str)));
573*7c568831SAndroid Build Coastguard Worker }
574*7c568831SAndroid Build Coastguard Worker 
575*7c568831SAndroid Build Coastguard Worker /**
576*7c568831SAndroid Build Coastguard Worker  * xmlBufFromBuffer:
577*7c568831SAndroid Build Coastguard Worker  * @buffer: incoming old buffer to convert to a new one
578*7c568831SAndroid Build Coastguard Worker  *
579*7c568831SAndroid Build Coastguard Worker  * Helper routine to switch from the old buffer structures in use
580*7c568831SAndroid Build Coastguard Worker  * in various APIs. It creates a wrapper xmlBufPtr which will be
581*7c568831SAndroid Build Coastguard Worker  * used for internal processing until the xmlBufBackToBuffer() is
582*7c568831SAndroid Build Coastguard Worker  * issued.
583*7c568831SAndroid Build Coastguard Worker  *
584*7c568831SAndroid Build Coastguard Worker  * Returns a new xmlBufPtr unless the call failed and NULL is returned
585*7c568831SAndroid Build Coastguard Worker  */
586*7c568831SAndroid Build Coastguard Worker xmlBufPtr
xmlBufFromBuffer(xmlBufferPtr buffer)587*7c568831SAndroid Build Coastguard Worker xmlBufFromBuffer(xmlBufferPtr buffer) {
588*7c568831SAndroid Build Coastguard Worker     xmlBufPtr ret;
589*7c568831SAndroid Build Coastguard Worker 
590*7c568831SAndroid Build Coastguard Worker     if (buffer == NULL)
591*7c568831SAndroid Build Coastguard Worker         return(NULL);
592*7c568831SAndroid Build Coastguard Worker 
593*7c568831SAndroid Build Coastguard Worker     ret = xmlMalloc(sizeof(xmlBuf));
594*7c568831SAndroid Build Coastguard Worker     if (ret == NULL)
595*7c568831SAndroid Build Coastguard Worker         return(NULL);
596*7c568831SAndroid Build Coastguard Worker 
597*7c568831SAndroid Build Coastguard Worker     ret->use = buffer->use;
598*7c568831SAndroid Build Coastguard Worker     ret->flags = 0;
599*7c568831SAndroid Build Coastguard Worker     ret->maxSize = SIZE_MAX - 1;
600*7c568831SAndroid Build Coastguard Worker 
601*7c568831SAndroid Build Coastguard Worker     if (buffer->content == NULL) {
602*7c568831SAndroid Build Coastguard Worker         ret->size = 50;
603*7c568831SAndroid Build Coastguard Worker         ret->mem = xmlMalloc(ret->size + 1);
604*7c568831SAndroid Build Coastguard Worker         ret->content = ret->mem;
605*7c568831SAndroid Build Coastguard Worker         if (ret->mem == NULL)
606*7c568831SAndroid Build Coastguard Worker             xmlBufMemoryError(ret);
607*7c568831SAndroid Build Coastguard Worker         else
608*7c568831SAndroid Build Coastguard Worker             ret->content[0] = 0;
609*7c568831SAndroid Build Coastguard Worker     } else {
610*7c568831SAndroid Build Coastguard Worker         ret->size = buffer->size - 1;
611*7c568831SAndroid Build Coastguard Worker         ret->content = buffer->content;
612*7c568831SAndroid Build Coastguard Worker         if (buffer->alloc == XML_BUFFER_ALLOC_IO)
613*7c568831SAndroid Build Coastguard Worker             ret->mem = buffer->contentIO;
614*7c568831SAndroid Build Coastguard Worker         else
615*7c568831SAndroid Build Coastguard Worker             ret->mem = buffer->content;
616*7c568831SAndroid Build Coastguard Worker     }
617*7c568831SAndroid Build Coastguard Worker 
618*7c568831SAndroid Build Coastguard Worker     UPDATE_COMPAT(ret);
619*7c568831SAndroid Build Coastguard Worker     return(ret);
620*7c568831SAndroid Build Coastguard Worker }
621*7c568831SAndroid Build Coastguard Worker 
622*7c568831SAndroid Build Coastguard Worker /**
623*7c568831SAndroid Build Coastguard Worker  * xmlBufBackToBuffer:
624*7c568831SAndroid Build Coastguard Worker  * @buf: new buffer wrapping the old one
625*7c568831SAndroid Build Coastguard Worker  *
626*7c568831SAndroid Build Coastguard Worker  * Function to be called once internal processing had been done to
627*7c568831SAndroid Build Coastguard Worker  * update back the buffer provided by the user. This can lead to
628*7c568831SAndroid Build Coastguard Worker  * a failure in case the size accumulated in the xmlBuf is larger
629*7c568831SAndroid Build Coastguard Worker  * than what an xmlBuffer can support on 64 bits (INT_MAX)
630*7c568831SAndroid Build Coastguard Worker  * The xmlBufPtr @buf wrapper is deallocated by this call in any case.
631*7c568831SAndroid Build Coastguard Worker  *
632*7c568831SAndroid Build Coastguard Worker  * Returns the old xmlBufferPtr unless the call failed and NULL is returned
633*7c568831SAndroid Build Coastguard Worker  */
634*7c568831SAndroid Build Coastguard Worker int
xmlBufBackToBuffer(xmlBufPtr buf,xmlBufferPtr ret)635*7c568831SAndroid Build Coastguard Worker xmlBufBackToBuffer(xmlBufPtr buf, xmlBufferPtr ret) {
636*7c568831SAndroid Build Coastguard Worker     if ((buf == NULL) || (ret == NULL))
637*7c568831SAndroid Build Coastguard Worker         return(-1);
638*7c568831SAndroid Build Coastguard Worker 
639*7c568831SAndroid Build Coastguard Worker     if ((BUF_ERROR(buf)) || (BUF_STATIC(buf)) ||
640*7c568831SAndroid Build Coastguard Worker         (buf->use >= INT_MAX)) {
641*7c568831SAndroid Build Coastguard Worker         xmlBufFree(buf);
642*7c568831SAndroid Build Coastguard Worker         ret->content = NULL;
643*7c568831SAndroid Build Coastguard Worker         ret->contentIO = NULL;
644*7c568831SAndroid Build Coastguard Worker         ret->use = 0;
645*7c568831SAndroid Build Coastguard Worker         ret->size = 0;
646*7c568831SAndroid Build Coastguard Worker         return(-1);
647*7c568831SAndroid Build Coastguard Worker     }
648*7c568831SAndroid Build Coastguard Worker 
649*7c568831SAndroid Build Coastguard Worker     ret->use = buf->use;
650*7c568831SAndroid Build Coastguard Worker     if (buf->size >= INT_MAX) {
651*7c568831SAndroid Build Coastguard Worker         /* Keep the buffer but provide a truncated size value. */
652*7c568831SAndroid Build Coastguard Worker         ret->size = INT_MAX;
653*7c568831SAndroid Build Coastguard Worker     } else {
654*7c568831SAndroid Build Coastguard Worker         ret->size = buf->size + 1;
655*7c568831SAndroid Build Coastguard Worker     }
656*7c568831SAndroid Build Coastguard Worker     ret->alloc = XML_BUFFER_ALLOC_IO;
657*7c568831SAndroid Build Coastguard Worker     ret->content = buf->content;
658*7c568831SAndroid Build Coastguard Worker     ret->contentIO = buf->mem;
659*7c568831SAndroid Build Coastguard Worker     xmlFree(buf);
660*7c568831SAndroid Build Coastguard Worker     return(0);
661*7c568831SAndroid Build Coastguard Worker }
662*7c568831SAndroid Build Coastguard Worker 
663*7c568831SAndroid Build Coastguard Worker /**
664*7c568831SAndroid Build Coastguard Worker  * xmlBufResetInput:
665*7c568831SAndroid Build Coastguard Worker  * @buf: an xmlBufPtr
666*7c568831SAndroid Build Coastguard Worker  * @input: an xmlParserInputPtr
667*7c568831SAndroid Build Coastguard Worker  *
668*7c568831SAndroid Build Coastguard Worker  * Update the input to use the current set of pointers from the buffer.
669*7c568831SAndroid Build Coastguard Worker  *
670*7c568831SAndroid Build Coastguard Worker  * Returns -1 in case of error, 0 otherwise
671*7c568831SAndroid Build Coastguard Worker  */
672*7c568831SAndroid Build Coastguard Worker int
xmlBufResetInput(xmlBufPtr buf,xmlParserInputPtr input)673*7c568831SAndroid Build Coastguard Worker xmlBufResetInput(xmlBufPtr buf, xmlParserInputPtr input) {
674*7c568831SAndroid Build Coastguard Worker     return(xmlBufUpdateInput(buf, input, 0));
675*7c568831SAndroid Build Coastguard Worker }
676*7c568831SAndroid Build Coastguard Worker 
677*7c568831SAndroid Build Coastguard Worker /**
678*7c568831SAndroid Build Coastguard Worker  * xmlBufUpdateInput:
679*7c568831SAndroid Build Coastguard Worker  * @buf: an xmlBufPtr
680*7c568831SAndroid Build Coastguard Worker  * @input: an xmlParserInputPtr
681*7c568831SAndroid Build Coastguard Worker  * @pos: the cur value relative to the beginning of the buffer
682*7c568831SAndroid Build Coastguard Worker  *
683*7c568831SAndroid Build Coastguard Worker  * Update the input to use the base and cur relative to the buffer
684*7c568831SAndroid Build Coastguard Worker  * after a possible reallocation of its content
685*7c568831SAndroid Build Coastguard Worker  *
686*7c568831SAndroid Build Coastguard Worker  * Returns -1 in case of error, 0 otherwise
687*7c568831SAndroid Build Coastguard Worker  */
688*7c568831SAndroid Build Coastguard Worker int
xmlBufUpdateInput(xmlBufPtr buf,xmlParserInputPtr input,size_t pos)689*7c568831SAndroid Build Coastguard Worker xmlBufUpdateInput(xmlBufPtr buf, xmlParserInputPtr input, size_t pos) {
690*7c568831SAndroid Build Coastguard Worker     if ((buf == NULL) || (input == NULL))
691*7c568831SAndroid Build Coastguard Worker         return(-1);
692*7c568831SAndroid Build Coastguard Worker     CHECK_COMPAT(buf)
693*7c568831SAndroid Build Coastguard Worker     input->base = buf->content;
694*7c568831SAndroid Build Coastguard Worker     input->cur = input->base + pos;
695*7c568831SAndroid Build Coastguard Worker     input->end = &buf->content[buf->use];
696*7c568831SAndroid Build Coastguard Worker     return(0);
697*7c568831SAndroid Build Coastguard Worker }
698*7c568831SAndroid Build Coastguard Worker 
699*7c568831SAndroid Build Coastguard Worker /************************************************************************
700*7c568831SAndroid Build Coastguard Worker  *									*
701*7c568831SAndroid Build Coastguard Worker  *			Old buffer implementation			*
702*7c568831SAndroid Build Coastguard Worker  *									*
703*7c568831SAndroid Build Coastguard Worker  ************************************************************************/
704*7c568831SAndroid Build Coastguard Worker 
705*7c568831SAndroid Build Coastguard Worker /**
706*7c568831SAndroid Build Coastguard Worker  * xmlSetBufferAllocationScheme:
707*7c568831SAndroid Build Coastguard Worker  * @scheme:  allocation method to use
708*7c568831SAndroid Build Coastguard Worker  *
709*7c568831SAndroid Build Coastguard Worker  * DEPRECATED: Use xmlBufferSetAllocationScheme.
710*7c568831SAndroid Build Coastguard Worker  *
711*7c568831SAndroid Build Coastguard Worker  * Set the buffer allocation method.  Types are
712*7c568831SAndroid Build Coastguard Worker  * XML_BUFFER_ALLOC_EXACT - use exact sizes, keeps memory usage down
713*7c568831SAndroid Build Coastguard Worker  * XML_BUFFER_ALLOC_DOUBLEIT - double buffer when extra needed,
714*7c568831SAndroid Build Coastguard Worker  *                             improves performance
715*7c568831SAndroid Build Coastguard Worker  */
716*7c568831SAndroid Build Coastguard Worker void
xmlSetBufferAllocationScheme(xmlBufferAllocationScheme scheme ATTRIBUTE_UNUSED)717*7c568831SAndroid Build Coastguard Worker xmlSetBufferAllocationScheme(xmlBufferAllocationScheme scheme ATTRIBUTE_UNUSED) {
718*7c568831SAndroid Build Coastguard Worker }
719*7c568831SAndroid Build Coastguard Worker 
720*7c568831SAndroid Build Coastguard Worker /**
721*7c568831SAndroid Build Coastguard Worker  * xmlGetBufferAllocationScheme:
722*7c568831SAndroid Build Coastguard Worker  *
723*7c568831SAndroid Build Coastguard Worker  * DEPRECATED: Use xmlBufferSetAllocationScheme.
724*7c568831SAndroid Build Coastguard Worker  *
725*7c568831SAndroid Build Coastguard Worker  * Types are
726*7c568831SAndroid Build Coastguard Worker  * XML_BUFFER_ALLOC_EXACT - use exact sizes, keeps memory usage down
727*7c568831SAndroid Build Coastguard Worker  * XML_BUFFER_ALLOC_DOUBLEIT - double buffer when extra needed,
728*7c568831SAndroid Build Coastguard Worker  *                             improves performance
729*7c568831SAndroid Build Coastguard Worker  * XML_BUFFER_ALLOC_HYBRID - use exact sizes on small strings to keep memory usage tight
730*7c568831SAndroid Build Coastguard Worker  *                            in normal usage, and doubleit on large strings to avoid
731*7c568831SAndroid Build Coastguard Worker  *                            pathological performance.
732*7c568831SAndroid Build Coastguard Worker  *
733*7c568831SAndroid Build Coastguard Worker  * Returns the current allocation scheme
734*7c568831SAndroid Build Coastguard Worker  */
735*7c568831SAndroid Build Coastguard Worker xmlBufferAllocationScheme
xmlGetBufferAllocationScheme(void)736*7c568831SAndroid Build Coastguard Worker xmlGetBufferAllocationScheme(void) {
737*7c568831SAndroid Build Coastguard Worker     return(XML_BUFFER_ALLOC_EXACT);
738*7c568831SAndroid Build Coastguard Worker }
739*7c568831SAndroid Build Coastguard Worker 
740*7c568831SAndroid Build Coastguard Worker /**
741*7c568831SAndroid Build Coastguard Worker  * xmlBufferCreate:
742*7c568831SAndroid Build Coastguard Worker  *
743*7c568831SAndroid Build Coastguard Worker  * routine to create an XML buffer.
744*7c568831SAndroid Build Coastguard Worker  * returns the new structure.
745*7c568831SAndroid Build Coastguard Worker  */
746*7c568831SAndroid Build Coastguard Worker xmlBufferPtr
xmlBufferCreate(void)747*7c568831SAndroid Build Coastguard Worker xmlBufferCreate(void) {
748*7c568831SAndroid Build Coastguard Worker     xmlBufferPtr ret;
749*7c568831SAndroid Build Coastguard Worker 
750*7c568831SAndroid Build Coastguard Worker     ret = xmlMalloc(sizeof(*ret));
751*7c568831SAndroid Build Coastguard Worker     if (ret == NULL)
752*7c568831SAndroid Build Coastguard Worker         return(NULL);
753*7c568831SAndroid Build Coastguard Worker 
754*7c568831SAndroid Build Coastguard Worker     ret->use = 0;
755*7c568831SAndroid Build Coastguard Worker     ret->size = 256;
756*7c568831SAndroid Build Coastguard Worker     ret->alloc = XML_BUFFER_ALLOC_IO;
757*7c568831SAndroid Build Coastguard Worker     ret->contentIO = xmlMalloc(ret->size);
758*7c568831SAndroid Build Coastguard Worker     if (ret->contentIO == NULL) {
759*7c568831SAndroid Build Coastguard Worker 	xmlFree(ret);
760*7c568831SAndroid Build Coastguard Worker         return(NULL);
761*7c568831SAndroid Build Coastguard Worker     }
762*7c568831SAndroid Build Coastguard Worker     ret->content = ret->contentIO;
763*7c568831SAndroid Build Coastguard Worker     ret->content[0] = 0;
764*7c568831SAndroid Build Coastguard Worker 
765*7c568831SAndroid Build Coastguard Worker     return(ret);
766*7c568831SAndroid Build Coastguard Worker }
767*7c568831SAndroid Build Coastguard Worker 
768*7c568831SAndroid Build Coastguard Worker /**
769*7c568831SAndroid Build Coastguard Worker  * xmlBufferCreateSize:
770*7c568831SAndroid Build Coastguard Worker  * @size: initial size of buffer
771*7c568831SAndroid Build Coastguard Worker  *
772*7c568831SAndroid Build Coastguard Worker  * routine to create an XML buffer.
773*7c568831SAndroid Build Coastguard Worker  * returns the new structure.
774*7c568831SAndroid Build Coastguard Worker  */
775*7c568831SAndroid Build Coastguard Worker xmlBufferPtr
xmlBufferCreateSize(size_t size)776*7c568831SAndroid Build Coastguard Worker xmlBufferCreateSize(size_t size) {
777*7c568831SAndroid Build Coastguard Worker     xmlBufferPtr ret;
778*7c568831SAndroid Build Coastguard Worker 
779*7c568831SAndroid Build Coastguard Worker     if (size >= INT_MAX)
780*7c568831SAndroid Build Coastguard Worker         return(NULL);
781*7c568831SAndroid Build Coastguard Worker 
782*7c568831SAndroid Build Coastguard Worker     ret = xmlMalloc(sizeof(*ret));
783*7c568831SAndroid Build Coastguard Worker     if (ret == NULL)
784*7c568831SAndroid Build Coastguard Worker         return(NULL);
785*7c568831SAndroid Build Coastguard Worker 
786*7c568831SAndroid Build Coastguard Worker     ret->use = 0;
787*7c568831SAndroid Build Coastguard Worker     ret->alloc = XML_BUFFER_ALLOC_IO;
788*7c568831SAndroid Build Coastguard Worker     ret->size = (size ? size + 1 : 0);         /* +1 for ending null */
789*7c568831SAndroid Build Coastguard Worker 
790*7c568831SAndroid Build Coastguard Worker     if (ret->size) {
791*7c568831SAndroid Build Coastguard Worker         ret->contentIO = xmlMalloc(ret->size);
792*7c568831SAndroid Build Coastguard Worker         if (ret->contentIO == NULL) {
793*7c568831SAndroid Build Coastguard Worker             xmlFree(ret);
794*7c568831SAndroid Build Coastguard Worker             return(NULL);
795*7c568831SAndroid Build Coastguard Worker         }
796*7c568831SAndroid Build Coastguard Worker         ret->content = ret->contentIO;
797*7c568831SAndroid Build Coastguard Worker         ret->content[0] = 0;
798*7c568831SAndroid Build Coastguard Worker     } else {
799*7c568831SAndroid Build Coastguard Worker         ret->contentIO = NULL;
800*7c568831SAndroid Build Coastguard Worker 	ret->content = NULL;
801*7c568831SAndroid Build Coastguard Worker     }
802*7c568831SAndroid Build Coastguard Worker 
803*7c568831SAndroid Build Coastguard Worker     return(ret);
804*7c568831SAndroid Build Coastguard Worker }
805*7c568831SAndroid Build Coastguard Worker 
806*7c568831SAndroid Build Coastguard Worker /**
807*7c568831SAndroid Build Coastguard Worker  * xmlBufferDetach:
808*7c568831SAndroid Build Coastguard Worker  * @buf:  the buffer
809*7c568831SAndroid Build Coastguard Worker  *
810*7c568831SAndroid Build Coastguard Worker  * Remove the string contained in a buffer and gie it back to the
811*7c568831SAndroid Build Coastguard Worker  * caller. The buffer is reset to an empty content.
812*7c568831SAndroid Build Coastguard Worker  * This doesn't work with immutable buffers as they can't be reset.
813*7c568831SAndroid Build Coastguard Worker  *
814*7c568831SAndroid Build Coastguard Worker  * Returns the previous string contained by the buffer.
815*7c568831SAndroid Build Coastguard Worker  */
816*7c568831SAndroid Build Coastguard Worker xmlChar *
xmlBufferDetach(xmlBufferPtr buf)817*7c568831SAndroid Build Coastguard Worker xmlBufferDetach(xmlBufferPtr buf) {
818*7c568831SAndroid Build Coastguard Worker     xmlChar *ret;
819*7c568831SAndroid Build Coastguard Worker 
820*7c568831SAndroid Build Coastguard Worker     if (buf == NULL)
821*7c568831SAndroid Build Coastguard Worker         return(NULL);
822*7c568831SAndroid Build Coastguard Worker 
823*7c568831SAndroid Build Coastguard Worker     if ((buf->alloc == XML_BUFFER_ALLOC_IO) &&
824*7c568831SAndroid Build Coastguard Worker         (buf->content != buf->contentIO)) {
825*7c568831SAndroid Build Coastguard Worker         ret = xmlStrndup(buf->content, buf->use);
826*7c568831SAndroid Build Coastguard Worker         xmlFree(buf->contentIO);
827*7c568831SAndroid Build Coastguard Worker     } else {
828*7c568831SAndroid Build Coastguard Worker         ret = buf->content;
829*7c568831SAndroid Build Coastguard Worker     }
830*7c568831SAndroid Build Coastguard Worker 
831*7c568831SAndroid Build Coastguard Worker     buf->contentIO = NULL;
832*7c568831SAndroid Build Coastguard Worker     buf->content = NULL;
833*7c568831SAndroid Build Coastguard Worker     buf->size = 0;
834*7c568831SAndroid Build Coastguard Worker     buf->use = 0;
835*7c568831SAndroid Build Coastguard Worker 
836*7c568831SAndroid Build Coastguard Worker     return ret;
837*7c568831SAndroid Build Coastguard Worker }
838*7c568831SAndroid Build Coastguard Worker 
839*7c568831SAndroid Build Coastguard Worker /**
840*7c568831SAndroid Build Coastguard Worker  * xmlBufferCreateStatic:
841*7c568831SAndroid Build Coastguard Worker  * @mem: the memory area
842*7c568831SAndroid Build Coastguard Worker  * @size:  the size in byte
843*7c568831SAndroid Build Coastguard Worker  *
844*7c568831SAndroid Build Coastguard Worker  * Returns an XML buffer initialized with bytes.
845*7c568831SAndroid Build Coastguard Worker  */
846*7c568831SAndroid Build Coastguard Worker xmlBufferPtr
xmlBufferCreateStatic(void * mem,size_t size)847*7c568831SAndroid Build Coastguard Worker xmlBufferCreateStatic(void *mem, size_t size) {
848*7c568831SAndroid Build Coastguard Worker     xmlBufferPtr buf = xmlBufferCreateSize(size);
849*7c568831SAndroid Build Coastguard Worker 
850*7c568831SAndroid Build Coastguard Worker     xmlBufferAdd(buf, mem, size);
851*7c568831SAndroid Build Coastguard Worker     return(buf);
852*7c568831SAndroid Build Coastguard Worker }
853*7c568831SAndroid Build Coastguard Worker 
854*7c568831SAndroid Build Coastguard Worker /**
855*7c568831SAndroid Build Coastguard Worker  * xmlBufferSetAllocationScheme:
856*7c568831SAndroid Build Coastguard Worker  * @buf:  the buffer to tune
857*7c568831SAndroid Build Coastguard Worker  * @scheme:  allocation scheme to use
858*7c568831SAndroid Build Coastguard Worker  *
859*7c568831SAndroid Build Coastguard Worker  * Sets the allocation scheme for this buffer.
860*7c568831SAndroid Build Coastguard Worker  *
861*7c568831SAndroid Build Coastguard Worker  * For libxml2 before 2.14, it is recommended to set this to
862*7c568831SAndroid Build Coastguard Worker  * XML_BUFFER_ALLOC_DOUBLE_IT. Has no effect on 2.14 or later.
863*7c568831SAndroid Build Coastguard Worker  */
864*7c568831SAndroid Build Coastguard Worker void
xmlBufferSetAllocationScheme(xmlBufferPtr buf ATTRIBUTE_UNUSED,xmlBufferAllocationScheme scheme ATTRIBUTE_UNUSED)865*7c568831SAndroid Build Coastguard Worker xmlBufferSetAllocationScheme(xmlBufferPtr buf ATTRIBUTE_UNUSED,
866*7c568831SAndroid Build Coastguard Worker                              xmlBufferAllocationScheme scheme ATTRIBUTE_UNUSED) {
867*7c568831SAndroid Build Coastguard Worker }
868*7c568831SAndroid Build Coastguard Worker 
869*7c568831SAndroid Build Coastguard Worker /**
870*7c568831SAndroid Build Coastguard Worker  * xmlBufferFree:
871*7c568831SAndroid Build Coastguard Worker  * @buf:  the buffer to free
872*7c568831SAndroid Build Coastguard Worker  *
873*7c568831SAndroid Build Coastguard Worker  * Frees an XML buffer. It frees both the content and the structure which
874*7c568831SAndroid Build Coastguard Worker  * encapsulate it.
875*7c568831SAndroid Build Coastguard Worker  */
876*7c568831SAndroid Build Coastguard Worker void
xmlBufferFree(xmlBufferPtr buf)877*7c568831SAndroid Build Coastguard Worker xmlBufferFree(xmlBufferPtr buf) {
878*7c568831SAndroid Build Coastguard Worker     if (buf == NULL)
879*7c568831SAndroid Build Coastguard Worker 	return;
880*7c568831SAndroid Build Coastguard Worker 
881*7c568831SAndroid Build Coastguard Worker     if (buf->alloc == XML_BUFFER_ALLOC_IO)
882*7c568831SAndroid Build Coastguard Worker         xmlFree(buf->contentIO);
883*7c568831SAndroid Build Coastguard Worker     else
884*7c568831SAndroid Build Coastguard Worker         xmlFree(buf->content);
885*7c568831SAndroid Build Coastguard Worker 
886*7c568831SAndroid Build Coastguard Worker     xmlFree(buf);
887*7c568831SAndroid Build Coastguard Worker }
888*7c568831SAndroid Build Coastguard Worker 
889*7c568831SAndroid Build Coastguard Worker /**
890*7c568831SAndroid Build Coastguard Worker  * xmlBufferEmpty:
891*7c568831SAndroid Build Coastguard Worker  * @buf:  the buffer
892*7c568831SAndroid Build Coastguard Worker  *
893*7c568831SAndroid Build Coastguard Worker  * empty a buffer.
894*7c568831SAndroid Build Coastguard Worker  */
895*7c568831SAndroid Build Coastguard Worker void
xmlBufferEmpty(xmlBufferPtr buf)896*7c568831SAndroid Build Coastguard Worker xmlBufferEmpty(xmlBufferPtr buf) {
897*7c568831SAndroid Build Coastguard Worker     if (buf == NULL)
898*7c568831SAndroid Build Coastguard Worker         return;
899*7c568831SAndroid Build Coastguard Worker     if (buf->content == NULL)
900*7c568831SAndroid Build Coastguard Worker         return;
901*7c568831SAndroid Build Coastguard Worker 
902*7c568831SAndroid Build Coastguard Worker     buf->use = 0;
903*7c568831SAndroid Build Coastguard Worker 
904*7c568831SAndroid Build Coastguard Worker     if (buf->alloc == XML_BUFFER_ALLOC_IO) {
905*7c568831SAndroid Build Coastguard Worker 	buf->size += buf->content - buf->contentIO;
906*7c568831SAndroid Build Coastguard Worker         buf->content = buf->contentIO;
907*7c568831SAndroid Build Coastguard Worker         buf->content[0] = 0;
908*7c568831SAndroid Build Coastguard Worker     } else {
909*7c568831SAndroid Build Coastguard Worker         buf->content[0] = 0;
910*7c568831SAndroid Build Coastguard Worker     }
911*7c568831SAndroid Build Coastguard Worker }
912*7c568831SAndroid Build Coastguard Worker 
913*7c568831SAndroid Build Coastguard Worker /**
914*7c568831SAndroid Build Coastguard Worker  * xmlBufferShrink:
915*7c568831SAndroid Build Coastguard Worker  * @buf:  the buffer to dump
916*7c568831SAndroid Build Coastguard Worker  * @len:  the number of xmlChar to remove
917*7c568831SAndroid Build Coastguard Worker  *
918*7c568831SAndroid Build Coastguard Worker  * DEPRECATED: Don't use.
919*7c568831SAndroid Build Coastguard Worker  *
920*7c568831SAndroid Build Coastguard Worker  * Remove the beginning of an XML buffer.
921*7c568831SAndroid Build Coastguard Worker  *
922*7c568831SAndroid Build Coastguard Worker  * Returns the number of #xmlChar removed, or -1 in case of failure.
923*7c568831SAndroid Build Coastguard Worker  */
924*7c568831SAndroid Build Coastguard Worker int
xmlBufferShrink(xmlBufferPtr buf,unsigned int len)925*7c568831SAndroid Build Coastguard Worker xmlBufferShrink(xmlBufferPtr buf, unsigned int len) {
926*7c568831SAndroid Build Coastguard Worker     if (buf == NULL)
927*7c568831SAndroid Build Coastguard Worker         return(-1);
928*7c568831SAndroid Build Coastguard Worker     if (len == 0)
929*7c568831SAndroid Build Coastguard Worker         return(0);
930*7c568831SAndroid Build Coastguard Worker     if (len > buf->use)
931*7c568831SAndroid Build Coastguard Worker         return(-1);
932*7c568831SAndroid Build Coastguard Worker 
933*7c568831SAndroid Build Coastguard Worker     buf->use -= len;
934*7c568831SAndroid Build Coastguard Worker 
935*7c568831SAndroid Build Coastguard Worker     if (buf->alloc == XML_BUFFER_ALLOC_IO) {
936*7c568831SAndroid Build Coastguard Worker         buf->content += len;
937*7c568831SAndroid Build Coastguard Worker 	buf->size -= len;
938*7c568831SAndroid Build Coastguard Worker     } else {
939*7c568831SAndroid Build Coastguard Worker 	memmove(buf->content, &buf->content[len], buf->use + 1);
940*7c568831SAndroid Build Coastguard Worker     }
941*7c568831SAndroid Build Coastguard Worker 
942*7c568831SAndroid Build Coastguard Worker     return(len);
943*7c568831SAndroid Build Coastguard Worker }
944*7c568831SAndroid Build Coastguard Worker 
945*7c568831SAndroid Build Coastguard Worker /**
946*7c568831SAndroid Build Coastguard Worker  * xmlBufferGrow:
947*7c568831SAndroid Build Coastguard Worker  * @buf:  the buffer
948*7c568831SAndroid Build Coastguard Worker  * @len:  the minimum free size to allocate
949*7c568831SAndroid Build Coastguard Worker  *
950*7c568831SAndroid Build Coastguard Worker  * DEPRECATED: Don't use.
951*7c568831SAndroid Build Coastguard Worker  *
952*7c568831SAndroid Build Coastguard Worker  * Grow the available space of an XML buffer.
953*7c568831SAndroid Build Coastguard Worker  *
954*7c568831SAndroid Build Coastguard Worker  * Returns the new available space or -1 in case of error
955*7c568831SAndroid Build Coastguard Worker  */
956*7c568831SAndroid Build Coastguard Worker int
xmlBufferGrow(xmlBufferPtr buf,unsigned int len)957*7c568831SAndroid Build Coastguard Worker xmlBufferGrow(xmlBufferPtr buf, unsigned int len) {
958*7c568831SAndroid Build Coastguard Worker     unsigned int size;
959*7c568831SAndroid Build Coastguard Worker     xmlChar *newbuf;
960*7c568831SAndroid Build Coastguard Worker 
961*7c568831SAndroid Build Coastguard Worker     if (buf == NULL)
962*7c568831SAndroid Build Coastguard Worker         return(-1);
963*7c568831SAndroid Build Coastguard Worker 
964*7c568831SAndroid Build Coastguard Worker     if (len < buf->size - buf->use)
965*7c568831SAndroid Build Coastguard Worker         return(0);
966*7c568831SAndroid Build Coastguard Worker     if (len >= INT_MAX - buf->use)
967*7c568831SAndroid Build Coastguard Worker         return(-1);
968*7c568831SAndroid Build Coastguard Worker 
969*7c568831SAndroid Build Coastguard Worker     if (buf->size > (size_t) len) {
970*7c568831SAndroid Build Coastguard Worker         if (buf->size <= INT_MAX / 2)
971*7c568831SAndroid Build Coastguard Worker             size = buf->size * 2;
972*7c568831SAndroid Build Coastguard Worker         else
973*7c568831SAndroid Build Coastguard Worker             size = INT_MAX;
974*7c568831SAndroid Build Coastguard Worker     } else {
975*7c568831SAndroid Build Coastguard Worker         size = buf->use + len + 1;
976*7c568831SAndroid Build Coastguard Worker         if (size <= INT_MAX - 100)
977*7c568831SAndroid Build Coastguard Worker             size += 100;
978*7c568831SAndroid Build Coastguard Worker     }
979*7c568831SAndroid Build Coastguard Worker 
980*7c568831SAndroid Build Coastguard Worker     if ((buf->alloc == XML_BUFFER_ALLOC_IO) &&
981*7c568831SAndroid Build Coastguard Worker         (buf->content != buf->contentIO)) {
982*7c568831SAndroid Build Coastguard Worker         newbuf = xmlMalloc(size);
983*7c568831SAndroid Build Coastguard Worker         if (newbuf == NULL)
984*7c568831SAndroid Build Coastguard Worker             return(-1);
985*7c568831SAndroid Build Coastguard Worker         if (buf->content != NULL)
986*7c568831SAndroid Build Coastguard Worker             memcpy(newbuf, buf->content, buf->use + 1);
987*7c568831SAndroid Build Coastguard Worker         xmlFree(buf->contentIO);
988*7c568831SAndroid Build Coastguard Worker     } else {
989*7c568831SAndroid Build Coastguard Worker         newbuf = xmlRealloc(buf->content, size);
990*7c568831SAndroid Build Coastguard Worker         if (newbuf == NULL)
991*7c568831SAndroid Build Coastguard Worker             return(-1);
992*7c568831SAndroid Build Coastguard Worker     }
993*7c568831SAndroid Build Coastguard Worker 
994*7c568831SAndroid Build Coastguard Worker     if (buf->alloc == XML_BUFFER_ALLOC_IO)
995*7c568831SAndroid Build Coastguard Worker         buf->contentIO = newbuf;
996*7c568831SAndroid Build Coastguard Worker     buf->content = newbuf;
997*7c568831SAndroid Build Coastguard Worker     buf->size = size;
998*7c568831SAndroid Build Coastguard Worker 
999*7c568831SAndroid Build Coastguard Worker     return(buf->size - buf->use - 1);
1000*7c568831SAndroid Build Coastguard Worker }
1001*7c568831SAndroid Build Coastguard Worker 
1002*7c568831SAndroid Build Coastguard Worker /**
1003*7c568831SAndroid Build Coastguard Worker  * xmlBufferDump:
1004*7c568831SAndroid Build Coastguard Worker  * @file:  the file output
1005*7c568831SAndroid Build Coastguard Worker  * @buf:  the buffer to dump
1006*7c568831SAndroid Build Coastguard Worker  *
1007*7c568831SAndroid Build Coastguard Worker  * Dumps an XML buffer to  a FILE *.
1008*7c568831SAndroid Build Coastguard Worker  * Returns the number of #xmlChar written
1009*7c568831SAndroid Build Coastguard Worker  */
1010*7c568831SAndroid Build Coastguard Worker int
xmlBufferDump(FILE * file,xmlBufferPtr buf)1011*7c568831SAndroid Build Coastguard Worker xmlBufferDump(FILE *file, xmlBufferPtr buf) {
1012*7c568831SAndroid Build Coastguard Worker     size_t ret;
1013*7c568831SAndroid Build Coastguard Worker 
1014*7c568831SAndroid Build Coastguard Worker     if (buf == NULL)
1015*7c568831SAndroid Build Coastguard Worker 	return(0);
1016*7c568831SAndroid Build Coastguard Worker     if (buf->content == NULL)
1017*7c568831SAndroid Build Coastguard Worker 	return(0);
1018*7c568831SAndroid Build Coastguard Worker     if (file == NULL)
1019*7c568831SAndroid Build Coastguard Worker 	file = stdout;
1020*7c568831SAndroid Build Coastguard Worker     ret = fwrite(buf->content, 1, buf->use, file);
1021*7c568831SAndroid Build Coastguard Worker     return(ret > INT_MAX ? INT_MAX : ret);
1022*7c568831SAndroid Build Coastguard Worker }
1023*7c568831SAndroid Build Coastguard Worker 
1024*7c568831SAndroid Build Coastguard Worker /**
1025*7c568831SAndroid Build Coastguard Worker  * xmlBufferContent:
1026*7c568831SAndroid Build Coastguard Worker  * @buf:  the buffer
1027*7c568831SAndroid Build Coastguard Worker  *
1028*7c568831SAndroid Build Coastguard Worker  * Function to extract the content of a buffer
1029*7c568831SAndroid Build Coastguard Worker  *
1030*7c568831SAndroid Build Coastguard Worker  * Returns the internal content
1031*7c568831SAndroid Build Coastguard Worker  */
1032*7c568831SAndroid Build Coastguard Worker 
1033*7c568831SAndroid Build Coastguard Worker const xmlChar *
xmlBufferContent(const xmlBuffer * buf)1034*7c568831SAndroid Build Coastguard Worker xmlBufferContent(const xmlBuffer *buf)
1035*7c568831SAndroid Build Coastguard Worker {
1036*7c568831SAndroid Build Coastguard Worker     if(!buf)
1037*7c568831SAndroid Build Coastguard Worker         return NULL;
1038*7c568831SAndroid Build Coastguard Worker 
1039*7c568831SAndroid Build Coastguard Worker     return buf->content;
1040*7c568831SAndroid Build Coastguard Worker }
1041*7c568831SAndroid Build Coastguard Worker 
1042*7c568831SAndroid Build Coastguard Worker /**
1043*7c568831SAndroid Build Coastguard Worker  * xmlBufferLength:
1044*7c568831SAndroid Build Coastguard Worker  * @buf:  the buffer
1045*7c568831SAndroid Build Coastguard Worker  *
1046*7c568831SAndroid Build Coastguard Worker  * Function to get the length of a buffer
1047*7c568831SAndroid Build Coastguard Worker  *
1048*7c568831SAndroid Build Coastguard Worker  * Returns the length of data in the internal content
1049*7c568831SAndroid Build Coastguard Worker  */
1050*7c568831SAndroid Build Coastguard Worker 
1051*7c568831SAndroid Build Coastguard Worker int
xmlBufferLength(const xmlBuffer * buf)1052*7c568831SAndroid Build Coastguard Worker xmlBufferLength(const xmlBuffer *buf)
1053*7c568831SAndroid Build Coastguard Worker {
1054*7c568831SAndroid Build Coastguard Worker     if(!buf)
1055*7c568831SAndroid Build Coastguard Worker         return 0;
1056*7c568831SAndroid Build Coastguard Worker 
1057*7c568831SAndroid Build Coastguard Worker     return buf->use;
1058*7c568831SAndroid Build Coastguard Worker }
1059*7c568831SAndroid Build Coastguard Worker 
1060*7c568831SAndroid Build Coastguard Worker /**
1061*7c568831SAndroid Build Coastguard Worker  * xmlBufferResize:
1062*7c568831SAndroid Build Coastguard Worker  * @buf:  the buffer to resize
1063*7c568831SAndroid Build Coastguard Worker  * @size:  the desired size
1064*7c568831SAndroid Build Coastguard Worker  *
1065*7c568831SAndroid Build Coastguard Worker  * DEPRECATED: Don't use.
1066*7c568831SAndroid Build Coastguard Worker 
1067*7c568831SAndroid Build Coastguard Worker  * Resize a buffer to accommodate minimum size of @size.
1068*7c568831SAndroid Build Coastguard Worker  *
1069*7c568831SAndroid Build Coastguard Worker  * Returns  0 in case of problems, 1 otherwise
1070*7c568831SAndroid Build Coastguard Worker  */
1071*7c568831SAndroid Build Coastguard Worker int
xmlBufferResize(xmlBufferPtr buf,unsigned int size)1072*7c568831SAndroid Build Coastguard Worker xmlBufferResize(xmlBufferPtr buf, unsigned int size)
1073*7c568831SAndroid Build Coastguard Worker {
1074*7c568831SAndroid Build Coastguard Worker     int res;
1075*7c568831SAndroid Build Coastguard Worker 
1076*7c568831SAndroid Build Coastguard Worker     if (buf == NULL)
1077*7c568831SAndroid Build Coastguard Worker         return(0);
1078*7c568831SAndroid Build Coastguard Worker     if (size < buf->size)
1079*7c568831SAndroid Build Coastguard Worker         return(1);
1080*7c568831SAndroid Build Coastguard Worker     res = xmlBufferGrow(buf, size - buf->use);
1081*7c568831SAndroid Build Coastguard Worker 
1082*7c568831SAndroid Build Coastguard Worker     return(res < 0 ? 0 : 1);
1083*7c568831SAndroid Build Coastguard Worker }
1084*7c568831SAndroid Build Coastguard Worker 
1085*7c568831SAndroid Build Coastguard Worker /**
1086*7c568831SAndroid Build Coastguard Worker  * xmlBufferAdd:
1087*7c568831SAndroid Build Coastguard Worker  * @buf:  the buffer to dump
1088*7c568831SAndroid Build Coastguard Worker  * @str:  the #xmlChar string
1089*7c568831SAndroid Build Coastguard Worker  * @len:  the number of #xmlChar to add
1090*7c568831SAndroid Build Coastguard Worker  *
1091*7c568831SAndroid Build Coastguard Worker  * Add a string range to an XML buffer. if len == -1, the length of
1092*7c568831SAndroid Build Coastguard Worker  * str is recomputed.
1093*7c568831SAndroid Build Coastguard Worker  *
1094*7c568831SAndroid Build Coastguard Worker  * Returns a xmlParserError code.
1095*7c568831SAndroid Build Coastguard Worker  */
1096*7c568831SAndroid Build Coastguard Worker int
xmlBufferAdd(xmlBufferPtr buf,const xmlChar * str,int len)1097*7c568831SAndroid Build Coastguard Worker xmlBufferAdd(xmlBufferPtr buf, const xmlChar *str, int len) {
1098*7c568831SAndroid Build Coastguard Worker     if ((buf == NULL) || (str == NULL))
1099*7c568831SAndroid Build Coastguard Worker 	return(XML_ERR_ARGUMENT);
1100*7c568831SAndroid Build Coastguard Worker     if (len < 0)
1101*7c568831SAndroid Build Coastguard Worker         len = xmlStrlen(str);
1102*7c568831SAndroid Build Coastguard Worker     if (len == 0)
1103*7c568831SAndroid Build Coastguard Worker         return(XML_ERR_OK);
1104*7c568831SAndroid Build Coastguard Worker 
1105*7c568831SAndroid Build Coastguard Worker     /* Note that both buf->size and buf->use can be zero here. */
1106*7c568831SAndroid Build Coastguard Worker     if ((unsigned) len >= buf->size - buf->use) {
1107*7c568831SAndroid Build Coastguard Worker         if (xmlBufferGrow(buf, len) < 0)
1108*7c568831SAndroid Build Coastguard Worker             return(XML_ERR_NO_MEMORY);
1109*7c568831SAndroid Build Coastguard Worker     }
1110*7c568831SAndroid Build Coastguard Worker 
1111*7c568831SAndroid Build Coastguard Worker     memmove(&buf->content[buf->use], str, len);
1112*7c568831SAndroid Build Coastguard Worker     buf->use += len;
1113*7c568831SAndroid Build Coastguard Worker     buf->content[buf->use] = 0;
1114*7c568831SAndroid Build Coastguard Worker     return(XML_ERR_OK);
1115*7c568831SAndroid Build Coastguard Worker }
1116*7c568831SAndroid Build Coastguard Worker 
1117*7c568831SAndroid Build Coastguard Worker /**
1118*7c568831SAndroid Build Coastguard Worker  * xmlBufferAddHead:
1119*7c568831SAndroid Build Coastguard Worker  * @buf:  the buffer
1120*7c568831SAndroid Build Coastguard Worker  * @str:  the #xmlChar string
1121*7c568831SAndroid Build Coastguard Worker  * @len:  the number of #xmlChar to add
1122*7c568831SAndroid Build Coastguard Worker  *
1123*7c568831SAndroid Build Coastguard Worker  * Add a string range to the beginning of an XML buffer.
1124*7c568831SAndroid Build Coastguard Worker  * if len == -1, the length of @str is recomputed.
1125*7c568831SAndroid Build Coastguard Worker  *
1126*7c568831SAndroid Build Coastguard Worker  * Returns a xmlParserError code.
1127*7c568831SAndroid Build Coastguard Worker  */
1128*7c568831SAndroid Build Coastguard Worker int
xmlBufferAddHead(xmlBufferPtr buf,const xmlChar * str,int len)1129*7c568831SAndroid Build Coastguard Worker xmlBufferAddHead(xmlBufferPtr buf, const xmlChar *str, int len) {
1130*7c568831SAndroid Build Coastguard Worker     unsigned start = 0;
1131*7c568831SAndroid Build Coastguard Worker 
1132*7c568831SAndroid Build Coastguard Worker     if ((buf == NULL) || (str == NULL))
1133*7c568831SAndroid Build Coastguard Worker 	return(XML_ERR_ARGUMENT);
1134*7c568831SAndroid Build Coastguard Worker     if (len < 0)
1135*7c568831SAndroid Build Coastguard Worker         len = xmlStrlen(str);
1136*7c568831SAndroid Build Coastguard Worker     if (len == 0)
1137*7c568831SAndroid Build Coastguard Worker         return(XML_ERR_OK);
1138*7c568831SAndroid Build Coastguard Worker 
1139*7c568831SAndroid Build Coastguard Worker     if (buf->alloc == XML_BUFFER_ALLOC_IO) {
1140*7c568831SAndroid Build Coastguard Worker         start = buf->content - buf->contentIO;
1141*7c568831SAndroid Build Coastguard Worker 
1142*7c568831SAndroid Build Coastguard Worker         /*
1143*7c568831SAndroid Build Coastguard Worker          * We can add it in the space previously shrunk
1144*7c568831SAndroid Build Coastguard Worker          */
1145*7c568831SAndroid Build Coastguard Worker         if ((unsigned) len <= start) {
1146*7c568831SAndroid Build Coastguard Worker             buf->content -= len;
1147*7c568831SAndroid Build Coastguard Worker             memmove(&buf->content[0], str, len);
1148*7c568831SAndroid Build Coastguard Worker             buf->use += len;
1149*7c568831SAndroid Build Coastguard Worker             buf->size += len;
1150*7c568831SAndroid Build Coastguard Worker             return(0);
1151*7c568831SAndroid Build Coastguard Worker         }
1152*7c568831SAndroid Build Coastguard Worker         if ((unsigned) len < buf->size + start - buf->use) {
1153*7c568831SAndroid Build Coastguard Worker             memmove(&buf->contentIO[len], buf->content, buf->use + 1);
1154*7c568831SAndroid Build Coastguard Worker             memmove(buf->contentIO, str, len);
1155*7c568831SAndroid Build Coastguard Worker             buf->content = buf->contentIO;
1156*7c568831SAndroid Build Coastguard Worker             buf->use += len;
1157*7c568831SAndroid Build Coastguard Worker             buf->size += start;
1158*7c568831SAndroid Build Coastguard Worker             return(0);
1159*7c568831SAndroid Build Coastguard Worker         }
1160*7c568831SAndroid Build Coastguard Worker     }
1161*7c568831SAndroid Build Coastguard Worker 
1162*7c568831SAndroid Build Coastguard Worker     if ((unsigned) len >= buf->size - buf->use) {
1163*7c568831SAndroid Build Coastguard Worker         if (xmlBufferGrow(buf, len) < 0)
1164*7c568831SAndroid Build Coastguard Worker             return(-1);
1165*7c568831SAndroid Build Coastguard Worker     }
1166*7c568831SAndroid Build Coastguard Worker 
1167*7c568831SAndroid Build Coastguard Worker     memmove(&buf->content[len], buf->content, buf->use + 1);
1168*7c568831SAndroid Build Coastguard Worker     memmove(buf->content, str, len);
1169*7c568831SAndroid Build Coastguard Worker     buf->use += len;
1170*7c568831SAndroid Build Coastguard Worker     return (0);
1171*7c568831SAndroid Build Coastguard Worker }
1172*7c568831SAndroid Build Coastguard Worker 
1173*7c568831SAndroid Build Coastguard Worker /**
1174*7c568831SAndroid Build Coastguard Worker  * xmlBufferCat:
1175*7c568831SAndroid Build Coastguard Worker  * @buf:  the buffer to add to
1176*7c568831SAndroid Build Coastguard Worker  * @str:  the #xmlChar string
1177*7c568831SAndroid Build Coastguard Worker  *
1178*7c568831SAndroid Build Coastguard Worker  * Append a zero terminated string to an XML buffer.
1179*7c568831SAndroid Build Coastguard Worker  *
1180*7c568831SAndroid Build Coastguard Worker  * Returns 0 successful, a positive error code number otherwise
1181*7c568831SAndroid Build Coastguard Worker  *         and -1 in case of internal or API error.
1182*7c568831SAndroid Build Coastguard Worker  */
1183*7c568831SAndroid Build Coastguard Worker int
xmlBufferCat(xmlBufferPtr buf,const xmlChar * str)1184*7c568831SAndroid Build Coastguard Worker xmlBufferCat(xmlBufferPtr buf, const xmlChar *str) {
1185*7c568831SAndroid Build Coastguard Worker     return(xmlBufferAdd(buf, str, -1));
1186*7c568831SAndroid Build Coastguard Worker }
1187*7c568831SAndroid Build Coastguard Worker 
1188*7c568831SAndroid Build Coastguard Worker /**
1189*7c568831SAndroid Build Coastguard Worker  * xmlBufferCCat:
1190*7c568831SAndroid Build Coastguard Worker  * @buf:  the buffer to dump
1191*7c568831SAndroid Build Coastguard Worker  * @str:  the C char string
1192*7c568831SAndroid Build Coastguard Worker  *
1193*7c568831SAndroid Build Coastguard Worker  * Append a zero terminated C string to an XML buffer.
1194*7c568831SAndroid Build Coastguard Worker  *
1195*7c568831SAndroid Build Coastguard Worker  * Returns 0 successful, a positive error code number otherwise
1196*7c568831SAndroid Build Coastguard Worker  *         and -1 in case of internal or API error.
1197*7c568831SAndroid Build Coastguard Worker  */
1198*7c568831SAndroid Build Coastguard Worker int
xmlBufferCCat(xmlBufferPtr buf,const char * str)1199*7c568831SAndroid Build Coastguard Worker xmlBufferCCat(xmlBufferPtr buf, const char *str) {
1200*7c568831SAndroid Build Coastguard Worker     return(xmlBufferAdd(buf, (const xmlChar *) str, -1));
1201*7c568831SAndroid Build Coastguard Worker }
1202*7c568831SAndroid Build Coastguard Worker 
1203*7c568831SAndroid Build Coastguard Worker /**
1204*7c568831SAndroid Build Coastguard Worker  * xmlBufferWriteCHAR:
1205*7c568831SAndroid Build Coastguard Worker  * @buf:  the XML buffer
1206*7c568831SAndroid Build Coastguard Worker  * @string:  the string to add
1207*7c568831SAndroid Build Coastguard Worker  *
1208*7c568831SAndroid Build Coastguard Worker  * routine which manages and grows an output buffer. This one adds
1209*7c568831SAndroid Build Coastguard Worker  * xmlChars at the end of the buffer.
1210*7c568831SAndroid Build Coastguard Worker  */
1211*7c568831SAndroid Build Coastguard Worker void
xmlBufferWriteCHAR(xmlBufferPtr buf,const xmlChar * string)1212*7c568831SAndroid Build Coastguard Worker xmlBufferWriteCHAR(xmlBufferPtr buf, const xmlChar *string) {
1213*7c568831SAndroid Build Coastguard Worker     xmlBufferAdd(buf, string, -1);
1214*7c568831SAndroid Build Coastguard Worker }
1215*7c568831SAndroid Build Coastguard Worker 
1216*7c568831SAndroid Build Coastguard Worker /**
1217*7c568831SAndroid Build Coastguard Worker  * xmlBufferWriteChar:
1218*7c568831SAndroid Build Coastguard Worker  * @buf:  the XML buffer output
1219*7c568831SAndroid Build Coastguard Worker  * @string:  the string to add
1220*7c568831SAndroid Build Coastguard Worker  *
1221*7c568831SAndroid Build Coastguard Worker  * routine which manage and grows an output buffer. This one add
1222*7c568831SAndroid Build Coastguard Worker  * C chars at the end of the array.
1223*7c568831SAndroid Build Coastguard Worker  */
1224*7c568831SAndroid Build Coastguard Worker void
xmlBufferWriteChar(xmlBufferPtr buf,const char * string)1225*7c568831SAndroid Build Coastguard Worker xmlBufferWriteChar(xmlBufferPtr buf, const char *string) {
1226*7c568831SAndroid Build Coastguard Worker     xmlBufferAdd(buf, (const xmlChar *) string, -1);
1227*7c568831SAndroid Build Coastguard Worker }
1228*7c568831SAndroid Build Coastguard Worker 
1229*7c568831SAndroid Build Coastguard Worker 
1230*7c568831SAndroid Build Coastguard Worker /**
1231*7c568831SAndroid Build Coastguard Worker  * xmlBufferWriteQuotedString:
1232*7c568831SAndroid Build Coastguard Worker  * @buf:  the XML buffer output
1233*7c568831SAndroid Build Coastguard Worker  * @string:  the string to add
1234*7c568831SAndroid Build Coastguard Worker  *
1235*7c568831SAndroid Build Coastguard Worker  * routine which manage and grows an output buffer. This one writes
1236*7c568831SAndroid Build Coastguard Worker  * a quoted or double quoted #xmlChar string, checking first if it holds
1237*7c568831SAndroid Build Coastguard Worker  * quote or double-quotes internally
1238*7c568831SAndroid Build Coastguard Worker  */
1239*7c568831SAndroid Build Coastguard Worker void
xmlBufferWriteQuotedString(xmlBufferPtr buf,const xmlChar * string)1240*7c568831SAndroid Build Coastguard Worker xmlBufferWriteQuotedString(xmlBufferPtr buf, const xmlChar *string) {
1241*7c568831SAndroid Build Coastguard Worker     const xmlChar *cur, *base;
1242*7c568831SAndroid Build Coastguard Worker     if (buf == NULL)
1243*7c568831SAndroid Build Coastguard Worker         return;
1244*7c568831SAndroid Build Coastguard Worker     if (xmlStrchr(string, '\"')) {
1245*7c568831SAndroid Build Coastguard Worker         if (xmlStrchr(string, '\'')) {
1246*7c568831SAndroid Build Coastguard Worker 	    xmlBufferCCat(buf, "\"");
1247*7c568831SAndroid Build Coastguard Worker             base = cur = string;
1248*7c568831SAndroid Build Coastguard Worker             while(*cur != 0){
1249*7c568831SAndroid Build Coastguard Worker                 if(*cur == '"'){
1250*7c568831SAndroid Build Coastguard Worker                     if (base != cur)
1251*7c568831SAndroid Build Coastguard Worker                         xmlBufferAdd(buf, base, cur - base);
1252*7c568831SAndroid Build Coastguard Worker                     xmlBufferAdd(buf, BAD_CAST "&quot;", 6);
1253*7c568831SAndroid Build Coastguard Worker                     cur++;
1254*7c568831SAndroid Build Coastguard Worker                     base = cur;
1255*7c568831SAndroid Build Coastguard Worker                 }
1256*7c568831SAndroid Build Coastguard Worker                 else {
1257*7c568831SAndroid Build Coastguard Worker                     cur++;
1258*7c568831SAndroid Build Coastguard Worker                 }
1259*7c568831SAndroid Build Coastguard Worker             }
1260*7c568831SAndroid Build Coastguard Worker             if (base != cur)
1261*7c568831SAndroid Build Coastguard Worker                 xmlBufferAdd(buf, base, cur - base);
1262*7c568831SAndroid Build Coastguard Worker 	    xmlBufferCCat(buf, "\"");
1263*7c568831SAndroid Build Coastguard Worker 	}
1264*7c568831SAndroid Build Coastguard Worker         else{
1265*7c568831SAndroid Build Coastguard Worker 	    xmlBufferCCat(buf, "\'");
1266*7c568831SAndroid Build Coastguard Worker             xmlBufferCat(buf, string);
1267*7c568831SAndroid Build Coastguard Worker 	    xmlBufferCCat(buf, "\'");
1268*7c568831SAndroid Build Coastguard Worker         }
1269*7c568831SAndroid Build Coastguard Worker     } else {
1270*7c568831SAndroid Build Coastguard Worker         xmlBufferCCat(buf, "\"");
1271*7c568831SAndroid Build Coastguard Worker         xmlBufferCat(buf, string);
1272*7c568831SAndroid Build Coastguard Worker         xmlBufferCCat(buf, "\"");
1273*7c568831SAndroid Build Coastguard Worker     }
1274*7c568831SAndroid Build Coastguard Worker }
1275*7c568831SAndroid Build Coastguard Worker 
1276