xref: /aosp_15_r20/external/libxml2/xmlsave.c (revision 7c5688314b92172186c154356a6374bf7684c3ca)
1*7c568831SAndroid Build Coastguard Worker /*
2*7c568831SAndroid Build Coastguard Worker  * xmlsave.c: Implementation of the document serializer
3*7c568831SAndroid Build Coastguard Worker  *
4*7c568831SAndroid Build Coastguard Worker  * See Copyright for the status of this software.
5*7c568831SAndroid Build Coastguard Worker  *
6*7c568831SAndroid Build Coastguard Worker  * [email protected]
7*7c568831SAndroid Build Coastguard Worker  */
8*7c568831SAndroid Build Coastguard Worker 
9*7c568831SAndroid Build Coastguard Worker #define IN_LIBXML
10*7c568831SAndroid Build Coastguard Worker #include "libxml.h"
11*7c568831SAndroid Build Coastguard Worker 
12*7c568831SAndroid Build Coastguard Worker #include <limits.h>
13*7c568831SAndroid Build Coastguard Worker #include <stdlib.h>
14*7c568831SAndroid Build Coastguard Worker #include <string.h>
15*7c568831SAndroid Build Coastguard Worker #include <libxml/xmlmemory.h>
16*7c568831SAndroid Build Coastguard Worker #include <libxml/parserInternals.h>
17*7c568831SAndroid Build Coastguard Worker #include <libxml/tree.h>
18*7c568831SAndroid Build Coastguard Worker #include <libxml/xmlsave.h>
19*7c568831SAndroid Build Coastguard Worker 
20*7c568831SAndroid Build Coastguard Worker #define MAX_INDENT 60
21*7c568831SAndroid Build Coastguard Worker 
22*7c568831SAndroid Build Coastguard Worker #include <libxml/HTMLtree.h>
23*7c568831SAndroid Build Coastguard Worker 
24*7c568831SAndroid Build Coastguard Worker #include "private/buf.h"
25*7c568831SAndroid Build Coastguard Worker #include "private/enc.h"
26*7c568831SAndroid Build Coastguard Worker #include "private/entities.h"
27*7c568831SAndroid Build Coastguard Worker #include "private/error.h"
28*7c568831SAndroid Build Coastguard Worker #include "private/io.h"
29*7c568831SAndroid Build Coastguard Worker #include "private/save.h"
30*7c568831SAndroid Build Coastguard Worker 
31*7c568831SAndroid Build Coastguard Worker #ifdef LIBXML_OUTPUT_ENABLED
32*7c568831SAndroid Build Coastguard Worker 
33*7c568831SAndroid Build Coastguard Worker #define XHTML_NS_NAME BAD_CAST "http://www.w3.org/1999/xhtml"
34*7c568831SAndroid Build Coastguard Worker 
35*7c568831SAndroid Build Coastguard Worker struct _xmlSaveCtxt {
36*7c568831SAndroid Build Coastguard Worker     void *_private;
37*7c568831SAndroid Build Coastguard Worker     int type;
38*7c568831SAndroid Build Coastguard Worker     int fd;
39*7c568831SAndroid Build Coastguard Worker     const xmlChar *filename;
40*7c568831SAndroid Build Coastguard Worker     const xmlChar *encoding;
41*7c568831SAndroid Build Coastguard Worker     xmlCharEncodingHandlerPtr handler;
42*7c568831SAndroid Build Coastguard Worker     xmlOutputBufferPtr buf;
43*7c568831SAndroid Build Coastguard Worker     int options;
44*7c568831SAndroid Build Coastguard Worker     int level;
45*7c568831SAndroid Build Coastguard Worker     int format;
46*7c568831SAndroid Build Coastguard Worker     char indent[MAX_INDENT + 1];	/* array for indenting output */
47*7c568831SAndroid Build Coastguard Worker     int indent_nr;
48*7c568831SAndroid Build Coastguard Worker     int indent_size;
49*7c568831SAndroid Build Coastguard Worker     xmlCharEncodingOutputFunc escape;	/* used for element content */
50*7c568831SAndroid Build Coastguard Worker };
51*7c568831SAndroid Build Coastguard Worker 
52*7c568831SAndroid Build Coastguard Worker /************************************************************************
53*7c568831SAndroid Build Coastguard Worker  *									*
54*7c568831SAndroid Build Coastguard Worker  *			Output error handlers				*
55*7c568831SAndroid Build Coastguard Worker  *									*
56*7c568831SAndroid Build Coastguard Worker  ************************************************************************/
57*7c568831SAndroid Build Coastguard Worker /**
58*7c568831SAndroid Build Coastguard Worker  * xmlSaveErrMemory:
59*7c568831SAndroid Build Coastguard Worker  * @extra:  extra information
60*7c568831SAndroid Build Coastguard Worker  *
61*7c568831SAndroid Build Coastguard Worker  * Handle an out of memory condition
62*7c568831SAndroid Build Coastguard Worker  */
63*7c568831SAndroid Build Coastguard Worker static void
xmlSaveErrMemory(xmlOutputBufferPtr out)64*7c568831SAndroid Build Coastguard Worker xmlSaveErrMemory(xmlOutputBufferPtr out)
65*7c568831SAndroid Build Coastguard Worker {
66*7c568831SAndroid Build Coastguard Worker     if (out != NULL)
67*7c568831SAndroid Build Coastguard Worker         out->error = XML_ERR_NO_MEMORY;
68*7c568831SAndroid Build Coastguard Worker     xmlRaiseMemoryError(NULL, NULL, NULL, XML_FROM_OUTPUT, NULL);
69*7c568831SAndroid Build Coastguard Worker }
70*7c568831SAndroid Build Coastguard Worker 
71*7c568831SAndroid Build Coastguard Worker /**
72*7c568831SAndroid Build Coastguard Worker  * xmlSaveErr:
73*7c568831SAndroid Build Coastguard Worker  * @code:  the error number
74*7c568831SAndroid Build Coastguard Worker  * @node:  the location of the error.
75*7c568831SAndroid Build Coastguard Worker  * @extra:  extra information
76*7c568831SAndroid Build Coastguard Worker  *
77*7c568831SAndroid Build Coastguard Worker  * Handle an out of memory condition
78*7c568831SAndroid Build Coastguard Worker  */
79*7c568831SAndroid Build Coastguard Worker static void
xmlSaveErr(xmlOutputBufferPtr out,int code,xmlNodePtr node,const char * extra)80*7c568831SAndroid Build Coastguard Worker xmlSaveErr(xmlOutputBufferPtr out, int code, xmlNodePtr node,
81*7c568831SAndroid Build Coastguard Worker            const char *extra)
82*7c568831SAndroid Build Coastguard Worker {
83*7c568831SAndroid Build Coastguard Worker     const char *msg = NULL;
84*7c568831SAndroid Build Coastguard Worker     int res;
85*7c568831SAndroid Build Coastguard Worker 
86*7c568831SAndroid Build Coastguard Worker     /* Don't overwrite memory errors */
87*7c568831SAndroid Build Coastguard Worker     if ((out != NULL) && (out->error == XML_ERR_NO_MEMORY))
88*7c568831SAndroid Build Coastguard Worker         return;
89*7c568831SAndroid Build Coastguard Worker 
90*7c568831SAndroid Build Coastguard Worker     if (code == XML_ERR_NO_MEMORY) {
91*7c568831SAndroid Build Coastguard Worker         xmlSaveErrMemory(out);
92*7c568831SAndroid Build Coastguard Worker         return;
93*7c568831SAndroid Build Coastguard Worker     }
94*7c568831SAndroid Build Coastguard Worker 
95*7c568831SAndroid Build Coastguard Worker     if (out != NULL)
96*7c568831SAndroid Build Coastguard Worker         out->error = code;
97*7c568831SAndroid Build Coastguard Worker 
98*7c568831SAndroid Build Coastguard Worker     if (code == XML_ERR_UNSUPPORTED_ENCODING) {
99*7c568831SAndroid Build Coastguard Worker         msg = "Unsupported encoding: %s";
100*7c568831SAndroid Build Coastguard Worker     } else {
101*7c568831SAndroid Build Coastguard Worker         msg = xmlErrString(code);
102*7c568831SAndroid Build Coastguard Worker         extra = NULL;
103*7c568831SAndroid Build Coastguard Worker     }
104*7c568831SAndroid Build Coastguard Worker 
105*7c568831SAndroid Build Coastguard Worker     res = xmlRaiseError(NULL, NULL, NULL, NULL, node,
106*7c568831SAndroid Build Coastguard Worker                         XML_FROM_OUTPUT, code, XML_ERR_ERROR, NULL, 0,
107*7c568831SAndroid Build Coastguard Worker                         extra, NULL, NULL, 0, 0,
108*7c568831SAndroid Build Coastguard Worker                         msg, extra);
109*7c568831SAndroid Build Coastguard Worker     if (res < 0)
110*7c568831SAndroid Build Coastguard Worker         xmlSaveErrMemory(out);
111*7c568831SAndroid Build Coastguard Worker }
112*7c568831SAndroid Build Coastguard Worker 
113*7c568831SAndroid Build Coastguard Worker /************************************************************************
114*7c568831SAndroid Build Coastguard Worker  *									*
115*7c568831SAndroid Build Coastguard Worker  *			Special escaping routines			*
116*7c568831SAndroid Build Coastguard Worker  *									*
117*7c568831SAndroid Build Coastguard Worker  ************************************************************************/
118*7c568831SAndroid Build Coastguard Worker 
119*7c568831SAndroid Build Coastguard Worker /*
120*7c568831SAndroid Build Coastguard Worker  * Tables generated with tools/genEscape.py
121*7c568831SAndroid Build Coastguard Worker  */
122*7c568831SAndroid Build Coastguard Worker 
123*7c568831SAndroid Build Coastguard Worker static const char xmlEscapeContent[] = {
124*7c568831SAndroid Build Coastguard Worker       8, '&', '#', 'x', 'F', 'F', 'F', 'D', ';',   4, '&', '#',
125*7c568831SAndroid Build Coastguard Worker     '9', ';',   5, '&', '#', '1', '0', ';',   5, '&', '#', '1',
126*7c568831SAndroid Build Coastguard Worker     '3', ';',   6, '&', 'q', 'u', 'o', 't', ';',   5, '&', 'a',
127*7c568831SAndroid Build Coastguard Worker     'm', 'p', ';',   4, '&', 'l', 't', ';',   4, '&', 'g', 't',
128*7c568831SAndroid Build Coastguard Worker     ';',
129*7c568831SAndroid Build Coastguard Worker };
130*7c568831SAndroid Build Coastguard Worker 
131*7c568831SAndroid Build Coastguard Worker static const signed char xmlEscapeTab[128] = {
132*7c568831SAndroid Build Coastguard Worker      0,  0,  0,  0,  0,  0,  0,  0,  0, -1, -1,  0,  0, 20,  0,  0,
133*7c568831SAndroid Build Coastguard Worker      0,  0,  0,  0, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
134*7c568831SAndroid Build Coastguard Worker     -1, -1, -1, -1, -1, -1, 33, -1, -1, -1, -1, -1, -1, -1, -1, -1,
135*7c568831SAndroid Build Coastguard Worker     -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 39, -1, 44, -1,
136*7c568831SAndroid Build Coastguard Worker     -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
137*7c568831SAndroid Build Coastguard Worker     -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
138*7c568831SAndroid Build Coastguard Worker     -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
139*7c568831SAndroid Build Coastguard Worker     -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
140*7c568831SAndroid Build Coastguard Worker };
141*7c568831SAndroid Build Coastguard Worker 
142*7c568831SAndroid Build Coastguard Worker static const signed char xmlEscapeTabAttr[128] = {
143*7c568831SAndroid Build Coastguard Worker      0,  0,  0,  0,  0,  0,  0,  0,  0,  9, 14,  0,  0, 20,  0,  0,
144*7c568831SAndroid Build Coastguard Worker      0,  0,  0,  0, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
145*7c568831SAndroid Build Coastguard Worker     -1, -1, 26, -1, -1, -1, 33, -1, -1, -1, -1, -1, -1, -1, -1, -1,
146*7c568831SAndroid Build Coastguard Worker     -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 39, -1, 44, -1,
147*7c568831SAndroid Build Coastguard Worker     -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
148*7c568831SAndroid Build Coastguard Worker     -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
149*7c568831SAndroid Build Coastguard Worker     -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
150*7c568831SAndroid Build Coastguard Worker     -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
151*7c568831SAndroid Build Coastguard Worker };
152*7c568831SAndroid Build Coastguard Worker 
153*7c568831SAndroid Build Coastguard Worker static void
xmlSerializeText(xmlOutputBufferPtr buf,const xmlChar * string,unsigned flags)154*7c568831SAndroid Build Coastguard Worker xmlSerializeText(xmlOutputBufferPtr buf, const xmlChar *string,
155*7c568831SAndroid Build Coastguard Worker                  unsigned flags) {
156*7c568831SAndroid Build Coastguard Worker     const char *cur;
157*7c568831SAndroid Build Coastguard Worker     const signed char *tab;
158*7c568831SAndroid Build Coastguard Worker 
159*7c568831SAndroid Build Coastguard Worker     if (string == NULL)
160*7c568831SAndroid Build Coastguard Worker         return;
161*7c568831SAndroid Build Coastguard Worker 
162*7c568831SAndroid Build Coastguard Worker     if (flags & XML_ESCAPE_ATTR)
163*7c568831SAndroid Build Coastguard Worker         tab = xmlEscapeTabAttr;
164*7c568831SAndroid Build Coastguard Worker     else
165*7c568831SAndroid Build Coastguard Worker         tab = xmlEscapeTab;
166*7c568831SAndroid Build Coastguard Worker 
167*7c568831SAndroid Build Coastguard Worker     cur = (const char *) string;
168*7c568831SAndroid Build Coastguard Worker 
169*7c568831SAndroid Build Coastguard Worker     while (*cur != 0) {
170*7c568831SAndroid Build Coastguard Worker         const char *base;
171*7c568831SAndroid Build Coastguard Worker         int c;
172*7c568831SAndroid Build Coastguard Worker         int offset;
173*7c568831SAndroid Build Coastguard Worker 
174*7c568831SAndroid Build Coastguard Worker         base = cur;
175*7c568831SAndroid Build Coastguard Worker         offset = -1;
176*7c568831SAndroid Build Coastguard Worker 
177*7c568831SAndroid Build Coastguard Worker         while (1) {
178*7c568831SAndroid Build Coastguard Worker             c = (unsigned char) *cur;
179*7c568831SAndroid Build Coastguard Worker 
180*7c568831SAndroid Build Coastguard Worker             if (c < 0x80) {
181*7c568831SAndroid Build Coastguard Worker                 offset = tab[c];
182*7c568831SAndroid Build Coastguard Worker                 if (offset >= 0)
183*7c568831SAndroid Build Coastguard Worker                     break;
184*7c568831SAndroid Build Coastguard Worker             } else if (flags & XML_ESCAPE_NON_ASCII) {
185*7c568831SAndroid Build Coastguard Worker                 break;
186*7c568831SAndroid Build Coastguard Worker             }
187*7c568831SAndroid Build Coastguard Worker 
188*7c568831SAndroid Build Coastguard Worker             cur += 1;
189*7c568831SAndroid Build Coastguard Worker         }
190*7c568831SAndroid Build Coastguard Worker 
191*7c568831SAndroid Build Coastguard Worker         if (cur > base)
192*7c568831SAndroid Build Coastguard Worker             xmlOutputBufferWrite(buf, cur - base, base);
193*7c568831SAndroid Build Coastguard Worker 
194*7c568831SAndroid Build Coastguard Worker         if (offset >= 0) {
195*7c568831SAndroid Build Coastguard Worker             if (c == 0)
196*7c568831SAndroid Build Coastguard Worker                 break;
197*7c568831SAndroid Build Coastguard Worker 
198*7c568831SAndroid Build Coastguard Worker             xmlOutputBufferWrite(buf, xmlEscapeContent[offset],
199*7c568831SAndroid Build Coastguard Worker                                  &xmlEscapeContent[offset+1]);
200*7c568831SAndroid Build Coastguard Worker             cur += 1;
201*7c568831SAndroid Build Coastguard Worker         } else {
202*7c568831SAndroid Build Coastguard Worker             char tempBuf[12];
203*7c568831SAndroid Build Coastguard Worker             int tempSize;
204*7c568831SAndroid Build Coastguard Worker             int val = 0, len = 4;
205*7c568831SAndroid Build Coastguard Worker 
206*7c568831SAndroid Build Coastguard Worker             val = xmlGetUTF8Char((const xmlChar *) cur, &len);
207*7c568831SAndroid Build Coastguard Worker             if (val < 0) {
208*7c568831SAndroid Build Coastguard Worker                 val = 0xFFFD;
209*7c568831SAndroid Build Coastguard Worker                 cur += 1;
210*7c568831SAndroid Build Coastguard Worker             } else {
211*7c568831SAndroid Build Coastguard Worker                 if (!IS_CHAR(val))
212*7c568831SAndroid Build Coastguard Worker                     val = 0xFFFD;
213*7c568831SAndroid Build Coastguard Worker                 cur += len;
214*7c568831SAndroid Build Coastguard Worker             }
215*7c568831SAndroid Build Coastguard Worker 
216*7c568831SAndroid Build Coastguard Worker             tempSize = xmlSerializeHexCharRef(tempBuf, val);
217*7c568831SAndroid Build Coastguard Worker             xmlOutputBufferWrite(buf, tempSize, tempBuf);
218*7c568831SAndroid Build Coastguard Worker         }
219*7c568831SAndroid Build Coastguard Worker     }
220*7c568831SAndroid Build Coastguard Worker }
221*7c568831SAndroid Build Coastguard Worker 
222*7c568831SAndroid Build Coastguard Worker /************************************************************************
223*7c568831SAndroid Build Coastguard Worker  *									*
224*7c568831SAndroid Build Coastguard Worker  *			Allocation and deallocation			*
225*7c568831SAndroid Build Coastguard Worker  *									*
226*7c568831SAndroid Build Coastguard Worker  ************************************************************************/
227*7c568831SAndroid Build Coastguard Worker 
228*7c568831SAndroid Build Coastguard Worker /**
229*7c568831SAndroid Build Coastguard Worker  * xmlSaveSetIndentString:
230*7c568831SAndroid Build Coastguard Worker  * @ctxt:  save context
231*7c568831SAndroid Build Coastguard Worker  * @indent:  indent string
232*7c568831SAndroid Build Coastguard Worker  *
233*7c568831SAndroid Build Coastguard Worker  * Sets the indent string.
234*7c568831SAndroid Build Coastguard Worker  *
235*7c568831SAndroid Build Coastguard Worker  * Available since 2.14.0.
236*7c568831SAndroid Build Coastguard Worker  *
237*7c568831SAndroid Build Coastguard Worker  * Returns 0 on success, -1 if the string is NULL, empty or too long.
238*7c568831SAndroid Build Coastguard Worker  */
239*7c568831SAndroid Build Coastguard Worker int
xmlSaveSetIndentString(xmlSaveCtxtPtr ctxt,const char * indent)240*7c568831SAndroid Build Coastguard Worker xmlSaveSetIndentString(xmlSaveCtxtPtr ctxt, const char *indent) {
241*7c568831SAndroid Build Coastguard Worker     size_t len;
242*7c568831SAndroid Build Coastguard Worker     int i;
243*7c568831SAndroid Build Coastguard Worker 
244*7c568831SAndroid Build Coastguard Worker     if ((ctxt == NULL) || (indent == NULL))
245*7c568831SAndroid Build Coastguard Worker         return(-1);
246*7c568831SAndroid Build Coastguard Worker 
247*7c568831SAndroid Build Coastguard Worker     len = strlen(indent);
248*7c568831SAndroid Build Coastguard Worker     if ((len <= 0) || (len > MAX_INDENT))
249*7c568831SAndroid Build Coastguard Worker         return(-1);
250*7c568831SAndroid Build Coastguard Worker 
251*7c568831SAndroid Build Coastguard Worker     ctxt->indent_size = len;
252*7c568831SAndroid Build Coastguard Worker     ctxt->indent_nr = MAX_INDENT / ctxt->indent_size;
253*7c568831SAndroid Build Coastguard Worker     for (i = 0; i < ctxt->indent_nr; i++)
254*7c568831SAndroid Build Coastguard Worker         memcpy(&ctxt->indent[i * ctxt->indent_size], indent, len);
255*7c568831SAndroid Build Coastguard Worker 
256*7c568831SAndroid Build Coastguard Worker     return(0);
257*7c568831SAndroid Build Coastguard Worker }
258*7c568831SAndroid Build Coastguard Worker 
259*7c568831SAndroid Build Coastguard Worker /**
260*7c568831SAndroid Build Coastguard Worker  * xmlSaveCtxtInit:
261*7c568831SAndroid Build Coastguard Worker  * @ctxt: the saving context
262*7c568831SAndroid Build Coastguard Worker  *
263*7c568831SAndroid Build Coastguard Worker  * Initialize a saving context
264*7c568831SAndroid Build Coastguard Worker  */
265*7c568831SAndroid Build Coastguard Worker static void
xmlSaveCtxtInit(xmlSaveCtxtPtr ctxt,int options)266*7c568831SAndroid Build Coastguard Worker xmlSaveCtxtInit(xmlSaveCtxtPtr ctxt, int options)
267*7c568831SAndroid Build Coastguard Worker {
268*7c568831SAndroid Build Coastguard Worker     if (ctxt == NULL) return;
269*7c568831SAndroid Build Coastguard Worker 
270*7c568831SAndroid Build Coastguard Worker     xmlSaveSetIndentString(ctxt, xmlTreeIndentString);
271*7c568831SAndroid Build Coastguard Worker 
272*7c568831SAndroid Build Coastguard Worker     if (options & XML_SAVE_FORMAT)
273*7c568831SAndroid Build Coastguard Worker         ctxt->format = 1;
274*7c568831SAndroid Build Coastguard Worker     else if (options & XML_SAVE_WSNONSIG)
275*7c568831SAndroid Build Coastguard Worker         ctxt->format = 2;
276*7c568831SAndroid Build Coastguard Worker 
277*7c568831SAndroid Build Coastguard Worker     if (((options & XML_SAVE_EMPTY) == 0) &&
278*7c568831SAndroid Build Coastguard Worker         (xmlSaveNoEmptyTags))
279*7c568831SAndroid Build Coastguard Worker 	options |= XML_SAVE_NO_EMPTY;
280*7c568831SAndroid Build Coastguard Worker 
281*7c568831SAndroid Build Coastguard Worker     ctxt->options = options;
282*7c568831SAndroid Build Coastguard Worker }
283*7c568831SAndroid Build Coastguard Worker 
284*7c568831SAndroid Build Coastguard Worker /**
285*7c568831SAndroid Build Coastguard Worker  * xmlFreeSaveCtxt:
286*7c568831SAndroid Build Coastguard Worker  *
287*7c568831SAndroid Build Coastguard Worker  * Free a saving context, destroying the output in any remaining buffer
288*7c568831SAndroid Build Coastguard Worker  */
289*7c568831SAndroid Build Coastguard Worker static void
xmlFreeSaveCtxt(xmlSaveCtxtPtr ctxt)290*7c568831SAndroid Build Coastguard Worker xmlFreeSaveCtxt(xmlSaveCtxtPtr ctxt)
291*7c568831SAndroid Build Coastguard Worker {
292*7c568831SAndroid Build Coastguard Worker     if (ctxt == NULL) return;
293*7c568831SAndroid Build Coastguard Worker     if (ctxt->encoding != NULL)
294*7c568831SAndroid Build Coastguard Worker         xmlFree((char *) ctxt->encoding);
295*7c568831SAndroid Build Coastguard Worker     if (ctxt->buf != NULL)
296*7c568831SAndroid Build Coastguard Worker         xmlOutputBufferClose(ctxt->buf);
297*7c568831SAndroid Build Coastguard Worker     xmlFree(ctxt);
298*7c568831SAndroid Build Coastguard Worker }
299*7c568831SAndroid Build Coastguard Worker 
300*7c568831SAndroid Build Coastguard Worker /**
301*7c568831SAndroid Build Coastguard Worker  * xmlNewSaveCtxt:
302*7c568831SAndroid Build Coastguard Worker  *
303*7c568831SAndroid Build Coastguard Worker  * Create a new saving context
304*7c568831SAndroid Build Coastguard Worker  *
305*7c568831SAndroid Build Coastguard Worker  * Returns the new structure or NULL in case of error
306*7c568831SAndroid Build Coastguard Worker  */
307*7c568831SAndroid Build Coastguard Worker static xmlSaveCtxtPtr
xmlNewSaveCtxt(const char * encoding,int options)308*7c568831SAndroid Build Coastguard Worker xmlNewSaveCtxt(const char *encoding, int options)
309*7c568831SAndroid Build Coastguard Worker {
310*7c568831SAndroid Build Coastguard Worker     xmlSaveCtxtPtr ret;
311*7c568831SAndroid Build Coastguard Worker 
312*7c568831SAndroid Build Coastguard Worker     ret = (xmlSaveCtxtPtr) xmlMalloc(sizeof(xmlSaveCtxt));
313*7c568831SAndroid Build Coastguard Worker     if (ret == NULL) {
314*7c568831SAndroid Build Coastguard Worker 	xmlSaveErrMemory(NULL);
315*7c568831SAndroid Build Coastguard Worker 	return ( NULL );
316*7c568831SAndroid Build Coastguard Worker     }
317*7c568831SAndroid Build Coastguard Worker     memset(ret, 0, sizeof(xmlSaveCtxt));
318*7c568831SAndroid Build Coastguard Worker 
319*7c568831SAndroid Build Coastguard Worker     if (encoding != NULL) {
320*7c568831SAndroid Build Coastguard Worker         int res;
321*7c568831SAndroid Build Coastguard Worker 
322*7c568831SAndroid Build Coastguard Worker         res = xmlOpenCharEncodingHandler(encoding, /* output */ 1,
323*7c568831SAndroid Build Coastguard Worker                                          &ret->handler);
324*7c568831SAndroid Build Coastguard Worker 	if (res != XML_ERR_OK) {
325*7c568831SAndroid Build Coastguard Worker 	    xmlSaveErr(NULL, res, NULL, encoding);
326*7c568831SAndroid Build Coastguard Worker             xmlFreeSaveCtxt(ret);
327*7c568831SAndroid Build Coastguard Worker 	    return(NULL);
328*7c568831SAndroid Build Coastguard Worker 	}
329*7c568831SAndroid Build Coastguard Worker         ret->encoding = xmlStrdup((const xmlChar *)encoding);
330*7c568831SAndroid Build Coastguard Worker     }
331*7c568831SAndroid Build Coastguard Worker 
332*7c568831SAndroid Build Coastguard Worker     xmlSaveCtxtInit(ret, options);
333*7c568831SAndroid Build Coastguard Worker 
334*7c568831SAndroid Build Coastguard Worker     return(ret);
335*7c568831SAndroid Build Coastguard Worker }
336*7c568831SAndroid Build Coastguard Worker 
337*7c568831SAndroid Build Coastguard Worker /************************************************************************
338*7c568831SAndroid Build Coastguard Worker  *									*
339*7c568831SAndroid Build Coastguard Worker  *		Dumping XML tree content to a simple buffer		*
340*7c568831SAndroid Build Coastguard Worker  *									*
341*7c568831SAndroid Build Coastguard Worker  ************************************************************************/
342*7c568831SAndroid Build Coastguard Worker 
343*7c568831SAndroid Build Coastguard Worker static void
xmlSaveWriteText(xmlSaveCtxt * ctxt,const xmlChar * text,unsigned flags)344*7c568831SAndroid Build Coastguard Worker xmlSaveWriteText(xmlSaveCtxt *ctxt, const xmlChar *text, unsigned flags) {
345*7c568831SAndroid Build Coastguard Worker     if (ctxt->encoding == NULL)
346*7c568831SAndroid Build Coastguard Worker         flags |= XML_ESCAPE_NON_ASCII;
347*7c568831SAndroid Build Coastguard Worker 
348*7c568831SAndroid Build Coastguard Worker     xmlSerializeText(ctxt->buf, text, flags);
349*7c568831SAndroid Build Coastguard Worker }
350*7c568831SAndroid Build Coastguard Worker 
351*7c568831SAndroid Build Coastguard Worker /**
352*7c568831SAndroid Build Coastguard Worker  * xmlSaveWriteAttrContent:
353*7c568831SAndroid Build Coastguard Worker  * @ctxt:  save context
354*7c568831SAndroid Build Coastguard Worker  * @attr:  the attribute pointer
355*7c568831SAndroid Build Coastguard Worker  *
356*7c568831SAndroid Build Coastguard Worker  * Serialize the attribute in the buffer
357*7c568831SAndroid Build Coastguard Worker  */
358*7c568831SAndroid Build Coastguard Worker static void
xmlSaveWriteAttrContent(xmlSaveCtxt * ctxt,xmlAttrPtr attr)359*7c568831SAndroid Build Coastguard Worker xmlSaveWriteAttrContent(xmlSaveCtxt *ctxt, xmlAttrPtr attr)
360*7c568831SAndroid Build Coastguard Worker {
361*7c568831SAndroid Build Coastguard Worker     xmlNodePtr children;
362*7c568831SAndroid Build Coastguard Worker     xmlOutputBufferPtr buf = ctxt->buf;
363*7c568831SAndroid Build Coastguard Worker 
364*7c568831SAndroid Build Coastguard Worker     children = attr->children;
365*7c568831SAndroid Build Coastguard Worker     while (children != NULL) {
366*7c568831SAndroid Build Coastguard Worker         switch (children->type) {
367*7c568831SAndroid Build Coastguard Worker             case XML_TEXT_NODE:
368*7c568831SAndroid Build Coastguard Worker 	        xmlSaveWriteText(ctxt, children->content, XML_ESCAPE_ATTR);
369*7c568831SAndroid Build Coastguard Worker 		break;
370*7c568831SAndroid Build Coastguard Worker             case XML_ENTITY_REF_NODE:
371*7c568831SAndroid Build Coastguard Worker                 xmlOutputBufferWrite(buf, 1, "&");
372*7c568831SAndroid Build Coastguard Worker                 xmlOutputBufferWriteString(buf, (const char *) children->name);
373*7c568831SAndroid Build Coastguard Worker                 xmlOutputBufferWrite(buf, 1, ";");
374*7c568831SAndroid Build Coastguard Worker                 break;
375*7c568831SAndroid Build Coastguard Worker             default:
376*7c568831SAndroid Build Coastguard Worker                 /* should not happen unless we have a badly built tree */
377*7c568831SAndroid Build Coastguard Worker                 break;
378*7c568831SAndroid Build Coastguard Worker         }
379*7c568831SAndroid Build Coastguard Worker         children = children->next;
380*7c568831SAndroid Build Coastguard Worker     }
381*7c568831SAndroid Build Coastguard Worker }
382*7c568831SAndroid Build Coastguard Worker 
383*7c568831SAndroid Build Coastguard Worker /**
384*7c568831SAndroid Build Coastguard Worker  * xmlBufDumpNotationDecl:
385*7c568831SAndroid Build Coastguard Worker  * @buf:  the XML buffer output
386*7c568831SAndroid Build Coastguard Worker  * @nota:  A notation declaration
387*7c568831SAndroid Build Coastguard Worker  *
388*7c568831SAndroid Build Coastguard Worker  * This will dump the content the notation declaration as an XML DTD definition
389*7c568831SAndroid Build Coastguard Worker  */
390*7c568831SAndroid Build Coastguard Worker static void
xmlBufDumpNotationDecl(xmlOutputBufferPtr buf,xmlNotationPtr nota)391*7c568831SAndroid Build Coastguard Worker xmlBufDumpNotationDecl(xmlOutputBufferPtr buf, xmlNotationPtr nota) {
392*7c568831SAndroid Build Coastguard Worker     xmlOutputBufferWrite(buf, 11, "<!NOTATION ");
393*7c568831SAndroid Build Coastguard Worker     xmlOutputBufferWriteString(buf, (const char *) nota->name);
394*7c568831SAndroid Build Coastguard Worker 
395*7c568831SAndroid Build Coastguard Worker     if (nota->PublicID != NULL) {
396*7c568831SAndroid Build Coastguard Worker 	xmlOutputBufferWrite(buf, 8, " PUBLIC ");
397*7c568831SAndroid Build Coastguard Worker 	xmlOutputBufferWriteQuotedString(buf, nota->PublicID);
398*7c568831SAndroid Build Coastguard Worker 	if (nota->SystemID != NULL) {
399*7c568831SAndroid Build Coastguard Worker 	    xmlOutputBufferWrite(buf, 1, " ");
400*7c568831SAndroid Build Coastguard Worker 	    xmlOutputBufferWriteQuotedString(buf, nota->SystemID);
401*7c568831SAndroid Build Coastguard Worker 	}
402*7c568831SAndroid Build Coastguard Worker     } else {
403*7c568831SAndroid Build Coastguard Worker 	xmlOutputBufferWrite(buf, 8, " SYSTEM ");
404*7c568831SAndroid Build Coastguard Worker 	xmlOutputBufferWriteQuotedString(buf, nota->SystemID);
405*7c568831SAndroid Build Coastguard Worker     }
406*7c568831SAndroid Build Coastguard Worker 
407*7c568831SAndroid Build Coastguard Worker     xmlOutputBufferWrite(buf, 3, " >\n");
408*7c568831SAndroid Build Coastguard Worker }
409*7c568831SAndroid Build Coastguard Worker 
410*7c568831SAndroid Build Coastguard Worker /**
411*7c568831SAndroid Build Coastguard Worker  * xmlBufDumpNotationDeclScan:
412*7c568831SAndroid Build Coastguard Worker  * @nota:  A notation declaration
413*7c568831SAndroid Build Coastguard Worker  * @buf:  the XML buffer output
414*7c568831SAndroid Build Coastguard Worker  *
415*7c568831SAndroid Build Coastguard Worker  * This is called with the hash scan function, and just reverses args
416*7c568831SAndroid Build Coastguard Worker  */
417*7c568831SAndroid Build Coastguard Worker static void
xmlBufDumpNotationDeclScan(void * nota,void * buf,const xmlChar * name ATTRIBUTE_UNUSED)418*7c568831SAndroid Build Coastguard Worker xmlBufDumpNotationDeclScan(void *nota, void *buf,
419*7c568831SAndroid Build Coastguard Worker                            const xmlChar *name ATTRIBUTE_UNUSED) {
420*7c568831SAndroid Build Coastguard Worker     xmlBufDumpNotationDecl((xmlOutputBufferPtr) buf, (xmlNotationPtr) nota);
421*7c568831SAndroid Build Coastguard Worker }
422*7c568831SAndroid Build Coastguard Worker 
423*7c568831SAndroid Build Coastguard Worker /**
424*7c568831SAndroid Build Coastguard Worker  * xmlBufDumpNotationTable:
425*7c568831SAndroid Build Coastguard Worker  * @buf:  an xmlBufPtr output
426*7c568831SAndroid Build Coastguard Worker  * @table:  A notation table
427*7c568831SAndroid Build Coastguard Worker  *
428*7c568831SAndroid Build Coastguard Worker  * This will dump the content of the notation table as an XML DTD definition
429*7c568831SAndroid Build Coastguard Worker  */
430*7c568831SAndroid Build Coastguard Worker static void
xmlBufDumpNotationTable(xmlOutputBufferPtr buf,xmlNotationTablePtr table)431*7c568831SAndroid Build Coastguard Worker xmlBufDumpNotationTable(xmlOutputBufferPtr buf, xmlNotationTablePtr table) {
432*7c568831SAndroid Build Coastguard Worker     xmlHashScan(table, xmlBufDumpNotationDeclScan, buf);
433*7c568831SAndroid Build Coastguard Worker }
434*7c568831SAndroid Build Coastguard Worker 
435*7c568831SAndroid Build Coastguard Worker /**
436*7c568831SAndroid Build Coastguard Worker  * xmlBufDumpElementOccur:
437*7c568831SAndroid Build Coastguard Worker  * @buf:  output buffer
438*7c568831SAndroid Build Coastguard Worker  * @cur:  element table
439*7c568831SAndroid Build Coastguard Worker  *
440*7c568831SAndroid Build Coastguard Worker  * Dump the occurrence operator of an element.
441*7c568831SAndroid Build Coastguard Worker  */
442*7c568831SAndroid Build Coastguard Worker static void
xmlBufDumpElementOccur(xmlOutputBufferPtr buf,xmlElementContentPtr cur)443*7c568831SAndroid Build Coastguard Worker xmlBufDumpElementOccur(xmlOutputBufferPtr buf, xmlElementContentPtr cur) {
444*7c568831SAndroid Build Coastguard Worker     switch (cur->ocur) {
445*7c568831SAndroid Build Coastguard Worker         case XML_ELEMENT_CONTENT_ONCE:
446*7c568831SAndroid Build Coastguard Worker             break;
447*7c568831SAndroid Build Coastguard Worker         case XML_ELEMENT_CONTENT_OPT:
448*7c568831SAndroid Build Coastguard Worker             xmlOutputBufferWrite(buf, 1, "?");
449*7c568831SAndroid Build Coastguard Worker             break;
450*7c568831SAndroid Build Coastguard Worker         case XML_ELEMENT_CONTENT_MULT:
451*7c568831SAndroid Build Coastguard Worker             xmlOutputBufferWrite(buf, 1, "*");
452*7c568831SAndroid Build Coastguard Worker             break;
453*7c568831SAndroid Build Coastguard Worker         case XML_ELEMENT_CONTENT_PLUS:
454*7c568831SAndroid Build Coastguard Worker             xmlOutputBufferWrite(buf, 1, "+");
455*7c568831SAndroid Build Coastguard Worker             break;
456*7c568831SAndroid Build Coastguard Worker     }
457*7c568831SAndroid Build Coastguard Worker }
458*7c568831SAndroid Build Coastguard Worker 
459*7c568831SAndroid Build Coastguard Worker /**
460*7c568831SAndroid Build Coastguard Worker  * xmlBufDumpElementContent:
461*7c568831SAndroid Build Coastguard Worker  * @buf:  output buffer
462*7c568831SAndroid Build Coastguard Worker  * @content:  element table
463*7c568831SAndroid Build Coastguard Worker  *
464*7c568831SAndroid Build Coastguard Worker  * This will dump the content of the element table as an XML DTD definition
465*7c568831SAndroid Build Coastguard Worker  */
466*7c568831SAndroid Build Coastguard Worker static void
xmlBufDumpElementContent(xmlOutputBufferPtr buf,xmlElementContentPtr content)467*7c568831SAndroid Build Coastguard Worker xmlBufDumpElementContent(xmlOutputBufferPtr buf,
468*7c568831SAndroid Build Coastguard Worker                          xmlElementContentPtr content) {
469*7c568831SAndroid Build Coastguard Worker     xmlElementContentPtr cur;
470*7c568831SAndroid Build Coastguard Worker 
471*7c568831SAndroid Build Coastguard Worker     if (content == NULL) return;
472*7c568831SAndroid Build Coastguard Worker 
473*7c568831SAndroid Build Coastguard Worker     xmlOutputBufferWrite(buf, 1, "(");
474*7c568831SAndroid Build Coastguard Worker     cur = content;
475*7c568831SAndroid Build Coastguard Worker 
476*7c568831SAndroid Build Coastguard Worker     do {
477*7c568831SAndroid Build Coastguard Worker         if (cur == NULL) return;
478*7c568831SAndroid Build Coastguard Worker 
479*7c568831SAndroid Build Coastguard Worker         switch (cur->type) {
480*7c568831SAndroid Build Coastguard Worker             case XML_ELEMENT_CONTENT_PCDATA:
481*7c568831SAndroid Build Coastguard Worker                 xmlOutputBufferWrite(buf, 7, "#PCDATA");
482*7c568831SAndroid Build Coastguard Worker                 break;
483*7c568831SAndroid Build Coastguard Worker             case XML_ELEMENT_CONTENT_ELEMENT:
484*7c568831SAndroid Build Coastguard Worker                 if (cur->prefix != NULL) {
485*7c568831SAndroid Build Coastguard Worker                     xmlOutputBufferWriteString(buf,
486*7c568831SAndroid Build Coastguard Worker                             (const char *) cur->prefix);
487*7c568831SAndroid Build Coastguard Worker                     xmlOutputBufferWrite(buf, 1, ":");
488*7c568831SAndroid Build Coastguard Worker                 }
489*7c568831SAndroid Build Coastguard Worker                 xmlOutputBufferWriteString(buf, (const char *) cur->name);
490*7c568831SAndroid Build Coastguard Worker                 break;
491*7c568831SAndroid Build Coastguard Worker             case XML_ELEMENT_CONTENT_SEQ:
492*7c568831SAndroid Build Coastguard Worker             case XML_ELEMENT_CONTENT_OR:
493*7c568831SAndroid Build Coastguard Worker                 if ((cur != content) &&
494*7c568831SAndroid Build Coastguard Worker                     (cur->parent != NULL) &&
495*7c568831SAndroid Build Coastguard Worker                     ((cur->type != cur->parent->type) ||
496*7c568831SAndroid Build Coastguard Worker                      (cur->ocur != XML_ELEMENT_CONTENT_ONCE)))
497*7c568831SAndroid Build Coastguard Worker                     xmlOutputBufferWrite(buf, 1, "(");
498*7c568831SAndroid Build Coastguard Worker                 cur = cur->c1;
499*7c568831SAndroid Build Coastguard Worker                 continue;
500*7c568831SAndroid Build Coastguard Worker         }
501*7c568831SAndroid Build Coastguard Worker 
502*7c568831SAndroid Build Coastguard Worker         while (cur != content) {
503*7c568831SAndroid Build Coastguard Worker             xmlElementContentPtr parent = cur->parent;
504*7c568831SAndroid Build Coastguard Worker 
505*7c568831SAndroid Build Coastguard Worker             if (parent == NULL) return;
506*7c568831SAndroid Build Coastguard Worker 
507*7c568831SAndroid Build Coastguard Worker             if (((cur->type == XML_ELEMENT_CONTENT_OR) ||
508*7c568831SAndroid Build Coastguard Worker                  (cur->type == XML_ELEMENT_CONTENT_SEQ)) &&
509*7c568831SAndroid Build Coastguard Worker                 ((cur->type != parent->type) ||
510*7c568831SAndroid Build Coastguard Worker                  (cur->ocur != XML_ELEMENT_CONTENT_ONCE)))
511*7c568831SAndroid Build Coastguard Worker                 xmlOutputBufferWrite(buf, 1, ")");
512*7c568831SAndroid Build Coastguard Worker             xmlBufDumpElementOccur(buf, cur);
513*7c568831SAndroid Build Coastguard Worker 
514*7c568831SAndroid Build Coastguard Worker             if (cur == parent->c1) {
515*7c568831SAndroid Build Coastguard Worker                 if (parent->type == XML_ELEMENT_CONTENT_SEQ)
516*7c568831SAndroid Build Coastguard Worker                     xmlOutputBufferWrite(buf, 3, " , ");
517*7c568831SAndroid Build Coastguard Worker                 else if (parent->type == XML_ELEMENT_CONTENT_OR)
518*7c568831SAndroid Build Coastguard Worker                     xmlOutputBufferWrite(buf, 3, " | ");
519*7c568831SAndroid Build Coastguard Worker 
520*7c568831SAndroid Build Coastguard Worker                 cur = parent->c2;
521*7c568831SAndroid Build Coastguard Worker                 break;
522*7c568831SAndroid Build Coastguard Worker             }
523*7c568831SAndroid Build Coastguard Worker 
524*7c568831SAndroid Build Coastguard Worker             cur = parent;
525*7c568831SAndroid Build Coastguard Worker         }
526*7c568831SAndroid Build Coastguard Worker     } while (cur != content);
527*7c568831SAndroid Build Coastguard Worker 
528*7c568831SAndroid Build Coastguard Worker     xmlOutputBufferWrite(buf, 1, ")");
529*7c568831SAndroid Build Coastguard Worker     xmlBufDumpElementOccur(buf, content);
530*7c568831SAndroid Build Coastguard Worker }
531*7c568831SAndroid Build Coastguard Worker 
532*7c568831SAndroid Build Coastguard Worker /**
533*7c568831SAndroid Build Coastguard Worker  * xmlBufDumpElementDecl:
534*7c568831SAndroid Build Coastguard Worker  * @buf:  an xmlBufPtr output
535*7c568831SAndroid Build Coastguard Worker  * @elem:  An element table
536*7c568831SAndroid Build Coastguard Worker  *
537*7c568831SAndroid Build Coastguard Worker  * This will dump the content of the element declaration as an XML
538*7c568831SAndroid Build Coastguard Worker  * DTD definition
539*7c568831SAndroid Build Coastguard Worker  */
540*7c568831SAndroid Build Coastguard Worker static void
xmlBufDumpElementDecl(xmlOutputBufferPtr buf,xmlElementPtr elem)541*7c568831SAndroid Build Coastguard Worker xmlBufDumpElementDecl(xmlOutputBufferPtr buf, xmlElementPtr elem) {
542*7c568831SAndroid Build Coastguard Worker     xmlOutputBufferWrite(buf, 10, "<!ELEMENT ");
543*7c568831SAndroid Build Coastguard Worker     if (elem->prefix != NULL) {
544*7c568831SAndroid Build Coastguard Worker         xmlOutputBufferWriteString(buf, (const char *) elem->prefix);
545*7c568831SAndroid Build Coastguard Worker         xmlOutputBufferWrite(buf, 1, ":");
546*7c568831SAndroid Build Coastguard Worker     }
547*7c568831SAndroid Build Coastguard Worker     xmlOutputBufferWriteString(buf, (const char *) elem->name);
548*7c568831SAndroid Build Coastguard Worker     xmlOutputBufferWrite(buf, 1, " ");
549*7c568831SAndroid Build Coastguard Worker 
550*7c568831SAndroid Build Coastguard Worker     switch (elem->etype) {
551*7c568831SAndroid Build Coastguard Worker 	case XML_ELEMENT_TYPE_EMPTY:
552*7c568831SAndroid Build Coastguard Worker 	    xmlOutputBufferWrite(buf, 5, "EMPTY");
553*7c568831SAndroid Build Coastguard Worker 	    break;
554*7c568831SAndroid Build Coastguard Worker 	case XML_ELEMENT_TYPE_ANY:
555*7c568831SAndroid Build Coastguard Worker 	    xmlOutputBufferWrite(buf, 3, "ANY");
556*7c568831SAndroid Build Coastguard Worker 	    break;
557*7c568831SAndroid Build Coastguard Worker 	case XML_ELEMENT_TYPE_MIXED:
558*7c568831SAndroid Build Coastguard Worker 	case XML_ELEMENT_TYPE_ELEMENT:
559*7c568831SAndroid Build Coastguard Worker 	    xmlBufDumpElementContent(buf, elem->content);
560*7c568831SAndroid Build Coastguard Worker 	    break;
561*7c568831SAndroid Build Coastguard Worker         default:
562*7c568831SAndroid Build Coastguard Worker             /* assert(0); */
563*7c568831SAndroid Build Coastguard Worker             break;
564*7c568831SAndroid Build Coastguard Worker     }
565*7c568831SAndroid Build Coastguard Worker 
566*7c568831SAndroid Build Coastguard Worker     xmlOutputBufferWrite(buf, 2, ">\n");
567*7c568831SAndroid Build Coastguard Worker }
568*7c568831SAndroid Build Coastguard Worker 
569*7c568831SAndroid Build Coastguard Worker /**
570*7c568831SAndroid Build Coastguard Worker  * xmlBufDumpEnumeration:
571*7c568831SAndroid Build Coastguard Worker  * @buf:  output buffer
572*7c568831SAndroid Build Coastguard Worker  * @enum:  An enumeration
573*7c568831SAndroid Build Coastguard Worker  *
574*7c568831SAndroid Build Coastguard Worker  * This will dump the content of the enumeration
575*7c568831SAndroid Build Coastguard Worker  */
576*7c568831SAndroid Build Coastguard Worker static void
xmlBufDumpEnumeration(xmlOutputBufferPtr buf,xmlEnumerationPtr cur)577*7c568831SAndroid Build Coastguard Worker xmlBufDumpEnumeration(xmlOutputBufferPtr buf, xmlEnumerationPtr cur) {
578*7c568831SAndroid Build Coastguard Worker     while (cur != NULL) {
579*7c568831SAndroid Build Coastguard Worker         xmlOutputBufferWriteString(buf, (const char *) cur->name);
580*7c568831SAndroid Build Coastguard Worker         if (cur->next != NULL)
581*7c568831SAndroid Build Coastguard Worker             xmlOutputBufferWrite(buf, 3, " | ");
582*7c568831SAndroid Build Coastguard Worker 
583*7c568831SAndroid Build Coastguard Worker         cur = cur->next;
584*7c568831SAndroid Build Coastguard Worker     }
585*7c568831SAndroid Build Coastguard Worker 
586*7c568831SAndroid Build Coastguard Worker     xmlOutputBufferWrite(buf, 1, ")");
587*7c568831SAndroid Build Coastguard Worker }
588*7c568831SAndroid Build Coastguard Worker /**
589*7c568831SAndroid Build Coastguard Worker  * xmlBufDumpAttributeDecl:
590*7c568831SAndroid Build Coastguard Worker  * @buf:  output buffer
591*7c568831SAndroid Build Coastguard Worker  * @attr:  An attribute declaration
592*7c568831SAndroid Build Coastguard Worker  *
593*7c568831SAndroid Build Coastguard Worker  * This will dump the content of the attribute declaration as an XML
594*7c568831SAndroid Build Coastguard Worker  * DTD definition
595*7c568831SAndroid Build Coastguard Worker  */
596*7c568831SAndroid Build Coastguard Worker static void
xmlBufDumpAttributeDecl(xmlOutputBufferPtr buf,xmlAttributePtr attr)597*7c568831SAndroid Build Coastguard Worker xmlBufDumpAttributeDecl(xmlOutputBufferPtr buf, xmlAttributePtr attr) {
598*7c568831SAndroid Build Coastguard Worker     xmlOutputBufferWrite(buf, 10, "<!ATTLIST ");
599*7c568831SAndroid Build Coastguard Worker     xmlOutputBufferWriteString(buf, (const char *) attr->elem);
600*7c568831SAndroid Build Coastguard Worker     xmlOutputBufferWrite(buf, 1, " ");
601*7c568831SAndroid Build Coastguard Worker     if (attr->prefix != NULL) {
602*7c568831SAndroid Build Coastguard Worker 	xmlOutputBufferWriteString(buf, (const char *) attr->prefix);
603*7c568831SAndroid Build Coastguard Worker 	xmlOutputBufferWrite(buf, 1, ":");
604*7c568831SAndroid Build Coastguard Worker     }
605*7c568831SAndroid Build Coastguard Worker     xmlOutputBufferWriteString(buf, (const char *) attr->name);
606*7c568831SAndroid Build Coastguard Worker 
607*7c568831SAndroid Build Coastguard Worker     switch (attr->atype) {
608*7c568831SAndroid Build Coastguard Worker 	case XML_ATTRIBUTE_CDATA:
609*7c568831SAndroid Build Coastguard Worker 	    xmlOutputBufferWrite(buf, 6, " CDATA");
610*7c568831SAndroid Build Coastguard Worker 	    break;
611*7c568831SAndroid Build Coastguard Worker 	case XML_ATTRIBUTE_ID:
612*7c568831SAndroid Build Coastguard Worker 	    xmlOutputBufferWrite(buf, 3, " ID");
613*7c568831SAndroid Build Coastguard Worker 	    break;
614*7c568831SAndroid Build Coastguard Worker 	case XML_ATTRIBUTE_IDREF:
615*7c568831SAndroid Build Coastguard Worker 	    xmlOutputBufferWrite(buf, 6, " IDREF");
616*7c568831SAndroid Build Coastguard Worker 	    break;
617*7c568831SAndroid Build Coastguard Worker 	case XML_ATTRIBUTE_IDREFS:
618*7c568831SAndroid Build Coastguard Worker 	    xmlOutputBufferWrite(buf, 7, " IDREFS");
619*7c568831SAndroid Build Coastguard Worker 	    break;
620*7c568831SAndroid Build Coastguard Worker 	case XML_ATTRIBUTE_ENTITY:
621*7c568831SAndroid Build Coastguard Worker 	    xmlOutputBufferWrite(buf, 7, " ENTITY");
622*7c568831SAndroid Build Coastguard Worker 	    break;
623*7c568831SAndroid Build Coastguard Worker 	case XML_ATTRIBUTE_ENTITIES:
624*7c568831SAndroid Build Coastguard Worker 	    xmlOutputBufferWrite(buf, 9, " ENTITIES");
625*7c568831SAndroid Build Coastguard Worker 	    break;
626*7c568831SAndroid Build Coastguard Worker 	case XML_ATTRIBUTE_NMTOKEN:
627*7c568831SAndroid Build Coastguard Worker 	    xmlOutputBufferWrite(buf, 8, " NMTOKEN");
628*7c568831SAndroid Build Coastguard Worker 	    break;
629*7c568831SAndroid Build Coastguard Worker 	case XML_ATTRIBUTE_NMTOKENS:
630*7c568831SAndroid Build Coastguard Worker 	    xmlOutputBufferWrite(buf, 9, " NMTOKENS");
631*7c568831SAndroid Build Coastguard Worker 	    break;
632*7c568831SAndroid Build Coastguard Worker 	case XML_ATTRIBUTE_ENUMERATION:
633*7c568831SAndroid Build Coastguard Worker 	    xmlOutputBufferWrite(buf, 2, " (");
634*7c568831SAndroid Build Coastguard Worker 	    xmlBufDumpEnumeration(buf, attr->tree);
635*7c568831SAndroid Build Coastguard Worker 	    break;
636*7c568831SAndroid Build Coastguard Worker 	case XML_ATTRIBUTE_NOTATION:
637*7c568831SAndroid Build Coastguard Worker 	    xmlOutputBufferWrite(buf, 11, " NOTATION (");
638*7c568831SAndroid Build Coastguard Worker 	    xmlBufDumpEnumeration(buf, attr->tree);
639*7c568831SAndroid Build Coastguard Worker 	    break;
640*7c568831SAndroid Build Coastguard Worker 	default:
641*7c568831SAndroid Build Coastguard Worker             /* assert(0); */
642*7c568831SAndroid Build Coastguard Worker             break;
643*7c568831SAndroid Build Coastguard Worker     }
644*7c568831SAndroid Build Coastguard Worker 
645*7c568831SAndroid Build Coastguard Worker     switch (attr->def) {
646*7c568831SAndroid Build Coastguard Worker 	case XML_ATTRIBUTE_NONE:
647*7c568831SAndroid Build Coastguard Worker 	    break;
648*7c568831SAndroid Build Coastguard Worker 	case XML_ATTRIBUTE_REQUIRED:
649*7c568831SAndroid Build Coastguard Worker 	    xmlOutputBufferWrite(buf, 10, " #REQUIRED");
650*7c568831SAndroid Build Coastguard Worker 	    break;
651*7c568831SAndroid Build Coastguard Worker 	case XML_ATTRIBUTE_IMPLIED:
652*7c568831SAndroid Build Coastguard Worker 	    xmlOutputBufferWrite(buf, 9, " #IMPLIED");
653*7c568831SAndroid Build Coastguard Worker 	    break;
654*7c568831SAndroid Build Coastguard Worker 	case XML_ATTRIBUTE_FIXED:
655*7c568831SAndroid Build Coastguard Worker 	    xmlOutputBufferWrite(buf, 7, " #FIXED");
656*7c568831SAndroid Build Coastguard Worker 	    break;
657*7c568831SAndroid Build Coastguard Worker 	default:
658*7c568831SAndroid Build Coastguard Worker             /* assert(0); */
659*7c568831SAndroid Build Coastguard Worker             break;
660*7c568831SAndroid Build Coastguard Worker     }
661*7c568831SAndroid Build Coastguard Worker 
662*7c568831SAndroid Build Coastguard Worker     if (attr->defaultValue != NULL) {
663*7c568831SAndroid Build Coastguard Worker 	xmlOutputBufferWrite(buf, 1, " ");
664*7c568831SAndroid Build Coastguard Worker 	xmlOutputBufferWriteQuotedString(buf, attr->defaultValue);
665*7c568831SAndroid Build Coastguard Worker     }
666*7c568831SAndroid Build Coastguard Worker 
667*7c568831SAndroid Build Coastguard Worker     xmlOutputBufferWrite(buf, 2, ">\n");
668*7c568831SAndroid Build Coastguard Worker }
669*7c568831SAndroid Build Coastguard Worker 
670*7c568831SAndroid Build Coastguard Worker /**
671*7c568831SAndroid Build Coastguard Worker  * xmlBufDumpEntityContent:
672*7c568831SAndroid Build Coastguard Worker  * @buf:  output buffer
673*7c568831SAndroid Build Coastguard Worker  * @content:  entity content.
674*7c568831SAndroid Build Coastguard Worker  *
675*7c568831SAndroid Build Coastguard Worker  * This will dump the quoted string value, taking care of the special
676*7c568831SAndroid Build Coastguard Worker  * treatment required by %
677*7c568831SAndroid Build Coastguard Worker  */
678*7c568831SAndroid Build Coastguard Worker static void
xmlBufDumpEntityContent(xmlOutputBufferPtr buf,const xmlChar * content)679*7c568831SAndroid Build Coastguard Worker xmlBufDumpEntityContent(xmlOutputBufferPtr buf, const xmlChar *content) {
680*7c568831SAndroid Build Coastguard Worker     if (xmlStrchr(content, '%')) {
681*7c568831SAndroid Build Coastguard Worker         const char * base, *cur;
682*7c568831SAndroid Build Coastguard Worker 
683*7c568831SAndroid Build Coastguard Worker 	xmlOutputBufferWrite(buf, 1, "\"");
684*7c568831SAndroid Build Coastguard Worker 	base = cur = (const char *) content;
685*7c568831SAndroid Build Coastguard Worker 	while (*cur != 0) {
686*7c568831SAndroid Build Coastguard Worker 	    if (*cur == '"') {
687*7c568831SAndroid Build Coastguard Worker 		if (base != cur)
688*7c568831SAndroid Build Coastguard Worker 		    xmlOutputBufferWrite(buf, cur - base, base);
689*7c568831SAndroid Build Coastguard Worker 		xmlOutputBufferWrite(buf, 6, "&quot;");
690*7c568831SAndroid Build Coastguard Worker 		cur++;
691*7c568831SAndroid Build Coastguard Worker 		base = cur;
692*7c568831SAndroid Build Coastguard Worker 	    } else if (*cur == '%') {
693*7c568831SAndroid Build Coastguard Worker 		if (base != cur)
694*7c568831SAndroid Build Coastguard Worker 		    xmlOutputBufferWrite(buf, cur - base, base);
695*7c568831SAndroid Build Coastguard Worker 		xmlOutputBufferWrite(buf, 6, "&#x25;");
696*7c568831SAndroid Build Coastguard Worker 		cur++;
697*7c568831SAndroid Build Coastguard Worker 		base = cur;
698*7c568831SAndroid Build Coastguard Worker 	    } else {
699*7c568831SAndroid Build Coastguard Worker 		cur++;
700*7c568831SAndroid Build Coastguard Worker 	    }
701*7c568831SAndroid Build Coastguard Worker 	}
702*7c568831SAndroid Build Coastguard Worker 	if (base != cur)
703*7c568831SAndroid Build Coastguard Worker 	    xmlOutputBufferWrite(buf, cur - base, base);
704*7c568831SAndroid Build Coastguard Worker 	xmlOutputBufferWrite(buf, 1, "\"");
705*7c568831SAndroid Build Coastguard Worker     } else {
706*7c568831SAndroid Build Coastguard Worker         xmlOutputBufferWriteQuotedString(buf, content);
707*7c568831SAndroid Build Coastguard Worker     }
708*7c568831SAndroid Build Coastguard Worker }
709*7c568831SAndroid Build Coastguard Worker 
710*7c568831SAndroid Build Coastguard Worker /**
711*7c568831SAndroid Build Coastguard Worker  * xmlBufDumpEntityDecl:
712*7c568831SAndroid Build Coastguard Worker  * @buf:  an xmlBufPtr output
713*7c568831SAndroid Build Coastguard Worker  * @ent:  An entity table
714*7c568831SAndroid Build Coastguard Worker  *
715*7c568831SAndroid Build Coastguard Worker  * This will dump the content of the entity table as an XML DTD definition
716*7c568831SAndroid Build Coastguard Worker  */
717*7c568831SAndroid Build Coastguard Worker static void
xmlBufDumpEntityDecl(xmlOutputBufferPtr buf,xmlEntityPtr ent)718*7c568831SAndroid Build Coastguard Worker xmlBufDumpEntityDecl(xmlOutputBufferPtr buf, xmlEntityPtr ent) {
719*7c568831SAndroid Build Coastguard Worker     if ((ent->etype == XML_INTERNAL_PARAMETER_ENTITY) ||
720*7c568831SAndroid Build Coastguard Worker         (ent->etype == XML_EXTERNAL_PARAMETER_ENTITY))
721*7c568831SAndroid Build Coastguard Worker         xmlOutputBufferWrite(buf, 11, "<!ENTITY % ");
722*7c568831SAndroid Build Coastguard Worker     else
723*7c568831SAndroid Build Coastguard Worker         xmlOutputBufferWrite(buf, 9, "<!ENTITY ");
724*7c568831SAndroid Build Coastguard Worker     xmlOutputBufferWriteString(buf, (const char *) ent->name);
725*7c568831SAndroid Build Coastguard Worker     xmlOutputBufferWrite(buf, 1, " ");
726*7c568831SAndroid Build Coastguard Worker 
727*7c568831SAndroid Build Coastguard Worker     if ((ent->etype == XML_EXTERNAL_GENERAL_PARSED_ENTITY) ||
728*7c568831SAndroid Build Coastguard Worker         (ent->etype == XML_EXTERNAL_GENERAL_UNPARSED_ENTITY) ||
729*7c568831SAndroid Build Coastguard Worker         (ent->etype == XML_EXTERNAL_PARAMETER_ENTITY)) {
730*7c568831SAndroid Build Coastguard Worker         if (ent->ExternalID != NULL) {
731*7c568831SAndroid Build Coastguard Worker              xmlOutputBufferWrite(buf, 7, "PUBLIC ");
732*7c568831SAndroid Build Coastguard Worker              xmlOutputBufferWriteQuotedString(buf, ent->ExternalID);
733*7c568831SAndroid Build Coastguard Worker              xmlOutputBufferWrite(buf, 1, " ");
734*7c568831SAndroid Build Coastguard Worker         } else {
735*7c568831SAndroid Build Coastguard Worker              xmlOutputBufferWrite(buf, 7, "SYSTEM ");
736*7c568831SAndroid Build Coastguard Worker         }
737*7c568831SAndroid Build Coastguard Worker         xmlOutputBufferWriteQuotedString(buf, ent->SystemID);
738*7c568831SAndroid Build Coastguard Worker     }
739*7c568831SAndroid Build Coastguard Worker 
740*7c568831SAndroid Build Coastguard Worker     if (ent->etype == XML_EXTERNAL_GENERAL_UNPARSED_ENTITY) {
741*7c568831SAndroid Build Coastguard Worker         if (ent->content != NULL) { /* Should be true ! */
742*7c568831SAndroid Build Coastguard Worker             xmlOutputBufferWrite(buf, 7, " NDATA ");
743*7c568831SAndroid Build Coastguard Worker             if (ent->orig != NULL)
744*7c568831SAndroid Build Coastguard Worker                 xmlOutputBufferWriteString(buf, (const char *) ent->orig);
745*7c568831SAndroid Build Coastguard Worker             else
746*7c568831SAndroid Build Coastguard Worker                 xmlOutputBufferWriteString(buf, (const char *) ent->content);
747*7c568831SAndroid Build Coastguard Worker         }
748*7c568831SAndroid Build Coastguard Worker     }
749*7c568831SAndroid Build Coastguard Worker 
750*7c568831SAndroid Build Coastguard Worker     if ((ent->etype == XML_INTERNAL_GENERAL_ENTITY) ||
751*7c568831SAndroid Build Coastguard Worker         (ent->etype == XML_INTERNAL_PARAMETER_ENTITY)) {
752*7c568831SAndroid Build Coastguard Worker         if (ent->orig != NULL)
753*7c568831SAndroid Build Coastguard Worker             xmlOutputBufferWriteQuotedString(buf, ent->orig);
754*7c568831SAndroid Build Coastguard Worker         else
755*7c568831SAndroid Build Coastguard Worker             xmlBufDumpEntityContent(buf, ent->content);
756*7c568831SAndroid Build Coastguard Worker     }
757*7c568831SAndroid Build Coastguard Worker 
758*7c568831SAndroid Build Coastguard Worker     xmlOutputBufferWrite(buf, 2, ">\n");
759*7c568831SAndroid Build Coastguard Worker }
760*7c568831SAndroid Build Coastguard Worker 
761*7c568831SAndroid Build Coastguard Worker /************************************************************************
762*7c568831SAndroid Build Coastguard Worker  *									*
763*7c568831SAndroid Build Coastguard Worker  *		Dumping XML tree content to an I/O output buffer	*
764*7c568831SAndroid Build Coastguard Worker  *									*
765*7c568831SAndroid Build Coastguard Worker  ************************************************************************/
766*7c568831SAndroid Build Coastguard Worker 
xmlSaveSwitchEncoding(xmlSaveCtxtPtr ctxt,const char * encoding)767*7c568831SAndroid Build Coastguard Worker static int xmlSaveSwitchEncoding(xmlSaveCtxtPtr ctxt, const char *encoding) {
768*7c568831SAndroid Build Coastguard Worker     xmlOutputBufferPtr buf = ctxt->buf;
769*7c568831SAndroid Build Coastguard Worker 
770*7c568831SAndroid Build Coastguard Worker     if ((encoding != NULL) && (buf->encoder == NULL) && (buf->conv == NULL)) {
771*7c568831SAndroid Build Coastguard Worker         xmlCharEncodingHandler *handler;
772*7c568831SAndroid Build Coastguard Worker         int res;
773*7c568831SAndroid Build Coastguard Worker 
774*7c568831SAndroid Build Coastguard Worker 	res = xmlOpenCharEncodingHandler(encoding, /* output */ 1, &handler);
775*7c568831SAndroid Build Coastguard Worker         if (res != XML_ERR_OK) {
776*7c568831SAndroid Build Coastguard Worker             xmlSaveErr(buf, res, NULL, encoding);
777*7c568831SAndroid Build Coastguard Worker             return(-1);
778*7c568831SAndroid Build Coastguard Worker         }
779*7c568831SAndroid Build Coastguard Worker 	buf->conv = xmlBufCreate(4000 /* MINLEN */);
780*7c568831SAndroid Build Coastguard Worker 	if (buf->conv == NULL) {
781*7c568831SAndroid Build Coastguard Worker 	    xmlCharEncCloseFunc(handler);
782*7c568831SAndroid Build Coastguard Worker             xmlSaveErrMemory(buf);
783*7c568831SAndroid Build Coastguard Worker 	    return(-1);
784*7c568831SAndroid Build Coastguard Worker 	}
785*7c568831SAndroid Build Coastguard Worker         buf->encoder = handler;
786*7c568831SAndroid Build Coastguard Worker 	/*
787*7c568831SAndroid Build Coastguard Worker 	 * initialize the state, e.g. if outputting a BOM
788*7c568831SAndroid Build Coastguard Worker 	 */
789*7c568831SAndroid Build Coastguard Worker         xmlCharEncOutput(buf, 1);
790*7c568831SAndroid Build Coastguard Worker     }
791*7c568831SAndroid Build Coastguard Worker     return(0);
792*7c568831SAndroid Build Coastguard Worker }
793*7c568831SAndroid Build Coastguard Worker 
xmlSaveClearEncoding(xmlSaveCtxtPtr ctxt)794*7c568831SAndroid Build Coastguard Worker static int xmlSaveClearEncoding(xmlSaveCtxtPtr ctxt) {
795*7c568831SAndroid Build Coastguard Worker     xmlOutputBufferPtr buf = ctxt->buf;
796*7c568831SAndroid Build Coastguard Worker     xmlOutputBufferFlush(buf);
797*7c568831SAndroid Build Coastguard Worker     xmlCharEncCloseFunc(buf->encoder);
798*7c568831SAndroid Build Coastguard Worker     xmlBufFree(buf->conv);
799*7c568831SAndroid Build Coastguard Worker     buf->encoder = NULL;
800*7c568831SAndroid Build Coastguard Worker     buf->conv = NULL;
801*7c568831SAndroid Build Coastguard Worker     return(0);
802*7c568831SAndroid Build Coastguard Worker }
803*7c568831SAndroid Build Coastguard Worker 
804*7c568831SAndroid Build Coastguard Worker #ifdef LIBXML_HTML_ENABLED
805*7c568831SAndroid Build Coastguard Worker static void
806*7c568831SAndroid Build Coastguard Worker xhtmlNodeDumpOutput(xmlSaveCtxtPtr ctxt, xmlNodePtr cur);
807*7c568831SAndroid Build Coastguard Worker #endif
808*7c568831SAndroid Build Coastguard Worker static void xmlNodeDumpOutputInternal(xmlSaveCtxtPtr ctxt, xmlNodePtr cur);
809*7c568831SAndroid Build Coastguard Worker static int xmlDocContentDumpOutput(xmlSaveCtxtPtr ctxt, xmlDocPtr cur);
810*7c568831SAndroid Build Coastguard Worker 
811*7c568831SAndroid Build Coastguard Worker static void
xmlSaveWriteIndent(xmlSaveCtxtPtr ctxt,int extra)812*7c568831SAndroid Build Coastguard Worker xmlSaveWriteIndent(xmlSaveCtxtPtr ctxt, int extra)
813*7c568831SAndroid Build Coastguard Worker {
814*7c568831SAndroid Build Coastguard Worker     int level;
815*7c568831SAndroid Build Coastguard Worker 
816*7c568831SAndroid Build Coastguard Worker     if ((ctxt->options & XML_SAVE_NO_INDENT) ||
817*7c568831SAndroid Build Coastguard Worker         (((ctxt->options & XML_SAVE_INDENT) == 0) &&
818*7c568831SAndroid Build Coastguard Worker          (xmlIndentTreeOutput == 0)))
819*7c568831SAndroid Build Coastguard Worker         return;
820*7c568831SAndroid Build Coastguard Worker 
821*7c568831SAndroid Build Coastguard Worker     level = ctxt->level + extra;
822*7c568831SAndroid Build Coastguard Worker     if (level > ctxt->indent_nr)
823*7c568831SAndroid Build Coastguard Worker         level = ctxt->indent_nr;
824*7c568831SAndroid Build Coastguard Worker     xmlOutputBufferWrite(ctxt->buf, ctxt->indent_size * level, ctxt->indent);
825*7c568831SAndroid Build Coastguard Worker }
826*7c568831SAndroid Build Coastguard Worker 
827*7c568831SAndroid Build Coastguard Worker /**
828*7c568831SAndroid Build Coastguard Worker  * xmlOutputBufferWriteWSNonSig:
829*7c568831SAndroid Build Coastguard Worker  * @ctxt:  The save context
830*7c568831SAndroid Build Coastguard Worker  * @extra: Number of extra indents to apply to ctxt->level
831*7c568831SAndroid Build Coastguard Worker  *
832*7c568831SAndroid Build Coastguard Worker  * Write out formatting for non-significant whitespace output.
833*7c568831SAndroid Build Coastguard Worker  */
834*7c568831SAndroid Build Coastguard Worker static void
xmlOutputBufferWriteWSNonSig(xmlSaveCtxtPtr ctxt,int extra)835*7c568831SAndroid Build Coastguard Worker xmlOutputBufferWriteWSNonSig(xmlSaveCtxtPtr ctxt, int extra)
836*7c568831SAndroid Build Coastguard Worker {
837*7c568831SAndroid Build Coastguard Worker     int i;
838*7c568831SAndroid Build Coastguard Worker     if ((ctxt == NULL) || (ctxt->buf == NULL))
839*7c568831SAndroid Build Coastguard Worker         return;
840*7c568831SAndroid Build Coastguard Worker     xmlOutputBufferWrite(ctxt->buf, 1, "\n");
841*7c568831SAndroid Build Coastguard Worker     for (i = 0; i < (ctxt->level + extra); i += ctxt->indent_nr) {
842*7c568831SAndroid Build Coastguard Worker         xmlOutputBufferWrite(ctxt->buf, ctxt->indent_size *
843*7c568831SAndroid Build Coastguard Worker                 ((ctxt->level + extra - i) > ctxt->indent_nr ?
844*7c568831SAndroid Build Coastguard Worker                  ctxt->indent_nr : (ctxt->level + extra - i)),
845*7c568831SAndroid Build Coastguard Worker                 ctxt->indent);
846*7c568831SAndroid Build Coastguard Worker     }
847*7c568831SAndroid Build Coastguard Worker }
848*7c568831SAndroid Build Coastguard Worker 
849*7c568831SAndroid Build Coastguard Worker /**
850*7c568831SAndroid Build Coastguard Worker  * xmlNsDumpOutput:
851*7c568831SAndroid Build Coastguard Worker  * @buf:  the XML buffer output
852*7c568831SAndroid Build Coastguard Worker  * @cur:  a namespace
853*7c568831SAndroid Build Coastguard Worker  * @ctxt: the output save context. Optional.
854*7c568831SAndroid Build Coastguard Worker  *
855*7c568831SAndroid Build Coastguard Worker  * Dump a local Namespace definition.
856*7c568831SAndroid Build Coastguard Worker  * Should be called in the context of attributes dumps.
857*7c568831SAndroid Build Coastguard Worker  * If @ctxt is supplied, @buf should be its buffer.
858*7c568831SAndroid Build Coastguard Worker  */
859*7c568831SAndroid Build Coastguard Worker static void
xmlNsDumpOutput(xmlOutputBufferPtr buf,xmlNsPtr cur,xmlSaveCtxtPtr ctxt)860*7c568831SAndroid Build Coastguard Worker xmlNsDumpOutput(xmlOutputBufferPtr buf, xmlNsPtr cur, xmlSaveCtxtPtr ctxt) {
861*7c568831SAndroid Build Coastguard Worker     unsigned escapeFlags = XML_ESCAPE_ATTR;
862*7c568831SAndroid Build Coastguard Worker 
863*7c568831SAndroid Build Coastguard Worker     if ((cur == NULL) || (buf == NULL)) return;
864*7c568831SAndroid Build Coastguard Worker 
865*7c568831SAndroid Build Coastguard Worker     if ((ctxt == NULL) || (ctxt->encoding == NULL))
866*7c568831SAndroid Build Coastguard Worker         escapeFlags |= XML_ESCAPE_NON_ASCII;
867*7c568831SAndroid Build Coastguard Worker 
868*7c568831SAndroid Build Coastguard Worker     if ((cur->type == XML_LOCAL_NAMESPACE) && (cur->href != NULL)) {
869*7c568831SAndroid Build Coastguard Worker 	if (xmlStrEqual(cur->prefix, BAD_CAST "xml"))
870*7c568831SAndroid Build Coastguard Worker 	    return;
871*7c568831SAndroid Build Coastguard Worker 
872*7c568831SAndroid Build Coastguard Worker 	if (ctxt != NULL && ctxt->format == 2)
873*7c568831SAndroid Build Coastguard Worker 	    xmlOutputBufferWriteWSNonSig(ctxt, 2);
874*7c568831SAndroid Build Coastguard Worker 	else
875*7c568831SAndroid Build Coastguard Worker 	    xmlOutputBufferWrite(buf, 1, " ");
876*7c568831SAndroid Build Coastguard Worker 
877*7c568831SAndroid Build Coastguard Worker         /* Within the context of an element attributes */
878*7c568831SAndroid Build Coastguard Worker 	if (cur->prefix != NULL) {
879*7c568831SAndroid Build Coastguard Worker 	    xmlOutputBufferWrite(buf, 6, "xmlns:");
880*7c568831SAndroid Build Coastguard Worker 	    xmlOutputBufferWriteString(buf, (const char *)cur->prefix);
881*7c568831SAndroid Build Coastguard Worker 	} else
882*7c568831SAndroid Build Coastguard Worker 	    xmlOutputBufferWrite(buf, 5, "xmlns");
883*7c568831SAndroid Build Coastguard Worker         xmlOutputBufferWrite(buf, 2, "=\"");
884*7c568831SAndroid Build Coastguard Worker         xmlSerializeText(buf, cur->href, escapeFlags);
885*7c568831SAndroid Build Coastguard Worker         xmlOutputBufferWrite(buf, 1, "\"");
886*7c568831SAndroid Build Coastguard Worker     }
887*7c568831SAndroid Build Coastguard Worker }
888*7c568831SAndroid Build Coastguard Worker 
889*7c568831SAndroid Build Coastguard Worker /**
890*7c568831SAndroid Build Coastguard Worker  * xmlNsListDumpOutputCtxt
891*7c568831SAndroid Build Coastguard Worker  * @ctxt: the save context
892*7c568831SAndroid Build Coastguard Worker  * @cur:  the first namespace
893*7c568831SAndroid Build Coastguard Worker  *
894*7c568831SAndroid Build Coastguard Worker  * Dump a list of local namespace definitions to a save context.
895*7c568831SAndroid Build Coastguard Worker  * Should be called in the context of attribute dumps.
896*7c568831SAndroid Build Coastguard Worker  */
897*7c568831SAndroid Build Coastguard Worker static void
xmlNsListDumpOutputCtxt(xmlSaveCtxtPtr ctxt,xmlNsPtr cur)898*7c568831SAndroid Build Coastguard Worker xmlNsListDumpOutputCtxt(xmlSaveCtxtPtr ctxt, xmlNsPtr cur) {
899*7c568831SAndroid Build Coastguard Worker     while (cur != NULL) {
900*7c568831SAndroid Build Coastguard Worker         xmlNsDumpOutput(ctxt->buf, cur, ctxt);
901*7c568831SAndroid Build Coastguard Worker 	cur = cur->next;
902*7c568831SAndroid Build Coastguard Worker     }
903*7c568831SAndroid Build Coastguard Worker }
904*7c568831SAndroid Build Coastguard Worker 
905*7c568831SAndroid Build Coastguard Worker /**
906*7c568831SAndroid Build Coastguard Worker  * xmlNsListDumpOutput:
907*7c568831SAndroid Build Coastguard Worker  * @buf:  the XML buffer output
908*7c568831SAndroid Build Coastguard Worker  * @cur:  the first namespace
909*7c568831SAndroid Build Coastguard Worker  *
910*7c568831SAndroid Build Coastguard Worker  * Dump a list of local Namespace definitions.
911*7c568831SAndroid Build Coastguard Worker  * Should be called in the context of attributes dumps.
912*7c568831SAndroid Build Coastguard Worker  */
913*7c568831SAndroid Build Coastguard Worker void
xmlNsListDumpOutput(xmlOutputBufferPtr buf,xmlNsPtr cur)914*7c568831SAndroid Build Coastguard Worker xmlNsListDumpOutput(xmlOutputBufferPtr buf, xmlNsPtr cur) {
915*7c568831SAndroid Build Coastguard Worker     while (cur != NULL) {
916*7c568831SAndroid Build Coastguard Worker         xmlNsDumpOutput(buf, cur, NULL);
917*7c568831SAndroid Build Coastguard Worker 	cur = cur->next;
918*7c568831SAndroid Build Coastguard Worker     }
919*7c568831SAndroid Build Coastguard Worker }
920*7c568831SAndroid Build Coastguard Worker 
921*7c568831SAndroid Build Coastguard Worker /**
922*7c568831SAndroid Build Coastguard Worker  * xmlDtdDumpOutput:
923*7c568831SAndroid Build Coastguard Worker  * @buf:  the XML buffer output
924*7c568831SAndroid Build Coastguard Worker  * @dtd:  the pointer to the DTD
925*7c568831SAndroid Build Coastguard Worker  *
926*7c568831SAndroid Build Coastguard Worker  * Dump the XML document DTD, if any.
927*7c568831SAndroid Build Coastguard Worker  */
928*7c568831SAndroid Build Coastguard Worker static void
xmlDtdDumpOutput(xmlSaveCtxtPtr ctxt,xmlDtdPtr dtd)929*7c568831SAndroid Build Coastguard Worker xmlDtdDumpOutput(xmlSaveCtxtPtr ctxt, xmlDtdPtr dtd) {
930*7c568831SAndroid Build Coastguard Worker     xmlOutputBufferPtr buf;
931*7c568831SAndroid Build Coastguard Worker     xmlNodePtr cur;
932*7c568831SAndroid Build Coastguard Worker     int format, level;
933*7c568831SAndroid Build Coastguard Worker 
934*7c568831SAndroid Build Coastguard Worker     if (dtd == NULL) return;
935*7c568831SAndroid Build Coastguard Worker     if ((ctxt == NULL) || (ctxt->buf == NULL))
936*7c568831SAndroid Build Coastguard Worker         return;
937*7c568831SAndroid Build Coastguard Worker     buf = ctxt->buf;
938*7c568831SAndroid Build Coastguard Worker     xmlOutputBufferWrite(buf, 10, "<!DOCTYPE ");
939*7c568831SAndroid Build Coastguard Worker     xmlOutputBufferWriteString(buf, (const char *)dtd->name);
940*7c568831SAndroid Build Coastguard Worker     if (dtd->ExternalID != NULL) {
941*7c568831SAndroid Build Coastguard Worker 	xmlOutputBufferWrite(buf, 8, " PUBLIC ");
942*7c568831SAndroid Build Coastguard Worker 	xmlOutputBufferWriteQuotedString(buf, dtd->ExternalID);
943*7c568831SAndroid Build Coastguard Worker 	xmlOutputBufferWrite(buf, 1, " ");
944*7c568831SAndroid Build Coastguard Worker 	xmlOutputBufferWriteQuotedString(buf, dtd->SystemID);
945*7c568831SAndroid Build Coastguard Worker     }  else if (dtd->SystemID != NULL) {
946*7c568831SAndroid Build Coastguard Worker 	xmlOutputBufferWrite(buf, 8, " SYSTEM ");
947*7c568831SAndroid Build Coastguard Worker 	xmlOutputBufferWriteQuotedString(buf, dtd->SystemID);
948*7c568831SAndroid Build Coastguard Worker     }
949*7c568831SAndroid Build Coastguard Worker     if ((dtd->entities == NULL) && (dtd->elements == NULL) &&
950*7c568831SAndroid Build Coastguard Worker         (dtd->attributes == NULL) && (dtd->notations == NULL) &&
951*7c568831SAndroid Build Coastguard Worker 	(dtd->pentities == NULL)) {
952*7c568831SAndroid Build Coastguard Worker 	xmlOutputBufferWrite(buf, 1, ">");
953*7c568831SAndroid Build Coastguard Worker 	return;
954*7c568831SAndroid Build Coastguard Worker     }
955*7c568831SAndroid Build Coastguard Worker     xmlOutputBufferWrite(buf, 3, " [\n");
956*7c568831SAndroid Build Coastguard Worker     /*
957*7c568831SAndroid Build Coastguard Worker      * Dump the notations first they are not in the DTD children list
958*7c568831SAndroid Build Coastguard Worker      * Do this only on a standalone DTD or on the internal subset though.
959*7c568831SAndroid Build Coastguard Worker      */
960*7c568831SAndroid Build Coastguard Worker     if ((dtd->notations != NULL) && ((dtd->doc == NULL) ||
961*7c568831SAndroid Build Coastguard Worker         (dtd->doc->intSubset == dtd))) {
962*7c568831SAndroid Build Coastguard Worker         xmlBufDumpNotationTable(buf, (xmlNotationTablePtr) dtd->notations);
963*7c568831SAndroid Build Coastguard Worker     }
964*7c568831SAndroid Build Coastguard Worker     format = ctxt->format;
965*7c568831SAndroid Build Coastguard Worker     level = ctxt->level;
966*7c568831SAndroid Build Coastguard Worker     ctxt->format = 0;
967*7c568831SAndroid Build Coastguard Worker     ctxt->level = -1;
968*7c568831SAndroid Build Coastguard Worker     for (cur = dtd->children; cur != NULL; cur = cur->next) {
969*7c568831SAndroid Build Coastguard Worker         xmlNodeDumpOutputInternal(ctxt, cur);
970*7c568831SAndroid Build Coastguard Worker     }
971*7c568831SAndroid Build Coastguard Worker     ctxt->format = format;
972*7c568831SAndroid Build Coastguard Worker     ctxt->level = level;
973*7c568831SAndroid Build Coastguard Worker     xmlOutputBufferWrite(buf, 2, "]>");
974*7c568831SAndroid Build Coastguard Worker }
975*7c568831SAndroid Build Coastguard Worker 
976*7c568831SAndroid Build Coastguard Worker /**
977*7c568831SAndroid Build Coastguard Worker  * xmlAttrDumpOutput:
978*7c568831SAndroid Build Coastguard Worker  * @buf:  the XML buffer output
979*7c568831SAndroid Build Coastguard Worker  * @cur:  the attribute pointer
980*7c568831SAndroid Build Coastguard Worker  *
981*7c568831SAndroid Build Coastguard Worker  * Dump an XML attribute
982*7c568831SAndroid Build Coastguard Worker  */
983*7c568831SAndroid Build Coastguard Worker static void
xmlAttrDumpOutput(xmlSaveCtxtPtr ctxt,xmlAttrPtr cur)984*7c568831SAndroid Build Coastguard Worker xmlAttrDumpOutput(xmlSaveCtxtPtr ctxt, xmlAttrPtr cur) {
985*7c568831SAndroid Build Coastguard Worker     xmlOutputBufferPtr buf;
986*7c568831SAndroid Build Coastguard Worker 
987*7c568831SAndroid Build Coastguard Worker     if (cur == NULL) return;
988*7c568831SAndroid Build Coastguard Worker     buf = ctxt->buf;
989*7c568831SAndroid Build Coastguard Worker     if (buf == NULL) return;
990*7c568831SAndroid Build Coastguard Worker     if (ctxt->format == 2)
991*7c568831SAndroid Build Coastguard Worker         xmlOutputBufferWriteWSNonSig(ctxt, 2);
992*7c568831SAndroid Build Coastguard Worker     else
993*7c568831SAndroid Build Coastguard Worker         xmlOutputBufferWrite(buf, 1, " ");
994*7c568831SAndroid Build Coastguard Worker     if ((cur->ns != NULL) && (cur->ns->prefix != NULL)) {
995*7c568831SAndroid Build Coastguard Worker         xmlOutputBufferWriteString(buf, (const char *)cur->ns->prefix);
996*7c568831SAndroid Build Coastguard Worker 	xmlOutputBufferWrite(buf, 1, ":");
997*7c568831SAndroid Build Coastguard Worker     }
998*7c568831SAndroid Build Coastguard Worker     xmlOutputBufferWriteString(buf, (const char *)cur->name);
999*7c568831SAndroid Build Coastguard Worker     xmlOutputBufferWrite(buf, 2, "=\"");
1000*7c568831SAndroid Build Coastguard Worker #ifdef LIBXML_HTML_ENABLED
1001*7c568831SAndroid Build Coastguard Worker     if ((ctxt->options & XML_SAVE_XHTML) &&
1002*7c568831SAndroid Build Coastguard Worker         (cur->ns == NULL) &&
1003*7c568831SAndroid Build Coastguard Worker         ((cur->children == NULL) ||
1004*7c568831SAndroid Build Coastguard Worker          (cur->children->content == NULL) ||
1005*7c568831SAndroid Build Coastguard Worker          (cur->children->content[0] == 0)) &&
1006*7c568831SAndroid Build Coastguard Worker         (htmlIsBooleanAttr(cur->name))) {
1007*7c568831SAndroid Build Coastguard Worker         xmlOutputBufferWriteString(buf, (const char *) cur->name);
1008*7c568831SAndroid Build Coastguard Worker     } else
1009*7c568831SAndroid Build Coastguard Worker #endif
1010*7c568831SAndroid Build Coastguard Worker     {
1011*7c568831SAndroid Build Coastguard Worker         xmlSaveWriteAttrContent(ctxt, cur);
1012*7c568831SAndroid Build Coastguard Worker     }
1013*7c568831SAndroid Build Coastguard Worker     xmlOutputBufferWrite(buf, 1, "\"");
1014*7c568831SAndroid Build Coastguard Worker }
1015*7c568831SAndroid Build Coastguard Worker 
1016*7c568831SAndroid Build Coastguard Worker #ifdef LIBXML_HTML_ENABLED
1017*7c568831SAndroid Build Coastguard Worker /**
1018*7c568831SAndroid Build Coastguard Worker  * htmlNodeDumpOutputInternal:
1019*7c568831SAndroid Build Coastguard Worker  * @cur:  the current node
1020*7c568831SAndroid Build Coastguard Worker  *
1021*7c568831SAndroid Build Coastguard Worker  * Dump an HTML node, recursive behaviour, children are printed too.
1022*7c568831SAndroid Build Coastguard Worker  */
1023*7c568831SAndroid Build Coastguard Worker static int
htmlNodeDumpOutputInternal(xmlSaveCtxtPtr ctxt,xmlNodePtr cur)1024*7c568831SAndroid Build Coastguard Worker htmlNodeDumpOutputInternal(xmlSaveCtxtPtr ctxt, xmlNodePtr cur) {
1025*7c568831SAndroid Build Coastguard Worker     const xmlChar *oldctxtenc = ctxt->encoding;
1026*7c568831SAndroid Build Coastguard Worker     const xmlChar *encoding = ctxt->encoding;
1027*7c568831SAndroid Build Coastguard Worker     xmlOutputBufferPtr buf = ctxt->buf;
1028*7c568831SAndroid Build Coastguard Worker     int switched_encoding = 0;
1029*7c568831SAndroid Build Coastguard Worker     xmlDocPtr doc;
1030*7c568831SAndroid Build Coastguard Worker 
1031*7c568831SAndroid Build Coastguard Worker     xmlInitParser();
1032*7c568831SAndroid Build Coastguard Worker 
1033*7c568831SAndroid Build Coastguard Worker     doc = cur->doc;
1034*7c568831SAndroid Build Coastguard Worker     if ((encoding == NULL) && (doc != NULL))
1035*7c568831SAndroid Build Coastguard Worker 	encoding = doc->encoding;
1036*7c568831SAndroid Build Coastguard Worker 
1037*7c568831SAndroid Build Coastguard Worker     if ((encoding != NULL) && (doc != NULL))
1038*7c568831SAndroid Build Coastguard Worker 	htmlSetMetaEncoding(doc, (const xmlChar *) encoding);
1039*7c568831SAndroid Build Coastguard Worker     if ((encoding == NULL) && (doc != NULL))
1040*7c568831SAndroid Build Coastguard Worker 	encoding = htmlGetMetaEncoding(doc);
1041*7c568831SAndroid Build Coastguard Worker     if (encoding == NULL)
1042*7c568831SAndroid Build Coastguard Worker 	encoding = BAD_CAST "HTML";
1043*7c568831SAndroid Build Coastguard Worker     if ((encoding != NULL) && (oldctxtenc == NULL) &&
1044*7c568831SAndroid Build Coastguard Worker 	(buf->encoder == NULL) && (buf->conv == NULL)) {
1045*7c568831SAndroid Build Coastguard Worker 	if (xmlSaveSwitchEncoding(ctxt, (const char*) encoding) < 0)
1046*7c568831SAndroid Build Coastguard Worker 	    return(-1);
1047*7c568831SAndroid Build Coastguard Worker 	switched_encoding = 1;
1048*7c568831SAndroid Build Coastguard Worker     }
1049*7c568831SAndroid Build Coastguard Worker     if (ctxt->options & XML_SAVE_FORMAT)
1050*7c568831SAndroid Build Coastguard Worker 	htmlNodeDumpFormatOutput(buf, doc, cur,
1051*7c568831SAndroid Build Coastguard Worker 				       (const char *)encoding, 1);
1052*7c568831SAndroid Build Coastguard Worker     else
1053*7c568831SAndroid Build Coastguard Worker 	htmlNodeDumpFormatOutput(buf, doc, cur,
1054*7c568831SAndroid Build Coastguard Worker 				       (const char *)encoding, 0);
1055*7c568831SAndroid Build Coastguard Worker     /*
1056*7c568831SAndroid Build Coastguard Worker      * Restore the state of the saving context at the end of the document
1057*7c568831SAndroid Build Coastguard Worker      */
1058*7c568831SAndroid Build Coastguard Worker     if ((switched_encoding) && (oldctxtenc == NULL)) {
1059*7c568831SAndroid Build Coastguard Worker 	xmlSaveClearEncoding(ctxt);
1060*7c568831SAndroid Build Coastguard Worker     }
1061*7c568831SAndroid Build Coastguard Worker     return(0);
1062*7c568831SAndroid Build Coastguard Worker }
1063*7c568831SAndroid Build Coastguard Worker #endif
1064*7c568831SAndroid Build Coastguard Worker 
1065*7c568831SAndroid Build Coastguard Worker /**
1066*7c568831SAndroid Build Coastguard Worker  * xmlNodeDumpOutputInternal:
1067*7c568831SAndroid Build Coastguard Worker  * @cur:  the current node
1068*7c568831SAndroid Build Coastguard Worker  *
1069*7c568831SAndroid Build Coastguard Worker  * Dump an XML node, recursive behaviour, children are printed too.
1070*7c568831SAndroid Build Coastguard Worker  */
1071*7c568831SAndroid Build Coastguard Worker static void
xmlNodeDumpOutputInternal(xmlSaveCtxtPtr ctxt,xmlNodePtr cur)1072*7c568831SAndroid Build Coastguard Worker xmlNodeDumpOutputInternal(xmlSaveCtxtPtr ctxt, xmlNodePtr cur) {
1073*7c568831SAndroid Build Coastguard Worker     int format = ctxt->format;
1074*7c568831SAndroid Build Coastguard Worker     xmlNodePtr tmp, root, unformattedNode = NULL, parent;
1075*7c568831SAndroid Build Coastguard Worker     xmlAttrPtr attr;
1076*7c568831SAndroid Build Coastguard Worker     xmlChar *start, *end;
1077*7c568831SAndroid Build Coastguard Worker     xmlOutputBufferPtr buf;
1078*7c568831SAndroid Build Coastguard Worker 
1079*7c568831SAndroid Build Coastguard Worker     if (cur == NULL) return;
1080*7c568831SAndroid Build Coastguard Worker     buf = ctxt->buf;
1081*7c568831SAndroid Build Coastguard Worker 
1082*7c568831SAndroid Build Coastguard Worker     root = cur;
1083*7c568831SAndroid Build Coastguard Worker     parent = cur->parent;
1084*7c568831SAndroid Build Coastguard Worker     while (1) {
1085*7c568831SAndroid Build Coastguard Worker         switch (cur->type) {
1086*7c568831SAndroid Build Coastguard Worker         case XML_DOCUMENT_NODE:
1087*7c568831SAndroid Build Coastguard Worker         case XML_HTML_DOCUMENT_NODE:
1088*7c568831SAndroid Build Coastguard Worker 	    xmlDocContentDumpOutput(ctxt, (xmlDocPtr) cur);
1089*7c568831SAndroid Build Coastguard Worker 	    break;
1090*7c568831SAndroid Build Coastguard Worker 
1091*7c568831SAndroid Build Coastguard Worker         case XML_DTD_NODE:
1092*7c568831SAndroid Build Coastguard Worker             xmlDtdDumpOutput(ctxt, (xmlDtdPtr) cur);
1093*7c568831SAndroid Build Coastguard Worker             break;
1094*7c568831SAndroid Build Coastguard Worker 
1095*7c568831SAndroid Build Coastguard Worker         case XML_DOCUMENT_FRAG_NODE:
1096*7c568831SAndroid Build Coastguard Worker             /* Always validate cur->parent when descending. */
1097*7c568831SAndroid Build Coastguard Worker             if ((cur->parent == parent) && (cur->children != NULL)) {
1098*7c568831SAndroid Build Coastguard Worker                 parent = cur;
1099*7c568831SAndroid Build Coastguard Worker                 cur = cur->children;
1100*7c568831SAndroid Build Coastguard Worker                 continue;
1101*7c568831SAndroid Build Coastguard Worker             }
1102*7c568831SAndroid Build Coastguard Worker 	    break;
1103*7c568831SAndroid Build Coastguard Worker 
1104*7c568831SAndroid Build Coastguard Worker         case XML_ELEMENT_DECL:
1105*7c568831SAndroid Build Coastguard Worker             xmlBufDumpElementDecl(buf, (xmlElementPtr) cur);
1106*7c568831SAndroid Build Coastguard Worker             break;
1107*7c568831SAndroid Build Coastguard Worker 
1108*7c568831SAndroid Build Coastguard Worker         case XML_ATTRIBUTE_DECL:
1109*7c568831SAndroid Build Coastguard Worker             xmlBufDumpAttributeDecl(buf, (xmlAttributePtr) cur);
1110*7c568831SAndroid Build Coastguard Worker             break;
1111*7c568831SAndroid Build Coastguard Worker 
1112*7c568831SAndroid Build Coastguard Worker         case XML_ENTITY_DECL:
1113*7c568831SAndroid Build Coastguard Worker             xmlBufDumpEntityDecl(buf, (xmlEntityPtr) cur);
1114*7c568831SAndroid Build Coastguard Worker             break;
1115*7c568831SAndroid Build Coastguard Worker 
1116*7c568831SAndroid Build Coastguard Worker         case XML_ELEMENT_NODE:
1117*7c568831SAndroid Build Coastguard Worker 	    if ((cur != root) && (ctxt->format == 1))
1118*7c568831SAndroid Build Coastguard Worker                 xmlSaveWriteIndent(ctxt, 0);
1119*7c568831SAndroid Build Coastguard Worker 
1120*7c568831SAndroid Build Coastguard Worker             /*
1121*7c568831SAndroid Build Coastguard Worker              * Some users like lxml are known to pass nodes with a corrupted
1122*7c568831SAndroid Build Coastguard Worker              * tree structure. Fall back to a recursive call to handle this
1123*7c568831SAndroid Build Coastguard Worker              * case.
1124*7c568831SAndroid Build Coastguard Worker              */
1125*7c568831SAndroid Build Coastguard Worker             if ((cur->parent != parent) && (cur->children != NULL)) {
1126*7c568831SAndroid Build Coastguard Worker                 xmlNodeDumpOutputInternal(ctxt, cur);
1127*7c568831SAndroid Build Coastguard Worker                 break;
1128*7c568831SAndroid Build Coastguard Worker             }
1129*7c568831SAndroid Build Coastguard Worker 
1130*7c568831SAndroid Build Coastguard Worker             xmlOutputBufferWrite(buf, 1, "<");
1131*7c568831SAndroid Build Coastguard Worker             if ((cur->ns != NULL) && (cur->ns->prefix != NULL)) {
1132*7c568831SAndroid Build Coastguard Worker                 xmlOutputBufferWriteString(buf, (const char *)cur->ns->prefix);
1133*7c568831SAndroid Build Coastguard Worker                 xmlOutputBufferWrite(buf, 1, ":");
1134*7c568831SAndroid Build Coastguard Worker             }
1135*7c568831SAndroid Build Coastguard Worker             xmlOutputBufferWriteString(buf, (const char *)cur->name);
1136*7c568831SAndroid Build Coastguard Worker             if (cur->nsDef)
1137*7c568831SAndroid Build Coastguard Worker                 xmlNsListDumpOutputCtxt(ctxt, cur->nsDef);
1138*7c568831SAndroid Build Coastguard Worker             for (attr = cur->properties; attr != NULL; attr = attr->next)
1139*7c568831SAndroid Build Coastguard Worker                 xmlAttrDumpOutput(ctxt, attr);
1140*7c568831SAndroid Build Coastguard Worker 
1141*7c568831SAndroid Build Coastguard Worker             if (cur->children == NULL) {
1142*7c568831SAndroid Build Coastguard Worker                 if ((ctxt->options & XML_SAVE_NO_EMPTY) == 0) {
1143*7c568831SAndroid Build Coastguard Worker                     if (ctxt->format == 2)
1144*7c568831SAndroid Build Coastguard Worker                         xmlOutputBufferWriteWSNonSig(ctxt, 0);
1145*7c568831SAndroid Build Coastguard Worker                     xmlOutputBufferWrite(buf, 2, "/>");
1146*7c568831SAndroid Build Coastguard Worker                 } else {
1147*7c568831SAndroid Build Coastguard Worker                     if (ctxt->format == 2)
1148*7c568831SAndroid Build Coastguard Worker                         xmlOutputBufferWriteWSNonSig(ctxt, 1);
1149*7c568831SAndroid Build Coastguard Worker                     xmlOutputBufferWrite(buf, 3, "></");
1150*7c568831SAndroid Build Coastguard Worker                     if ((cur->ns != NULL) && (cur->ns->prefix != NULL)) {
1151*7c568831SAndroid Build Coastguard Worker                         xmlOutputBufferWriteString(buf,
1152*7c568831SAndroid Build Coastguard Worker                                 (const char *)cur->ns->prefix);
1153*7c568831SAndroid Build Coastguard Worker                         xmlOutputBufferWrite(buf, 1, ":");
1154*7c568831SAndroid Build Coastguard Worker                     }
1155*7c568831SAndroid Build Coastguard Worker                     xmlOutputBufferWriteString(buf, (const char *)cur->name);
1156*7c568831SAndroid Build Coastguard Worker                     if (ctxt->format == 2)
1157*7c568831SAndroid Build Coastguard Worker                         xmlOutputBufferWriteWSNonSig(ctxt, 0);
1158*7c568831SAndroid Build Coastguard Worker                     xmlOutputBufferWrite(buf, 1, ">");
1159*7c568831SAndroid Build Coastguard Worker                 }
1160*7c568831SAndroid Build Coastguard Worker             } else {
1161*7c568831SAndroid Build Coastguard Worker                 if (ctxt->format == 1) {
1162*7c568831SAndroid Build Coastguard Worker                     tmp = cur->children;
1163*7c568831SAndroid Build Coastguard Worker                     while (tmp != NULL) {
1164*7c568831SAndroid Build Coastguard Worker                         if ((tmp->type == XML_TEXT_NODE) ||
1165*7c568831SAndroid Build Coastguard Worker                             (tmp->type == XML_CDATA_SECTION_NODE) ||
1166*7c568831SAndroid Build Coastguard Worker                             (tmp->type == XML_ENTITY_REF_NODE)) {
1167*7c568831SAndroid Build Coastguard Worker                             ctxt->format = 0;
1168*7c568831SAndroid Build Coastguard Worker                             unformattedNode = cur;
1169*7c568831SAndroid Build Coastguard Worker                             break;
1170*7c568831SAndroid Build Coastguard Worker                         }
1171*7c568831SAndroid Build Coastguard Worker                         tmp = tmp->next;
1172*7c568831SAndroid Build Coastguard Worker                     }
1173*7c568831SAndroid Build Coastguard Worker                 }
1174*7c568831SAndroid Build Coastguard Worker                 if (ctxt->format == 2)
1175*7c568831SAndroid Build Coastguard Worker                     xmlOutputBufferWriteWSNonSig(ctxt, 1);
1176*7c568831SAndroid Build Coastguard Worker                 xmlOutputBufferWrite(buf, 1, ">");
1177*7c568831SAndroid Build Coastguard Worker                 if (ctxt->format == 1) xmlOutputBufferWrite(buf, 1, "\n");
1178*7c568831SAndroid Build Coastguard Worker                 if (ctxt->level >= 0) ctxt->level++;
1179*7c568831SAndroid Build Coastguard Worker                 parent = cur;
1180*7c568831SAndroid Build Coastguard Worker                 cur = cur->children;
1181*7c568831SAndroid Build Coastguard Worker                 continue;
1182*7c568831SAndroid Build Coastguard Worker             }
1183*7c568831SAndroid Build Coastguard Worker 
1184*7c568831SAndroid Build Coastguard Worker             break;
1185*7c568831SAndroid Build Coastguard Worker 
1186*7c568831SAndroid Build Coastguard Worker         case XML_TEXT_NODE:
1187*7c568831SAndroid Build Coastguard Worker 	    if (cur->content == NULL)
1188*7c568831SAndroid Build Coastguard Worker                 break;
1189*7c568831SAndroid Build Coastguard Worker 	    if (cur->name != xmlStringTextNoenc) {
1190*7c568831SAndroid Build Coastguard Worker                 if (ctxt->escape)
1191*7c568831SAndroid Build Coastguard Worker                     xmlOutputBufferWriteEscape(buf, cur->content,
1192*7c568831SAndroid Build Coastguard Worker                                                ctxt->escape);
1193*7c568831SAndroid Build Coastguard Worker #ifdef TEST_OUTPUT_BUFFER_WRITE_ESCAPE
1194*7c568831SAndroid Build Coastguard Worker                 else if (ctxt->encoding)
1195*7c568831SAndroid Build Coastguard Worker                     xmlOutputBufferWriteEscape(buf, cur->content, NULL);
1196*7c568831SAndroid Build Coastguard Worker #endif
1197*7c568831SAndroid Build Coastguard Worker                 else
1198*7c568831SAndroid Build Coastguard Worker                     xmlSaveWriteText(ctxt, cur->content, /* flags */ 0);
1199*7c568831SAndroid Build Coastguard Worker 	    } else {
1200*7c568831SAndroid Build Coastguard Worker 		/*
1201*7c568831SAndroid Build Coastguard Worker 		 * Disable escaping, needed for XSLT
1202*7c568831SAndroid Build Coastguard Worker 		 */
1203*7c568831SAndroid Build Coastguard Worker 		xmlOutputBufferWriteString(buf, (const char *) cur->content);
1204*7c568831SAndroid Build Coastguard Worker 	    }
1205*7c568831SAndroid Build Coastguard Worker 	    break;
1206*7c568831SAndroid Build Coastguard Worker 
1207*7c568831SAndroid Build Coastguard Worker         case XML_PI_NODE:
1208*7c568831SAndroid Build Coastguard Worker 	    if ((cur != root) && (ctxt->format == 1))
1209*7c568831SAndroid Build Coastguard Worker                 xmlSaveWriteIndent(ctxt, 0);
1210*7c568831SAndroid Build Coastguard Worker 
1211*7c568831SAndroid Build Coastguard Worker             if (cur->content != NULL) {
1212*7c568831SAndroid Build Coastguard Worker                 xmlOutputBufferWrite(buf, 2, "<?");
1213*7c568831SAndroid Build Coastguard Worker                 xmlOutputBufferWriteString(buf, (const char *)cur->name);
1214*7c568831SAndroid Build Coastguard Worker                 if (cur->content != NULL) {
1215*7c568831SAndroid Build Coastguard Worker                     if (ctxt->format == 2)
1216*7c568831SAndroid Build Coastguard Worker                         xmlOutputBufferWriteWSNonSig(ctxt, 0);
1217*7c568831SAndroid Build Coastguard Worker                     else
1218*7c568831SAndroid Build Coastguard Worker                         xmlOutputBufferWrite(buf, 1, " ");
1219*7c568831SAndroid Build Coastguard Worker                     xmlOutputBufferWriteString(buf,
1220*7c568831SAndroid Build Coastguard Worker                             (const char *)cur->content);
1221*7c568831SAndroid Build Coastguard Worker                 }
1222*7c568831SAndroid Build Coastguard Worker                 xmlOutputBufferWrite(buf, 2, "?>");
1223*7c568831SAndroid Build Coastguard Worker             } else {
1224*7c568831SAndroid Build Coastguard Worker                 xmlOutputBufferWrite(buf, 2, "<?");
1225*7c568831SAndroid Build Coastguard Worker                 xmlOutputBufferWriteString(buf, (const char *)cur->name);
1226*7c568831SAndroid Build Coastguard Worker                 if (ctxt->format == 2)
1227*7c568831SAndroid Build Coastguard Worker                     xmlOutputBufferWriteWSNonSig(ctxt, 0);
1228*7c568831SAndroid Build Coastguard Worker                 xmlOutputBufferWrite(buf, 2, "?>");
1229*7c568831SAndroid Build Coastguard Worker             }
1230*7c568831SAndroid Build Coastguard Worker             break;
1231*7c568831SAndroid Build Coastguard Worker 
1232*7c568831SAndroid Build Coastguard Worker         case XML_COMMENT_NODE:
1233*7c568831SAndroid Build Coastguard Worker 	    if ((cur != root) && (ctxt->format == 1))
1234*7c568831SAndroid Build Coastguard Worker                 xmlSaveWriteIndent(ctxt, 0);
1235*7c568831SAndroid Build Coastguard Worker 
1236*7c568831SAndroid Build Coastguard Worker             if (cur->content != NULL) {
1237*7c568831SAndroid Build Coastguard Worker                 xmlOutputBufferWrite(buf, 4, "<!--");
1238*7c568831SAndroid Build Coastguard Worker                 xmlOutputBufferWriteString(buf, (const char *)cur->content);
1239*7c568831SAndroid Build Coastguard Worker                 xmlOutputBufferWrite(buf, 3, "-->");
1240*7c568831SAndroid Build Coastguard Worker             }
1241*7c568831SAndroid Build Coastguard Worker             break;
1242*7c568831SAndroid Build Coastguard Worker 
1243*7c568831SAndroid Build Coastguard Worker         case XML_ENTITY_REF_NODE:
1244*7c568831SAndroid Build Coastguard Worker             xmlOutputBufferWrite(buf, 1, "&");
1245*7c568831SAndroid Build Coastguard Worker             xmlOutputBufferWriteString(buf, (const char *)cur->name);
1246*7c568831SAndroid Build Coastguard Worker             xmlOutputBufferWrite(buf, 1, ";");
1247*7c568831SAndroid Build Coastguard Worker             break;
1248*7c568831SAndroid Build Coastguard Worker 
1249*7c568831SAndroid Build Coastguard Worker         case XML_CDATA_SECTION_NODE:
1250*7c568831SAndroid Build Coastguard Worker             if (cur->content == NULL || *cur->content == '\0') {
1251*7c568831SAndroid Build Coastguard Worker                 xmlOutputBufferWrite(buf, 12, "<![CDATA[]]>");
1252*7c568831SAndroid Build Coastguard Worker             } else {
1253*7c568831SAndroid Build Coastguard Worker                 start = end = cur->content;
1254*7c568831SAndroid Build Coastguard Worker                 while (*end != '\0') {
1255*7c568831SAndroid Build Coastguard Worker                     if ((*end == ']') && (*(end + 1) == ']') &&
1256*7c568831SAndroid Build Coastguard Worker                         (*(end + 2) == '>')) {
1257*7c568831SAndroid Build Coastguard Worker                         end = end + 2;
1258*7c568831SAndroid Build Coastguard Worker                         xmlOutputBufferWrite(buf, 9, "<![CDATA[");
1259*7c568831SAndroid Build Coastguard Worker                         xmlOutputBufferWrite(buf, end - start,
1260*7c568831SAndroid Build Coastguard Worker                                 (const char *)start);
1261*7c568831SAndroid Build Coastguard Worker                         xmlOutputBufferWrite(buf, 3, "]]>");
1262*7c568831SAndroid Build Coastguard Worker                         start = end;
1263*7c568831SAndroid Build Coastguard Worker                     }
1264*7c568831SAndroid Build Coastguard Worker                     end++;
1265*7c568831SAndroid Build Coastguard Worker                 }
1266*7c568831SAndroid Build Coastguard Worker                 if (start != end) {
1267*7c568831SAndroid Build Coastguard Worker                     xmlOutputBufferWrite(buf, 9, "<![CDATA[");
1268*7c568831SAndroid Build Coastguard Worker                     xmlOutputBufferWriteString(buf, (const char *)start);
1269*7c568831SAndroid Build Coastguard Worker                     xmlOutputBufferWrite(buf, 3, "]]>");
1270*7c568831SAndroid Build Coastguard Worker                 }
1271*7c568831SAndroid Build Coastguard Worker             }
1272*7c568831SAndroid Build Coastguard Worker             break;
1273*7c568831SAndroid Build Coastguard Worker 
1274*7c568831SAndroid Build Coastguard Worker         case XML_ATTRIBUTE_NODE:
1275*7c568831SAndroid Build Coastguard Worker             xmlAttrDumpOutput(ctxt, (xmlAttrPtr) cur);
1276*7c568831SAndroid Build Coastguard Worker             break;
1277*7c568831SAndroid Build Coastguard Worker 
1278*7c568831SAndroid Build Coastguard Worker         case XML_NAMESPACE_DECL:
1279*7c568831SAndroid Build Coastguard Worker             xmlNsDumpOutput(buf, (xmlNsPtr) cur, ctxt);
1280*7c568831SAndroid Build Coastguard Worker             break;
1281*7c568831SAndroid Build Coastguard Worker 
1282*7c568831SAndroid Build Coastguard Worker         default:
1283*7c568831SAndroid Build Coastguard Worker             break;
1284*7c568831SAndroid Build Coastguard Worker         }
1285*7c568831SAndroid Build Coastguard Worker 
1286*7c568831SAndroid Build Coastguard Worker         while (1) {
1287*7c568831SAndroid Build Coastguard Worker             if (cur == root)
1288*7c568831SAndroid Build Coastguard Worker                 return;
1289*7c568831SAndroid Build Coastguard Worker             if ((ctxt->format == 1) &&
1290*7c568831SAndroid Build Coastguard Worker                 (cur->type != XML_XINCLUDE_START) &&
1291*7c568831SAndroid Build Coastguard Worker                 (cur->type != XML_XINCLUDE_END))
1292*7c568831SAndroid Build Coastguard Worker                 xmlOutputBufferWrite(buf, 1, "\n");
1293*7c568831SAndroid Build Coastguard Worker             if (cur->next != NULL) {
1294*7c568831SAndroid Build Coastguard Worker                 cur = cur->next;
1295*7c568831SAndroid Build Coastguard Worker                 break;
1296*7c568831SAndroid Build Coastguard Worker             }
1297*7c568831SAndroid Build Coastguard Worker 
1298*7c568831SAndroid Build Coastguard Worker             cur = parent;
1299*7c568831SAndroid Build Coastguard Worker             /* cur->parent was validated when descending. */
1300*7c568831SAndroid Build Coastguard Worker             parent = cur->parent;
1301*7c568831SAndroid Build Coastguard Worker 
1302*7c568831SAndroid Build Coastguard Worker             if (cur->type == XML_ELEMENT_NODE) {
1303*7c568831SAndroid Build Coastguard Worker                 if (ctxt->level > 0) ctxt->level--;
1304*7c568831SAndroid Build Coastguard Worker                 if (ctxt->format == 1)
1305*7c568831SAndroid Build Coastguard Worker                     xmlSaveWriteIndent(ctxt, 0);
1306*7c568831SAndroid Build Coastguard Worker 
1307*7c568831SAndroid Build Coastguard Worker                 xmlOutputBufferWrite(buf, 2, "</");
1308*7c568831SAndroid Build Coastguard Worker                 if ((cur->ns != NULL) && (cur->ns->prefix != NULL)) {
1309*7c568831SAndroid Build Coastguard Worker                     xmlOutputBufferWriteString(buf,
1310*7c568831SAndroid Build Coastguard Worker                             (const char *)cur->ns->prefix);
1311*7c568831SAndroid Build Coastguard Worker                     xmlOutputBufferWrite(buf, 1, ":");
1312*7c568831SAndroid Build Coastguard Worker                 }
1313*7c568831SAndroid Build Coastguard Worker 
1314*7c568831SAndroid Build Coastguard Worker                 xmlOutputBufferWriteString(buf, (const char *)cur->name);
1315*7c568831SAndroid Build Coastguard Worker                 if (ctxt->format == 2)
1316*7c568831SAndroid Build Coastguard Worker                     xmlOutputBufferWriteWSNonSig(ctxt, 0);
1317*7c568831SAndroid Build Coastguard Worker                 xmlOutputBufferWrite(buf, 1, ">");
1318*7c568831SAndroid Build Coastguard Worker 
1319*7c568831SAndroid Build Coastguard Worker                 if (cur == unformattedNode) {
1320*7c568831SAndroid Build Coastguard Worker                     ctxt->format = format;
1321*7c568831SAndroid Build Coastguard Worker                     unformattedNode = NULL;
1322*7c568831SAndroid Build Coastguard Worker                 }
1323*7c568831SAndroid Build Coastguard Worker             }
1324*7c568831SAndroid Build Coastguard Worker         }
1325*7c568831SAndroid Build Coastguard Worker     }
1326*7c568831SAndroid Build Coastguard Worker }
1327*7c568831SAndroid Build Coastguard Worker 
1328*7c568831SAndroid Build Coastguard Worker /**
1329*7c568831SAndroid Build Coastguard Worker  * xmlDocContentDumpOutput:
1330*7c568831SAndroid Build Coastguard Worker  * @cur:  the document
1331*7c568831SAndroid Build Coastguard Worker  *
1332*7c568831SAndroid Build Coastguard Worker  * Dump an XML document.
1333*7c568831SAndroid Build Coastguard Worker  */
1334*7c568831SAndroid Build Coastguard Worker static int
xmlDocContentDumpOutput(xmlSaveCtxtPtr ctxt,xmlDocPtr cur)1335*7c568831SAndroid Build Coastguard Worker xmlDocContentDumpOutput(xmlSaveCtxtPtr ctxt, xmlDocPtr cur) {
1336*7c568831SAndroid Build Coastguard Worker #ifdef LIBXML_HTML_ENABLED
1337*7c568831SAndroid Build Coastguard Worker     xmlDtdPtr dtd;
1338*7c568831SAndroid Build Coastguard Worker     int is_xhtml = 0;
1339*7c568831SAndroid Build Coastguard Worker #endif
1340*7c568831SAndroid Build Coastguard Worker     const xmlChar *oldctxtenc = ctxt->encoding;
1341*7c568831SAndroid Build Coastguard Worker     const xmlChar *encoding = ctxt->encoding;
1342*7c568831SAndroid Build Coastguard Worker     xmlOutputBufferPtr buf = ctxt->buf;
1343*7c568831SAndroid Build Coastguard Worker     xmlCharEncoding enc;
1344*7c568831SAndroid Build Coastguard Worker     int switched_encoding = 0;
1345*7c568831SAndroid Build Coastguard Worker 
1346*7c568831SAndroid Build Coastguard Worker     xmlInitParser();
1347*7c568831SAndroid Build Coastguard Worker 
1348*7c568831SAndroid Build Coastguard Worker     if ((cur->type != XML_HTML_DOCUMENT_NODE) &&
1349*7c568831SAndroid Build Coastguard Worker         (cur->type != XML_DOCUMENT_NODE))
1350*7c568831SAndroid Build Coastguard Worker 	 return(-1);
1351*7c568831SAndroid Build Coastguard Worker 
1352*7c568831SAndroid Build Coastguard Worker     if (ctxt->encoding == NULL)
1353*7c568831SAndroid Build Coastguard Worker 	encoding = cur->encoding;
1354*7c568831SAndroid Build Coastguard Worker 
1355*7c568831SAndroid Build Coastguard Worker     if (((cur->type == XML_HTML_DOCUMENT_NODE) &&
1356*7c568831SAndroid Build Coastguard Worker          ((ctxt->options & XML_SAVE_AS_XML) == 0) &&
1357*7c568831SAndroid Build Coastguard Worker          ((ctxt->options & XML_SAVE_XHTML) == 0)) ||
1358*7c568831SAndroid Build Coastguard Worker         (ctxt->options & XML_SAVE_AS_HTML)) {
1359*7c568831SAndroid Build Coastguard Worker #ifdef LIBXML_HTML_ENABLED
1360*7c568831SAndroid Build Coastguard Worker         if (encoding != NULL)
1361*7c568831SAndroid Build Coastguard Worker 	    htmlSetMetaEncoding(cur, (const xmlChar *) encoding);
1362*7c568831SAndroid Build Coastguard Worker         if (encoding == NULL)
1363*7c568831SAndroid Build Coastguard Worker 	    encoding = htmlGetMetaEncoding(cur);
1364*7c568831SAndroid Build Coastguard Worker         if (encoding == NULL)
1365*7c568831SAndroid Build Coastguard Worker 	    encoding = BAD_CAST "HTML";
1366*7c568831SAndroid Build Coastguard Worker 	if ((encoding != NULL) && (oldctxtenc == NULL) &&
1367*7c568831SAndroid Build Coastguard Worker 	    (buf->encoder == NULL) && (buf->conv == NULL)) {
1368*7c568831SAndroid Build Coastguard Worker 	    if (xmlSaveSwitchEncoding(ctxt, (const char*) encoding) < 0) {
1369*7c568831SAndroid Build Coastguard Worker 		return(-1);
1370*7c568831SAndroid Build Coastguard Worker 	    }
1371*7c568831SAndroid Build Coastguard Worker 	}
1372*7c568831SAndroid Build Coastguard Worker         if (ctxt->options & XML_SAVE_FORMAT)
1373*7c568831SAndroid Build Coastguard Worker 	    htmlDocContentDumpFormatOutput(buf, cur,
1374*7c568831SAndroid Build Coastguard Worker 	                                   (const char *)encoding, 1);
1375*7c568831SAndroid Build Coastguard Worker 	else
1376*7c568831SAndroid Build Coastguard Worker 	    htmlDocContentDumpFormatOutput(buf, cur,
1377*7c568831SAndroid Build Coastguard Worker 	                                   (const char *)encoding, 0);
1378*7c568831SAndroid Build Coastguard Worker 	return(0);
1379*7c568831SAndroid Build Coastguard Worker #else
1380*7c568831SAndroid Build Coastguard Worker         return(-1);
1381*7c568831SAndroid Build Coastguard Worker #endif
1382*7c568831SAndroid Build Coastguard Worker     } else if ((cur->type == XML_DOCUMENT_NODE) ||
1383*7c568831SAndroid Build Coastguard Worker                (ctxt->options & XML_SAVE_AS_XML) ||
1384*7c568831SAndroid Build Coastguard Worker                (ctxt->options & XML_SAVE_XHTML)) {
1385*7c568831SAndroid Build Coastguard Worker 	enc = xmlParseCharEncoding((const char*) encoding);
1386*7c568831SAndroid Build Coastguard Worker 	if ((encoding != NULL) && (oldctxtenc == NULL) &&
1387*7c568831SAndroid Build Coastguard Worker 	    (buf->encoder == NULL) && (buf->conv == NULL) &&
1388*7c568831SAndroid Build Coastguard Worker 	    ((ctxt->options & XML_SAVE_NO_DECL) == 0)) {
1389*7c568831SAndroid Build Coastguard Worker 	    if ((enc != XML_CHAR_ENCODING_UTF8) &&
1390*7c568831SAndroid Build Coastguard Worker 		(enc != XML_CHAR_ENCODING_NONE) &&
1391*7c568831SAndroid Build Coastguard Worker 		(enc != XML_CHAR_ENCODING_ASCII)) {
1392*7c568831SAndroid Build Coastguard Worker 		/*
1393*7c568831SAndroid Build Coastguard Worker 		 * we need to switch to this encoding but just for this
1394*7c568831SAndroid Build Coastguard Worker 		 * document since we output the XMLDecl the conversion
1395*7c568831SAndroid Build Coastguard Worker 		 * must be done to not generate not well formed documents.
1396*7c568831SAndroid Build Coastguard Worker 		 */
1397*7c568831SAndroid Build Coastguard Worker 		if (xmlSaveSwitchEncoding(ctxt, (const char*) encoding) < 0)
1398*7c568831SAndroid Build Coastguard Worker 		    return(-1);
1399*7c568831SAndroid Build Coastguard Worker 		switched_encoding = 1;
1400*7c568831SAndroid Build Coastguard Worker 	    }
1401*7c568831SAndroid Build Coastguard Worker 	}
1402*7c568831SAndroid Build Coastguard Worker 
1403*7c568831SAndroid Build Coastguard Worker 
1404*7c568831SAndroid Build Coastguard Worker 	/*
1405*7c568831SAndroid Build Coastguard Worker 	 * Save the XML declaration
1406*7c568831SAndroid Build Coastguard Worker 	 */
1407*7c568831SAndroid Build Coastguard Worker 	if ((ctxt->options & XML_SAVE_NO_DECL) == 0) {
1408*7c568831SAndroid Build Coastguard Worker 	    xmlOutputBufferWrite(buf, 14, "<?xml version=");
1409*7c568831SAndroid Build Coastguard Worker 	    if (cur->version != NULL)
1410*7c568831SAndroid Build Coastguard Worker 		xmlOutputBufferWriteQuotedString(buf, cur->version);
1411*7c568831SAndroid Build Coastguard Worker 	    else
1412*7c568831SAndroid Build Coastguard Worker 		xmlOutputBufferWrite(buf, 5, "\"1.0\"");
1413*7c568831SAndroid Build Coastguard Worker 	    if (encoding != NULL) {
1414*7c568831SAndroid Build Coastguard Worker 		xmlOutputBufferWrite(buf, 10, " encoding=");
1415*7c568831SAndroid Build Coastguard Worker 		xmlOutputBufferWriteQuotedString(buf, (xmlChar *) encoding);
1416*7c568831SAndroid Build Coastguard Worker 	    }
1417*7c568831SAndroid Build Coastguard Worker 	    switch (cur->standalone) {
1418*7c568831SAndroid Build Coastguard Worker 		case 0:
1419*7c568831SAndroid Build Coastguard Worker 		    xmlOutputBufferWrite(buf, 16, " standalone=\"no\"");
1420*7c568831SAndroid Build Coastguard Worker 		    break;
1421*7c568831SAndroid Build Coastguard Worker 		case 1:
1422*7c568831SAndroid Build Coastguard Worker 		    xmlOutputBufferWrite(buf, 17, " standalone=\"yes\"");
1423*7c568831SAndroid Build Coastguard Worker 		    break;
1424*7c568831SAndroid Build Coastguard Worker 	    }
1425*7c568831SAndroid Build Coastguard Worker 	    xmlOutputBufferWrite(buf, 3, "?>\n");
1426*7c568831SAndroid Build Coastguard Worker 	}
1427*7c568831SAndroid Build Coastguard Worker 
1428*7c568831SAndroid Build Coastguard Worker #ifdef LIBXML_HTML_ENABLED
1429*7c568831SAndroid Build Coastguard Worker         if (ctxt->options & XML_SAVE_XHTML)
1430*7c568831SAndroid Build Coastguard Worker             is_xhtml = 1;
1431*7c568831SAndroid Build Coastguard Worker 	if ((ctxt->options & XML_SAVE_NO_XHTML) == 0) {
1432*7c568831SAndroid Build Coastguard Worker 	    dtd = xmlGetIntSubset(cur);
1433*7c568831SAndroid Build Coastguard Worker 	    if (dtd != NULL) {
1434*7c568831SAndroid Build Coastguard Worker 		is_xhtml = xmlIsXHTML(dtd->SystemID, dtd->ExternalID);
1435*7c568831SAndroid Build Coastguard Worker 		if (is_xhtml < 0) is_xhtml = 0;
1436*7c568831SAndroid Build Coastguard Worker 	    }
1437*7c568831SAndroid Build Coastguard Worker 	}
1438*7c568831SAndroid Build Coastguard Worker #endif
1439*7c568831SAndroid Build Coastguard Worker 	if (cur->children != NULL) {
1440*7c568831SAndroid Build Coastguard Worker 	    xmlNodePtr child = cur->children;
1441*7c568831SAndroid Build Coastguard Worker 
1442*7c568831SAndroid Build Coastguard Worker 	    while (child != NULL) {
1443*7c568831SAndroid Build Coastguard Worker 		ctxt->level = 0;
1444*7c568831SAndroid Build Coastguard Worker #ifdef LIBXML_HTML_ENABLED
1445*7c568831SAndroid Build Coastguard Worker 		if (is_xhtml)
1446*7c568831SAndroid Build Coastguard Worker 		    xhtmlNodeDumpOutput(ctxt, child);
1447*7c568831SAndroid Build Coastguard Worker 		else
1448*7c568831SAndroid Build Coastguard Worker #endif
1449*7c568831SAndroid Build Coastguard Worker 		    xmlNodeDumpOutputInternal(ctxt, child);
1450*7c568831SAndroid Build Coastguard Worker                 if ((child->type != XML_XINCLUDE_START) &&
1451*7c568831SAndroid Build Coastguard Worker                     (child->type != XML_XINCLUDE_END))
1452*7c568831SAndroid Build Coastguard Worker                     xmlOutputBufferWrite(buf, 1, "\n");
1453*7c568831SAndroid Build Coastguard Worker 		child = child->next;
1454*7c568831SAndroid Build Coastguard Worker 	    }
1455*7c568831SAndroid Build Coastguard Worker 	}
1456*7c568831SAndroid Build Coastguard Worker     }
1457*7c568831SAndroid Build Coastguard Worker 
1458*7c568831SAndroid Build Coastguard Worker     /*
1459*7c568831SAndroid Build Coastguard Worker      * Restore the state of the saving context at the end of the document
1460*7c568831SAndroid Build Coastguard Worker      */
1461*7c568831SAndroid Build Coastguard Worker     if ((switched_encoding) && (oldctxtenc == NULL)) {
1462*7c568831SAndroid Build Coastguard Worker 	xmlSaveClearEncoding(ctxt);
1463*7c568831SAndroid Build Coastguard Worker     }
1464*7c568831SAndroid Build Coastguard Worker     return(0);
1465*7c568831SAndroid Build Coastguard Worker }
1466*7c568831SAndroid Build Coastguard Worker 
1467*7c568831SAndroid Build Coastguard Worker #ifdef LIBXML_HTML_ENABLED
1468*7c568831SAndroid Build Coastguard Worker /************************************************************************
1469*7c568831SAndroid Build Coastguard Worker  *									*
1470*7c568831SAndroid Build Coastguard Worker  *		Functions specific to XHTML serialization		*
1471*7c568831SAndroid Build Coastguard Worker  *									*
1472*7c568831SAndroid Build Coastguard Worker  ************************************************************************/
1473*7c568831SAndroid Build Coastguard Worker 
1474*7c568831SAndroid Build Coastguard Worker /**
1475*7c568831SAndroid Build Coastguard Worker  * xhtmlIsEmpty:
1476*7c568831SAndroid Build Coastguard Worker  * @node:  the node
1477*7c568831SAndroid Build Coastguard Worker  *
1478*7c568831SAndroid Build Coastguard Worker  * Check if a node is an empty xhtml node
1479*7c568831SAndroid Build Coastguard Worker  *
1480*7c568831SAndroid Build Coastguard Worker  * Returns 1 if the node is an empty node, 0 if not and -1 in case of error
1481*7c568831SAndroid Build Coastguard Worker  */
1482*7c568831SAndroid Build Coastguard Worker static int
xhtmlIsEmpty(xmlNodePtr node)1483*7c568831SAndroid Build Coastguard Worker xhtmlIsEmpty(xmlNodePtr node) {
1484*7c568831SAndroid Build Coastguard Worker     if (node == NULL)
1485*7c568831SAndroid Build Coastguard Worker 	return(-1);
1486*7c568831SAndroid Build Coastguard Worker     if (node->type != XML_ELEMENT_NODE)
1487*7c568831SAndroid Build Coastguard Worker 	return(0);
1488*7c568831SAndroid Build Coastguard Worker     if ((node->ns != NULL) && (!xmlStrEqual(node->ns->href, XHTML_NS_NAME)))
1489*7c568831SAndroid Build Coastguard Worker 	return(0);
1490*7c568831SAndroid Build Coastguard Worker     if (node->children != NULL)
1491*7c568831SAndroid Build Coastguard Worker 	return(0);
1492*7c568831SAndroid Build Coastguard Worker     switch (node->name ? node->name[0] : 0) {
1493*7c568831SAndroid Build Coastguard Worker 	case 'a':
1494*7c568831SAndroid Build Coastguard Worker 	    if (xmlStrEqual(node->name, BAD_CAST "area"))
1495*7c568831SAndroid Build Coastguard Worker 		return(1);
1496*7c568831SAndroid Build Coastguard Worker 	    return(0);
1497*7c568831SAndroid Build Coastguard Worker 	case 'b':
1498*7c568831SAndroid Build Coastguard Worker 	    if (xmlStrEqual(node->name, BAD_CAST "br"))
1499*7c568831SAndroid Build Coastguard Worker 		return(1);
1500*7c568831SAndroid Build Coastguard Worker 	    if (xmlStrEqual(node->name, BAD_CAST "base"))
1501*7c568831SAndroid Build Coastguard Worker 		return(1);
1502*7c568831SAndroid Build Coastguard Worker 	    if (xmlStrEqual(node->name, BAD_CAST "basefont"))
1503*7c568831SAndroid Build Coastguard Worker 		return(1);
1504*7c568831SAndroid Build Coastguard Worker 	    return(0);
1505*7c568831SAndroid Build Coastguard Worker 	case 'c':
1506*7c568831SAndroid Build Coastguard Worker 	    if (xmlStrEqual(node->name, BAD_CAST "col"))
1507*7c568831SAndroid Build Coastguard Worker 		return(1);
1508*7c568831SAndroid Build Coastguard Worker 	    return(0);
1509*7c568831SAndroid Build Coastguard Worker 	case 'f':
1510*7c568831SAndroid Build Coastguard Worker 	    if (xmlStrEqual(node->name, BAD_CAST "frame"))
1511*7c568831SAndroid Build Coastguard Worker 		return(1);
1512*7c568831SAndroid Build Coastguard Worker 	    return(0);
1513*7c568831SAndroid Build Coastguard Worker 	case 'h':
1514*7c568831SAndroid Build Coastguard Worker 	    if (xmlStrEqual(node->name, BAD_CAST "hr"))
1515*7c568831SAndroid Build Coastguard Worker 		return(1);
1516*7c568831SAndroid Build Coastguard Worker 	    return(0);
1517*7c568831SAndroid Build Coastguard Worker 	case 'i':
1518*7c568831SAndroid Build Coastguard Worker 	    if (xmlStrEqual(node->name, BAD_CAST "img"))
1519*7c568831SAndroid Build Coastguard Worker 		return(1);
1520*7c568831SAndroid Build Coastguard Worker 	    if (xmlStrEqual(node->name, BAD_CAST "input"))
1521*7c568831SAndroid Build Coastguard Worker 		return(1);
1522*7c568831SAndroid Build Coastguard Worker 	    if (xmlStrEqual(node->name, BAD_CAST "isindex"))
1523*7c568831SAndroid Build Coastguard Worker 		return(1);
1524*7c568831SAndroid Build Coastguard Worker 	    return(0);
1525*7c568831SAndroid Build Coastguard Worker 	case 'l':
1526*7c568831SAndroid Build Coastguard Worker 	    if (xmlStrEqual(node->name, BAD_CAST "link"))
1527*7c568831SAndroid Build Coastguard Worker 		return(1);
1528*7c568831SAndroid Build Coastguard Worker 	    return(0);
1529*7c568831SAndroid Build Coastguard Worker 	case 'm':
1530*7c568831SAndroid Build Coastguard Worker 	    if (xmlStrEqual(node->name, BAD_CAST "meta"))
1531*7c568831SAndroid Build Coastguard Worker 		return(1);
1532*7c568831SAndroid Build Coastguard Worker 	    return(0);
1533*7c568831SAndroid Build Coastguard Worker 	case 'p':
1534*7c568831SAndroid Build Coastguard Worker 	    if (xmlStrEqual(node->name, BAD_CAST "param"))
1535*7c568831SAndroid Build Coastguard Worker 		return(1);
1536*7c568831SAndroid Build Coastguard Worker 	    return(0);
1537*7c568831SAndroid Build Coastguard Worker     }
1538*7c568831SAndroid Build Coastguard Worker     return(0);
1539*7c568831SAndroid Build Coastguard Worker }
1540*7c568831SAndroid Build Coastguard Worker 
1541*7c568831SAndroid Build Coastguard Worker /**
1542*7c568831SAndroid Build Coastguard Worker  * xhtmlAttrListDumpOutput:
1543*7c568831SAndroid Build Coastguard Worker  * @cur:  the first attribute pointer
1544*7c568831SAndroid Build Coastguard Worker  *
1545*7c568831SAndroid Build Coastguard Worker  * Dump a list of XML attributes
1546*7c568831SAndroid Build Coastguard Worker  */
1547*7c568831SAndroid Build Coastguard Worker static void
xhtmlAttrListDumpOutput(xmlSaveCtxtPtr ctxt,xmlAttrPtr cur)1548*7c568831SAndroid Build Coastguard Worker xhtmlAttrListDumpOutput(xmlSaveCtxtPtr ctxt, xmlAttrPtr cur) {
1549*7c568831SAndroid Build Coastguard Worker     xmlAttrPtr xml_lang = NULL;
1550*7c568831SAndroid Build Coastguard Worker     xmlAttrPtr lang = NULL;
1551*7c568831SAndroid Build Coastguard Worker     xmlAttrPtr name = NULL;
1552*7c568831SAndroid Build Coastguard Worker     xmlAttrPtr id = NULL;
1553*7c568831SAndroid Build Coastguard Worker     xmlNodePtr parent;
1554*7c568831SAndroid Build Coastguard Worker     xmlOutputBufferPtr buf;
1555*7c568831SAndroid Build Coastguard Worker 
1556*7c568831SAndroid Build Coastguard Worker     if (cur == NULL) return;
1557*7c568831SAndroid Build Coastguard Worker     buf = ctxt->buf;
1558*7c568831SAndroid Build Coastguard Worker     parent = cur->parent;
1559*7c568831SAndroid Build Coastguard Worker     while (cur != NULL) {
1560*7c568831SAndroid Build Coastguard Worker 	if ((cur->ns == NULL) && (xmlStrEqual(cur->name, BAD_CAST "id")))
1561*7c568831SAndroid Build Coastguard Worker 	    id = cur;
1562*7c568831SAndroid Build Coastguard Worker 	else
1563*7c568831SAndroid Build Coastguard Worker 	if ((cur->ns == NULL) && (xmlStrEqual(cur->name, BAD_CAST "name")))
1564*7c568831SAndroid Build Coastguard Worker 	    name = cur;
1565*7c568831SAndroid Build Coastguard Worker 	else
1566*7c568831SAndroid Build Coastguard Worker 	if ((cur->ns == NULL) && (xmlStrEqual(cur->name, BAD_CAST "lang")))
1567*7c568831SAndroid Build Coastguard Worker 	    lang = cur;
1568*7c568831SAndroid Build Coastguard Worker 	else
1569*7c568831SAndroid Build Coastguard Worker 	if ((cur->ns != NULL) && (xmlStrEqual(cur->name, BAD_CAST "lang")) &&
1570*7c568831SAndroid Build Coastguard Worker 	    (xmlStrEqual(cur->ns->prefix, BAD_CAST "xml")))
1571*7c568831SAndroid Build Coastguard Worker 	    xml_lang = cur;
1572*7c568831SAndroid Build Coastguard Worker         xmlAttrDumpOutput(ctxt, cur);
1573*7c568831SAndroid Build Coastguard Worker 	cur = cur->next;
1574*7c568831SAndroid Build Coastguard Worker     }
1575*7c568831SAndroid Build Coastguard Worker     /*
1576*7c568831SAndroid Build Coastguard Worker      * C.8
1577*7c568831SAndroid Build Coastguard Worker      */
1578*7c568831SAndroid Build Coastguard Worker     if ((name != NULL) && (id == NULL)) {
1579*7c568831SAndroid Build Coastguard Worker 	if ((parent != NULL) && (parent->name != NULL) &&
1580*7c568831SAndroid Build Coastguard Worker 	    ((xmlStrEqual(parent->name, BAD_CAST "a")) ||
1581*7c568831SAndroid Build Coastguard Worker 	     (xmlStrEqual(parent->name, BAD_CAST "p")) ||
1582*7c568831SAndroid Build Coastguard Worker 	     (xmlStrEqual(parent->name, BAD_CAST "div")) ||
1583*7c568831SAndroid Build Coastguard Worker 	     (xmlStrEqual(parent->name, BAD_CAST "img")) ||
1584*7c568831SAndroid Build Coastguard Worker 	     (xmlStrEqual(parent->name, BAD_CAST "map")) ||
1585*7c568831SAndroid Build Coastguard Worker 	     (xmlStrEqual(parent->name, BAD_CAST "applet")) ||
1586*7c568831SAndroid Build Coastguard Worker 	     (xmlStrEqual(parent->name, BAD_CAST "form")) ||
1587*7c568831SAndroid Build Coastguard Worker 	     (xmlStrEqual(parent->name, BAD_CAST "frame")) ||
1588*7c568831SAndroid Build Coastguard Worker 	     (xmlStrEqual(parent->name, BAD_CAST "iframe")))) {
1589*7c568831SAndroid Build Coastguard Worker 	    xmlOutputBufferWrite(buf, 5, " id=\"");
1590*7c568831SAndroid Build Coastguard Worker             xmlSaveWriteAttrContent(ctxt, name);
1591*7c568831SAndroid Build Coastguard Worker 	    xmlOutputBufferWrite(buf, 1, "\"");
1592*7c568831SAndroid Build Coastguard Worker 	}
1593*7c568831SAndroid Build Coastguard Worker     }
1594*7c568831SAndroid Build Coastguard Worker     /*
1595*7c568831SAndroid Build Coastguard Worker      * C.7.
1596*7c568831SAndroid Build Coastguard Worker      */
1597*7c568831SAndroid Build Coastguard Worker     if ((lang != NULL) && (xml_lang == NULL)) {
1598*7c568831SAndroid Build Coastguard Worker 	xmlOutputBufferWrite(buf, 11, " xml:lang=\"");
1599*7c568831SAndroid Build Coastguard Worker         xmlSaveWriteAttrContent(ctxt, lang);
1600*7c568831SAndroid Build Coastguard Worker 	xmlOutputBufferWrite(buf, 1, "\"");
1601*7c568831SAndroid Build Coastguard Worker     } else
1602*7c568831SAndroid Build Coastguard Worker     if ((xml_lang != NULL) && (lang == NULL)) {
1603*7c568831SAndroid Build Coastguard Worker 	xmlOutputBufferWrite(buf, 7, " lang=\"");
1604*7c568831SAndroid Build Coastguard Worker         xmlSaveWriteAttrContent(ctxt, xml_lang);
1605*7c568831SAndroid Build Coastguard Worker 	xmlOutputBufferWrite(buf, 1, "\"");
1606*7c568831SAndroid Build Coastguard Worker     }
1607*7c568831SAndroid Build Coastguard Worker }
1608*7c568831SAndroid Build Coastguard Worker 
1609*7c568831SAndroid Build Coastguard Worker /**
1610*7c568831SAndroid Build Coastguard Worker  * xhtmlNodeDumpOutput:
1611*7c568831SAndroid Build Coastguard Worker  * @buf:  the XML buffer output
1612*7c568831SAndroid Build Coastguard Worker  * @doc:  the XHTML document
1613*7c568831SAndroid Build Coastguard Worker  * @cur:  the current node
1614*7c568831SAndroid Build Coastguard Worker  * @level: the imbrication level for indenting
1615*7c568831SAndroid Build Coastguard Worker  * @format: is formatting allowed
1616*7c568831SAndroid Build Coastguard Worker  * @encoding:  an optional encoding string
1617*7c568831SAndroid Build Coastguard Worker  *
1618*7c568831SAndroid Build Coastguard Worker  * Dump an XHTML node, recursive behaviour, children are printed too.
1619*7c568831SAndroid Build Coastguard Worker  */
1620*7c568831SAndroid Build Coastguard Worker static void
xhtmlNodeDumpOutput(xmlSaveCtxtPtr ctxt,xmlNodePtr cur)1621*7c568831SAndroid Build Coastguard Worker xhtmlNodeDumpOutput(xmlSaveCtxtPtr ctxt, xmlNodePtr cur) {
1622*7c568831SAndroid Build Coastguard Worker     int format = ctxt->format, addmeta, oldoptions;
1623*7c568831SAndroid Build Coastguard Worker     xmlNodePtr tmp, root, unformattedNode = NULL, parent;
1624*7c568831SAndroid Build Coastguard Worker     xmlChar *start, *end;
1625*7c568831SAndroid Build Coastguard Worker     xmlOutputBufferPtr buf = ctxt->buf;
1626*7c568831SAndroid Build Coastguard Worker 
1627*7c568831SAndroid Build Coastguard Worker     if (cur == NULL) return;
1628*7c568831SAndroid Build Coastguard Worker 
1629*7c568831SAndroid Build Coastguard Worker     oldoptions = ctxt->options;
1630*7c568831SAndroid Build Coastguard Worker     ctxt->options |= XML_SAVE_XHTML;
1631*7c568831SAndroid Build Coastguard Worker 
1632*7c568831SAndroid Build Coastguard Worker     root = cur;
1633*7c568831SAndroid Build Coastguard Worker     parent = cur->parent;
1634*7c568831SAndroid Build Coastguard Worker     while (1) {
1635*7c568831SAndroid Build Coastguard Worker         switch (cur->type) {
1636*7c568831SAndroid Build Coastguard Worker         case XML_DOCUMENT_NODE:
1637*7c568831SAndroid Build Coastguard Worker         case XML_HTML_DOCUMENT_NODE:
1638*7c568831SAndroid Build Coastguard Worker             xmlDocContentDumpOutput(ctxt, (xmlDocPtr) cur);
1639*7c568831SAndroid Build Coastguard Worker 	    break;
1640*7c568831SAndroid Build Coastguard Worker 
1641*7c568831SAndroid Build Coastguard Worker         case XML_NAMESPACE_DECL:
1642*7c568831SAndroid Build Coastguard Worker 	    xmlNsDumpOutput(buf, (xmlNsPtr) cur, ctxt);
1643*7c568831SAndroid Build Coastguard Worker 	    break;
1644*7c568831SAndroid Build Coastguard Worker 
1645*7c568831SAndroid Build Coastguard Worker         case XML_DTD_NODE:
1646*7c568831SAndroid Build Coastguard Worker             xmlDtdDumpOutput(ctxt, (xmlDtdPtr) cur);
1647*7c568831SAndroid Build Coastguard Worker 	    break;
1648*7c568831SAndroid Build Coastguard Worker 
1649*7c568831SAndroid Build Coastguard Worker         case XML_DOCUMENT_FRAG_NODE:
1650*7c568831SAndroid Build Coastguard Worker             /* Always validate cur->parent when descending. */
1651*7c568831SAndroid Build Coastguard Worker             if ((cur->parent == parent) && (cur->children != NULL)) {
1652*7c568831SAndroid Build Coastguard Worker                 parent = cur;
1653*7c568831SAndroid Build Coastguard Worker                 cur = cur->children;
1654*7c568831SAndroid Build Coastguard Worker                 continue;
1655*7c568831SAndroid Build Coastguard Worker             }
1656*7c568831SAndroid Build Coastguard Worker             break;
1657*7c568831SAndroid Build Coastguard Worker 
1658*7c568831SAndroid Build Coastguard Worker         case XML_ELEMENT_DECL:
1659*7c568831SAndroid Build Coastguard Worker             xmlBufDumpElementDecl(buf, (xmlElementPtr) cur);
1660*7c568831SAndroid Build Coastguard Worker 	    break;
1661*7c568831SAndroid Build Coastguard Worker 
1662*7c568831SAndroid Build Coastguard Worker         case XML_ATTRIBUTE_DECL:
1663*7c568831SAndroid Build Coastguard Worker             xmlBufDumpAttributeDecl(buf, (xmlAttributePtr) cur);
1664*7c568831SAndroid Build Coastguard Worker 	    break;
1665*7c568831SAndroid Build Coastguard Worker 
1666*7c568831SAndroid Build Coastguard Worker         case XML_ENTITY_DECL:
1667*7c568831SAndroid Build Coastguard Worker             xmlBufDumpEntityDecl(buf, (xmlEntityPtr) cur);
1668*7c568831SAndroid Build Coastguard Worker 	    break;
1669*7c568831SAndroid Build Coastguard Worker 
1670*7c568831SAndroid Build Coastguard Worker         case XML_ELEMENT_NODE:
1671*7c568831SAndroid Build Coastguard Worker             addmeta = 0;
1672*7c568831SAndroid Build Coastguard Worker 
1673*7c568831SAndroid Build Coastguard Worker 	    if ((cur != root) && (ctxt->format == 1))
1674*7c568831SAndroid Build Coastguard Worker                 xmlSaveWriteIndent(ctxt, 0);
1675*7c568831SAndroid Build Coastguard Worker 
1676*7c568831SAndroid Build Coastguard Worker             /*
1677*7c568831SAndroid Build Coastguard Worker              * Some users like lxml are known to pass nodes with a corrupted
1678*7c568831SAndroid Build Coastguard Worker              * tree structure. Fall back to a recursive call to handle this
1679*7c568831SAndroid Build Coastguard Worker              * case.
1680*7c568831SAndroid Build Coastguard Worker              */
1681*7c568831SAndroid Build Coastguard Worker             if ((cur->parent != parent) && (cur->children != NULL)) {
1682*7c568831SAndroid Build Coastguard Worker                 xhtmlNodeDumpOutput(ctxt, cur);
1683*7c568831SAndroid Build Coastguard Worker                 break;
1684*7c568831SAndroid Build Coastguard Worker             }
1685*7c568831SAndroid Build Coastguard Worker 
1686*7c568831SAndroid Build Coastguard Worker             xmlOutputBufferWrite(buf, 1, "<");
1687*7c568831SAndroid Build Coastguard Worker             if ((cur->ns != NULL) && (cur->ns->prefix != NULL)) {
1688*7c568831SAndroid Build Coastguard Worker                 xmlOutputBufferWriteString(buf, (const char *)cur->ns->prefix);
1689*7c568831SAndroid Build Coastguard Worker                 xmlOutputBufferWrite(buf, 1, ":");
1690*7c568831SAndroid Build Coastguard Worker             }
1691*7c568831SAndroid Build Coastguard Worker 
1692*7c568831SAndroid Build Coastguard Worker             xmlOutputBufferWriteString(buf, (const char *)cur->name);
1693*7c568831SAndroid Build Coastguard Worker             if (cur->nsDef)
1694*7c568831SAndroid Build Coastguard Worker                 xmlNsListDumpOutputCtxt(ctxt, cur->nsDef);
1695*7c568831SAndroid Build Coastguard Worker             if ((xmlStrEqual(cur->name, BAD_CAST "html") &&
1696*7c568831SAndroid Build Coastguard Worker                 (cur->ns == NULL) && (cur->nsDef == NULL))) {
1697*7c568831SAndroid Build Coastguard Worker                 /*
1698*7c568831SAndroid Build Coastguard Worker                  * 3.1.1. Strictly Conforming Documents A.3.1.1 3/
1699*7c568831SAndroid Build Coastguard Worker                  */
1700*7c568831SAndroid Build Coastguard Worker                 xmlOutputBufferWriteString(buf,
1701*7c568831SAndroid Build Coastguard Worker                         " xmlns=\"http://www.w3.org/1999/xhtml\"");
1702*7c568831SAndroid Build Coastguard Worker             }
1703*7c568831SAndroid Build Coastguard Worker             if (cur->properties != NULL)
1704*7c568831SAndroid Build Coastguard Worker                 xhtmlAttrListDumpOutput(ctxt, cur->properties);
1705*7c568831SAndroid Build Coastguard Worker 
1706*7c568831SAndroid Build Coastguard Worker             if ((parent != NULL) &&
1707*7c568831SAndroid Build Coastguard Worker                 (parent->parent == (xmlNodePtr) cur->doc) &&
1708*7c568831SAndroid Build Coastguard Worker                 xmlStrEqual(cur->name, BAD_CAST"head") &&
1709*7c568831SAndroid Build Coastguard Worker                 xmlStrEqual(parent->name, BAD_CAST"html")) {
1710*7c568831SAndroid Build Coastguard Worker 
1711*7c568831SAndroid Build Coastguard Worker                 tmp = cur->children;
1712*7c568831SAndroid Build Coastguard Worker                 while (tmp != NULL) {
1713*7c568831SAndroid Build Coastguard Worker                     if (xmlStrEqual(tmp->name, BAD_CAST"meta")) {
1714*7c568831SAndroid Build Coastguard Worker                         xmlChar *httpequiv;
1715*7c568831SAndroid Build Coastguard Worker 
1716*7c568831SAndroid Build Coastguard Worker                         httpequiv = xmlGetProp(tmp, BAD_CAST"http-equiv");
1717*7c568831SAndroid Build Coastguard Worker                         if (httpequiv != NULL) {
1718*7c568831SAndroid Build Coastguard Worker                             if (xmlStrcasecmp(httpequiv,
1719*7c568831SAndroid Build Coastguard Worker                                         BAD_CAST"Content-Type") == 0) {
1720*7c568831SAndroid Build Coastguard Worker                                 xmlFree(httpequiv);
1721*7c568831SAndroid Build Coastguard Worker                                 break;
1722*7c568831SAndroid Build Coastguard Worker                             }
1723*7c568831SAndroid Build Coastguard Worker                             xmlFree(httpequiv);
1724*7c568831SAndroid Build Coastguard Worker                         }
1725*7c568831SAndroid Build Coastguard Worker                     }
1726*7c568831SAndroid Build Coastguard Worker                     tmp = tmp->next;
1727*7c568831SAndroid Build Coastguard Worker                 }
1728*7c568831SAndroid Build Coastguard Worker                 if (tmp == NULL)
1729*7c568831SAndroid Build Coastguard Worker                     addmeta = 1;
1730*7c568831SAndroid Build Coastguard Worker             }
1731*7c568831SAndroid Build Coastguard Worker 
1732*7c568831SAndroid Build Coastguard Worker             if (cur->children == NULL) {
1733*7c568831SAndroid Build Coastguard Worker                 if (((cur->ns == NULL) || (cur->ns->prefix == NULL)) &&
1734*7c568831SAndroid Build Coastguard Worker                     ((xhtmlIsEmpty(cur) == 1) && (addmeta == 0))) {
1735*7c568831SAndroid Build Coastguard Worker                     /*
1736*7c568831SAndroid Build Coastguard Worker                      * C.2. Empty Elements
1737*7c568831SAndroid Build Coastguard Worker                      */
1738*7c568831SAndroid Build Coastguard Worker                     xmlOutputBufferWrite(buf, 3, " />");
1739*7c568831SAndroid Build Coastguard Worker                 } else {
1740*7c568831SAndroid Build Coastguard Worker                     if (addmeta == 1) {
1741*7c568831SAndroid Build Coastguard Worker                         xmlOutputBufferWrite(buf, 1, ">");
1742*7c568831SAndroid Build Coastguard Worker                         if (ctxt->format == 1) {
1743*7c568831SAndroid Build Coastguard Worker                             xmlOutputBufferWrite(buf, 1, "\n");
1744*7c568831SAndroid Build Coastguard Worker                             xmlSaveWriteIndent(ctxt, 1);
1745*7c568831SAndroid Build Coastguard Worker                         }
1746*7c568831SAndroid Build Coastguard Worker                         xmlOutputBufferWriteString(buf,
1747*7c568831SAndroid Build Coastguard Worker                                 "<meta http-equiv=\"Content-Type\" "
1748*7c568831SAndroid Build Coastguard Worker                                 "content=\"text/html; charset=");
1749*7c568831SAndroid Build Coastguard Worker                         if (ctxt->encoding) {
1750*7c568831SAndroid Build Coastguard Worker                             xmlOutputBufferWriteString(buf,
1751*7c568831SAndroid Build Coastguard Worker                                     (const char *)ctxt->encoding);
1752*7c568831SAndroid Build Coastguard Worker                         } else {
1753*7c568831SAndroid Build Coastguard Worker                             xmlOutputBufferWrite(buf, 5, "UTF-8");
1754*7c568831SAndroid Build Coastguard Worker                         }
1755*7c568831SAndroid Build Coastguard Worker                         xmlOutputBufferWrite(buf, 4, "\" />");
1756*7c568831SAndroid Build Coastguard Worker                         if (ctxt->format == 1)
1757*7c568831SAndroid Build Coastguard Worker                             xmlOutputBufferWrite(buf, 1, "\n");
1758*7c568831SAndroid Build Coastguard Worker                     } else {
1759*7c568831SAndroid Build Coastguard Worker                         xmlOutputBufferWrite(buf, 1, ">");
1760*7c568831SAndroid Build Coastguard Worker                     }
1761*7c568831SAndroid Build Coastguard Worker                     /*
1762*7c568831SAndroid Build Coastguard Worker                      * C.3. Element Minimization and Empty Element Content
1763*7c568831SAndroid Build Coastguard Worker                      */
1764*7c568831SAndroid Build Coastguard Worker                     xmlOutputBufferWrite(buf, 2, "</");
1765*7c568831SAndroid Build Coastguard Worker                     if ((cur->ns != NULL) && (cur->ns->prefix != NULL)) {
1766*7c568831SAndroid Build Coastguard Worker                         xmlOutputBufferWriteString(buf,
1767*7c568831SAndroid Build Coastguard Worker                                 (const char *)cur->ns->prefix);
1768*7c568831SAndroid Build Coastguard Worker                         xmlOutputBufferWrite(buf, 1, ":");
1769*7c568831SAndroid Build Coastguard Worker                     }
1770*7c568831SAndroid Build Coastguard Worker                     xmlOutputBufferWriteString(buf, (const char *)cur->name);
1771*7c568831SAndroid Build Coastguard Worker                     xmlOutputBufferWrite(buf, 1, ">");
1772*7c568831SAndroid Build Coastguard Worker                 }
1773*7c568831SAndroid Build Coastguard Worker             } else {
1774*7c568831SAndroid Build Coastguard Worker                 xmlOutputBufferWrite(buf, 1, ">");
1775*7c568831SAndroid Build Coastguard Worker                 if (addmeta == 1) {
1776*7c568831SAndroid Build Coastguard Worker                     if (ctxt->format == 1) {
1777*7c568831SAndroid Build Coastguard Worker                         xmlOutputBufferWrite(buf, 1, "\n");
1778*7c568831SAndroid Build Coastguard Worker                         xmlSaveWriteIndent(ctxt, 1);
1779*7c568831SAndroid Build Coastguard Worker                     }
1780*7c568831SAndroid Build Coastguard Worker                     xmlOutputBufferWriteString(buf,
1781*7c568831SAndroid Build Coastguard Worker                             "<meta http-equiv=\"Content-Type\" "
1782*7c568831SAndroid Build Coastguard Worker                             "content=\"text/html; charset=");
1783*7c568831SAndroid Build Coastguard Worker                     if (ctxt->encoding) {
1784*7c568831SAndroid Build Coastguard Worker                         xmlOutputBufferWriteString(buf,
1785*7c568831SAndroid Build Coastguard Worker                                 (const char *)ctxt->encoding);
1786*7c568831SAndroid Build Coastguard Worker                     } else {
1787*7c568831SAndroid Build Coastguard Worker                         xmlOutputBufferWrite(buf, 5, "UTF-8");
1788*7c568831SAndroid Build Coastguard Worker                     }
1789*7c568831SAndroid Build Coastguard Worker                     xmlOutputBufferWrite(buf, 4, "\" />");
1790*7c568831SAndroid Build Coastguard Worker                 }
1791*7c568831SAndroid Build Coastguard Worker 
1792*7c568831SAndroid Build Coastguard Worker                 if (ctxt->format == 1) {
1793*7c568831SAndroid Build Coastguard Worker                     tmp = cur->children;
1794*7c568831SAndroid Build Coastguard Worker                     while (tmp != NULL) {
1795*7c568831SAndroid Build Coastguard Worker                         if ((tmp->type == XML_TEXT_NODE) ||
1796*7c568831SAndroid Build Coastguard Worker                             (tmp->type == XML_ENTITY_REF_NODE)) {
1797*7c568831SAndroid Build Coastguard Worker                             unformattedNode = cur;
1798*7c568831SAndroid Build Coastguard Worker                             ctxt->format = 0;
1799*7c568831SAndroid Build Coastguard Worker                             break;
1800*7c568831SAndroid Build Coastguard Worker                         }
1801*7c568831SAndroid Build Coastguard Worker                         tmp = tmp->next;
1802*7c568831SAndroid Build Coastguard Worker                     }
1803*7c568831SAndroid Build Coastguard Worker                 }
1804*7c568831SAndroid Build Coastguard Worker 
1805*7c568831SAndroid Build Coastguard Worker                 if (ctxt->format == 1) xmlOutputBufferWrite(buf, 1, "\n");
1806*7c568831SAndroid Build Coastguard Worker                 if (ctxt->level >= 0) ctxt->level++;
1807*7c568831SAndroid Build Coastguard Worker                 parent = cur;
1808*7c568831SAndroid Build Coastguard Worker                 cur = cur->children;
1809*7c568831SAndroid Build Coastguard Worker                 continue;
1810*7c568831SAndroid Build Coastguard Worker             }
1811*7c568831SAndroid Build Coastguard Worker 
1812*7c568831SAndroid Build Coastguard Worker             break;
1813*7c568831SAndroid Build Coastguard Worker 
1814*7c568831SAndroid Build Coastguard Worker         case XML_TEXT_NODE:
1815*7c568831SAndroid Build Coastguard Worker 	    if (cur->content == NULL)
1816*7c568831SAndroid Build Coastguard Worker                 break;
1817*7c568831SAndroid Build Coastguard Worker 	    if ((cur->name == xmlStringText) ||
1818*7c568831SAndroid Build Coastguard Worker 		(cur->name != xmlStringTextNoenc)) {
1819*7c568831SAndroid Build Coastguard Worker                 if (ctxt->escape)
1820*7c568831SAndroid Build Coastguard Worker                     xmlOutputBufferWriteEscape(buf, cur->content,
1821*7c568831SAndroid Build Coastguard Worker                                                ctxt->escape);
1822*7c568831SAndroid Build Coastguard Worker                 else
1823*7c568831SAndroid Build Coastguard Worker                     xmlSaveWriteText(ctxt, cur->content, /* flags */ 0);
1824*7c568831SAndroid Build Coastguard Worker 	    } else {
1825*7c568831SAndroid Build Coastguard Worker 		/*
1826*7c568831SAndroid Build Coastguard Worker 		 * Disable escaping, needed for XSLT
1827*7c568831SAndroid Build Coastguard Worker 		 */
1828*7c568831SAndroid Build Coastguard Worker 		xmlOutputBufferWriteString(buf, (const char *) cur->content);
1829*7c568831SAndroid Build Coastguard Worker 	    }
1830*7c568831SAndroid Build Coastguard Worker 	    break;
1831*7c568831SAndroid Build Coastguard Worker 
1832*7c568831SAndroid Build Coastguard Worker         case XML_PI_NODE:
1833*7c568831SAndroid Build Coastguard Worker             if (cur->content != NULL) {
1834*7c568831SAndroid Build Coastguard Worker                 xmlOutputBufferWrite(buf, 2, "<?");
1835*7c568831SAndroid Build Coastguard Worker                 xmlOutputBufferWriteString(buf, (const char *)cur->name);
1836*7c568831SAndroid Build Coastguard Worker                 if (cur->content != NULL) {
1837*7c568831SAndroid Build Coastguard Worker                     xmlOutputBufferWrite(buf, 1, " ");
1838*7c568831SAndroid Build Coastguard Worker                     xmlOutputBufferWriteString(buf,
1839*7c568831SAndroid Build Coastguard Worker                             (const char *)cur->content);
1840*7c568831SAndroid Build Coastguard Worker                 }
1841*7c568831SAndroid Build Coastguard Worker                 xmlOutputBufferWrite(buf, 2, "?>");
1842*7c568831SAndroid Build Coastguard Worker             } else {
1843*7c568831SAndroid Build Coastguard Worker                 xmlOutputBufferWrite(buf, 2, "<?");
1844*7c568831SAndroid Build Coastguard Worker                 xmlOutputBufferWriteString(buf, (const char *)cur->name);
1845*7c568831SAndroid Build Coastguard Worker                 xmlOutputBufferWrite(buf, 2, "?>");
1846*7c568831SAndroid Build Coastguard Worker             }
1847*7c568831SAndroid Build Coastguard Worker             break;
1848*7c568831SAndroid Build Coastguard Worker 
1849*7c568831SAndroid Build Coastguard Worker         case XML_COMMENT_NODE:
1850*7c568831SAndroid Build Coastguard Worker             if (cur->content != NULL) {
1851*7c568831SAndroid Build Coastguard Worker                 xmlOutputBufferWrite(buf, 4, "<!--");
1852*7c568831SAndroid Build Coastguard Worker                 xmlOutputBufferWriteString(buf, (const char *)cur->content);
1853*7c568831SAndroid Build Coastguard Worker                 xmlOutputBufferWrite(buf, 3, "-->");
1854*7c568831SAndroid Build Coastguard Worker             }
1855*7c568831SAndroid Build Coastguard Worker             break;
1856*7c568831SAndroid Build Coastguard Worker 
1857*7c568831SAndroid Build Coastguard Worker         case XML_ENTITY_REF_NODE:
1858*7c568831SAndroid Build Coastguard Worker             xmlOutputBufferWrite(buf, 1, "&");
1859*7c568831SAndroid Build Coastguard Worker             xmlOutputBufferWriteString(buf, (const char *)cur->name);
1860*7c568831SAndroid Build Coastguard Worker             xmlOutputBufferWrite(buf, 1, ";");
1861*7c568831SAndroid Build Coastguard Worker             break;
1862*7c568831SAndroid Build Coastguard Worker 
1863*7c568831SAndroid Build Coastguard Worker         case XML_CDATA_SECTION_NODE:
1864*7c568831SAndroid Build Coastguard Worker             if (cur->content == NULL || *cur->content == '\0') {
1865*7c568831SAndroid Build Coastguard Worker                 xmlOutputBufferWrite(buf, 12, "<![CDATA[]]>");
1866*7c568831SAndroid Build Coastguard Worker             } else {
1867*7c568831SAndroid Build Coastguard Worker                 start = end = cur->content;
1868*7c568831SAndroid Build Coastguard Worker                 while (*end != '\0') {
1869*7c568831SAndroid Build Coastguard Worker                     if (*end == ']' && *(end + 1) == ']' &&
1870*7c568831SAndroid Build Coastguard Worker                         *(end + 2) == '>') {
1871*7c568831SAndroid Build Coastguard Worker                         end = end + 2;
1872*7c568831SAndroid Build Coastguard Worker                         xmlOutputBufferWrite(buf, 9, "<![CDATA[");
1873*7c568831SAndroid Build Coastguard Worker                         xmlOutputBufferWrite(buf, end - start,
1874*7c568831SAndroid Build Coastguard Worker                                 (const char *)start);
1875*7c568831SAndroid Build Coastguard Worker                         xmlOutputBufferWrite(buf, 3, "]]>");
1876*7c568831SAndroid Build Coastguard Worker                         start = end;
1877*7c568831SAndroid Build Coastguard Worker                     }
1878*7c568831SAndroid Build Coastguard Worker                     end++;
1879*7c568831SAndroid Build Coastguard Worker                 }
1880*7c568831SAndroid Build Coastguard Worker                 if (start != end) {
1881*7c568831SAndroid Build Coastguard Worker                     xmlOutputBufferWrite(buf, 9, "<![CDATA[");
1882*7c568831SAndroid Build Coastguard Worker                     xmlOutputBufferWriteString(buf, (const char *)start);
1883*7c568831SAndroid Build Coastguard Worker                     xmlOutputBufferWrite(buf, 3, "]]>");
1884*7c568831SAndroid Build Coastguard Worker                 }
1885*7c568831SAndroid Build Coastguard Worker             }
1886*7c568831SAndroid Build Coastguard Worker             break;
1887*7c568831SAndroid Build Coastguard Worker 
1888*7c568831SAndroid Build Coastguard Worker         case XML_ATTRIBUTE_NODE:
1889*7c568831SAndroid Build Coastguard Worker             xmlAttrDumpOutput(ctxt, (xmlAttrPtr) cur);
1890*7c568831SAndroid Build Coastguard Worker 	    break;
1891*7c568831SAndroid Build Coastguard Worker 
1892*7c568831SAndroid Build Coastguard Worker         default:
1893*7c568831SAndroid Build Coastguard Worker             break;
1894*7c568831SAndroid Build Coastguard Worker         }
1895*7c568831SAndroid Build Coastguard Worker 
1896*7c568831SAndroid Build Coastguard Worker         while (1) {
1897*7c568831SAndroid Build Coastguard Worker             if (cur == root)
1898*7c568831SAndroid Build Coastguard Worker                 return;
1899*7c568831SAndroid Build Coastguard Worker             if (ctxt->format == 1)
1900*7c568831SAndroid Build Coastguard Worker                 xmlOutputBufferWrite(buf, 1, "\n");
1901*7c568831SAndroid Build Coastguard Worker             if (cur->next != NULL) {
1902*7c568831SAndroid Build Coastguard Worker                 cur = cur->next;
1903*7c568831SAndroid Build Coastguard Worker                 break;
1904*7c568831SAndroid Build Coastguard Worker             }
1905*7c568831SAndroid Build Coastguard Worker 
1906*7c568831SAndroid Build Coastguard Worker             cur = parent;
1907*7c568831SAndroid Build Coastguard Worker             /* cur->parent was validated when descending. */
1908*7c568831SAndroid Build Coastguard Worker             parent = cur->parent;
1909*7c568831SAndroid Build Coastguard Worker 
1910*7c568831SAndroid Build Coastguard Worker             if (cur->type == XML_ELEMENT_NODE) {
1911*7c568831SAndroid Build Coastguard Worker                 if (ctxt->level > 0) ctxt->level--;
1912*7c568831SAndroid Build Coastguard Worker                 if (ctxt->format == 1)
1913*7c568831SAndroid Build Coastguard Worker                     xmlSaveWriteIndent(ctxt, 0);
1914*7c568831SAndroid Build Coastguard Worker 
1915*7c568831SAndroid Build Coastguard Worker                 xmlOutputBufferWrite(buf, 2, "</");
1916*7c568831SAndroid Build Coastguard Worker                 if ((cur->ns != NULL) && (cur->ns->prefix != NULL)) {
1917*7c568831SAndroid Build Coastguard Worker                     xmlOutputBufferWriteString(buf,
1918*7c568831SAndroid Build Coastguard Worker                             (const char *)cur->ns->prefix);
1919*7c568831SAndroid Build Coastguard Worker                     xmlOutputBufferWrite(buf, 1, ":");
1920*7c568831SAndroid Build Coastguard Worker                 }
1921*7c568831SAndroid Build Coastguard Worker 
1922*7c568831SAndroid Build Coastguard Worker                 xmlOutputBufferWriteString(buf, (const char *)cur->name);
1923*7c568831SAndroid Build Coastguard Worker                 xmlOutputBufferWrite(buf, 1, ">");
1924*7c568831SAndroid Build Coastguard Worker 
1925*7c568831SAndroid Build Coastguard Worker                 if (cur == unformattedNode) {
1926*7c568831SAndroid Build Coastguard Worker                     ctxt->format = format;
1927*7c568831SAndroid Build Coastguard Worker                     unformattedNode = NULL;
1928*7c568831SAndroid Build Coastguard Worker                 }
1929*7c568831SAndroid Build Coastguard Worker             }
1930*7c568831SAndroid Build Coastguard Worker         }
1931*7c568831SAndroid Build Coastguard Worker     }
1932*7c568831SAndroid Build Coastguard Worker 
1933*7c568831SAndroid Build Coastguard Worker     ctxt->options = oldoptions;
1934*7c568831SAndroid Build Coastguard Worker }
1935*7c568831SAndroid Build Coastguard Worker #endif
1936*7c568831SAndroid Build Coastguard Worker 
1937*7c568831SAndroid Build Coastguard Worker /************************************************************************
1938*7c568831SAndroid Build Coastguard Worker  *									*
1939*7c568831SAndroid Build Coastguard Worker  *			Public entry points				*
1940*7c568831SAndroid Build Coastguard Worker  *									*
1941*7c568831SAndroid Build Coastguard Worker  ************************************************************************/
1942*7c568831SAndroid Build Coastguard Worker 
1943*7c568831SAndroid Build Coastguard Worker /**
1944*7c568831SAndroid Build Coastguard Worker  * xmlSaveToFd:
1945*7c568831SAndroid Build Coastguard Worker  * @fd:  a file descriptor number
1946*7c568831SAndroid Build Coastguard Worker  * @encoding:  the encoding name to use or NULL
1947*7c568831SAndroid Build Coastguard Worker  * @options:  a set of xmlSaveOptions
1948*7c568831SAndroid Build Coastguard Worker  *
1949*7c568831SAndroid Build Coastguard Worker  * Create a document saving context serializing to a file descriptor
1950*7c568831SAndroid Build Coastguard Worker  * with the encoding and the options given.
1951*7c568831SAndroid Build Coastguard Worker  *
1952*7c568831SAndroid Build Coastguard Worker  * Returns a new serialization context or NULL in case of error.
1953*7c568831SAndroid Build Coastguard Worker  */
1954*7c568831SAndroid Build Coastguard Worker xmlSaveCtxtPtr
xmlSaveToFd(int fd,const char * encoding,int options)1955*7c568831SAndroid Build Coastguard Worker xmlSaveToFd(int fd, const char *encoding, int options)
1956*7c568831SAndroid Build Coastguard Worker {
1957*7c568831SAndroid Build Coastguard Worker     xmlSaveCtxtPtr ret;
1958*7c568831SAndroid Build Coastguard Worker 
1959*7c568831SAndroid Build Coastguard Worker     ret = xmlNewSaveCtxt(encoding, options);
1960*7c568831SAndroid Build Coastguard Worker     if (ret == NULL) return(NULL);
1961*7c568831SAndroid Build Coastguard Worker     ret->buf = xmlOutputBufferCreateFd(fd, ret->handler);
1962*7c568831SAndroid Build Coastguard Worker     if (ret->buf == NULL) {
1963*7c568831SAndroid Build Coastguard Worker 	xmlFreeSaveCtxt(ret);
1964*7c568831SAndroid Build Coastguard Worker 	return(NULL);
1965*7c568831SAndroid Build Coastguard Worker     }
1966*7c568831SAndroid Build Coastguard Worker     return(ret);
1967*7c568831SAndroid Build Coastguard Worker }
1968*7c568831SAndroid Build Coastguard Worker 
1969*7c568831SAndroid Build Coastguard Worker /**
1970*7c568831SAndroid Build Coastguard Worker  * xmlSaveToFilename:
1971*7c568831SAndroid Build Coastguard Worker  * @filename:  a file name or an URL
1972*7c568831SAndroid Build Coastguard Worker  * @encoding:  the encoding name to use or NULL
1973*7c568831SAndroid Build Coastguard Worker  * @options:  a set of xmlSaveOptions
1974*7c568831SAndroid Build Coastguard Worker  *
1975*7c568831SAndroid Build Coastguard Worker  * Create a document saving context serializing to a filename or possibly
1976*7c568831SAndroid Build Coastguard Worker  * to an URL (but this is less reliable) with the encoding and the options
1977*7c568831SAndroid Build Coastguard Worker  * given.
1978*7c568831SAndroid Build Coastguard Worker  *
1979*7c568831SAndroid Build Coastguard Worker  * Returns a new serialization context or NULL in case of error.
1980*7c568831SAndroid Build Coastguard Worker  */
1981*7c568831SAndroid Build Coastguard Worker xmlSaveCtxtPtr
xmlSaveToFilename(const char * filename,const char * encoding,int options)1982*7c568831SAndroid Build Coastguard Worker xmlSaveToFilename(const char *filename, const char *encoding, int options)
1983*7c568831SAndroid Build Coastguard Worker {
1984*7c568831SAndroid Build Coastguard Worker     xmlSaveCtxtPtr ret;
1985*7c568831SAndroid Build Coastguard Worker     int compression = 0; /* TODO handle compression option */
1986*7c568831SAndroid Build Coastguard Worker 
1987*7c568831SAndroid Build Coastguard Worker     ret = xmlNewSaveCtxt(encoding, options);
1988*7c568831SAndroid Build Coastguard Worker     if (ret == NULL) return(NULL);
1989*7c568831SAndroid Build Coastguard Worker     ret->buf = xmlOutputBufferCreateFilename(filename, ret->handler,
1990*7c568831SAndroid Build Coastguard Worker                                              compression);
1991*7c568831SAndroid Build Coastguard Worker     if (ret->buf == NULL) {
1992*7c568831SAndroid Build Coastguard Worker 	xmlFreeSaveCtxt(ret);
1993*7c568831SAndroid Build Coastguard Worker 	return(NULL);
1994*7c568831SAndroid Build Coastguard Worker     }
1995*7c568831SAndroid Build Coastguard Worker     return(ret);
1996*7c568831SAndroid Build Coastguard Worker }
1997*7c568831SAndroid Build Coastguard Worker 
1998*7c568831SAndroid Build Coastguard Worker /**
1999*7c568831SAndroid Build Coastguard Worker  * xmlSaveToBuffer:
2000*7c568831SAndroid Build Coastguard Worker  * @buffer:  a buffer
2001*7c568831SAndroid Build Coastguard Worker  * @encoding:  the encoding name to use or NULL
2002*7c568831SAndroid Build Coastguard Worker  * @options:  a set of xmlSaveOptions
2003*7c568831SAndroid Build Coastguard Worker  *
2004*7c568831SAndroid Build Coastguard Worker  * Create a document saving context serializing to a buffer
2005*7c568831SAndroid Build Coastguard Worker  * with the encoding and the options given
2006*7c568831SAndroid Build Coastguard Worker  *
2007*7c568831SAndroid Build Coastguard Worker  * Returns a new serialization context or NULL in case of error.
2008*7c568831SAndroid Build Coastguard Worker  */
2009*7c568831SAndroid Build Coastguard Worker 
2010*7c568831SAndroid Build Coastguard Worker xmlSaveCtxtPtr
xmlSaveToBuffer(xmlBufferPtr buffer,const char * encoding,int options)2011*7c568831SAndroid Build Coastguard Worker xmlSaveToBuffer(xmlBufferPtr buffer, const char *encoding, int options)
2012*7c568831SAndroid Build Coastguard Worker {
2013*7c568831SAndroid Build Coastguard Worker     xmlSaveCtxtPtr ret;
2014*7c568831SAndroid Build Coastguard Worker 
2015*7c568831SAndroid Build Coastguard Worker     ret = xmlNewSaveCtxt(encoding, options);
2016*7c568831SAndroid Build Coastguard Worker     if (ret == NULL) return(NULL);
2017*7c568831SAndroid Build Coastguard Worker     ret->buf = xmlOutputBufferCreateBuffer(buffer, ret->handler);
2018*7c568831SAndroid Build Coastguard Worker     if (ret->buf == NULL) {
2019*7c568831SAndroid Build Coastguard Worker 	xmlFreeSaveCtxt(ret);
2020*7c568831SAndroid Build Coastguard Worker 	return(NULL);
2021*7c568831SAndroid Build Coastguard Worker     }
2022*7c568831SAndroid Build Coastguard Worker     return(ret);
2023*7c568831SAndroid Build Coastguard Worker }
2024*7c568831SAndroid Build Coastguard Worker 
2025*7c568831SAndroid Build Coastguard Worker /**
2026*7c568831SAndroid Build Coastguard Worker  * xmlSaveToIO:
2027*7c568831SAndroid Build Coastguard Worker  * @iowrite:  an I/O write function
2028*7c568831SAndroid Build Coastguard Worker  * @ioclose:  an I/O close function
2029*7c568831SAndroid Build Coastguard Worker  * @ioctx:  an I/O handler
2030*7c568831SAndroid Build Coastguard Worker  * @encoding:  the encoding name to use or NULL
2031*7c568831SAndroid Build Coastguard Worker  * @options:  a set of xmlSaveOptions
2032*7c568831SAndroid Build Coastguard Worker  *
2033*7c568831SAndroid Build Coastguard Worker  * Create a document saving context serializing to a file descriptor
2034*7c568831SAndroid Build Coastguard Worker  * with the encoding and the options given
2035*7c568831SAndroid Build Coastguard Worker  *
2036*7c568831SAndroid Build Coastguard Worker  * Returns a new serialization context or NULL in case of error.
2037*7c568831SAndroid Build Coastguard Worker  */
2038*7c568831SAndroid Build Coastguard Worker xmlSaveCtxtPtr
xmlSaveToIO(xmlOutputWriteCallback iowrite,xmlOutputCloseCallback ioclose,void * ioctx,const char * encoding,int options)2039*7c568831SAndroid Build Coastguard Worker xmlSaveToIO(xmlOutputWriteCallback iowrite,
2040*7c568831SAndroid Build Coastguard Worker             xmlOutputCloseCallback ioclose,
2041*7c568831SAndroid Build Coastguard Worker             void *ioctx, const char *encoding, int options)
2042*7c568831SAndroid Build Coastguard Worker {
2043*7c568831SAndroid Build Coastguard Worker     xmlSaveCtxtPtr ret;
2044*7c568831SAndroid Build Coastguard Worker 
2045*7c568831SAndroid Build Coastguard Worker     ret = xmlNewSaveCtxt(encoding, options);
2046*7c568831SAndroid Build Coastguard Worker     if (ret == NULL) return(NULL);
2047*7c568831SAndroid Build Coastguard Worker     ret->buf = xmlOutputBufferCreateIO(iowrite, ioclose, ioctx, ret->handler);
2048*7c568831SAndroid Build Coastguard Worker     if (ret->buf == NULL) {
2049*7c568831SAndroid Build Coastguard Worker 	xmlFreeSaveCtxt(ret);
2050*7c568831SAndroid Build Coastguard Worker 	return(NULL);
2051*7c568831SAndroid Build Coastguard Worker     }
2052*7c568831SAndroid Build Coastguard Worker     return(ret);
2053*7c568831SAndroid Build Coastguard Worker }
2054*7c568831SAndroid Build Coastguard Worker 
2055*7c568831SAndroid Build Coastguard Worker /**
2056*7c568831SAndroid Build Coastguard Worker  * xmlSaveDoc:
2057*7c568831SAndroid Build Coastguard Worker  * @ctxt:  a document saving context
2058*7c568831SAndroid Build Coastguard Worker  * @doc:  a document
2059*7c568831SAndroid Build Coastguard Worker  *
2060*7c568831SAndroid Build Coastguard Worker  * Save a full document to a saving context
2061*7c568831SAndroid Build Coastguard Worker  * TODO: The function is not fully implemented yet as it does not return the
2062*7c568831SAndroid Build Coastguard Worker  * byte count but 0 instead
2063*7c568831SAndroid Build Coastguard Worker  *
2064*7c568831SAndroid Build Coastguard Worker  * Returns the number of byte written or -1 in case of error
2065*7c568831SAndroid Build Coastguard Worker  */
2066*7c568831SAndroid Build Coastguard Worker long
xmlSaveDoc(xmlSaveCtxtPtr ctxt,xmlDocPtr doc)2067*7c568831SAndroid Build Coastguard Worker xmlSaveDoc(xmlSaveCtxtPtr ctxt, xmlDocPtr doc)
2068*7c568831SAndroid Build Coastguard Worker {
2069*7c568831SAndroid Build Coastguard Worker     long ret = 0;
2070*7c568831SAndroid Build Coastguard Worker 
2071*7c568831SAndroid Build Coastguard Worker     if ((ctxt == NULL) || (doc == NULL)) return(-1);
2072*7c568831SAndroid Build Coastguard Worker     if (xmlDocContentDumpOutput(ctxt, doc) < 0)
2073*7c568831SAndroid Build Coastguard Worker         return(-1);
2074*7c568831SAndroid Build Coastguard Worker     return(ret);
2075*7c568831SAndroid Build Coastguard Worker }
2076*7c568831SAndroid Build Coastguard Worker 
2077*7c568831SAndroid Build Coastguard Worker /**
2078*7c568831SAndroid Build Coastguard Worker  * xmlSaveTree:
2079*7c568831SAndroid Build Coastguard Worker  * @ctxt:  a document saving context
2080*7c568831SAndroid Build Coastguard Worker  * @cur:  the top node of the subtree to save
2081*7c568831SAndroid Build Coastguard Worker  *
2082*7c568831SAndroid Build Coastguard Worker  * Save a subtree starting at the node parameter to a saving context
2083*7c568831SAndroid Build Coastguard Worker  * TODO: The function is not fully implemented yet as it does not return the
2084*7c568831SAndroid Build Coastguard Worker  * byte count but 0 instead
2085*7c568831SAndroid Build Coastguard Worker  *
2086*7c568831SAndroid Build Coastguard Worker  * Returns the number of byte written or -1 in case of error
2087*7c568831SAndroid Build Coastguard Worker  */
2088*7c568831SAndroid Build Coastguard Worker long
xmlSaveTree(xmlSaveCtxtPtr ctxt,xmlNodePtr cur)2089*7c568831SAndroid Build Coastguard Worker xmlSaveTree(xmlSaveCtxtPtr ctxt, xmlNodePtr cur)
2090*7c568831SAndroid Build Coastguard Worker {
2091*7c568831SAndroid Build Coastguard Worker     long ret = 0;
2092*7c568831SAndroid Build Coastguard Worker 
2093*7c568831SAndroid Build Coastguard Worker     if ((ctxt == NULL) || (cur == NULL)) return(-1);
2094*7c568831SAndroid Build Coastguard Worker #ifdef LIBXML_HTML_ENABLED
2095*7c568831SAndroid Build Coastguard Worker     if (ctxt->options & XML_SAVE_XHTML) {
2096*7c568831SAndroid Build Coastguard Worker         xhtmlNodeDumpOutput(ctxt, cur);
2097*7c568831SAndroid Build Coastguard Worker         return(ret);
2098*7c568831SAndroid Build Coastguard Worker     }
2099*7c568831SAndroid Build Coastguard Worker     if (((cur->type != XML_NAMESPACE_DECL) && (cur->doc != NULL) &&
2100*7c568831SAndroid Build Coastguard Worker          (cur->doc->type == XML_HTML_DOCUMENT_NODE) &&
2101*7c568831SAndroid Build Coastguard Worker          ((ctxt->options & XML_SAVE_AS_XML) == 0)) ||
2102*7c568831SAndroid Build Coastguard Worker         (ctxt->options & XML_SAVE_AS_HTML)) {
2103*7c568831SAndroid Build Coastguard Worker 	htmlNodeDumpOutputInternal(ctxt, cur);
2104*7c568831SAndroid Build Coastguard Worker 	return(ret);
2105*7c568831SAndroid Build Coastguard Worker     }
2106*7c568831SAndroid Build Coastguard Worker #endif
2107*7c568831SAndroid Build Coastguard Worker     xmlNodeDumpOutputInternal(ctxt, cur);
2108*7c568831SAndroid Build Coastguard Worker     return(ret);
2109*7c568831SAndroid Build Coastguard Worker }
2110*7c568831SAndroid Build Coastguard Worker 
2111*7c568831SAndroid Build Coastguard Worker /**
2112*7c568831SAndroid Build Coastguard Worker  * xmlSaveNotationDecl:
2113*7c568831SAndroid Build Coastguard Worker  * @ctxt:  save context
2114*7c568831SAndroid Build Coastguard Worker  * @cur:  notation
2115*7c568831SAndroid Build Coastguard Worker  *
2116*7c568831SAndroid Build Coastguard Worker  * Serialize a notation declaration.
2117*7c568831SAndroid Build Coastguard Worker  *
2118*7c568831SAndroid Build Coastguard Worker  * Return 0 on succes, -1 on error.
2119*7c568831SAndroid Build Coastguard Worker  */
2120*7c568831SAndroid Build Coastguard Worker int
xmlSaveNotationDecl(xmlSaveCtxtPtr ctxt,xmlNotationPtr cur)2121*7c568831SAndroid Build Coastguard Worker xmlSaveNotationDecl(xmlSaveCtxtPtr ctxt, xmlNotationPtr cur) {
2122*7c568831SAndroid Build Coastguard Worker     if (ctxt == NULL)
2123*7c568831SAndroid Build Coastguard Worker         return(-1);
2124*7c568831SAndroid Build Coastguard Worker     xmlBufDumpNotationDecl(ctxt->buf, cur);
2125*7c568831SAndroid Build Coastguard Worker     return(0);
2126*7c568831SAndroid Build Coastguard Worker }
2127*7c568831SAndroid Build Coastguard Worker 
2128*7c568831SAndroid Build Coastguard Worker /**
2129*7c568831SAndroid Build Coastguard Worker  * xmlSaveNotationTable:
2130*7c568831SAndroid Build Coastguard Worker  * @ctxt:  save context
2131*7c568831SAndroid Build Coastguard Worker  * @cur:  notation table
2132*7c568831SAndroid Build Coastguard Worker  *
2133*7c568831SAndroid Build Coastguard Worker  * Serialize notation declarations of a document.
2134*7c568831SAndroid Build Coastguard Worker  *
2135*7c568831SAndroid Build Coastguard Worker  * Return 0 on succes, -1 on error.
2136*7c568831SAndroid Build Coastguard Worker  */
2137*7c568831SAndroid Build Coastguard Worker int
xmlSaveNotationTable(xmlSaveCtxtPtr ctxt,xmlNotationTablePtr cur)2138*7c568831SAndroid Build Coastguard Worker xmlSaveNotationTable(xmlSaveCtxtPtr ctxt, xmlNotationTablePtr cur) {
2139*7c568831SAndroid Build Coastguard Worker     if (ctxt == NULL)
2140*7c568831SAndroid Build Coastguard Worker         return(-1);
2141*7c568831SAndroid Build Coastguard Worker     xmlBufDumpNotationTable(ctxt->buf, cur);
2142*7c568831SAndroid Build Coastguard Worker     return(0);
2143*7c568831SAndroid Build Coastguard Worker }
2144*7c568831SAndroid Build Coastguard Worker 
2145*7c568831SAndroid Build Coastguard Worker /**
2146*7c568831SAndroid Build Coastguard Worker  * xmlSaveFlush:
2147*7c568831SAndroid Build Coastguard Worker  * @ctxt:  a document saving context
2148*7c568831SAndroid Build Coastguard Worker  *
2149*7c568831SAndroid Build Coastguard Worker  * Flush a document saving context, i.e. make sure that all bytes have
2150*7c568831SAndroid Build Coastguard Worker  * been output.
2151*7c568831SAndroid Build Coastguard Worker  *
2152*7c568831SAndroid Build Coastguard Worker  * Returns the number of byte written or -1 in case of error.
2153*7c568831SAndroid Build Coastguard Worker  */
2154*7c568831SAndroid Build Coastguard Worker int
xmlSaveFlush(xmlSaveCtxtPtr ctxt)2155*7c568831SAndroid Build Coastguard Worker xmlSaveFlush(xmlSaveCtxtPtr ctxt)
2156*7c568831SAndroid Build Coastguard Worker {
2157*7c568831SAndroid Build Coastguard Worker     if (ctxt == NULL) return(-1);
2158*7c568831SAndroid Build Coastguard Worker     if (ctxt->buf == NULL) return(-1);
2159*7c568831SAndroid Build Coastguard Worker     return(xmlOutputBufferFlush(ctxt->buf));
2160*7c568831SAndroid Build Coastguard Worker }
2161*7c568831SAndroid Build Coastguard Worker 
2162*7c568831SAndroid Build Coastguard Worker /**
2163*7c568831SAndroid Build Coastguard Worker  * xmlSaveClose:
2164*7c568831SAndroid Build Coastguard Worker  * @ctxt:  a document saving context
2165*7c568831SAndroid Build Coastguard Worker  *
2166*7c568831SAndroid Build Coastguard Worker  * Close a document saving context, i.e. make sure that all bytes have
2167*7c568831SAndroid Build Coastguard Worker  * been output and free the associated data.
2168*7c568831SAndroid Build Coastguard Worker  *
2169*7c568831SAndroid Build Coastguard Worker  * Returns the number of byte written or -1 in case of error.
2170*7c568831SAndroid Build Coastguard Worker  */
2171*7c568831SAndroid Build Coastguard Worker int
xmlSaveClose(xmlSaveCtxtPtr ctxt)2172*7c568831SAndroid Build Coastguard Worker xmlSaveClose(xmlSaveCtxtPtr ctxt)
2173*7c568831SAndroid Build Coastguard Worker {
2174*7c568831SAndroid Build Coastguard Worker     int ret;
2175*7c568831SAndroid Build Coastguard Worker 
2176*7c568831SAndroid Build Coastguard Worker     if (ctxt == NULL) return(-1);
2177*7c568831SAndroid Build Coastguard Worker     ret = xmlSaveFlush(ctxt);
2178*7c568831SAndroid Build Coastguard Worker     xmlFreeSaveCtxt(ctxt);
2179*7c568831SAndroid Build Coastguard Worker     return(ret);
2180*7c568831SAndroid Build Coastguard Worker }
2181*7c568831SAndroid Build Coastguard Worker 
2182*7c568831SAndroid Build Coastguard Worker /**
2183*7c568831SAndroid Build Coastguard Worker  * xmlSaveFinish:
2184*7c568831SAndroid Build Coastguard Worker  * @ctxt:  a document saving context
2185*7c568831SAndroid Build Coastguard Worker  *
2186*7c568831SAndroid Build Coastguard Worker  * Close a document saving context, i.e. make sure that all bytes have
2187*7c568831SAndroid Build Coastguard Worker  * been output and free the associated data.
2188*7c568831SAndroid Build Coastguard Worker  *
2189*7c568831SAndroid Build Coastguard Worker  * Available since 2.13.0.
2190*7c568831SAndroid Build Coastguard Worker  *
2191*7c568831SAndroid Build Coastguard Worker  * Returns an xmlParserErrors code.
2192*7c568831SAndroid Build Coastguard Worker  */
2193*7c568831SAndroid Build Coastguard Worker int
xmlSaveFinish(xmlSaveCtxtPtr ctxt)2194*7c568831SAndroid Build Coastguard Worker xmlSaveFinish(xmlSaveCtxtPtr ctxt)
2195*7c568831SAndroid Build Coastguard Worker {
2196*7c568831SAndroid Build Coastguard Worker     int ret;
2197*7c568831SAndroid Build Coastguard Worker 
2198*7c568831SAndroid Build Coastguard Worker     if (ctxt == NULL)
2199*7c568831SAndroid Build Coastguard Worker         return(XML_ERR_INTERNAL_ERROR);
2200*7c568831SAndroid Build Coastguard Worker     xmlSaveFlush(ctxt);
2201*7c568831SAndroid Build Coastguard Worker     ret = ctxt->buf->error;
2202*7c568831SAndroid Build Coastguard Worker     xmlFreeSaveCtxt(ctxt);
2203*7c568831SAndroid Build Coastguard Worker     return(ret);
2204*7c568831SAndroid Build Coastguard Worker }
2205*7c568831SAndroid Build Coastguard Worker 
2206*7c568831SAndroid Build Coastguard Worker /**
2207*7c568831SAndroid Build Coastguard Worker  * xmlSaveSetEscape:
2208*7c568831SAndroid Build Coastguard Worker  * @ctxt:  a document saving context
2209*7c568831SAndroid Build Coastguard Worker  * @escape:  the escaping function
2210*7c568831SAndroid Build Coastguard Worker  *
2211*7c568831SAndroid Build Coastguard Worker  * DEPRECATED: Don't use.
2212*7c568831SAndroid Build Coastguard Worker  *
2213*7c568831SAndroid Build Coastguard Worker  * Set a custom escaping function to be used for text in element content
2214*7c568831SAndroid Build Coastguard Worker  *
2215*7c568831SAndroid Build Coastguard Worker  * Returns 0 if successful or -1 in case of error.
2216*7c568831SAndroid Build Coastguard Worker  */
2217*7c568831SAndroid Build Coastguard Worker int
xmlSaveSetEscape(xmlSaveCtxtPtr ctxt,xmlCharEncodingOutputFunc escape)2218*7c568831SAndroid Build Coastguard Worker xmlSaveSetEscape(xmlSaveCtxtPtr ctxt, xmlCharEncodingOutputFunc escape)
2219*7c568831SAndroid Build Coastguard Worker {
2220*7c568831SAndroid Build Coastguard Worker     if (ctxt == NULL) return(-1);
2221*7c568831SAndroid Build Coastguard Worker     ctxt->escape = escape;
2222*7c568831SAndroid Build Coastguard Worker     return(0);
2223*7c568831SAndroid Build Coastguard Worker }
2224*7c568831SAndroid Build Coastguard Worker 
2225*7c568831SAndroid Build Coastguard Worker /**
2226*7c568831SAndroid Build Coastguard Worker  * xmlSaveSetAttrEscape:
2227*7c568831SAndroid Build Coastguard Worker  * @ctxt:  a document saving context
2228*7c568831SAndroid Build Coastguard Worker  * @escape:  the escaping function
2229*7c568831SAndroid Build Coastguard Worker  *
2230*7c568831SAndroid Build Coastguard Worker  * DEPRECATED: Don't use.
2231*7c568831SAndroid Build Coastguard Worker  *
2232*7c568831SAndroid Build Coastguard Worker  * Has no effect.
2233*7c568831SAndroid Build Coastguard Worker  *
2234*7c568831SAndroid Build Coastguard Worker  * Returns 0 if successful or -1 in case of error.
2235*7c568831SAndroid Build Coastguard Worker  */
2236*7c568831SAndroid Build Coastguard Worker int
xmlSaveSetAttrEscape(xmlSaveCtxtPtr ctxt,xmlCharEncodingOutputFunc escape ATTRIBUTE_UNUSED)2237*7c568831SAndroid Build Coastguard Worker xmlSaveSetAttrEscape(xmlSaveCtxtPtr ctxt,
2238*7c568831SAndroid Build Coastguard Worker                      xmlCharEncodingOutputFunc escape ATTRIBUTE_UNUSED)
2239*7c568831SAndroid Build Coastguard Worker {
2240*7c568831SAndroid Build Coastguard Worker     if (ctxt == NULL) return(-1);
2241*7c568831SAndroid Build Coastguard Worker     return(0);
2242*7c568831SAndroid Build Coastguard Worker }
2243*7c568831SAndroid Build Coastguard Worker 
2244*7c568831SAndroid Build Coastguard Worker /************************************************************************
2245*7c568831SAndroid Build Coastguard Worker  *									*
2246*7c568831SAndroid Build Coastguard Worker  *		Public entry points based on buffers			*
2247*7c568831SAndroid Build Coastguard Worker  *									*
2248*7c568831SAndroid Build Coastguard Worker  ************************************************************************/
2249*7c568831SAndroid Build Coastguard Worker 
2250*7c568831SAndroid Build Coastguard Worker /**
2251*7c568831SAndroid Build Coastguard Worker  * xmlBufAttrSerializeTxtContent:
2252*7c568831SAndroid Build Coastguard Worker  * @buf:  output buffer
2253*7c568831SAndroid Build Coastguard Worker  * @doc:  the document
2254*7c568831SAndroid Build Coastguard Worker  * @string: the text content
2255*7c568831SAndroid Build Coastguard Worker  *
2256*7c568831SAndroid Build Coastguard Worker  * Serialize text attribute values to an xmlBufPtr
2257*7c568831SAndroid Build Coastguard Worker  */
2258*7c568831SAndroid Build Coastguard Worker void
xmlBufAttrSerializeTxtContent(xmlOutputBufferPtr buf,xmlDocPtr doc,const xmlChar * string)2259*7c568831SAndroid Build Coastguard Worker xmlBufAttrSerializeTxtContent(xmlOutputBufferPtr buf, xmlDocPtr doc,
2260*7c568831SAndroid Build Coastguard Worker                               const xmlChar *string)
2261*7c568831SAndroid Build Coastguard Worker {
2262*7c568831SAndroid Build Coastguard Worker     int flags = XML_ESCAPE_ATTR;
2263*7c568831SAndroid Build Coastguard Worker 
2264*7c568831SAndroid Build Coastguard Worker     if ((doc == NULL) || (doc->encoding == NULL))
2265*7c568831SAndroid Build Coastguard Worker         flags |= XML_ESCAPE_NON_ASCII;
2266*7c568831SAndroid Build Coastguard Worker     xmlSerializeText(buf, string, flags);
2267*7c568831SAndroid Build Coastguard Worker }
2268*7c568831SAndroid Build Coastguard Worker 
2269*7c568831SAndroid Build Coastguard Worker /**
2270*7c568831SAndroid Build Coastguard Worker  * xmlAttrSerializeTxtContent:
2271*7c568831SAndroid Build Coastguard Worker  * @buf:  the XML buffer output
2272*7c568831SAndroid Build Coastguard Worker  * @doc:  the document
2273*7c568831SAndroid Build Coastguard Worker  * @attr: the attribute node
2274*7c568831SAndroid Build Coastguard Worker  * @string: the text content
2275*7c568831SAndroid Build Coastguard Worker  *
2276*7c568831SAndroid Build Coastguard Worker  * Serialize text attribute values to an xml simple buffer
2277*7c568831SAndroid Build Coastguard Worker  */
2278*7c568831SAndroid Build Coastguard Worker void
xmlAttrSerializeTxtContent(xmlBufferPtr buf,xmlDocPtr doc,xmlAttrPtr attr ATTRIBUTE_UNUSED,const xmlChar * string)2279*7c568831SAndroid Build Coastguard Worker xmlAttrSerializeTxtContent(xmlBufferPtr buf, xmlDocPtr doc,
2280*7c568831SAndroid Build Coastguard Worker                            xmlAttrPtr attr ATTRIBUTE_UNUSED,
2281*7c568831SAndroid Build Coastguard Worker                            const xmlChar *string)
2282*7c568831SAndroid Build Coastguard Worker {
2283*7c568831SAndroid Build Coastguard Worker     xmlOutputBufferPtr out;
2284*7c568831SAndroid Build Coastguard Worker 
2285*7c568831SAndroid Build Coastguard Worker     if ((buf == NULL) || (string == NULL))
2286*7c568831SAndroid Build Coastguard Worker         return;
2287*7c568831SAndroid Build Coastguard Worker     out = xmlOutputBufferCreateBuffer(buf, NULL);
2288*7c568831SAndroid Build Coastguard Worker     xmlBufAttrSerializeTxtContent(out, doc, string);
2289*7c568831SAndroid Build Coastguard Worker     xmlOutputBufferFlush(out);
2290*7c568831SAndroid Build Coastguard Worker     if ((out == NULL) || (out->error))
2291*7c568831SAndroid Build Coastguard Worker         xmlFree(xmlBufferDetach(buf));
2292*7c568831SAndroid Build Coastguard Worker     xmlOutputBufferClose(out);
2293*7c568831SAndroid Build Coastguard Worker }
2294*7c568831SAndroid Build Coastguard Worker 
2295*7c568831SAndroid Build Coastguard Worker /**
2296*7c568831SAndroid Build Coastguard Worker  * xmlNodeDump:
2297*7c568831SAndroid Build Coastguard Worker  * @buf:  the XML buffer output
2298*7c568831SAndroid Build Coastguard Worker  * @doc:  the document
2299*7c568831SAndroid Build Coastguard Worker  * @cur:  the current node
2300*7c568831SAndroid Build Coastguard Worker  * @level: the imbrication level for indenting
2301*7c568831SAndroid Build Coastguard Worker  * @format: is formatting allowed
2302*7c568831SAndroid Build Coastguard Worker  *
2303*7c568831SAndroid Build Coastguard Worker  * Dump an XML node, recursive behaviour,children are printed too.
2304*7c568831SAndroid Build Coastguard Worker  * Note that @format = 1 provide node indenting only if xmlIndentTreeOutput = 1
2305*7c568831SAndroid Build Coastguard Worker  * or xmlKeepBlanksDefault(0) was called.
2306*7c568831SAndroid Build Coastguard Worker  * Since this is using xmlBuffer structures it is limited to 2GB and somehow
2307*7c568831SAndroid Build Coastguard Worker  * deprecated, use xmlNodeDumpOutput() instead.
2308*7c568831SAndroid Build Coastguard Worker  *
2309*7c568831SAndroid Build Coastguard Worker  * Returns the number of bytes written to the buffer or -1 in case of error
2310*7c568831SAndroid Build Coastguard Worker  */
2311*7c568831SAndroid Build Coastguard Worker int
xmlNodeDump(xmlBufferPtr buf,xmlDocPtr doc,xmlNodePtr cur,int level,int format)2312*7c568831SAndroid Build Coastguard Worker xmlNodeDump(xmlBufferPtr buf, xmlDocPtr doc, xmlNodePtr cur, int level,
2313*7c568831SAndroid Build Coastguard Worker             int format)
2314*7c568831SAndroid Build Coastguard Worker {
2315*7c568831SAndroid Build Coastguard Worker     xmlBufPtr buffer;
2316*7c568831SAndroid Build Coastguard Worker     size_t ret1;
2317*7c568831SAndroid Build Coastguard Worker     int ret2;
2318*7c568831SAndroid Build Coastguard Worker 
2319*7c568831SAndroid Build Coastguard Worker     if ((buf == NULL) || (cur == NULL))
2320*7c568831SAndroid Build Coastguard Worker         return(-1);
2321*7c568831SAndroid Build Coastguard Worker     if (level < 0)
2322*7c568831SAndroid Build Coastguard Worker         level = 0;
2323*7c568831SAndroid Build Coastguard Worker     else if (level > 100)
2324*7c568831SAndroid Build Coastguard Worker         level = 100;
2325*7c568831SAndroid Build Coastguard Worker     buffer = xmlBufFromBuffer(buf);
2326*7c568831SAndroid Build Coastguard Worker     if (buffer == NULL)
2327*7c568831SAndroid Build Coastguard Worker         return(-1);
2328*7c568831SAndroid Build Coastguard Worker     ret1 = xmlBufNodeDump(buffer, doc, cur, level, format);
2329*7c568831SAndroid Build Coastguard Worker     ret2 = xmlBufBackToBuffer(buffer, buf);
2330*7c568831SAndroid Build Coastguard Worker     if ((ret1 == (size_t) -1) || (ret2 < 0))
2331*7c568831SAndroid Build Coastguard Worker         return(-1);
2332*7c568831SAndroid Build Coastguard Worker     return(ret1 > INT_MAX ? INT_MAX : ret1);
2333*7c568831SAndroid Build Coastguard Worker }
2334*7c568831SAndroid Build Coastguard Worker 
2335*7c568831SAndroid Build Coastguard Worker /**
2336*7c568831SAndroid Build Coastguard Worker  * xmlBufNodeDump:
2337*7c568831SAndroid Build Coastguard Worker  * @buf:  the XML buffer output
2338*7c568831SAndroid Build Coastguard Worker  * @doc:  the document
2339*7c568831SAndroid Build Coastguard Worker  * @cur:  the current node
2340*7c568831SAndroid Build Coastguard Worker  * @level: the imbrication level for indenting
2341*7c568831SAndroid Build Coastguard Worker  * @format: is formatting allowed
2342*7c568831SAndroid Build Coastguard Worker  *
2343*7c568831SAndroid Build Coastguard Worker  * Dump an XML node, recursive behaviour,children are printed too.
2344*7c568831SAndroid Build Coastguard Worker  * Note that @format = 1 provide node indenting only if xmlIndentTreeOutput = 1
2345*7c568831SAndroid Build Coastguard Worker  * or xmlKeepBlanksDefault(0) was called
2346*7c568831SAndroid Build Coastguard Worker  *
2347*7c568831SAndroid Build Coastguard Worker  * Returns the number of bytes written to the buffer, in case of error 0
2348*7c568831SAndroid Build Coastguard Worker  *     is returned or @buf stores the error
2349*7c568831SAndroid Build Coastguard Worker  */
2350*7c568831SAndroid Build Coastguard Worker 
2351*7c568831SAndroid Build Coastguard Worker size_t
xmlBufNodeDump(xmlBufPtr buf,xmlDocPtr doc,xmlNodePtr cur,int level,int format)2352*7c568831SAndroid Build Coastguard Worker xmlBufNodeDump(xmlBufPtr buf, xmlDocPtr doc, xmlNodePtr cur, int level,
2353*7c568831SAndroid Build Coastguard Worker             int format)
2354*7c568831SAndroid Build Coastguard Worker {
2355*7c568831SAndroid Build Coastguard Worker     size_t use;
2356*7c568831SAndroid Build Coastguard Worker     size_t ret;
2357*7c568831SAndroid Build Coastguard Worker     xmlOutputBufferPtr outbuf;
2358*7c568831SAndroid Build Coastguard Worker 
2359*7c568831SAndroid Build Coastguard Worker     xmlInitParser();
2360*7c568831SAndroid Build Coastguard Worker 
2361*7c568831SAndroid Build Coastguard Worker     if (cur == NULL) {
2362*7c568831SAndroid Build Coastguard Worker         return ((size_t) -1);
2363*7c568831SAndroid Build Coastguard Worker     }
2364*7c568831SAndroid Build Coastguard Worker     if (buf == NULL) {
2365*7c568831SAndroid Build Coastguard Worker         return ((size_t) -1);
2366*7c568831SAndroid Build Coastguard Worker     }
2367*7c568831SAndroid Build Coastguard Worker     outbuf = (xmlOutputBufferPtr) xmlMalloc(sizeof(xmlOutputBuffer));
2368*7c568831SAndroid Build Coastguard Worker     if (outbuf == NULL) {
2369*7c568831SAndroid Build Coastguard Worker         xmlSaveErrMemory(NULL);
2370*7c568831SAndroid Build Coastguard Worker         return ((size_t) -1);
2371*7c568831SAndroid Build Coastguard Worker     }
2372*7c568831SAndroid Build Coastguard Worker     memset(outbuf, 0, (size_t) sizeof(xmlOutputBuffer));
2373*7c568831SAndroid Build Coastguard Worker     outbuf->buffer = buf;
2374*7c568831SAndroid Build Coastguard Worker     outbuf->encoder = NULL;
2375*7c568831SAndroid Build Coastguard Worker     outbuf->writecallback = NULL;
2376*7c568831SAndroid Build Coastguard Worker     outbuf->closecallback = NULL;
2377*7c568831SAndroid Build Coastguard Worker     outbuf->context = NULL;
2378*7c568831SAndroid Build Coastguard Worker     outbuf->written = 0;
2379*7c568831SAndroid Build Coastguard Worker 
2380*7c568831SAndroid Build Coastguard Worker     use = xmlBufUse(buf);
2381*7c568831SAndroid Build Coastguard Worker     xmlNodeDumpOutput(outbuf, doc, cur, level, format, NULL);
2382*7c568831SAndroid Build Coastguard Worker     if (outbuf->error)
2383*7c568831SAndroid Build Coastguard Worker         ret = (size_t) -1;
2384*7c568831SAndroid Build Coastguard Worker     else
2385*7c568831SAndroid Build Coastguard Worker         ret = xmlBufUse(buf) - use;
2386*7c568831SAndroid Build Coastguard Worker     xmlFree(outbuf);
2387*7c568831SAndroid Build Coastguard Worker     return (ret);
2388*7c568831SAndroid Build Coastguard Worker }
2389*7c568831SAndroid Build Coastguard Worker 
2390*7c568831SAndroid Build Coastguard Worker /**
2391*7c568831SAndroid Build Coastguard Worker  * xmlElemDump:
2392*7c568831SAndroid Build Coastguard Worker  * @f:  the FILE * for the output
2393*7c568831SAndroid Build Coastguard Worker  * @doc:  the document
2394*7c568831SAndroid Build Coastguard Worker  * @cur:  the current node
2395*7c568831SAndroid Build Coastguard Worker  *
2396*7c568831SAndroid Build Coastguard Worker  * Dump an XML/HTML node, recursive behaviour, children are printed too.
2397*7c568831SAndroid Build Coastguard Worker  */
2398*7c568831SAndroid Build Coastguard Worker void
xmlElemDump(FILE * f,xmlDocPtr doc,xmlNodePtr cur)2399*7c568831SAndroid Build Coastguard Worker xmlElemDump(FILE * f, xmlDocPtr doc, xmlNodePtr cur)
2400*7c568831SAndroid Build Coastguard Worker {
2401*7c568831SAndroid Build Coastguard Worker     xmlOutputBufferPtr outbuf;
2402*7c568831SAndroid Build Coastguard Worker 
2403*7c568831SAndroid Build Coastguard Worker     xmlInitParser();
2404*7c568831SAndroid Build Coastguard Worker 
2405*7c568831SAndroid Build Coastguard Worker     if (cur == NULL) {
2406*7c568831SAndroid Build Coastguard Worker         return;
2407*7c568831SAndroid Build Coastguard Worker     }
2408*7c568831SAndroid Build Coastguard Worker 
2409*7c568831SAndroid Build Coastguard Worker     outbuf = xmlOutputBufferCreateFile(f, NULL);
2410*7c568831SAndroid Build Coastguard Worker     if (outbuf == NULL)
2411*7c568831SAndroid Build Coastguard Worker         return;
2412*7c568831SAndroid Build Coastguard Worker #ifdef LIBXML_HTML_ENABLED
2413*7c568831SAndroid Build Coastguard Worker     if ((doc != NULL) && (doc->type == XML_HTML_DOCUMENT_NODE))
2414*7c568831SAndroid Build Coastguard Worker         htmlNodeDumpOutput(outbuf, doc, cur, NULL);
2415*7c568831SAndroid Build Coastguard Worker     else
2416*7c568831SAndroid Build Coastguard Worker #endif /* LIBXML_HTML_ENABLED */
2417*7c568831SAndroid Build Coastguard Worker         xmlNodeDumpOutput(outbuf, doc, cur, 0, 1, NULL);
2418*7c568831SAndroid Build Coastguard Worker     xmlOutputBufferClose(outbuf);
2419*7c568831SAndroid Build Coastguard Worker }
2420*7c568831SAndroid Build Coastguard Worker 
2421*7c568831SAndroid Build Coastguard Worker /************************************************************************
2422*7c568831SAndroid Build Coastguard Worker  *									*
2423*7c568831SAndroid Build Coastguard Worker  *		Saving functions front-ends				*
2424*7c568831SAndroid Build Coastguard Worker  *									*
2425*7c568831SAndroid Build Coastguard Worker  ************************************************************************/
2426*7c568831SAndroid Build Coastguard Worker 
2427*7c568831SAndroid Build Coastguard Worker /**
2428*7c568831SAndroid Build Coastguard Worker  * xmlNodeDumpOutput:
2429*7c568831SAndroid Build Coastguard Worker  * @buf:  the XML buffer output
2430*7c568831SAndroid Build Coastguard Worker  * @doc:  the document
2431*7c568831SAndroid Build Coastguard Worker  * @cur:  the current node
2432*7c568831SAndroid Build Coastguard Worker  * @level: the imbrication level for indenting
2433*7c568831SAndroid Build Coastguard Worker  * @format: is formatting allowed
2434*7c568831SAndroid Build Coastguard Worker  * @encoding:  an optional encoding string
2435*7c568831SAndroid Build Coastguard Worker  *
2436*7c568831SAndroid Build Coastguard Worker  * Dump an XML node, recursive behaviour, children are printed too.
2437*7c568831SAndroid Build Coastguard Worker  * Note that @format = 1 provide node indenting only if xmlIndentTreeOutput = 1
2438*7c568831SAndroid Build Coastguard Worker  * or xmlKeepBlanksDefault(0) was called
2439*7c568831SAndroid Build Coastguard Worker  */
2440*7c568831SAndroid Build Coastguard Worker void
xmlNodeDumpOutput(xmlOutputBufferPtr buf,xmlDocPtr doc,xmlNodePtr cur,int level,int format,const char * encoding)2441*7c568831SAndroid Build Coastguard Worker xmlNodeDumpOutput(xmlOutputBufferPtr buf, xmlDocPtr doc, xmlNodePtr cur,
2442*7c568831SAndroid Build Coastguard Worker                   int level, int format, const char *encoding)
2443*7c568831SAndroid Build Coastguard Worker {
2444*7c568831SAndroid Build Coastguard Worker     xmlSaveCtxt ctxt;
2445*7c568831SAndroid Build Coastguard Worker     int options;
2446*7c568831SAndroid Build Coastguard Worker #ifdef LIBXML_HTML_ENABLED
2447*7c568831SAndroid Build Coastguard Worker     xmlDtdPtr dtd;
2448*7c568831SAndroid Build Coastguard Worker     int is_xhtml = 0;
2449*7c568831SAndroid Build Coastguard Worker #endif
2450*7c568831SAndroid Build Coastguard Worker 
2451*7c568831SAndroid Build Coastguard Worker     (void) doc;
2452*7c568831SAndroid Build Coastguard Worker 
2453*7c568831SAndroid Build Coastguard Worker     xmlInitParser();
2454*7c568831SAndroid Build Coastguard Worker 
2455*7c568831SAndroid Build Coastguard Worker     if ((buf == NULL) || (cur == NULL)) return;
2456*7c568831SAndroid Build Coastguard Worker 
2457*7c568831SAndroid Build Coastguard Worker     if (level < 0)
2458*7c568831SAndroid Build Coastguard Worker         level = 0;
2459*7c568831SAndroid Build Coastguard Worker     else if (level > 100)
2460*7c568831SAndroid Build Coastguard Worker         level = 100;
2461*7c568831SAndroid Build Coastguard Worker 
2462*7c568831SAndroid Build Coastguard Worker     if (encoding == NULL)
2463*7c568831SAndroid Build Coastguard Worker         encoding = "UTF-8";
2464*7c568831SAndroid Build Coastguard Worker 
2465*7c568831SAndroid Build Coastguard Worker     memset(&ctxt, 0, sizeof(ctxt));
2466*7c568831SAndroid Build Coastguard Worker     ctxt.buf = buf;
2467*7c568831SAndroid Build Coastguard Worker     ctxt.level = level;
2468*7c568831SAndroid Build Coastguard Worker     ctxt.encoding = (const xmlChar *) encoding;
2469*7c568831SAndroid Build Coastguard Worker 
2470*7c568831SAndroid Build Coastguard Worker     options = XML_SAVE_AS_XML;
2471*7c568831SAndroid Build Coastguard Worker     if (format)
2472*7c568831SAndroid Build Coastguard Worker         options |= XML_SAVE_FORMAT;
2473*7c568831SAndroid Build Coastguard Worker     xmlSaveCtxtInit(&ctxt, options);
2474*7c568831SAndroid Build Coastguard Worker 
2475*7c568831SAndroid Build Coastguard Worker #ifdef LIBXML_HTML_ENABLED
2476*7c568831SAndroid Build Coastguard Worker     dtd = xmlGetIntSubset(doc);
2477*7c568831SAndroid Build Coastguard Worker     if (dtd != NULL) {
2478*7c568831SAndroid Build Coastguard Worker 	is_xhtml = xmlIsXHTML(dtd->SystemID, dtd->ExternalID);
2479*7c568831SAndroid Build Coastguard Worker 	if (is_xhtml < 0)
2480*7c568831SAndroid Build Coastguard Worker 	    is_xhtml = 0;
2481*7c568831SAndroid Build Coastguard Worker     }
2482*7c568831SAndroid Build Coastguard Worker 
2483*7c568831SAndroid Build Coastguard Worker     if (is_xhtml)
2484*7c568831SAndroid Build Coastguard Worker         xhtmlNodeDumpOutput(&ctxt, cur);
2485*7c568831SAndroid Build Coastguard Worker     else
2486*7c568831SAndroid Build Coastguard Worker #endif
2487*7c568831SAndroid Build Coastguard Worker         xmlNodeDumpOutputInternal(&ctxt, cur);
2488*7c568831SAndroid Build Coastguard Worker }
2489*7c568831SAndroid Build Coastguard Worker 
2490*7c568831SAndroid Build Coastguard Worker /**
2491*7c568831SAndroid Build Coastguard Worker  * xmlDocDumpFormatMemoryEnc:
2492*7c568831SAndroid Build Coastguard Worker  * @out_doc:  Document to generate XML text from
2493*7c568831SAndroid Build Coastguard Worker  * @doc_txt_ptr:  Memory pointer for allocated XML text
2494*7c568831SAndroid Build Coastguard Worker  * @doc_txt_len:  Length of the generated XML text
2495*7c568831SAndroid Build Coastguard Worker  * @txt_encoding:  Character encoding to use when generating XML text
2496*7c568831SAndroid Build Coastguard Worker  * @format:  should formatting spaces been added
2497*7c568831SAndroid Build Coastguard Worker  *
2498*7c568831SAndroid Build Coastguard Worker  * Dump the current DOM tree into memory using the character encoding specified
2499*7c568831SAndroid Build Coastguard Worker  * by the caller.  Note it is up to the caller of this function to free the
2500*7c568831SAndroid Build Coastguard Worker  * allocated memory with xmlFree().
2501*7c568831SAndroid Build Coastguard Worker  * Note that @format = 1 provide node indenting only if xmlIndentTreeOutput = 1
2502*7c568831SAndroid Build Coastguard Worker  * or xmlKeepBlanksDefault(0) was called
2503*7c568831SAndroid Build Coastguard Worker  */
2504*7c568831SAndroid Build Coastguard Worker 
2505*7c568831SAndroid Build Coastguard Worker void
xmlDocDumpFormatMemoryEnc(xmlDocPtr out_doc,xmlChar ** doc_txt_ptr,int * doc_txt_len,const char * txt_encoding,int format)2506*7c568831SAndroid Build Coastguard Worker xmlDocDumpFormatMemoryEnc(xmlDocPtr out_doc, xmlChar **doc_txt_ptr,
2507*7c568831SAndroid Build Coastguard Worker 		int * doc_txt_len, const char * txt_encoding,
2508*7c568831SAndroid Build Coastguard Worker 		int format) {
2509*7c568831SAndroid Build Coastguard Worker     xmlSaveCtxt ctxt;
2510*7c568831SAndroid Build Coastguard Worker     int options;
2511*7c568831SAndroid Build Coastguard Worker     int                         dummy = 0;
2512*7c568831SAndroid Build Coastguard Worker     xmlOutputBufferPtr          out_buff = NULL;
2513*7c568831SAndroid Build Coastguard Worker     xmlCharEncodingHandlerPtr   conv_hdlr = NULL;
2514*7c568831SAndroid Build Coastguard Worker 
2515*7c568831SAndroid Build Coastguard Worker     if (doc_txt_len == NULL) {
2516*7c568831SAndroid Build Coastguard Worker         doc_txt_len = &dummy;   /*  Continue, caller just won't get length */
2517*7c568831SAndroid Build Coastguard Worker     }
2518*7c568831SAndroid Build Coastguard Worker 
2519*7c568831SAndroid Build Coastguard Worker     if (doc_txt_ptr == NULL) {
2520*7c568831SAndroid Build Coastguard Worker         *doc_txt_len = 0;
2521*7c568831SAndroid Build Coastguard Worker         return;
2522*7c568831SAndroid Build Coastguard Worker     }
2523*7c568831SAndroid Build Coastguard Worker 
2524*7c568831SAndroid Build Coastguard Worker     *doc_txt_ptr = NULL;
2525*7c568831SAndroid Build Coastguard Worker     *doc_txt_len = 0;
2526*7c568831SAndroid Build Coastguard Worker 
2527*7c568831SAndroid Build Coastguard Worker     if (out_doc == NULL) {
2528*7c568831SAndroid Build Coastguard Worker         /*  No document, no output  */
2529*7c568831SAndroid Build Coastguard Worker         return;
2530*7c568831SAndroid Build Coastguard Worker     }
2531*7c568831SAndroid Build Coastguard Worker 
2532*7c568831SAndroid Build Coastguard Worker     /*
2533*7c568831SAndroid Build Coastguard Worker      *  Validate the encoding value, if provided.
2534*7c568831SAndroid Build Coastguard Worker      *  This logic is copied from xmlSaveFileEnc.
2535*7c568831SAndroid Build Coastguard Worker      */
2536*7c568831SAndroid Build Coastguard Worker 
2537*7c568831SAndroid Build Coastguard Worker     if (txt_encoding == NULL)
2538*7c568831SAndroid Build Coastguard Worker 	txt_encoding = (const char *) out_doc->encoding;
2539*7c568831SAndroid Build Coastguard Worker     if (txt_encoding != NULL) {
2540*7c568831SAndroid Build Coastguard Worker         int res;
2541*7c568831SAndroid Build Coastguard Worker 
2542*7c568831SAndroid Build Coastguard Worker 	res = xmlOpenCharEncodingHandler(txt_encoding, /* output */ 1,
2543*7c568831SAndroid Build Coastguard Worker                                          &conv_hdlr);
2544*7c568831SAndroid Build Coastguard Worker 	if (res != XML_ERR_OK) {
2545*7c568831SAndroid Build Coastguard Worker             xmlSaveErr(NULL, res, NULL, txt_encoding);
2546*7c568831SAndroid Build Coastguard Worker 	    return;
2547*7c568831SAndroid Build Coastguard Worker 	}
2548*7c568831SAndroid Build Coastguard Worker     }
2549*7c568831SAndroid Build Coastguard Worker 
2550*7c568831SAndroid Build Coastguard Worker     out_buff = xmlAllocOutputBuffer(conv_hdlr);
2551*7c568831SAndroid Build Coastguard Worker     if (out_buff == NULL ) {
2552*7c568831SAndroid Build Coastguard Worker         xmlSaveErrMemory(NULL);
2553*7c568831SAndroid Build Coastguard Worker         return;
2554*7c568831SAndroid Build Coastguard Worker     }
2555*7c568831SAndroid Build Coastguard Worker 
2556*7c568831SAndroid Build Coastguard Worker     memset(&ctxt, 0, sizeof(ctxt));
2557*7c568831SAndroid Build Coastguard Worker     ctxt.buf = out_buff;
2558*7c568831SAndroid Build Coastguard Worker     ctxt.level = 0;
2559*7c568831SAndroid Build Coastguard Worker     ctxt.encoding = (const xmlChar *) txt_encoding;
2560*7c568831SAndroid Build Coastguard Worker 
2561*7c568831SAndroid Build Coastguard Worker     options = XML_SAVE_AS_XML;
2562*7c568831SAndroid Build Coastguard Worker     if (format)
2563*7c568831SAndroid Build Coastguard Worker         options |= XML_SAVE_FORMAT;
2564*7c568831SAndroid Build Coastguard Worker     xmlSaveCtxtInit(&ctxt, options);
2565*7c568831SAndroid Build Coastguard Worker 
2566*7c568831SAndroid Build Coastguard Worker     xmlDocContentDumpOutput(&ctxt, out_doc);
2567*7c568831SAndroid Build Coastguard Worker     xmlOutputBufferFlush(out_buff);
2568*7c568831SAndroid Build Coastguard Worker 
2569*7c568831SAndroid Build Coastguard Worker     if (!out_buff->error) {
2570*7c568831SAndroid Build Coastguard Worker         if (out_buff->conv != NULL) {
2571*7c568831SAndroid Build Coastguard Worker             *doc_txt_len = xmlBufUse(out_buff->conv);
2572*7c568831SAndroid Build Coastguard Worker             *doc_txt_ptr = xmlBufDetach(out_buff->conv);
2573*7c568831SAndroid Build Coastguard Worker         } else {
2574*7c568831SAndroid Build Coastguard Worker             *doc_txt_len = xmlBufUse(out_buff->buffer);
2575*7c568831SAndroid Build Coastguard Worker             *doc_txt_ptr = xmlBufDetach(out_buff->buffer);
2576*7c568831SAndroid Build Coastguard Worker         }
2577*7c568831SAndroid Build Coastguard Worker     }
2578*7c568831SAndroid Build Coastguard Worker 
2579*7c568831SAndroid Build Coastguard Worker     xmlOutputBufferClose(out_buff);
2580*7c568831SAndroid Build Coastguard Worker }
2581*7c568831SAndroid Build Coastguard Worker 
2582*7c568831SAndroid Build Coastguard Worker /**
2583*7c568831SAndroid Build Coastguard Worker  * xmlDocDumpMemory:
2584*7c568831SAndroid Build Coastguard Worker  * @cur:  the document
2585*7c568831SAndroid Build Coastguard Worker  * @mem:  OUT: the memory pointer
2586*7c568831SAndroid Build Coastguard Worker  * @size:  OUT: the memory length
2587*7c568831SAndroid Build Coastguard Worker  *
2588*7c568831SAndroid Build Coastguard Worker  * Dump an XML document in memory and return the #xmlChar * and it's size
2589*7c568831SAndroid Build Coastguard Worker  * in bytes. It's up to the caller to free the memory with xmlFree().
2590*7c568831SAndroid Build Coastguard Worker  * The resulting byte array is zero terminated, though the last 0 is not
2591*7c568831SAndroid Build Coastguard Worker  * included in the returned size.
2592*7c568831SAndroid Build Coastguard Worker  */
2593*7c568831SAndroid Build Coastguard Worker void
xmlDocDumpMemory(xmlDocPtr cur,xmlChar ** mem,int * size)2594*7c568831SAndroid Build Coastguard Worker xmlDocDumpMemory(xmlDocPtr cur, xmlChar**mem, int *size) {
2595*7c568831SAndroid Build Coastguard Worker     xmlDocDumpFormatMemoryEnc(cur, mem, size, NULL, 0);
2596*7c568831SAndroid Build Coastguard Worker }
2597*7c568831SAndroid Build Coastguard Worker 
2598*7c568831SAndroid Build Coastguard Worker /**
2599*7c568831SAndroid Build Coastguard Worker  * xmlDocDumpFormatMemory:
2600*7c568831SAndroid Build Coastguard Worker  * @cur:  the document
2601*7c568831SAndroid Build Coastguard Worker  * @mem:  OUT: the memory pointer
2602*7c568831SAndroid Build Coastguard Worker  * @size:  OUT: the memory length
2603*7c568831SAndroid Build Coastguard Worker  * @format:  should formatting spaces been added
2604*7c568831SAndroid Build Coastguard Worker  *
2605*7c568831SAndroid Build Coastguard Worker  *
2606*7c568831SAndroid Build Coastguard Worker  * Dump an XML document in memory and return the #xmlChar * and it's size.
2607*7c568831SAndroid Build Coastguard Worker  * It's up to the caller to free the memory with xmlFree().
2608*7c568831SAndroid Build Coastguard Worker  * Note that @format = 1 provide node indenting only if xmlIndentTreeOutput = 1
2609*7c568831SAndroid Build Coastguard Worker  * or xmlKeepBlanksDefault(0) was called
2610*7c568831SAndroid Build Coastguard Worker  */
2611*7c568831SAndroid Build Coastguard Worker void
xmlDocDumpFormatMemory(xmlDocPtr cur,xmlChar ** mem,int * size,int format)2612*7c568831SAndroid Build Coastguard Worker xmlDocDumpFormatMemory(xmlDocPtr cur, xmlChar**mem, int *size, int format) {
2613*7c568831SAndroid Build Coastguard Worker     xmlDocDumpFormatMemoryEnc(cur, mem, size, NULL, format);
2614*7c568831SAndroid Build Coastguard Worker }
2615*7c568831SAndroid Build Coastguard Worker 
2616*7c568831SAndroid Build Coastguard Worker /**
2617*7c568831SAndroid Build Coastguard Worker  * xmlDocDumpMemoryEnc:
2618*7c568831SAndroid Build Coastguard Worker  * @out_doc:  Document to generate XML text from
2619*7c568831SAndroid Build Coastguard Worker  * @doc_txt_ptr:  Memory pointer for allocated XML text
2620*7c568831SAndroid Build Coastguard Worker  * @doc_txt_len:  Length of the generated XML text
2621*7c568831SAndroid Build Coastguard Worker  * @txt_encoding:  Character encoding to use when generating XML text
2622*7c568831SAndroid Build Coastguard Worker  *
2623*7c568831SAndroid Build Coastguard Worker  * Dump the current DOM tree into memory using the character encoding specified
2624*7c568831SAndroid Build Coastguard Worker  * by the caller.  Note it is up to the caller of this function to free the
2625*7c568831SAndroid Build Coastguard Worker  * allocated memory with xmlFree().
2626*7c568831SAndroid Build Coastguard Worker  */
2627*7c568831SAndroid Build Coastguard Worker 
2628*7c568831SAndroid Build Coastguard Worker void
xmlDocDumpMemoryEnc(xmlDocPtr out_doc,xmlChar ** doc_txt_ptr,int * doc_txt_len,const char * txt_encoding)2629*7c568831SAndroid Build Coastguard Worker xmlDocDumpMemoryEnc(xmlDocPtr out_doc, xmlChar **doc_txt_ptr,
2630*7c568831SAndroid Build Coastguard Worker 	            int * doc_txt_len, const char * txt_encoding) {
2631*7c568831SAndroid Build Coastguard Worker     xmlDocDumpFormatMemoryEnc(out_doc, doc_txt_ptr, doc_txt_len,
2632*7c568831SAndroid Build Coastguard Worker 	                      txt_encoding, 0);
2633*7c568831SAndroid Build Coastguard Worker }
2634*7c568831SAndroid Build Coastguard Worker 
2635*7c568831SAndroid Build Coastguard Worker /**
2636*7c568831SAndroid Build Coastguard Worker  * xmlDocFormatDump:
2637*7c568831SAndroid Build Coastguard Worker  * @f:  the FILE*
2638*7c568831SAndroid Build Coastguard Worker  * @cur:  the document
2639*7c568831SAndroid Build Coastguard Worker  * @format: should formatting spaces been added
2640*7c568831SAndroid Build Coastguard Worker  *
2641*7c568831SAndroid Build Coastguard Worker  * Dump an XML document to an open FILE.
2642*7c568831SAndroid Build Coastguard Worker  *
2643*7c568831SAndroid Build Coastguard Worker  * returns: the number of bytes written or -1 in case of failure.
2644*7c568831SAndroid Build Coastguard Worker  * Note that @format = 1 provide node indenting only if xmlIndentTreeOutput = 1
2645*7c568831SAndroid Build Coastguard Worker  * or xmlKeepBlanksDefault(0) was called
2646*7c568831SAndroid Build Coastguard Worker  */
2647*7c568831SAndroid Build Coastguard Worker int
xmlDocFormatDump(FILE * f,xmlDocPtr cur,int format)2648*7c568831SAndroid Build Coastguard Worker xmlDocFormatDump(FILE *f, xmlDocPtr cur, int format) {
2649*7c568831SAndroid Build Coastguard Worker     xmlSaveCtxt ctxt;
2650*7c568831SAndroid Build Coastguard Worker     xmlOutputBufferPtr buf;
2651*7c568831SAndroid Build Coastguard Worker     const char * encoding;
2652*7c568831SAndroid Build Coastguard Worker     xmlCharEncodingHandlerPtr handler = NULL;
2653*7c568831SAndroid Build Coastguard Worker     int ret;
2654*7c568831SAndroid Build Coastguard Worker     int options;
2655*7c568831SAndroid Build Coastguard Worker 
2656*7c568831SAndroid Build Coastguard Worker     if (cur == NULL) {
2657*7c568831SAndroid Build Coastguard Worker 	return(-1);
2658*7c568831SAndroid Build Coastguard Worker     }
2659*7c568831SAndroid Build Coastguard Worker     encoding = (const char *) cur->encoding;
2660*7c568831SAndroid Build Coastguard Worker 
2661*7c568831SAndroid Build Coastguard Worker     if (encoding != NULL) {
2662*7c568831SAndroid Build Coastguard Worker         int res;
2663*7c568831SAndroid Build Coastguard Worker 
2664*7c568831SAndroid Build Coastguard Worker 	res = xmlOpenCharEncodingHandler(encoding, /* output */ 1, &handler);
2665*7c568831SAndroid Build Coastguard Worker 	if (res != XML_ERR_OK) {
2666*7c568831SAndroid Build Coastguard Worker 	    xmlFree((char *) cur->encoding);
2667*7c568831SAndroid Build Coastguard Worker 	    encoding = NULL;
2668*7c568831SAndroid Build Coastguard Worker 	}
2669*7c568831SAndroid Build Coastguard Worker     }
2670*7c568831SAndroid Build Coastguard Worker     buf = xmlOutputBufferCreateFile(f, handler);
2671*7c568831SAndroid Build Coastguard Worker     if (buf == NULL) return(-1);
2672*7c568831SAndroid Build Coastguard Worker     memset(&ctxt, 0, sizeof(ctxt));
2673*7c568831SAndroid Build Coastguard Worker     ctxt.buf = buf;
2674*7c568831SAndroid Build Coastguard Worker     ctxt.level = 0;
2675*7c568831SAndroid Build Coastguard Worker     ctxt.encoding = (const xmlChar *) encoding;
2676*7c568831SAndroid Build Coastguard Worker 
2677*7c568831SAndroid Build Coastguard Worker     options = XML_SAVE_AS_XML;
2678*7c568831SAndroid Build Coastguard Worker     if (format)
2679*7c568831SAndroid Build Coastguard Worker         options |= XML_SAVE_FORMAT;
2680*7c568831SAndroid Build Coastguard Worker     xmlSaveCtxtInit(&ctxt, options);
2681*7c568831SAndroid Build Coastguard Worker 
2682*7c568831SAndroid Build Coastguard Worker     xmlDocContentDumpOutput(&ctxt, cur);
2683*7c568831SAndroid Build Coastguard Worker 
2684*7c568831SAndroid Build Coastguard Worker     ret = xmlOutputBufferClose(buf);
2685*7c568831SAndroid Build Coastguard Worker     return(ret);
2686*7c568831SAndroid Build Coastguard Worker }
2687*7c568831SAndroid Build Coastguard Worker 
2688*7c568831SAndroid Build Coastguard Worker /**
2689*7c568831SAndroid Build Coastguard Worker  * xmlDocDump:
2690*7c568831SAndroid Build Coastguard Worker  * @f:  the FILE*
2691*7c568831SAndroid Build Coastguard Worker  * @cur:  the document
2692*7c568831SAndroid Build Coastguard Worker  *
2693*7c568831SAndroid Build Coastguard Worker  * Dump an XML document to an open FILE.
2694*7c568831SAndroid Build Coastguard Worker  *
2695*7c568831SAndroid Build Coastguard Worker  * returns: the number of bytes written or -1 in case of failure.
2696*7c568831SAndroid Build Coastguard Worker  */
2697*7c568831SAndroid Build Coastguard Worker int
xmlDocDump(FILE * f,xmlDocPtr cur)2698*7c568831SAndroid Build Coastguard Worker xmlDocDump(FILE *f, xmlDocPtr cur) {
2699*7c568831SAndroid Build Coastguard Worker     return(xmlDocFormatDump (f, cur, 0));
2700*7c568831SAndroid Build Coastguard Worker }
2701*7c568831SAndroid Build Coastguard Worker 
2702*7c568831SAndroid Build Coastguard Worker /**
2703*7c568831SAndroid Build Coastguard Worker  * xmlSaveFileTo:
2704*7c568831SAndroid Build Coastguard Worker  * @buf:  an output I/O buffer
2705*7c568831SAndroid Build Coastguard Worker  * @cur:  the document
2706*7c568831SAndroid Build Coastguard Worker  * @encoding:  the encoding if any assuming the I/O layer handles the transcoding
2707*7c568831SAndroid Build Coastguard Worker  *
2708*7c568831SAndroid Build Coastguard Worker  * Dump an XML document to an I/O buffer.
2709*7c568831SAndroid Build Coastguard Worker  * Warning ! This call xmlOutputBufferClose() on buf which is not available
2710*7c568831SAndroid Build Coastguard Worker  * after this call.
2711*7c568831SAndroid Build Coastguard Worker  *
2712*7c568831SAndroid Build Coastguard Worker  * returns: the number of bytes written or -1 in case of failure.
2713*7c568831SAndroid Build Coastguard Worker  */
2714*7c568831SAndroid Build Coastguard Worker int
xmlSaveFileTo(xmlOutputBufferPtr buf,xmlDocPtr cur,const char * encoding)2715*7c568831SAndroid Build Coastguard Worker xmlSaveFileTo(xmlOutputBufferPtr buf, xmlDocPtr cur, const char *encoding) {
2716*7c568831SAndroid Build Coastguard Worker     xmlSaveCtxt ctxt;
2717*7c568831SAndroid Build Coastguard Worker     int ret;
2718*7c568831SAndroid Build Coastguard Worker 
2719*7c568831SAndroid Build Coastguard Worker     if (buf == NULL) return(-1);
2720*7c568831SAndroid Build Coastguard Worker     if (cur == NULL) {
2721*7c568831SAndroid Build Coastguard Worker         xmlOutputBufferClose(buf);
2722*7c568831SAndroid Build Coastguard Worker 	return(-1);
2723*7c568831SAndroid Build Coastguard Worker     }
2724*7c568831SAndroid Build Coastguard Worker     memset(&ctxt, 0, sizeof(ctxt));
2725*7c568831SAndroid Build Coastguard Worker     ctxt.buf = buf;
2726*7c568831SAndroid Build Coastguard Worker     ctxt.level = 0;
2727*7c568831SAndroid Build Coastguard Worker     ctxt.encoding = (const xmlChar *) encoding;
2728*7c568831SAndroid Build Coastguard Worker 
2729*7c568831SAndroid Build Coastguard Worker     xmlSaveCtxtInit(&ctxt, XML_SAVE_AS_XML);
2730*7c568831SAndroid Build Coastguard Worker 
2731*7c568831SAndroid Build Coastguard Worker     xmlDocContentDumpOutput(&ctxt, cur);
2732*7c568831SAndroid Build Coastguard Worker     ret = xmlOutputBufferClose(buf);
2733*7c568831SAndroid Build Coastguard Worker     return(ret);
2734*7c568831SAndroid Build Coastguard Worker }
2735*7c568831SAndroid Build Coastguard Worker 
2736*7c568831SAndroid Build Coastguard Worker /**
2737*7c568831SAndroid Build Coastguard Worker  * xmlSaveFormatFileTo:
2738*7c568831SAndroid Build Coastguard Worker  * @buf:  an output I/O buffer
2739*7c568831SAndroid Build Coastguard Worker  * @cur:  the document
2740*7c568831SAndroid Build Coastguard Worker  * @encoding:  the encoding if any assuming the I/O layer handles the transcoding
2741*7c568831SAndroid Build Coastguard Worker  * @format: should formatting spaces been added
2742*7c568831SAndroid Build Coastguard Worker  *
2743*7c568831SAndroid Build Coastguard Worker  * Dump an XML document to an I/O buffer.
2744*7c568831SAndroid Build Coastguard Worker  * Warning ! This call xmlOutputBufferClose() on buf which is not available
2745*7c568831SAndroid Build Coastguard Worker  * after this call.
2746*7c568831SAndroid Build Coastguard Worker  *
2747*7c568831SAndroid Build Coastguard Worker  * returns: the number of bytes written or -1 in case of failure.
2748*7c568831SAndroid Build Coastguard Worker  */
2749*7c568831SAndroid Build Coastguard Worker int
xmlSaveFormatFileTo(xmlOutputBufferPtr buf,xmlDocPtr cur,const char * encoding,int format)2750*7c568831SAndroid Build Coastguard Worker xmlSaveFormatFileTo(xmlOutputBufferPtr buf, xmlDocPtr cur,
2751*7c568831SAndroid Build Coastguard Worker                     const char *encoding, int format)
2752*7c568831SAndroid Build Coastguard Worker {
2753*7c568831SAndroid Build Coastguard Worker     xmlSaveCtxt ctxt;
2754*7c568831SAndroid Build Coastguard Worker     int ret;
2755*7c568831SAndroid Build Coastguard Worker     int options;
2756*7c568831SAndroid Build Coastguard Worker 
2757*7c568831SAndroid Build Coastguard Worker     if (buf == NULL) return(-1);
2758*7c568831SAndroid Build Coastguard Worker     if ((cur == NULL) ||
2759*7c568831SAndroid Build Coastguard Worker         ((cur->type != XML_DOCUMENT_NODE) &&
2760*7c568831SAndroid Build Coastguard Worker 	 (cur->type != XML_HTML_DOCUMENT_NODE))) {
2761*7c568831SAndroid Build Coastguard Worker         xmlOutputBufferClose(buf);
2762*7c568831SAndroid Build Coastguard Worker 	return(-1);
2763*7c568831SAndroid Build Coastguard Worker     }
2764*7c568831SAndroid Build Coastguard Worker     memset(&ctxt, 0, sizeof(ctxt));
2765*7c568831SAndroid Build Coastguard Worker     ctxt.buf = buf;
2766*7c568831SAndroid Build Coastguard Worker     ctxt.level = 0;
2767*7c568831SAndroid Build Coastguard Worker     ctxt.encoding = (const xmlChar *) encoding;
2768*7c568831SAndroid Build Coastguard Worker 
2769*7c568831SAndroid Build Coastguard Worker     options = XML_SAVE_AS_XML;
2770*7c568831SAndroid Build Coastguard Worker     if (format)
2771*7c568831SAndroid Build Coastguard Worker         options |= XML_SAVE_FORMAT;
2772*7c568831SAndroid Build Coastguard Worker     xmlSaveCtxtInit(&ctxt, options);
2773*7c568831SAndroid Build Coastguard Worker 
2774*7c568831SAndroid Build Coastguard Worker     xmlDocContentDumpOutput(&ctxt, cur);
2775*7c568831SAndroid Build Coastguard Worker     ret = xmlOutputBufferClose(buf);
2776*7c568831SAndroid Build Coastguard Worker     return (ret);
2777*7c568831SAndroid Build Coastguard Worker }
2778*7c568831SAndroid Build Coastguard Worker 
2779*7c568831SAndroid Build Coastguard Worker /**
2780*7c568831SAndroid Build Coastguard Worker  * xmlSaveFormatFileEnc:
2781*7c568831SAndroid Build Coastguard Worker  * @filename:  the filename or URL to output
2782*7c568831SAndroid Build Coastguard Worker  * @cur:  the document being saved
2783*7c568831SAndroid Build Coastguard Worker  * @encoding:  the name of the encoding to use or NULL.
2784*7c568831SAndroid Build Coastguard Worker  * @format:  should formatting spaces be added.
2785*7c568831SAndroid Build Coastguard Worker  *
2786*7c568831SAndroid Build Coastguard Worker  * Dump an XML document to a file or an URL.
2787*7c568831SAndroid Build Coastguard Worker  *
2788*7c568831SAndroid Build Coastguard Worker  * Returns the number of bytes written or -1 in case of error.
2789*7c568831SAndroid Build Coastguard Worker  * Note that @format = 1 provide node indenting only if xmlIndentTreeOutput = 1
2790*7c568831SAndroid Build Coastguard Worker  * or xmlKeepBlanksDefault(0) was called
2791*7c568831SAndroid Build Coastguard Worker  */
2792*7c568831SAndroid Build Coastguard Worker int
xmlSaveFormatFileEnc(const char * filename,xmlDocPtr cur,const char * encoding,int format)2793*7c568831SAndroid Build Coastguard Worker xmlSaveFormatFileEnc( const char * filename, xmlDocPtr cur,
2794*7c568831SAndroid Build Coastguard Worker 			const char * encoding, int format ) {
2795*7c568831SAndroid Build Coastguard Worker     xmlSaveCtxt ctxt;
2796*7c568831SAndroid Build Coastguard Worker     xmlOutputBufferPtr buf;
2797*7c568831SAndroid Build Coastguard Worker     xmlCharEncodingHandlerPtr handler = NULL;
2798*7c568831SAndroid Build Coastguard Worker     int ret;
2799*7c568831SAndroid Build Coastguard Worker     int options;
2800*7c568831SAndroid Build Coastguard Worker 
2801*7c568831SAndroid Build Coastguard Worker     if (cur == NULL)
2802*7c568831SAndroid Build Coastguard Worker 	return(-1);
2803*7c568831SAndroid Build Coastguard Worker 
2804*7c568831SAndroid Build Coastguard Worker     if (encoding == NULL)
2805*7c568831SAndroid Build Coastguard Worker 	encoding = (const char *) cur->encoding;
2806*7c568831SAndroid Build Coastguard Worker 
2807*7c568831SAndroid Build Coastguard Worker     if (encoding != NULL) {
2808*7c568831SAndroid Build Coastguard Worker         int res;
2809*7c568831SAndroid Build Coastguard Worker 
2810*7c568831SAndroid Build Coastguard Worker         res = xmlOpenCharEncodingHandler(encoding, /* output */ 1, &handler);
2811*7c568831SAndroid Build Coastguard Worker         if (res != XML_ERR_OK)
2812*7c568831SAndroid Build Coastguard Worker             return(-1);
2813*7c568831SAndroid Build Coastguard Worker     }
2814*7c568831SAndroid Build Coastguard Worker 
2815*7c568831SAndroid Build Coastguard Worker #ifdef LIBXML_ZLIB_ENABLED
2816*7c568831SAndroid Build Coastguard Worker     if (cur->compression < 0) cur->compression = xmlGetCompressMode();
2817*7c568831SAndroid Build Coastguard Worker #endif
2818*7c568831SAndroid Build Coastguard Worker     /*
2819*7c568831SAndroid Build Coastguard Worker      * save the content to a temp buffer.
2820*7c568831SAndroid Build Coastguard Worker      */
2821*7c568831SAndroid Build Coastguard Worker     buf = xmlOutputBufferCreateFilename(filename, handler, cur->compression);
2822*7c568831SAndroid Build Coastguard Worker     if (buf == NULL) return(-1);
2823*7c568831SAndroid Build Coastguard Worker     memset(&ctxt, 0, sizeof(ctxt));
2824*7c568831SAndroid Build Coastguard Worker     ctxt.buf = buf;
2825*7c568831SAndroid Build Coastguard Worker     ctxt.level = 0;
2826*7c568831SAndroid Build Coastguard Worker     ctxt.encoding = (const xmlChar *) encoding;
2827*7c568831SAndroid Build Coastguard Worker 
2828*7c568831SAndroid Build Coastguard Worker     options = XML_SAVE_AS_XML;
2829*7c568831SAndroid Build Coastguard Worker     if (format)
2830*7c568831SAndroid Build Coastguard Worker         options |= XML_SAVE_FORMAT;
2831*7c568831SAndroid Build Coastguard Worker     xmlSaveCtxtInit(&ctxt, options);
2832*7c568831SAndroid Build Coastguard Worker 
2833*7c568831SAndroid Build Coastguard Worker     xmlDocContentDumpOutput(&ctxt, cur);
2834*7c568831SAndroid Build Coastguard Worker 
2835*7c568831SAndroid Build Coastguard Worker     ret = xmlOutputBufferClose(buf);
2836*7c568831SAndroid Build Coastguard Worker     return(ret);
2837*7c568831SAndroid Build Coastguard Worker }
2838*7c568831SAndroid Build Coastguard Worker 
2839*7c568831SAndroid Build Coastguard Worker 
2840*7c568831SAndroid Build Coastguard Worker /**
2841*7c568831SAndroid Build Coastguard Worker  * xmlSaveFileEnc:
2842*7c568831SAndroid Build Coastguard Worker  * @filename:  the filename (or URL)
2843*7c568831SAndroid Build Coastguard Worker  * @cur:  the document
2844*7c568831SAndroid Build Coastguard Worker  * @encoding:  the name of an encoding (or NULL)
2845*7c568831SAndroid Build Coastguard Worker  *
2846*7c568831SAndroid Build Coastguard Worker  * Dump an XML document, converting it to the given encoding
2847*7c568831SAndroid Build Coastguard Worker  *
2848*7c568831SAndroid Build Coastguard Worker  * returns: the number of bytes written or -1 in case of failure.
2849*7c568831SAndroid Build Coastguard Worker  */
2850*7c568831SAndroid Build Coastguard Worker int
xmlSaveFileEnc(const char * filename,xmlDocPtr cur,const char * encoding)2851*7c568831SAndroid Build Coastguard Worker xmlSaveFileEnc(const char *filename, xmlDocPtr cur, const char *encoding) {
2852*7c568831SAndroid Build Coastguard Worker     return ( xmlSaveFormatFileEnc( filename, cur, encoding, 0 ) );
2853*7c568831SAndroid Build Coastguard Worker }
2854*7c568831SAndroid Build Coastguard Worker 
2855*7c568831SAndroid Build Coastguard Worker /**
2856*7c568831SAndroid Build Coastguard Worker  * xmlSaveFormatFile:
2857*7c568831SAndroid Build Coastguard Worker  * @filename:  the filename (or URL)
2858*7c568831SAndroid Build Coastguard Worker  * @cur:  the document
2859*7c568831SAndroid Build Coastguard Worker  * @format:  should formatting spaces been added
2860*7c568831SAndroid Build Coastguard Worker  *
2861*7c568831SAndroid Build Coastguard Worker  * Dump an XML document to a file. Will use compression if
2862*7c568831SAndroid Build Coastguard Worker  * compiled in and enabled. If @filename is "-" the stdout file is
2863*7c568831SAndroid Build Coastguard Worker  * used. If @format is set then the document will be indented on output.
2864*7c568831SAndroid Build Coastguard Worker  * Note that @format = 1 provide node indenting only if xmlIndentTreeOutput = 1
2865*7c568831SAndroid Build Coastguard Worker  * or xmlKeepBlanksDefault(0) was called
2866*7c568831SAndroid Build Coastguard Worker  *
2867*7c568831SAndroid Build Coastguard Worker  * returns: the number of bytes written or -1 in case of failure.
2868*7c568831SAndroid Build Coastguard Worker  */
2869*7c568831SAndroid Build Coastguard Worker int
xmlSaveFormatFile(const char * filename,xmlDocPtr cur,int format)2870*7c568831SAndroid Build Coastguard Worker xmlSaveFormatFile(const char *filename, xmlDocPtr cur, int format) {
2871*7c568831SAndroid Build Coastguard Worker     return ( xmlSaveFormatFileEnc( filename, cur, NULL, format ) );
2872*7c568831SAndroid Build Coastguard Worker }
2873*7c568831SAndroid Build Coastguard Worker 
2874*7c568831SAndroid Build Coastguard Worker /**
2875*7c568831SAndroid Build Coastguard Worker  * xmlSaveFile:
2876*7c568831SAndroid Build Coastguard Worker  * @filename:  the filename (or URL)
2877*7c568831SAndroid Build Coastguard Worker  * @cur:  the document
2878*7c568831SAndroid Build Coastguard Worker  *
2879*7c568831SAndroid Build Coastguard Worker  * Dump an XML document to a file. Will use compression if
2880*7c568831SAndroid Build Coastguard Worker  * compiled in and enabled. If @filename is "-" the stdout file is
2881*7c568831SAndroid Build Coastguard Worker  * used.
2882*7c568831SAndroid Build Coastguard Worker  * returns: the number of bytes written or -1 in case of failure.
2883*7c568831SAndroid Build Coastguard Worker  */
2884*7c568831SAndroid Build Coastguard Worker int
xmlSaveFile(const char * filename,xmlDocPtr cur)2885*7c568831SAndroid Build Coastguard Worker xmlSaveFile(const char *filename, xmlDocPtr cur) {
2886*7c568831SAndroid Build Coastguard Worker     return(xmlSaveFormatFileEnc(filename, cur, NULL, 0));
2887*7c568831SAndroid Build Coastguard Worker }
2888*7c568831SAndroid Build Coastguard Worker 
2889*7c568831SAndroid Build Coastguard Worker #endif /* LIBXML_OUTPUT_ENABLED */
2890*7c568831SAndroid Build Coastguard Worker 
2891