~ubuntu-branches/ubuntu/utopic/libxml2/utopic

« back to all changes in this revision

Viewing changes to .pc/0027-Fix-xmlTextWriterWriteElement-when-a-null-content-is.patch/xmlwriter.c

  • Committer: Package Import Robot
  • Author(s): Aron Xu, Christian Svensson, Daniel Schepler, Helmut Grohne, Adam Conrad, Matthias Klose, Aron Xu
  • Date: 2014-07-09 05:40:15 UTC
  • mto: This revision was merged to the branch mainline in revision 75.
  • Revision ID: package-import@ubuntu.com-20140709054015-rdnfjxrf3zvmw6l7
[ Christian Svensson ]
* Do not build-depend on readline (Closes: #742350)

[ Daniel Schepler ]
* Patch to bootstrap without python (Closes: #738080)

[ Helmut Grohne ]
* Drop unneeded B-D on perl and binutils (Closes: #753005)

[ Adam Conrad ]
* Actually run dh_autoreconf, which the old/new mixed rules file misses.

[ Matthias Klose ]
* Add patch to fix python multiarch issue
* Allow the package to cross-build by tweaking B-Ds on python
* Set PYTHON_LIBS for cross builds

[ Aron Xu ]
* Use correct $CC
* Configure udeb without python
* New round of cherry-picking upstream fixes
  - Includes fixes for CVE-2014-0191 (Closes: #747309).
* Call prename with -vf
* Require python-all-dev (>= 2.7.5-5~)
* Bump std-ver: 3.9.4 -> 3.9.5, no change

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
 
 
2
/*
 
3
 * xmlwriter.c: XML text writer implementation
 
4
 *
 
5
 * For license and disclaimer see the license and disclaimer of
 
6
 * libxml2.
 
7
 *
 
8
 * alfred@mickautsch.de
 
9
 */
 
10
 
 
11
#define IN_LIBXML
 
12
#include "libxml.h"
 
13
#include <string.h>
 
14
 
 
15
#include <libxml/xmlmemory.h>
 
16
#include <libxml/parser.h>
 
17
#include <libxml/uri.h>
 
18
#include <libxml/HTMLtree.h>
 
19
 
 
20
#ifdef LIBXML_WRITER_ENABLED
 
21
 
 
22
#include <libxml/xmlwriter.h>
 
23
 
 
24
#include "buf.h"
 
25
#include "enc.h"
 
26
#include "save.h"
 
27
 
 
28
#define B64LINELEN 72
 
29
#define B64CRLF "\r\n"
 
30
 
 
31
/*
 
32
 * The following VA_COPY was coded following an example in
 
33
 * the Samba project.  It may not be sufficient for some
 
34
 * esoteric implementations of va_list (i.e. it may need
 
35
 * something involving a memcpy) but (hopefully) will be
 
36
 * sufficient for libxml2.
 
37
 */
 
38
#ifndef VA_COPY
 
39
  #ifdef HAVE_VA_COPY
 
40
    #define VA_COPY(dest, src) va_copy(dest, src)
 
41
  #else
 
42
    #ifdef HAVE___VA_COPY
 
43
      #define VA_COPY(dest,src) __va_copy(dest, src)
 
44
    #else
 
45
      #define VA_COPY(dest,src) (dest) = (src)
 
46
    #endif
 
47
  #endif
 
48
#endif
 
49
 
 
50
/*
 
51
 * Types are kept private
 
52
 */
 
53
typedef enum {
 
54
    XML_TEXTWRITER_NONE = 0,
 
55
    XML_TEXTWRITER_NAME,
 
56
    XML_TEXTWRITER_ATTRIBUTE,
 
57
    XML_TEXTWRITER_TEXT,
 
58
    XML_TEXTWRITER_PI,
 
59
    XML_TEXTWRITER_PI_TEXT,
 
60
    XML_TEXTWRITER_CDATA,
 
61
    XML_TEXTWRITER_DTD,
 
62
    XML_TEXTWRITER_DTD_TEXT,
 
63
    XML_TEXTWRITER_DTD_ELEM,
 
64
    XML_TEXTWRITER_DTD_ELEM_TEXT,
 
65
    XML_TEXTWRITER_DTD_ATTL,
 
66
    XML_TEXTWRITER_DTD_ATTL_TEXT,
 
67
    XML_TEXTWRITER_DTD_ENTY,    /* entity */
 
68
    XML_TEXTWRITER_DTD_ENTY_TEXT,
 
69
    XML_TEXTWRITER_DTD_PENT,    /* parameter entity */
 
70
    XML_TEXTWRITER_COMMENT
 
71
} xmlTextWriterState;
 
72
 
 
73
typedef struct _xmlTextWriterStackEntry xmlTextWriterStackEntry;
 
74
 
 
75
struct _xmlTextWriterStackEntry {
 
76
    xmlChar *name;
 
77
    xmlTextWriterState state;
 
78
};
 
79
 
 
80
typedef struct _xmlTextWriterNsStackEntry xmlTextWriterNsStackEntry;
 
81
struct _xmlTextWriterNsStackEntry {
 
82
    xmlChar *prefix;
 
83
    xmlChar *uri;
 
84
    xmlLinkPtr elem;
 
85
};
 
86
 
 
87
struct _xmlTextWriter {
 
88
    xmlOutputBufferPtr out;     /* output buffer */
 
89
    xmlListPtr nodes;           /* element name stack */
 
90
    xmlListPtr nsstack;         /* name spaces stack */
 
91
    int level;
 
92
    int indent;                 /* enable indent */
 
93
    int doindent;               /* internal indent flag */
 
94
    xmlChar *ichar;             /* indent character */
 
95
    char qchar;                 /* character used for quoting attribute values */
 
96
    xmlParserCtxtPtr ctxt;
 
97
    int no_doc_free;
 
98
    xmlDocPtr doc;
 
99
};
 
100
 
 
101
static void xmlFreeTextWriterStackEntry(xmlLinkPtr lk);
 
102
static int xmlCmpTextWriterStackEntry(const void *data0,
 
103
                                      const void *data1);
 
104
static int xmlTextWriterOutputNSDecl(xmlTextWriterPtr writer);
 
105
static void xmlFreeTextWriterNsStackEntry(xmlLinkPtr lk);
 
106
static int xmlCmpTextWriterNsStackEntry(const void *data0,
 
107
                                        const void *data1);
 
108
static int xmlTextWriterWriteDocCallback(void *context,
 
109
                                         const xmlChar * str, int len);
 
110
static int xmlTextWriterCloseDocCallback(void *context);
 
111
 
 
112
static xmlChar *xmlTextWriterVSprintf(const char *format, va_list argptr);
 
113
static int xmlOutputBufferWriteBase64(xmlOutputBufferPtr out, int len,
 
114
                                      const unsigned char *data);
 
115
static void xmlTextWriterStartDocumentCallback(void *ctx);
 
116
static int xmlTextWriterWriteIndent(xmlTextWriterPtr writer);
 
117
static int
 
118
  xmlTextWriterHandleStateDependencies(xmlTextWriterPtr writer,
 
119
                                       xmlTextWriterStackEntry * p);
 
120
 
 
121
/**
 
122
 * xmlWriterErrMsg:
 
123
 * @ctxt:  a writer context
 
124
 * @error:  the error number
 
125
 * @msg:  the error message
 
126
 *
 
127
 * Handle a writer error
 
128
 */
 
129
static void
 
130
xmlWriterErrMsg(xmlTextWriterPtr ctxt, xmlParserErrors error,
 
131
               const char *msg)
 
132
{
 
133
    if (ctxt != NULL) {
 
134
        __xmlRaiseError(NULL, NULL, NULL, ctxt->ctxt,
 
135
                    NULL, XML_FROM_WRITER, error, XML_ERR_FATAL,
 
136
                    NULL, 0, NULL, NULL, NULL, 0, 0, "%s", msg);
 
137
    } else {
 
138
        __xmlRaiseError(NULL, NULL, NULL, NULL, NULL, XML_FROM_WRITER, error,
 
139
                    XML_ERR_FATAL, NULL, 0, NULL, NULL, NULL, 0, 0, "%s", msg);
 
140
    }
 
141
}
 
142
 
 
143
/**
 
144
 * xmlWriterErrMsgInt:
 
145
 * @ctxt:  a writer context
 
146
 * @error:  the error number
 
147
 * @msg:  the error message
 
148
 * @val:  an int
 
149
 *
 
150
 * Handle a writer error
 
151
 */
 
152
static void
 
153
xmlWriterErrMsgInt(xmlTextWriterPtr ctxt, xmlParserErrors error,
 
154
               const char *msg, int val)
 
155
{
 
156
    if (ctxt != NULL) {
 
157
        __xmlRaiseError(NULL, NULL, NULL, ctxt->ctxt,
 
158
                    NULL, XML_FROM_WRITER, error, XML_ERR_FATAL,
 
159
                    NULL, 0, NULL, NULL, NULL, val, 0, msg, val);
 
160
    } else {
 
161
        __xmlRaiseError(NULL, NULL, NULL, NULL, NULL, XML_FROM_WRITER, error,
 
162
                    XML_ERR_FATAL, NULL, 0, NULL, NULL, NULL, val, 0, msg, val);
 
163
    }
 
164
}
 
165
 
 
166
/**
 
167
 * xmlNewTextWriter:
 
168
 * @out:  an xmlOutputBufferPtr
 
169
 *
 
170
 * Create a new xmlNewTextWriter structure using an xmlOutputBufferPtr
 
171
 * NOTE: the @out parameter will be deallocated when the writer is closed
 
172
 *       (if the call succeed.)
 
173
 *
 
174
 * Returns the new xmlTextWriterPtr or NULL in case of error
 
175
 */
 
176
xmlTextWriterPtr
 
177
xmlNewTextWriter(xmlOutputBufferPtr out)
 
178
{
 
179
    xmlTextWriterPtr ret;
 
180
 
 
181
    ret = (xmlTextWriterPtr) xmlMalloc(sizeof(xmlTextWriter));
 
182
    if (ret == NULL) {
 
183
        xmlWriterErrMsg(NULL, XML_ERR_NO_MEMORY,
 
184
                        "xmlNewTextWriter : out of memory!\n");
 
185
        return NULL;
 
186
    }
 
187
    memset(ret, 0, (size_t) sizeof(xmlTextWriter));
 
188
 
 
189
    ret->nodes = xmlListCreate((xmlListDeallocator)
 
190
                               xmlFreeTextWriterStackEntry,
 
191
                               (xmlListDataCompare)
 
192
                               xmlCmpTextWriterStackEntry);
 
193
    if (ret->nodes == NULL) {
 
194
        xmlWriterErrMsg(NULL, XML_ERR_NO_MEMORY,
 
195
                        "xmlNewTextWriter : out of memory!\n");
 
196
        xmlFree(ret);
 
197
        return NULL;
 
198
    }
 
199
 
 
200
    ret->nsstack = xmlListCreate((xmlListDeallocator)
 
201
                                 xmlFreeTextWriterNsStackEntry,
 
202
                                 (xmlListDataCompare)
 
203
                                 xmlCmpTextWriterNsStackEntry);
 
204
    if (ret->nsstack == NULL) {
 
205
        xmlWriterErrMsg(NULL, XML_ERR_NO_MEMORY,
 
206
                        "xmlNewTextWriter : out of memory!\n");
 
207
        xmlListDelete(ret->nodes);
 
208
        xmlFree(ret);
 
209
        return NULL;
 
210
    }
 
211
 
 
212
    ret->out = out;
 
213
    ret->ichar = xmlStrdup(BAD_CAST " ");
 
214
    ret->qchar = '"';
 
215
 
 
216
    if (!ret->ichar) {
 
217
        xmlListDelete(ret->nodes);
 
218
        xmlListDelete(ret->nsstack);
 
219
        xmlFree(ret);
 
220
        xmlWriterErrMsg(NULL, XML_ERR_NO_MEMORY,
 
221
                        "xmlNewTextWriter : out of memory!\n");
 
222
        return NULL;
 
223
    }
 
224
 
 
225
    ret->doc = xmlNewDoc(NULL);
 
226
 
 
227
    ret->no_doc_free = 0;
 
228
 
 
229
    return ret;
 
230
}
 
231
 
 
232
/**
 
233
 * xmlNewTextWriterFilename:
 
234
 * @uri:  the URI of the resource for the output
 
235
 * @compression:  compress the output?
 
236
 *
 
237
 * Create a new xmlNewTextWriter structure with @uri as output
 
238
 *
 
239
 * Returns the new xmlTextWriterPtr or NULL in case of error
 
240
 */
 
241
xmlTextWriterPtr
 
242
xmlNewTextWriterFilename(const char *uri, int compression)
 
243
{
 
244
    xmlTextWriterPtr ret;
 
245
    xmlOutputBufferPtr out;
 
246
 
 
247
    out = xmlOutputBufferCreateFilename(uri, NULL, compression);
 
248
    if (out == NULL) {
 
249
        xmlWriterErrMsg(NULL, XML_IO_EIO,
 
250
                        "xmlNewTextWriterFilename : cannot open uri\n");
 
251
        return NULL;
 
252
    }
 
253
 
 
254
    ret = xmlNewTextWriter(out);
 
255
    if (ret == NULL) {
 
256
        xmlWriterErrMsg(NULL, XML_ERR_NO_MEMORY,
 
257
                        "xmlNewTextWriterFilename : out of memory!\n");
 
258
        xmlOutputBufferClose(out);
 
259
        return NULL;
 
260
    }
 
261
 
 
262
    ret->indent = 0;
 
263
    ret->doindent = 0;
 
264
    return ret;
 
265
}
 
266
 
 
267
/**
 
268
 * xmlNewTextWriterMemory:
 
269
 * @buf:  xmlBufferPtr
 
270
 * @compression:  compress the output?
 
271
 *
 
272
 * Create a new xmlNewTextWriter structure with @buf as output
 
273
 * TODO: handle compression
 
274
 *
 
275
 * Returns the new xmlTextWriterPtr or NULL in case of error
 
276
 */
 
277
xmlTextWriterPtr
 
278
xmlNewTextWriterMemory(xmlBufferPtr buf, int compression ATTRIBUTE_UNUSED)
 
279
{
 
280
    xmlTextWriterPtr ret;
 
281
    xmlOutputBufferPtr out;
 
282
 
 
283
/*::todo handle compression */
 
284
    out = xmlOutputBufferCreateBuffer(buf, NULL);
 
285
 
 
286
    if (out == NULL) {
 
287
        xmlWriterErrMsg(NULL, XML_ERR_NO_MEMORY,
 
288
                        "xmlNewTextWriterMemory : out of memory!\n");
 
289
        return NULL;
 
290
    }
 
291
 
 
292
    ret = xmlNewTextWriter(out);
 
293
    if (ret == NULL) {
 
294
        xmlWriterErrMsg(NULL, XML_ERR_NO_MEMORY,
 
295
                        "xmlNewTextWriterMemory : out of memory!\n");
 
296
        xmlOutputBufferClose(out);
 
297
        return NULL;
 
298
    }
 
299
 
 
300
    return ret;
 
301
}
 
302
 
 
303
/**
 
304
 * xmlNewTextWriterPushParser:
 
305
 * @ctxt: xmlParserCtxtPtr to hold the new XML document tree
 
306
 * @compression:  compress the output?
 
307
 *
 
308
 * Create a new xmlNewTextWriter structure with @ctxt as output
 
309
 * NOTE: the @ctxt context will be freed with the resulting writer
 
310
 *       (if the call succeeds).
 
311
 * TODO: handle compression
 
312
 *
 
313
 * Returns the new xmlTextWriterPtr or NULL in case of error
 
314
 */
 
315
xmlTextWriterPtr
 
316
xmlNewTextWriterPushParser(xmlParserCtxtPtr ctxt,
 
317
                           int compression ATTRIBUTE_UNUSED)
 
318
{
 
319
    xmlTextWriterPtr ret;
 
320
    xmlOutputBufferPtr out;
 
321
 
 
322
    if (ctxt == NULL) {
 
323
        xmlWriterErrMsg(NULL, XML_ERR_INTERNAL_ERROR,
 
324
                        "xmlNewTextWriterPushParser : invalid context!\n");
 
325
        return NULL;
 
326
    }
 
327
 
 
328
    out = xmlOutputBufferCreateIO((xmlOutputWriteCallback)
 
329
                                  xmlTextWriterWriteDocCallback,
 
330
                                  (xmlOutputCloseCallback)
 
331
                                  xmlTextWriterCloseDocCallback,
 
332
                                  (void *) ctxt, NULL);
 
333
    if (out == NULL) {
 
334
        xmlWriterErrMsg(NULL, XML_ERR_INTERNAL_ERROR,
 
335
                        "xmlNewTextWriterPushParser : error at xmlOutputBufferCreateIO!\n");
 
336
        return NULL;
 
337
    }
 
338
 
 
339
    ret = xmlNewTextWriter(out);
 
340
    if (ret == NULL) {
 
341
        xmlWriterErrMsg(NULL, XML_ERR_INTERNAL_ERROR,
 
342
                        "xmlNewTextWriterPushParser : error at xmlNewTextWriter!\n");
 
343
        xmlOutputBufferClose(out);
 
344
        return NULL;
 
345
    }
 
346
 
 
347
    ret->ctxt = ctxt;
 
348
 
 
349
    return ret;
 
350
}
 
351
 
 
352
/**
 
353
 * xmlNewTextWriterDoc:
 
354
 * @doc: address of a xmlDocPtr to hold the new XML document tree
 
355
 * @compression:  compress the output?
 
356
 *
 
357
 * Create a new xmlNewTextWriter structure with @*doc as output
 
358
 *
 
359
 * Returns the new xmlTextWriterPtr or NULL in case of error
 
360
 */
 
361
xmlTextWriterPtr
 
362
xmlNewTextWriterDoc(xmlDocPtr * doc, int compression)
 
363
{
 
364
    xmlTextWriterPtr ret;
 
365
    xmlSAXHandler saxHandler;
 
366
    xmlParserCtxtPtr ctxt;
 
367
 
 
368
    memset(&saxHandler, '\0', sizeof(saxHandler));
 
369
    xmlSAX2InitDefaultSAXHandler(&saxHandler, 1);
 
370
    saxHandler.startDocument = xmlTextWriterStartDocumentCallback;
 
371
    saxHandler.startElement = xmlSAX2StartElement;
 
372
    saxHandler.endElement = xmlSAX2EndElement;
 
373
 
 
374
    ctxt = xmlCreatePushParserCtxt(&saxHandler, NULL, NULL, 0, NULL);
 
375
    if (ctxt == NULL) {
 
376
        xmlWriterErrMsg(NULL, XML_ERR_INTERNAL_ERROR,
 
377
                "xmlNewTextWriterDoc : error at xmlCreatePushParserCtxt!\n");
 
378
        return NULL;
 
379
    }
 
380
    /*
 
381
     * For some reason this seems to completely break if node names
 
382
     * are interned.
 
383
     */
 
384
    ctxt->dictNames = 0;
 
385
 
 
386
    ctxt->myDoc = xmlNewDoc(BAD_CAST XML_DEFAULT_VERSION);
 
387
    if (ctxt->myDoc == NULL) {
 
388
        xmlFreeParserCtxt(ctxt);
 
389
        xmlWriterErrMsg(NULL, XML_ERR_INTERNAL_ERROR,
 
390
                        "xmlNewTextWriterDoc : error at xmlNewDoc!\n");
 
391
        return NULL;
 
392
    }
 
393
 
 
394
    ret = xmlNewTextWriterPushParser(ctxt, compression);
 
395
    if (ret == NULL) {
 
396
        xmlFreeDoc(ctxt->myDoc);
 
397
        xmlFreeParserCtxt(ctxt);
 
398
        xmlWriterErrMsg(NULL, XML_ERR_INTERNAL_ERROR,
 
399
                "xmlNewTextWriterDoc : error at xmlNewTextWriterPushParser!\n");
 
400
        return NULL;
 
401
    }
 
402
 
 
403
    xmlSetDocCompressMode(ctxt->myDoc, compression);
 
404
 
 
405
    if (doc != NULL) {
 
406
        *doc = ctxt->myDoc;
 
407
        ret->no_doc_free = 1;
 
408
    }
 
409
 
 
410
    return ret;
 
411
}
 
412
 
 
413
/**
 
414
 * xmlNewTextWriterTree:
 
415
 * @doc: xmlDocPtr
 
416
 * @node: xmlNodePtr or NULL for doc->children
 
417
 * @compression:  compress the output?
 
418
 *
 
419
 * Create a new xmlNewTextWriter structure with @doc as output
 
420
 * starting at @node
 
421
 *
 
422
 * Returns the new xmlTextWriterPtr or NULL in case of error
 
423
 */
 
424
xmlTextWriterPtr
 
425
xmlNewTextWriterTree(xmlDocPtr doc, xmlNodePtr node, int compression)
 
426
{
 
427
    xmlTextWriterPtr ret;
 
428
    xmlSAXHandler saxHandler;
 
429
    xmlParserCtxtPtr ctxt;
 
430
 
 
431
    if (doc == NULL) {
 
432
        xmlWriterErrMsg(NULL, XML_ERR_INTERNAL_ERROR,
 
433
                        "xmlNewTextWriterTree : invalid document tree!\n");
 
434
        return NULL;
 
435
    }
 
436
 
 
437
    memset(&saxHandler, '\0', sizeof(saxHandler));
 
438
    xmlSAX2InitDefaultSAXHandler(&saxHandler, 1);
 
439
    saxHandler.startDocument = xmlTextWriterStartDocumentCallback;
 
440
    saxHandler.startElement = xmlSAX2StartElement;
 
441
    saxHandler.endElement = xmlSAX2EndElement;
 
442
 
 
443
    ctxt = xmlCreatePushParserCtxt(&saxHandler, NULL, NULL, 0, NULL);
 
444
    if (ctxt == NULL) {
 
445
        xmlWriterErrMsg(NULL, XML_ERR_INTERNAL_ERROR,
 
446
                        "xmlNewTextWriterDoc : error at xmlCreatePushParserCtxt!\n");
 
447
        return NULL;
 
448
    }
 
449
    /*
 
450
     * For some reason this seems to completely break if node names
 
451
     * are interned.
 
452
     */
 
453
    ctxt->dictNames = 0;
 
454
 
 
455
    ret = xmlNewTextWriterPushParser(ctxt, compression);
 
456
    if (ret == NULL) {
 
457
        xmlFreeParserCtxt(ctxt);
 
458
        xmlWriterErrMsg(NULL, XML_ERR_INTERNAL_ERROR,
 
459
                        "xmlNewTextWriterDoc : error at xmlNewTextWriterPushParser!\n");
 
460
        return NULL;
 
461
    }
 
462
 
 
463
    ctxt->myDoc = doc;
 
464
    ctxt->node = node;
 
465
    ret->no_doc_free = 1;
 
466
 
 
467
    xmlSetDocCompressMode(doc, compression);
 
468
 
 
469
    return ret;
 
470
}
 
471
 
 
472
/**
 
473
 * xmlFreeTextWriter:
 
474
 * @writer:  the xmlTextWriterPtr
 
475
 *
 
476
 * Deallocate all the resources associated to the writer
 
477
 */
 
478
void
 
479
xmlFreeTextWriter(xmlTextWriterPtr writer)
 
480
{
 
481
    if (writer == NULL)
 
482
        return;
 
483
 
 
484
    if (writer->out != NULL)
 
485
        xmlOutputBufferClose(writer->out);
 
486
 
 
487
    if (writer->nodes != NULL)
 
488
        xmlListDelete(writer->nodes);
 
489
 
 
490
    if (writer->nsstack != NULL)
 
491
        xmlListDelete(writer->nsstack);
 
492
 
 
493
    if (writer->ctxt != NULL) {
 
494
        if ((writer->ctxt->myDoc != NULL) && (writer->no_doc_free == 0)) {
 
495
            xmlFreeDoc(writer->ctxt->myDoc);
 
496
            writer->ctxt->myDoc = NULL;
 
497
        }
 
498
        xmlFreeParserCtxt(writer->ctxt);
 
499
    }
 
500
 
 
501
    if (writer->doc != NULL)
 
502
        xmlFreeDoc(writer->doc);
 
503
 
 
504
    if (writer->ichar != NULL)
 
505
        xmlFree(writer->ichar);
 
506
    xmlFree(writer);
 
507
}
 
508
 
 
509
/**
 
510
 * xmlTextWriterStartDocument:
 
511
 * @writer:  the xmlTextWriterPtr
 
512
 * @version:  the xml version ("1.0") or NULL for default ("1.0")
 
513
 * @encoding:  the encoding or NULL for default
 
514
 * @standalone: "yes" or "no" or NULL for default
 
515
 *
 
516
 * Start a new xml document
 
517
 *
 
518
 * Returns the bytes written (may be 0 because of buffering) or -1 in case of error
 
519
 */
 
520
int
 
521
xmlTextWriterStartDocument(xmlTextWriterPtr writer, const char *version,
 
522
                           const char *encoding, const char *standalone)
 
523
{
 
524
    int count;
 
525
    int sum;
 
526
    xmlLinkPtr lk;
 
527
    xmlCharEncodingHandlerPtr encoder;
 
528
 
 
529
    if ((writer == NULL) || (writer->out == NULL)) {
 
530
        xmlWriterErrMsg(writer, XML_ERR_INTERNAL_ERROR,
 
531
                        "xmlTextWriterStartDocument : invalid writer!\n");
 
532
        return -1;
 
533
    }
 
534
 
 
535
    lk = xmlListFront(writer->nodes);
 
536
    if ((lk != NULL) && (xmlLinkGetData(lk) != NULL)) {
 
537
        xmlWriterErrMsg(writer, XML_ERR_INTERNAL_ERROR,
 
538
                        "xmlTextWriterStartDocument : not allowed in this context!\n");
 
539
        return -1;
 
540
    }
 
541
 
 
542
    encoder = NULL;
 
543
    if (encoding != NULL) {
 
544
        encoder = xmlFindCharEncodingHandler(encoding);
 
545
        if (encoder == NULL) {
 
546
            xmlWriterErrMsg(writer, XML_ERR_NO_MEMORY,
 
547
                            "xmlTextWriterStartDocument : out of memory!\n");
 
548
            return -1;
 
549
        }
 
550
    }
 
551
 
 
552
    writer->out->encoder = encoder;
 
553
    if (encoder != NULL) {
 
554
        if (writer->out->conv == NULL) {
 
555
            writer->out->conv = xmlBufCreateSize(4000);
 
556
        }
 
557
        xmlCharEncOutput(writer->out, 1);
 
558
        if ((writer->doc != NULL) && (writer->doc->encoding == NULL))
 
559
            writer->doc->encoding = xmlStrdup((xmlChar *)writer->out->encoder->name);
 
560
    } else
 
561
        writer->out->conv = NULL;
 
562
 
 
563
    sum = 0;
 
564
    count = xmlOutputBufferWriteString(writer->out, "<?xml version=");
 
565
    if (count < 0)
 
566
        return -1;
 
567
    sum += count;
 
568
    count = xmlOutputBufferWrite(writer->out, 1, &writer->qchar);
 
569
    if (count < 0)
 
570
        return -1;
 
571
    sum += count;
 
572
    if (version != 0)
 
573
        count = xmlOutputBufferWriteString(writer->out, version);
 
574
    else
 
575
        count = xmlOutputBufferWriteString(writer->out, "1.0");
 
576
    if (count < 0)
 
577
        return -1;
 
578
    sum += count;
 
579
    count = xmlOutputBufferWrite(writer->out, 1, &writer->qchar);
 
580
    if (count < 0)
 
581
        return -1;
 
582
    sum += count;
 
583
    if (writer->out->encoder != 0) {
 
584
        count = xmlOutputBufferWriteString(writer->out, " encoding=");
 
585
        if (count < 0)
 
586
            return -1;
 
587
        sum += count;
 
588
        count = xmlOutputBufferWrite(writer->out, 1, &writer->qchar);
 
589
        if (count < 0)
 
590
            return -1;
 
591
        sum += count;
 
592
        count =
 
593
            xmlOutputBufferWriteString(writer->out,
 
594
                                       writer->out->encoder->name);
 
595
        if (count < 0)
 
596
            return -1;
 
597
        sum += count;
 
598
        count = xmlOutputBufferWrite(writer->out, 1, &writer->qchar);
 
599
        if (count < 0)
 
600
            return -1;
 
601
        sum += count;
 
602
    }
 
603
 
 
604
    if (standalone != 0) {
 
605
        count = xmlOutputBufferWriteString(writer->out, " standalone=");
 
606
        if (count < 0)
 
607
            return -1;
 
608
        sum += count;
 
609
        count = xmlOutputBufferWrite(writer->out, 1, &writer->qchar);
 
610
        if (count < 0)
 
611
            return -1;
 
612
        sum += count;
 
613
        count = xmlOutputBufferWriteString(writer->out, standalone);
 
614
        if (count < 0)
 
615
            return -1;
 
616
        sum += count;
 
617
        count = xmlOutputBufferWrite(writer->out, 1, &writer->qchar);
 
618
        if (count < 0)
 
619
            return -1;
 
620
        sum += count;
 
621
    }
 
622
 
 
623
    count = xmlOutputBufferWriteString(writer->out, "?>\n");
 
624
    if (count < 0)
 
625
        return -1;
 
626
    sum += count;
 
627
 
 
628
    return sum;
 
629
}
 
630
 
 
631
/**
 
632
 * xmlTextWriterEndDocument:
 
633
 * @writer:  the xmlTextWriterPtr
 
634
 *
 
635
 * End an xml document. All open elements are closed, and
 
636
 * the content is flushed to the output.
 
637
 *
 
638
 * Returns the bytes written or -1 in case of error
 
639
 */
 
640
int
 
641
xmlTextWriterEndDocument(xmlTextWriterPtr writer)
 
642
{
 
643
    int count;
 
644
    int sum;
 
645
    xmlLinkPtr lk;
 
646
    xmlTextWriterStackEntry *p;
 
647
 
 
648
    if (writer == NULL) {
 
649
        xmlWriterErrMsg(writer, XML_ERR_INTERNAL_ERROR,
 
650
                        "xmlTextWriterEndDocument : invalid writer!\n");
 
651
        return -1;
 
652
    }
 
653
 
 
654
    sum = 0;
 
655
    while ((lk = xmlListFront(writer->nodes)) != NULL) {
 
656
        p = (xmlTextWriterStackEntry *) xmlLinkGetData(lk);
 
657
        if (p == 0)
 
658
            break;
 
659
        switch (p->state) {
 
660
            case XML_TEXTWRITER_NAME:
 
661
            case XML_TEXTWRITER_ATTRIBUTE:
 
662
            case XML_TEXTWRITER_TEXT:
 
663
                count = xmlTextWriterEndElement(writer);
 
664
                if (count < 0)
 
665
                    return -1;
 
666
                sum += count;
 
667
                break;
 
668
            case XML_TEXTWRITER_PI:
 
669
            case XML_TEXTWRITER_PI_TEXT:
 
670
                count = xmlTextWriterEndPI(writer);
 
671
                if (count < 0)
 
672
                    return -1;
 
673
                sum += count;
 
674
                break;
 
675
            case XML_TEXTWRITER_CDATA:
 
676
                count = xmlTextWriterEndCDATA(writer);
 
677
                if (count < 0)
 
678
                    return -1;
 
679
                sum += count;
 
680
                break;
 
681
            case XML_TEXTWRITER_DTD:
 
682
            case XML_TEXTWRITER_DTD_TEXT:
 
683
            case XML_TEXTWRITER_DTD_ELEM:
 
684
            case XML_TEXTWRITER_DTD_ELEM_TEXT:
 
685
            case XML_TEXTWRITER_DTD_ATTL:
 
686
            case XML_TEXTWRITER_DTD_ATTL_TEXT:
 
687
            case XML_TEXTWRITER_DTD_ENTY:
 
688
            case XML_TEXTWRITER_DTD_ENTY_TEXT:
 
689
            case XML_TEXTWRITER_DTD_PENT:
 
690
                count = xmlTextWriterEndDTD(writer);
 
691
                if (count < 0)
 
692
                    return -1;
 
693
                sum += count;
 
694
                break;
 
695
            case XML_TEXTWRITER_COMMENT:
 
696
                count = xmlTextWriterEndComment(writer);
 
697
                if (count < 0)
 
698
                    return -1;
 
699
                sum += count;
 
700
                break;
 
701
            default:
 
702
                break;
 
703
        }
 
704
    }
 
705
 
 
706
    if (!writer->indent) {
 
707
        count = xmlOutputBufferWriteString(writer->out, "\n");
 
708
        if (count < 0)
 
709
            return -1;
 
710
        sum += count;
 
711
    }
 
712
 
 
713
    sum += xmlTextWriterFlush(writer);
 
714
 
 
715
    return sum;
 
716
}
 
717
 
 
718
/**
 
719
 * xmlTextWriterStartComment:
 
720
 * @writer:  the xmlTextWriterPtr
 
721
 *
 
722
 * Start an xml comment.
 
723
 *
 
724
 * Returns the bytes written (may be 0 because of buffering) or -1 in case of error
 
725
 */
 
726
int
 
727
xmlTextWriterStartComment(xmlTextWriterPtr writer)
 
728
{
 
729
    int count;
 
730
    int sum;
 
731
    xmlLinkPtr lk;
 
732
    xmlTextWriterStackEntry *p;
 
733
 
 
734
    if (writer == NULL) {
 
735
        xmlWriterErrMsg(writer, XML_ERR_INTERNAL_ERROR,
 
736
                        "xmlTextWriterStartComment : invalid writer!\n");
 
737
        return -1;
 
738
    }
 
739
 
 
740
    sum = 0;
 
741
    lk = xmlListFront(writer->nodes);
 
742
    if (lk != 0) {
 
743
        p = (xmlTextWriterStackEntry *) xmlLinkGetData(lk);
 
744
        if (p != 0) {
 
745
            switch (p->state) {
 
746
                case XML_TEXTWRITER_TEXT:
 
747
                case XML_TEXTWRITER_NONE:
 
748
                    break;
 
749
                case XML_TEXTWRITER_NAME:
 
750
                    /* Output namespace declarations */
 
751
                    count = xmlTextWriterOutputNSDecl(writer);
 
752
                    if (count < 0)
 
753
                        return -1;
 
754
                    sum += count;
 
755
                    count = xmlOutputBufferWriteString(writer->out, ">");
 
756
                    if (count < 0)
 
757
                        return -1;
 
758
                    sum += count;
 
759
                    if (writer->indent) {
 
760
                        count =
 
761
                            xmlOutputBufferWriteString(writer->out, "\n");
 
762
                        if (count < 0)
 
763
                            return -1;
 
764
                        sum += count;
 
765
                    }
 
766
                    p->state = XML_TEXTWRITER_TEXT;
 
767
                    break;
 
768
                default:
 
769
                    return -1;
 
770
            }
 
771
        }
 
772
    }
 
773
 
 
774
    p = (xmlTextWriterStackEntry *)
 
775
        xmlMalloc(sizeof(xmlTextWriterStackEntry));
 
776
    if (p == 0) {
 
777
        xmlWriterErrMsg(writer, XML_ERR_NO_MEMORY,
 
778
                        "xmlTextWriterStartElement : out of memory!\n");
 
779
        return -1;
 
780
    }
 
781
 
 
782
    p->name = NULL;
 
783
    p->state = XML_TEXTWRITER_COMMENT;
 
784
 
 
785
    xmlListPushFront(writer->nodes, p);
 
786
 
 
787
    if (writer->indent) {
 
788
        count = xmlTextWriterWriteIndent(writer);
 
789
        if (count < 0)
 
790
            return -1;
 
791
        sum += count;
 
792
    }
 
793
 
 
794
    count = xmlOutputBufferWriteString(writer->out, "<!--");
 
795
    if (count < 0)
 
796
        return -1;
 
797
    sum += count;
 
798
 
 
799
    return sum;
 
800
}
 
801
 
 
802
/**
 
803
 * xmlTextWriterEndComment:
 
804
 * @writer:  the xmlTextWriterPtr
 
805
 *
 
806
 * End the current xml coment.
 
807
 *
 
808
 * Returns the bytes written (may be 0 because of buffering) or -1 in case of error
 
809
 */
 
810
int
 
811
xmlTextWriterEndComment(xmlTextWriterPtr writer)
 
812
{
 
813
    int count;
 
814
    int sum;
 
815
    xmlLinkPtr lk;
 
816
    xmlTextWriterStackEntry *p;
 
817
 
 
818
    if (writer == NULL) {
 
819
        xmlWriterErrMsg(writer, XML_ERR_INTERNAL_ERROR,
 
820
                        "xmlTextWriterEndComment : invalid writer!\n");
 
821
        return -1;
 
822
    }
 
823
 
 
824
    lk = xmlListFront(writer->nodes);
 
825
    if (lk == 0) {
 
826
        xmlWriterErrMsg(writer, XML_ERR_INTERNAL_ERROR,
 
827
                        "xmlTextWriterEndComment : not allowed in this context!\n");
 
828
        return -1;
 
829
    }
 
830
 
 
831
    p = (xmlTextWriterStackEntry *) xmlLinkGetData(lk);
 
832
    if (p == 0)
 
833
        return -1;
 
834
 
 
835
    sum = 0;
 
836
    switch (p->state) {
 
837
        case XML_TEXTWRITER_COMMENT:
 
838
            count = xmlOutputBufferWriteString(writer->out, "-->");
 
839
            if (count < 0)
 
840
                return -1;
 
841
            sum += count;
 
842
            break;
 
843
        default:
 
844
            return -1;
 
845
    }
 
846
 
 
847
    if (writer->indent) {
 
848
        count = xmlOutputBufferWriteString(writer->out, "\n");
 
849
        if (count < 0)
 
850
            return -1;
 
851
        sum += count;
 
852
    }
 
853
 
 
854
    xmlListPopFront(writer->nodes);
 
855
    return sum;
 
856
}
 
857
 
 
858
/**
 
859
 * xmlTextWriterWriteFormatComment:
 
860
 * @writer:  the xmlTextWriterPtr
 
861
 * @format:  format string (see printf)
 
862
 * @...:  extra parameters for the format
 
863
 *
 
864
 * Write an xml comment.
 
865
 *
 
866
 * Returns the bytes written (may be 0 because of buffering) or -1 in case of error
 
867
 */
 
868
int XMLCDECL
 
869
xmlTextWriterWriteFormatComment(xmlTextWriterPtr writer,
 
870
                                const char *format, ...)
 
871
{
 
872
    int rc;
 
873
    va_list ap;
 
874
 
 
875
    va_start(ap, format);
 
876
 
 
877
    rc = xmlTextWriterWriteVFormatComment(writer, format, ap);
 
878
 
 
879
    va_end(ap);
 
880
    return rc;
 
881
}
 
882
 
 
883
/**
 
884
 * xmlTextWriterWriteVFormatComment:
 
885
 * @writer:  the xmlTextWriterPtr
 
886
 * @format:  format string (see printf)
 
887
 * @argptr:  pointer to the first member of the variable argument list.
 
888
 *
 
889
 * Write an xml comment.
 
890
 *
 
891
 * Returns the bytes written (may be 0 because of buffering) or -1 in case of error
 
892
 */
 
893
int
 
894
xmlTextWriterWriteVFormatComment(xmlTextWriterPtr writer,
 
895
                                 const char *format, va_list argptr)
 
896
{
 
897
    int rc;
 
898
    xmlChar *buf;
 
899
 
 
900
    if (writer == NULL) {
 
901
        xmlWriterErrMsg(writer, XML_ERR_INTERNAL_ERROR,
 
902
                        "xmlTextWriterWriteVFormatComment : invalid writer!\n");
 
903
        return -1;
 
904
    }
 
905
 
 
906
    buf = xmlTextWriterVSprintf(format, argptr);
 
907
    if (buf == NULL)
 
908
        return -1;
 
909
 
 
910
    rc = xmlTextWriterWriteComment(writer, buf);
 
911
 
 
912
    xmlFree(buf);
 
913
    return rc;
 
914
}
 
915
 
 
916
/**
 
917
 * xmlTextWriterWriteComment:
 
918
 * @writer:  the xmlTextWriterPtr
 
919
 * @content:  comment string
 
920
 *
 
921
 * Write an xml comment.
 
922
 *
 
923
 * Returns the bytes written (may be 0 because of buffering) or -1 in case of error
 
924
 */
 
925
int
 
926
xmlTextWriterWriteComment(xmlTextWriterPtr writer, const xmlChar * content)
 
927
{
 
928
    int count;
 
929
    int sum;
 
930
 
 
931
    sum = 0;
 
932
    count = xmlTextWriterStartComment(writer);
 
933
    if (count < 0)
 
934
        return -1;
 
935
    sum += count;
 
936
    count = xmlTextWriterWriteString(writer, content);
 
937
    if (count < 0)
 
938
        return -1;
 
939
    sum += count;
 
940
    count = xmlTextWriterEndComment(writer);
 
941
    if (count < 0)
 
942
        return -1;
 
943
    sum += count;
 
944
 
 
945
    return sum;
 
946
}
 
947
 
 
948
/**
 
949
 * xmlTextWriterStartElement:
 
950
 * @writer:  the xmlTextWriterPtr
 
951
 * @name:  element name
 
952
 *
 
953
 * Start an xml element.
 
954
 *
 
955
 * Returns the bytes written (may be 0 because of buffering) or -1 in case of error
 
956
 */
 
957
int
 
958
xmlTextWriterStartElement(xmlTextWriterPtr writer, const xmlChar * name)
 
959
{
 
960
    int count;
 
961
    int sum;
 
962
    xmlLinkPtr lk;
 
963
    xmlTextWriterStackEntry *p;
 
964
 
 
965
    if ((writer == NULL) || (name == NULL) || (*name == '\0'))
 
966
        return -1;
 
967
 
 
968
    sum = 0;
 
969
    lk = xmlListFront(writer->nodes);
 
970
    if (lk != 0) {
 
971
        p = (xmlTextWriterStackEntry *) xmlLinkGetData(lk);
 
972
        if (p != 0) {
 
973
            switch (p->state) {
 
974
                case XML_TEXTWRITER_PI:
 
975
                case XML_TEXTWRITER_PI_TEXT:
 
976
                    return -1;
 
977
                case XML_TEXTWRITER_NONE:
 
978
                    break;
 
979
                                case XML_TEXTWRITER_ATTRIBUTE:
 
980
                                        count = xmlTextWriterEndAttribute(writer);
 
981
                                        if (count < 0)
 
982
                                                return -1;
 
983
                                        sum += count;
 
984
                                        /* fallthrough */
 
985
                case XML_TEXTWRITER_NAME:
 
986
                    /* Output namespace declarations */
 
987
                    count = xmlTextWriterOutputNSDecl(writer);
 
988
                    if (count < 0)
 
989
                        return -1;
 
990
                    sum += count;
 
991
                    count = xmlOutputBufferWriteString(writer->out, ">");
 
992
                    if (count < 0)
 
993
                        return -1;
 
994
                    sum += count;
 
995
                    if (writer->indent)
 
996
                        count =
 
997
                            xmlOutputBufferWriteString(writer->out, "\n");
 
998
                    p->state = XML_TEXTWRITER_TEXT;
 
999
                    break;
 
1000
                default:
 
1001
                    break;
 
1002
            }
 
1003
        }
 
1004
    }
 
1005
 
 
1006
    p = (xmlTextWriterStackEntry *)
 
1007
        xmlMalloc(sizeof(xmlTextWriterStackEntry));
 
1008
    if (p == 0) {
 
1009
        xmlWriterErrMsg(writer, XML_ERR_NO_MEMORY,
 
1010
                        "xmlTextWriterStartElement : out of memory!\n");
 
1011
        return -1;
 
1012
    }
 
1013
 
 
1014
    p->name = xmlStrdup(name);
 
1015
    if (p->name == 0) {
 
1016
        xmlWriterErrMsg(writer, XML_ERR_NO_MEMORY,
 
1017
                        "xmlTextWriterStartElement : out of memory!\n");
 
1018
        xmlFree(p);
 
1019
        return -1;
 
1020
    }
 
1021
    p->state = XML_TEXTWRITER_NAME;
 
1022
 
 
1023
    xmlListPushFront(writer->nodes, p);
 
1024
 
 
1025
    if (writer->indent) {
 
1026
        count = xmlTextWriterWriteIndent(writer);
 
1027
        sum += count;
 
1028
    }
 
1029
 
 
1030
    count = xmlOutputBufferWriteString(writer->out, "<");
 
1031
    if (count < 0)
 
1032
        return -1;
 
1033
    sum += count;
 
1034
    count =
 
1035
        xmlOutputBufferWriteString(writer->out, (const char *) p->name);
 
1036
    if (count < 0)
 
1037
        return -1;
 
1038
    sum += count;
 
1039
 
 
1040
    return sum;
 
1041
}
 
1042
 
 
1043
/**
 
1044
 * xmlTextWriterStartElementNS:
 
1045
 * @writer:  the xmlTextWriterPtr
 
1046
 * @prefix:  namespace prefix or NULL
 
1047
 * @name:  element local name
 
1048
 * @namespaceURI:  namespace URI or NULL
 
1049
 *
 
1050
 * Start an xml element with namespace support.
 
1051
 *
 
1052
 * Returns the bytes written (may be 0 because of buffering) or -1 in case of error
 
1053
 */
 
1054
int
 
1055
xmlTextWriterStartElementNS(xmlTextWriterPtr writer,
 
1056
                            const xmlChar * prefix, const xmlChar * name,
 
1057
                            const xmlChar * namespaceURI)
 
1058
{
 
1059
    int count;
 
1060
    int sum;
 
1061
    xmlChar *buf;
 
1062
 
 
1063
    if ((writer == NULL) || (name == NULL) || (*name == '\0'))
 
1064
        return -1;
 
1065
 
 
1066
    buf = NULL;
 
1067
    if (prefix != 0) {
 
1068
        buf = xmlStrdup(prefix);
 
1069
        buf = xmlStrcat(buf, BAD_CAST ":");
 
1070
    }
 
1071
    buf = xmlStrcat(buf, name);
 
1072
 
 
1073
    sum = 0;
 
1074
    count = xmlTextWriterStartElement(writer, buf);
 
1075
    xmlFree(buf);
 
1076
    if (count < 0)
 
1077
        return -1;
 
1078
    sum += count;
 
1079
 
 
1080
    if (namespaceURI != 0) {
 
1081
        xmlTextWriterNsStackEntry *p = (xmlTextWriterNsStackEntry *)
 
1082
        xmlMalloc(sizeof(xmlTextWriterNsStackEntry));
 
1083
        if (p == 0) {
 
1084
            xmlWriterErrMsg(writer, XML_ERR_NO_MEMORY,
 
1085
                            "xmlTextWriterStartElementNS : out of memory!\n");
 
1086
            return -1;
 
1087
        }
 
1088
 
 
1089
        buf = xmlStrdup(BAD_CAST "xmlns");
 
1090
        if (prefix != 0) {
 
1091
            buf = xmlStrcat(buf, BAD_CAST ":");
 
1092
            buf = xmlStrcat(buf, prefix);
 
1093
        }
 
1094
 
 
1095
        p->prefix = buf;
 
1096
        p->uri = xmlStrdup(namespaceURI);
 
1097
        if (p->uri == 0) {
 
1098
            xmlWriterErrMsg(writer, XML_ERR_NO_MEMORY,
 
1099
                            "xmlTextWriterStartElementNS : out of memory!\n");
 
1100
            xmlFree(p);
 
1101
            return -1;
 
1102
        }
 
1103
        p->elem = xmlListFront(writer->nodes);
 
1104
 
 
1105
        xmlListPushFront(writer->nsstack, p);
 
1106
    }
 
1107
 
 
1108
    return sum;
 
1109
}
 
1110
 
 
1111
/**
 
1112
 * xmlTextWriterEndElement:
 
1113
 * @writer:  the xmlTextWriterPtr
 
1114
 *
 
1115
 * End the current xml element.
 
1116
 *
 
1117
 * Returns the bytes written (may be 0 because of buffering) or -1 in case of error
 
1118
 */
 
1119
int
 
1120
xmlTextWriterEndElement(xmlTextWriterPtr writer)
 
1121
{
 
1122
    int count;
 
1123
    int sum;
 
1124
    xmlLinkPtr lk;
 
1125
    xmlTextWriterStackEntry *p;
 
1126
 
 
1127
    if (writer == NULL)
 
1128
        return -1;
 
1129
 
 
1130
    lk = xmlListFront(writer->nodes);
 
1131
    if (lk == 0) {
 
1132
        xmlListDelete(writer->nsstack);
 
1133
        writer->nsstack = NULL;
 
1134
        return -1;
 
1135
    }
 
1136
 
 
1137
    p = (xmlTextWriterStackEntry *) xmlLinkGetData(lk);
 
1138
    if (p == 0) {
 
1139
        xmlListDelete(writer->nsstack);
 
1140
        writer->nsstack = NULL;
 
1141
        return -1;
 
1142
    }
 
1143
 
 
1144
    sum = 0;
 
1145
    switch (p->state) {
 
1146
        case XML_TEXTWRITER_ATTRIBUTE:
 
1147
            count = xmlTextWriterEndAttribute(writer);
 
1148
            if (count < 0) {
 
1149
                xmlListDelete(writer->nsstack);
 
1150
                writer->nsstack = NULL;
 
1151
                return -1;
 
1152
            }
 
1153
            sum += count;
 
1154
            /* fallthrough */
 
1155
        case XML_TEXTWRITER_NAME:
 
1156
            /* Output namespace declarations */
 
1157
            count = xmlTextWriterOutputNSDecl(writer);
 
1158
            if (count < 0)
 
1159
                return -1;
 
1160
            sum += count;
 
1161
 
 
1162
            if (writer->indent) /* next element needs indent */
 
1163
                writer->doindent = 1;
 
1164
            count = xmlOutputBufferWriteString(writer->out, "/>");
 
1165
            if (count < 0)
 
1166
                return -1;
 
1167
            sum += count;
 
1168
            break;
 
1169
        case XML_TEXTWRITER_TEXT:
 
1170
            if ((writer->indent) && (writer->doindent)) {
 
1171
                count = xmlTextWriterWriteIndent(writer);
 
1172
                sum += count;
 
1173
                writer->doindent = 1;
 
1174
            } else
 
1175
                writer->doindent = 1;
 
1176
            count = xmlOutputBufferWriteString(writer->out, "</");
 
1177
            if (count < 0)
 
1178
                return -1;
 
1179
            sum += count;
 
1180
            count = xmlOutputBufferWriteString(writer->out,
 
1181
                                               (const char *) p->name);
 
1182
            if (count < 0)
 
1183
                return -1;
 
1184
            sum += count;
 
1185
            count = xmlOutputBufferWriteString(writer->out, ">");
 
1186
            if (count < 0)
 
1187
                return -1;
 
1188
            sum += count;
 
1189
            break;
 
1190
        default:
 
1191
            return -1;
 
1192
    }
 
1193
 
 
1194
    if (writer->indent) {
 
1195
        count = xmlOutputBufferWriteString(writer->out, "\n");
 
1196
        sum += count;
 
1197
    }
 
1198
 
 
1199
    xmlListPopFront(writer->nodes);
 
1200
    return sum;
 
1201
}
 
1202
 
 
1203
/**
 
1204
 * xmlTextWriterFullEndElement:
 
1205
 * @writer:  the xmlTextWriterPtr
 
1206
 *
 
1207
 * End the current xml element. Writes an end tag even if the element is empty
 
1208
 *
 
1209
 * Returns the bytes written (may be 0 because of buffering) or -1 in case of error
 
1210
 */
 
1211
int
 
1212
xmlTextWriterFullEndElement(xmlTextWriterPtr writer)
 
1213
{
 
1214
    int count;
 
1215
    int sum;
 
1216
    xmlLinkPtr lk;
 
1217
    xmlTextWriterStackEntry *p;
 
1218
 
 
1219
    if (writer == NULL)
 
1220
        return -1;
 
1221
 
 
1222
    lk = xmlListFront(writer->nodes);
 
1223
    if (lk == 0)
 
1224
        return -1;
 
1225
 
 
1226
    p = (xmlTextWriterStackEntry *) xmlLinkGetData(lk);
 
1227
    if (p == 0)
 
1228
        return -1;
 
1229
 
 
1230
    sum = 0;
 
1231
    switch (p->state) {
 
1232
        case XML_TEXTWRITER_ATTRIBUTE:
 
1233
            count = xmlTextWriterEndAttribute(writer);
 
1234
            if (count < 0)
 
1235
                return -1;
 
1236
            sum += count;
 
1237
            /* fallthrough */
 
1238
        case XML_TEXTWRITER_NAME:
 
1239
            /* Output namespace declarations */
 
1240
            count = xmlTextWriterOutputNSDecl(writer);
 
1241
            if (count < 0)
 
1242
                return -1;
 
1243
            sum += count;
 
1244
 
 
1245
            count = xmlOutputBufferWriteString(writer->out, ">");
 
1246
            if (count < 0)
 
1247
                return -1;
 
1248
            sum += count;
 
1249
            if (writer->indent)
 
1250
                writer->doindent = 0;
 
1251
            /* fallthrough */
 
1252
        case XML_TEXTWRITER_TEXT:
 
1253
            if ((writer->indent) && (writer->doindent)) {
 
1254
                count = xmlTextWriterWriteIndent(writer);
 
1255
                sum += count;
 
1256
                writer->doindent = 1;
 
1257
            } else
 
1258
                writer->doindent = 1;
 
1259
            count = xmlOutputBufferWriteString(writer->out, "</");
 
1260
            if (count < 0)
 
1261
                return -1;
 
1262
            sum += count;
 
1263
            count = xmlOutputBufferWriteString(writer->out,
 
1264
                                               (const char *) p->name);
 
1265
            if (count < 0)
 
1266
                return -1;
 
1267
            sum += count;
 
1268
            count = xmlOutputBufferWriteString(writer->out, ">");
 
1269
            if (count < 0)
 
1270
                return -1;
 
1271
            sum += count;
 
1272
            break;
 
1273
        default:
 
1274
            return -1;
 
1275
    }
 
1276
 
 
1277
    if (writer->indent) {
 
1278
        count = xmlOutputBufferWriteString(writer->out, "\n");
 
1279
        sum += count;
 
1280
    }
 
1281
 
 
1282
    xmlListPopFront(writer->nodes);
 
1283
    return sum;
 
1284
}
 
1285
 
 
1286
/**
 
1287
 * xmlTextWriterWriteFormatRaw:
 
1288
 * @writer:  the xmlTextWriterPtr
 
1289
 * @format:  format string (see printf)
 
1290
 * @...:  extra parameters for the format
 
1291
 *
 
1292
 * Write a formatted raw xml text.
 
1293
 *
 
1294
 * Returns the bytes written (may be 0 because of buffering) or -1 in case of error
 
1295
 */
 
1296
int XMLCDECL
 
1297
xmlTextWriterWriteFormatRaw(xmlTextWriterPtr writer, const char *format,
 
1298
                            ...)
 
1299
{
 
1300
    int rc;
 
1301
    va_list ap;
 
1302
 
 
1303
    va_start(ap, format);
 
1304
 
 
1305
    rc = xmlTextWriterWriteVFormatRaw(writer, format, ap);
 
1306
 
 
1307
    va_end(ap);
 
1308
    return rc;
 
1309
}
 
1310
 
 
1311
/**
 
1312
 * xmlTextWriterWriteVFormatRaw:
 
1313
 * @writer:  the xmlTextWriterPtr
 
1314
 * @format:  format string (see printf)
 
1315
 * @argptr:  pointer to the first member of the variable argument list.
 
1316
 *
 
1317
 * Write a formatted raw xml text.
 
1318
 *
 
1319
 * Returns the bytes written (may be 0 because of buffering) or -1 in case of error
 
1320
 */
 
1321
int
 
1322
xmlTextWriterWriteVFormatRaw(xmlTextWriterPtr writer, const char *format,
 
1323
                             va_list argptr)
 
1324
{
 
1325
    int rc;
 
1326
    xmlChar *buf;
 
1327
 
 
1328
    if (writer == NULL)
 
1329
        return -1;
 
1330
 
 
1331
    buf = xmlTextWriterVSprintf(format, argptr);
 
1332
    if (buf == NULL)
 
1333
        return -1;
 
1334
 
 
1335
    rc = xmlTextWriterWriteRaw(writer, buf);
 
1336
 
 
1337
    xmlFree(buf);
 
1338
    return rc;
 
1339
}
 
1340
 
 
1341
/**
 
1342
 * xmlTextWriterWriteRawLen:
 
1343
 * @writer:  the xmlTextWriterPtr
 
1344
 * @content:  text string
 
1345
 * @len:  length of the text string
 
1346
 *
 
1347
 * Write an xml text.
 
1348
 * TODO: what about entities and special chars??
 
1349
 *
 
1350
 * Returns the bytes written (may be 0 because of buffering) or -1 in case of error
 
1351
 */
 
1352
int
 
1353
xmlTextWriterWriteRawLen(xmlTextWriterPtr writer, const xmlChar * content,
 
1354
                         int len)
 
1355
{
 
1356
    int count;
 
1357
    int sum;
 
1358
    xmlLinkPtr lk;
 
1359
    xmlTextWriterStackEntry *p;
 
1360
 
 
1361
    if (writer == NULL) {
 
1362
        xmlWriterErrMsg(writer, XML_ERR_INTERNAL_ERROR,
 
1363
                        "xmlTextWriterWriteRawLen : invalid writer!\n");
 
1364
        return -1;
 
1365
    }
 
1366
 
 
1367
    if ((content == NULL) || (len < 0)) {
 
1368
        xmlWriterErrMsg(writer, XML_ERR_INTERNAL_ERROR,
 
1369
                        "xmlTextWriterWriteRawLen : invalid content!\n");
 
1370
        return -1;
 
1371
    }
 
1372
 
 
1373
    sum = 0;
 
1374
    lk = xmlListFront(writer->nodes);
 
1375
    if (lk != 0) {
 
1376
        p = (xmlTextWriterStackEntry *) xmlLinkGetData(lk);
 
1377
        count = xmlTextWriterHandleStateDependencies(writer, p);
 
1378
        if (count < 0)
 
1379
            return -1;
 
1380
        sum += count;
 
1381
    }
 
1382
 
 
1383
    if (writer->indent)
 
1384
        writer->doindent = 0;
 
1385
 
 
1386
    if (content != NULL) {
 
1387
        count =
 
1388
            xmlOutputBufferWrite(writer->out, len, (const char *) content);
 
1389
        if (count < 0)
 
1390
            return -1;
 
1391
        sum += count;
 
1392
    }
 
1393
 
 
1394
    return sum;
 
1395
}
 
1396
 
 
1397
/**
 
1398
 * xmlTextWriterWriteRaw:
 
1399
 * @writer:  the xmlTextWriterPtr
 
1400
 * @content:  text string
 
1401
 *
 
1402
 * Write a raw xml text.
 
1403
 *
 
1404
 * Returns the bytes written (may be 0 because of buffering) or -1 in case of error
 
1405
 */
 
1406
int
 
1407
xmlTextWriterWriteRaw(xmlTextWriterPtr writer, const xmlChar * content)
 
1408
{
 
1409
    return xmlTextWriterWriteRawLen(writer, content, xmlStrlen(content));
 
1410
}
 
1411
 
 
1412
/**
 
1413
 * xmlTextWriterWriteFormatString:
 
1414
 * @writer:  the xmlTextWriterPtr
 
1415
 * @format:  format string (see printf)
 
1416
 * @...:  extra parameters for the format
 
1417
 *
 
1418
 * Write a formatted xml text.
 
1419
 *
 
1420
 * Returns the bytes written (may be 0 because of buffering) or -1 in case of error
 
1421
 */
 
1422
int XMLCDECL
 
1423
xmlTextWriterWriteFormatString(xmlTextWriterPtr writer, const char *format,
 
1424
                               ...)
 
1425
{
 
1426
    int rc;
 
1427
    va_list ap;
 
1428
 
 
1429
    if ((writer == NULL) || (format == NULL))
 
1430
        return -1;
 
1431
 
 
1432
    va_start(ap, format);
 
1433
 
 
1434
    rc = xmlTextWriterWriteVFormatString(writer, format, ap);
 
1435
 
 
1436
    va_end(ap);
 
1437
    return rc;
 
1438
}
 
1439
 
 
1440
/**
 
1441
 * xmlTextWriterWriteVFormatString:
 
1442
 * @writer:  the xmlTextWriterPtr
 
1443
 * @format:  format string (see printf)
 
1444
 * @argptr:  pointer to the first member of the variable argument list.
 
1445
 *
 
1446
 * Write a formatted xml text.
 
1447
 *
 
1448
 * Returns the bytes written (may be 0 because of buffering) or -1 in case of error
 
1449
 */
 
1450
int
 
1451
xmlTextWriterWriteVFormatString(xmlTextWriterPtr writer,
 
1452
                                const char *format, va_list argptr)
 
1453
{
 
1454
    int rc;
 
1455
    xmlChar *buf;
 
1456
 
 
1457
    if ((writer == NULL) || (format == NULL))
 
1458
        return -1;
 
1459
 
 
1460
    buf = xmlTextWriterVSprintf(format, argptr);
 
1461
    if (buf == NULL)
 
1462
        return -1;
 
1463
 
 
1464
    rc = xmlTextWriterWriteString(writer, buf);
 
1465
 
 
1466
    xmlFree(buf);
 
1467
    return rc;
 
1468
}
 
1469
 
 
1470
/**
 
1471
 * xmlTextWriterWriteString:
 
1472
 * @writer:  the xmlTextWriterPtr
 
1473
 * @content:  text string
 
1474
 *
 
1475
 * Write an xml text.
 
1476
 *
 
1477
 * Returns the bytes written (may be 0 because of buffering) or -1 in case of error
 
1478
 */
 
1479
int
 
1480
xmlTextWriterWriteString(xmlTextWriterPtr writer, const xmlChar * content)
 
1481
{
 
1482
    int count;
 
1483
    int sum;
 
1484
    xmlLinkPtr lk;
 
1485
    xmlTextWriterStackEntry *p;
 
1486
    xmlChar *buf;
 
1487
 
 
1488
    if ((writer == NULL) || (content == NULL))
 
1489
        return -1;
 
1490
 
 
1491
    sum = 0;
 
1492
    buf = (xmlChar *) content;
 
1493
    lk = xmlListFront(writer->nodes);
 
1494
    if (lk != 0) {
 
1495
        p = (xmlTextWriterStackEntry *) xmlLinkGetData(lk);
 
1496
        if (p != 0) {
 
1497
            switch (p->state) {
 
1498
                case XML_TEXTWRITER_NAME:
 
1499
                case XML_TEXTWRITER_TEXT:
 
1500
#if 0
 
1501
                    buf = NULL;
 
1502
                    xmlOutputBufferWriteEscape(writer->out, content, NULL);
 
1503
#endif
 
1504
                    buf = xmlEncodeSpecialChars(NULL, content);
 
1505
                    break;
 
1506
                case XML_TEXTWRITER_ATTRIBUTE:
 
1507
                    buf = NULL;
 
1508
                    xmlBufAttrSerializeTxtContent(writer->out->buffer,
 
1509
                                                  writer->doc, NULL, content);
 
1510
                    break;
 
1511
                default:
 
1512
                    break;
 
1513
            }
 
1514
        }
 
1515
    }
 
1516
 
 
1517
    if (buf != NULL) {
 
1518
        count = xmlTextWriterWriteRaw(writer, buf);
 
1519
 
 
1520
        if (buf != content)     /* buf was allocated by us, so free it */
 
1521
            xmlFree(buf);
 
1522
 
 
1523
        if (count < 0)
 
1524
            return -1;
 
1525
        sum += count;
 
1526
    }
 
1527
 
 
1528
    return sum;
 
1529
}
 
1530
 
 
1531
/**
 
1532
 * xmlOutputBufferWriteBase64:
 
1533
 * @out: the xmlOutputBufferPtr
 
1534
 * @data:   binary data
 
1535
 * @len:  the number of bytes to encode
 
1536
 *
 
1537
 * Write base64 encoded data to an xmlOutputBuffer.
 
1538
 * Adapted from John Walker's base64.c (http://www.fourmilab.ch/).
 
1539
 *
 
1540
 * Returns the bytes written (may be 0 because of buffering) or -1 in case of error
 
1541
 */
 
1542
static int
 
1543
xmlOutputBufferWriteBase64(xmlOutputBufferPtr out, int len,
 
1544
                           const unsigned char *data)
 
1545
{
 
1546
    static unsigned char dtable[64] =
 
1547
            {'A','B','C','D','E','F','G','H','I','J','K','L','M',
 
1548
             'N','O','P','Q','R','S','T','U','V','W','X','Y','Z',
 
1549
             'a','b','c','d','e','f','g','h','i','j','k','l','m',
 
1550
             'n','o','p','q','r','s','t','u','v','w','x','y','z',
 
1551
             '0','1','2','3','4','5','6','7','8','9','+','/'};
 
1552
 
 
1553
    int i;
 
1554
    int linelen;
 
1555
    int count;
 
1556
    int sum;
 
1557
 
 
1558
    if ((out == NULL) || (len < 0) || (data == NULL))
 
1559
        return(-1);
 
1560
 
 
1561
    linelen = 0;
 
1562
    sum = 0;
 
1563
 
 
1564
    i = 0;
 
1565
    while (1) {
 
1566
        unsigned char igroup[3];
 
1567
        unsigned char ogroup[4];
 
1568
        int c;
 
1569
        int n;
 
1570
 
 
1571
        igroup[0] = igroup[1] = igroup[2] = 0;
 
1572
        for (n = 0; n < 3 && i < len; n++, i++) {
 
1573
            c = data[i];
 
1574
            igroup[n] = (unsigned char) c;
 
1575
        }
 
1576
 
 
1577
        if (n > 0) {
 
1578
            ogroup[0] = dtable[igroup[0] >> 2];
 
1579
            ogroup[1] = dtable[((igroup[0] & 3) << 4) | (igroup[1] >> 4)];
 
1580
            ogroup[2] =
 
1581
                dtable[((igroup[1] & 0xF) << 2) | (igroup[2] >> 6)];
 
1582
            ogroup[3] = dtable[igroup[2] & 0x3F];
 
1583
 
 
1584
            if (n < 3) {
 
1585
                ogroup[3] = '=';
 
1586
                if (n < 2) {
 
1587
                    ogroup[2] = '=';
 
1588
                }
 
1589
            }
 
1590
 
 
1591
            if (linelen >= B64LINELEN) {
 
1592
                count = xmlOutputBufferWrite(out, 2, B64CRLF);
 
1593
                if (count == -1)
 
1594
                    return -1;
 
1595
                sum += count;
 
1596
                linelen = 0;
 
1597
            }
 
1598
            count = xmlOutputBufferWrite(out, 4, (const char *) ogroup);
 
1599
            if (count == -1)
 
1600
                return -1;
 
1601
            sum += count;
 
1602
 
 
1603
            linelen += 4;
 
1604
        }
 
1605
 
 
1606
        if (i >= len)
 
1607
            break;
 
1608
    }
 
1609
 
 
1610
    return sum;
 
1611
}
 
1612
 
 
1613
/**
 
1614
 * xmlTextWriterWriteBase64:
 
1615
 * @writer: the xmlTextWriterPtr
 
1616
 * @data:   binary data
 
1617
 * @start:  the position within the data of the first byte to encode
 
1618
 * @len:  the number of bytes to encode
 
1619
 *
 
1620
 * Write an base64 encoded xml text.
 
1621
 *
 
1622
 * Returns the bytes written (may be 0 because of buffering) or -1 in case of error
 
1623
 */
 
1624
int
 
1625
xmlTextWriterWriteBase64(xmlTextWriterPtr writer, const char *data,
 
1626
                         int start, int len)
 
1627
{
 
1628
    int count;
 
1629
    int sum;
 
1630
    xmlLinkPtr lk;
 
1631
    xmlTextWriterStackEntry *p;
 
1632
 
 
1633
    if ((writer == NULL) || (data == NULL) || (start < 0) || (len < 0))
 
1634
        return -1;
 
1635
 
 
1636
    sum = 0;
 
1637
    lk = xmlListFront(writer->nodes);
 
1638
    if (lk != 0) {
 
1639
        p = (xmlTextWriterStackEntry *) xmlLinkGetData(lk);
 
1640
        if (p != 0) {
 
1641
            count = xmlTextWriterHandleStateDependencies(writer, p);
 
1642
            if (count < 0)
 
1643
                return -1;
 
1644
            sum += count;
 
1645
        }
 
1646
    }
 
1647
 
 
1648
    if (writer->indent)
 
1649
        writer->doindent = 0;
 
1650
 
 
1651
    count =
 
1652
        xmlOutputBufferWriteBase64(writer->out, len,
 
1653
                                   (unsigned char *) data + start);
 
1654
    if (count < 0)
 
1655
        return -1;
 
1656
    sum += count;
 
1657
 
 
1658
    return sum;
 
1659
}
 
1660
 
 
1661
/**
 
1662
 * xmlOutputBufferWriteBinHex:
 
1663
 * @out: the xmlOutputBufferPtr
 
1664
 * @data:   binary data
 
1665
 * @len:  the number of bytes to encode
 
1666
 *
 
1667
 * Write hqx encoded data to an xmlOutputBuffer.
 
1668
 * ::todo
 
1669
 *
 
1670
 * Returns the bytes written (may be 0 because of buffering)
 
1671
 * or -1 in case of error
 
1672
 */
 
1673
static int
 
1674
xmlOutputBufferWriteBinHex(xmlOutputBufferPtr out,
 
1675
                           int len, const unsigned char *data)
 
1676
{
 
1677
    int count;
 
1678
    int sum;
 
1679
    static char hex[16] =
 
1680
        {'0','1','2','3','4','5','6','7','8','9','A','B','C','D','E','F'};
 
1681
    int i;
 
1682
 
 
1683
    if ((out == NULL) || (data == NULL) || (len < 0)) {
 
1684
        return -1;
 
1685
    }
 
1686
 
 
1687
    sum = 0;
 
1688
    for (i = 0; i < len; i++) {
 
1689
        count =
 
1690
            xmlOutputBufferWrite(out, 1,
 
1691
                                 (const char *) &hex[data[i] >> 4]);
 
1692
        if (count == -1)
 
1693
            return -1;
 
1694
        sum += count;
 
1695
        count =
 
1696
            xmlOutputBufferWrite(out, 1,
 
1697
                                 (const char *) &hex[data[i] & 0xF]);
 
1698
        if (count == -1)
 
1699
            return -1;
 
1700
        sum += count;
 
1701
    }
 
1702
 
 
1703
    return sum;
 
1704
}
 
1705
 
 
1706
/**
 
1707
 * xmlTextWriterWriteBinHex:
 
1708
 * @writer: the xmlTextWriterPtr
 
1709
 * @data:   binary data
 
1710
 * @start:  the position within the data of the first byte to encode
 
1711
 * @len:  the number of bytes to encode
 
1712
 *
 
1713
 * Write a BinHex encoded xml text.
 
1714
 *
 
1715
 * Returns the bytes written (may be 0 because of buffering) or -1 in case of error
 
1716
 */
 
1717
int
 
1718
xmlTextWriterWriteBinHex(xmlTextWriterPtr writer, const char *data,
 
1719
                         int start, int len)
 
1720
{
 
1721
    int count;
 
1722
    int sum;
 
1723
    xmlLinkPtr lk;
 
1724
    xmlTextWriterStackEntry *p;
 
1725
 
 
1726
    if ((writer == NULL) || (data == NULL) || (start < 0) || (len < 0))
 
1727
        return -1;
 
1728
 
 
1729
    sum = 0;
 
1730
    lk = xmlListFront(writer->nodes);
 
1731
    if (lk != 0) {
 
1732
        p = (xmlTextWriterStackEntry *) xmlLinkGetData(lk);
 
1733
        if (p != 0) {
 
1734
            count = xmlTextWriterHandleStateDependencies(writer, p);
 
1735
            if (count < 0)
 
1736
                return -1;
 
1737
            sum += count;
 
1738
        }
 
1739
    }
 
1740
 
 
1741
    if (writer->indent)
 
1742
        writer->doindent = 0;
 
1743
 
 
1744
    count =
 
1745
        xmlOutputBufferWriteBinHex(writer->out, len,
 
1746
                                   (unsigned char *) data + start);
 
1747
    if (count < 0)
 
1748
        return -1;
 
1749
    sum += count;
 
1750
 
 
1751
    return sum;
 
1752
}
 
1753
 
 
1754
/**
 
1755
 * xmlTextWriterStartAttribute:
 
1756
 * @writer:  the xmlTextWriterPtr
 
1757
 * @name:  element name
 
1758
 *
 
1759
 * Start an xml attribute.
 
1760
 *
 
1761
 * Returns the bytes written (may be 0 because of buffering) or -1 in case of error
 
1762
 */
 
1763
int
 
1764
xmlTextWriterStartAttribute(xmlTextWriterPtr writer, const xmlChar * name)
 
1765
{
 
1766
    int count;
 
1767
    int sum;
 
1768
    xmlLinkPtr lk;
 
1769
    xmlTextWriterStackEntry *p;
 
1770
 
 
1771
    if ((writer == NULL) || (name == NULL) || (*name == '\0'))
 
1772
        return -1;
 
1773
 
 
1774
    sum = 0;
 
1775
    lk = xmlListFront(writer->nodes);
 
1776
    if (lk == 0)
 
1777
        return -1;
 
1778
 
 
1779
    p = (xmlTextWriterStackEntry *) xmlLinkGetData(lk);
 
1780
    if (p == 0)
 
1781
        return -1;
 
1782
 
 
1783
    switch (p->state) {
 
1784
        case XML_TEXTWRITER_ATTRIBUTE:
 
1785
            count = xmlTextWriterEndAttribute(writer);
 
1786
            if (count < 0)
 
1787
                return -1;
 
1788
            sum += count;
 
1789
            /* fallthrough */
 
1790
        case XML_TEXTWRITER_NAME:
 
1791
            count = xmlOutputBufferWriteString(writer->out, " ");
 
1792
            if (count < 0)
 
1793
                return -1;
 
1794
            sum += count;
 
1795
            count =
 
1796
                xmlOutputBufferWriteString(writer->out,
 
1797
                                           (const char *) name);
 
1798
            if (count < 0)
 
1799
                return -1;
 
1800
            sum += count;
 
1801
            count = xmlOutputBufferWriteString(writer->out, "=");
 
1802
            if (count < 0)
 
1803
                return -1;
 
1804
            sum += count;
 
1805
            count = xmlOutputBufferWrite(writer->out, 1, &writer->qchar);
 
1806
            if (count < 0)
 
1807
                return -1;
 
1808
            sum += count;
 
1809
            p->state = XML_TEXTWRITER_ATTRIBUTE;
 
1810
            break;
 
1811
        default:
 
1812
            return -1;
 
1813
    }
 
1814
 
 
1815
    return sum;
 
1816
}
 
1817
 
 
1818
/**
 
1819
 * xmlTextWriterStartAttributeNS:
 
1820
 * @writer:  the xmlTextWriterPtr
 
1821
 * @prefix:  namespace prefix or NULL
 
1822
 * @name:  element local name
 
1823
 * @namespaceURI:  namespace URI or NULL
 
1824
 *
 
1825
 * Start an xml attribute with namespace support.
 
1826
 *
 
1827
 * Returns the bytes written (may be 0 because of buffering) or -1 in case of error
 
1828
 */
 
1829
int
 
1830
xmlTextWriterStartAttributeNS(xmlTextWriterPtr writer,
 
1831
                              const xmlChar * prefix, const xmlChar * name,
 
1832
                              const xmlChar * namespaceURI)
 
1833
{
 
1834
    int count;
 
1835
    int sum;
 
1836
    xmlChar *buf;
 
1837
    xmlTextWriterNsStackEntry *p;
 
1838
 
 
1839
    if ((writer == NULL) || (name == NULL) || (*name == '\0'))
 
1840
        return -1;
 
1841
 
 
1842
    /* Handle namespace first in case of error */
 
1843
    if (namespaceURI != 0) {
 
1844
        xmlTextWriterNsStackEntry nsentry, *curns;
 
1845
 
 
1846
        buf = xmlStrdup(BAD_CAST "xmlns");
 
1847
        if (prefix != 0) {
 
1848
            buf = xmlStrcat(buf, BAD_CAST ":");
 
1849
            buf = xmlStrcat(buf, prefix);
 
1850
        }
 
1851
 
 
1852
        nsentry.prefix = buf;
 
1853
        nsentry.uri = (xmlChar *)namespaceURI;
 
1854
        nsentry.elem = xmlListFront(writer->nodes);
 
1855
 
 
1856
        curns = (xmlTextWriterNsStackEntry *)xmlListSearch(writer->nsstack,
 
1857
                                                           (void *)&nsentry);
 
1858
        if ((curns != NULL)) {
 
1859
            xmlFree(buf);
 
1860
            if (xmlStrcmp(curns->uri, namespaceURI) == 0) {
 
1861
                /* Namespace already defined on element skip */
 
1862
                buf = NULL;
 
1863
            } else {
 
1864
                /* Prefix mismatch so error out */
 
1865
                return -1;
 
1866
            }
 
1867
        }
 
1868
 
 
1869
        /* Do not add namespace decl to list - it is already there */
 
1870
        if (buf != NULL) {
 
1871
            p = (xmlTextWriterNsStackEntry *)
 
1872
                xmlMalloc(sizeof(xmlTextWriterNsStackEntry));
 
1873
            if (p == 0) {
 
1874
                xmlWriterErrMsg(writer, XML_ERR_NO_MEMORY,
 
1875
                                                                        "xmlTextWriterStartAttributeNS : out of memory!\n");
 
1876
                return -1;
 
1877
            }
 
1878
 
 
1879
            p->prefix = buf;
 
1880
            p->uri = xmlStrdup(namespaceURI);
 
1881
            if (p->uri == 0) {
 
1882
                xmlWriterErrMsg(writer, XML_ERR_NO_MEMORY,
 
1883
                        "xmlTextWriterStartAttributeNS : out of memory!\n");
 
1884
                xmlFree(p);
 
1885
                return -1;
 
1886
            }
 
1887
            p->elem = xmlListFront(writer->nodes);
 
1888
 
 
1889
            xmlListPushFront(writer->nsstack, p);
 
1890
        }
 
1891
    }
 
1892
 
 
1893
    buf = NULL;
 
1894
    if (prefix != 0) {
 
1895
        buf = xmlStrdup(prefix);
 
1896
        buf = xmlStrcat(buf, BAD_CAST ":");
 
1897
    }
 
1898
    buf = xmlStrcat(buf, name);
 
1899
 
 
1900
    sum = 0;
 
1901
    count = xmlTextWriterStartAttribute(writer, buf);
 
1902
    xmlFree(buf);
 
1903
    if (count < 0)
 
1904
        return -1;
 
1905
    sum += count;
 
1906
 
 
1907
    return sum;
 
1908
}
 
1909
 
 
1910
/**
 
1911
 * xmlTextWriterEndAttribute:
 
1912
 * @writer:  the xmlTextWriterPtr
 
1913
 *
 
1914
 * End the current xml element.
 
1915
 *
 
1916
 * Returns the bytes written (may be 0 because of buffering) or -1 in case of error
 
1917
 */
 
1918
int
 
1919
xmlTextWriterEndAttribute(xmlTextWriterPtr writer)
 
1920
{
 
1921
    int count;
 
1922
    int sum;
 
1923
    xmlLinkPtr lk;
 
1924
    xmlTextWriterStackEntry *p;
 
1925
 
 
1926
    if (writer == NULL)
 
1927
        return -1;
 
1928
 
 
1929
    lk = xmlListFront(writer->nodes);
 
1930
    if (lk == 0) {
 
1931
        return -1;
 
1932
    }
 
1933
 
 
1934
    p = (xmlTextWriterStackEntry *) xmlLinkGetData(lk);
 
1935
    if (p == 0) {
 
1936
        return -1;
 
1937
    }
 
1938
 
 
1939
    sum = 0;
 
1940
    switch (p->state) {
 
1941
        case XML_TEXTWRITER_ATTRIBUTE:
 
1942
            p->state = XML_TEXTWRITER_NAME;
 
1943
 
 
1944
            count = xmlOutputBufferWrite(writer->out, 1, &writer->qchar);
 
1945
            if (count < 0) {
 
1946
                return -1;
 
1947
            }
 
1948
            sum += count;
 
1949
            break;
 
1950
        default:
 
1951
            return -1;
 
1952
    }
 
1953
 
 
1954
    return sum;
 
1955
}
 
1956
 
 
1957
/**
 
1958
 * xmlTextWriterWriteFormatAttribute:
 
1959
 * @writer:  the xmlTextWriterPtr
 
1960
 * @name:  attribute name
 
1961
 * @format:  format string (see printf)
 
1962
 * @...:  extra parameters for the format
 
1963
 *
 
1964
 * Write a formatted xml attribute.
 
1965
 *
 
1966
 * Returns the bytes written (may be 0 because of buffering) or -1 in case of error
 
1967
 */
 
1968
int XMLCDECL
 
1969
xmlTextWriterWriteFormatAttribute(xmlTextWriterPtr writer,
 
1970
                                  const xmlChar * name, const char *format,
 
1971
                                  ...)
 
1972
{
 
1973
    int rc;
 
1974
    va_list ap;
 
1975
 
 
1976
    va_start(ap, format);
 
1977
 
 
1978
    rc = xmlTextWriterWriteVFormatAttribute(writer, name, format, ap);
 
1979
 
 
1980
    va_end(ap);
 
1981
    return rc;
 
1982
}
 
1983
 
 
1984
/**
 
1985
 * xmlTextWriterWriteVFormatAttribute:
 
1986
 * @writer:  the xmlTextWriterPtr
 
1987
 * @name:  attribute name
 
1988
 * @format:  format string (see printf)
 
1989
 * @argptr:  pointer to the first member of the variable argument list.
 
1990
 *
 
1991
 * Write a formatted xml attribute.
 
1992
 *
 
1993
 * Returns the bytes written (may be 0 because of buffering) or -1 in case of error
 
1994
 */
 
1995
int
 
1996
xmlTextWriterWriteVFormatAttribute(xmlTextWriterPtr writer,
 
1997
                                   const xmlChar * name,
 
1998
                                   const char *format, va_list argptr)
 
1999
{
 
2000
    int rc;
 
2001
    xmlChar *buf;
 
2002
 
 
2003
    if (writer == NULL)
 
2004
        return -1;
 
2005
 
 
2006
    buf = xmlTextWriterVSprintf(format, argptr);
 
2007
    if (buf == NULL)
 
2008
        return -1;
 
2009
 
 
2010
    rc = xmlTextWriterWriteAttribute(writer, name, buf);
 
2011
 
 
2012
    xmlFree(buf);
 
2013
    return rc;
 
2014
}
 
2015
 
 
2016
/**
 
2017
 * xmlTextWriterWriteAttribute:
 
2018
 * @writer:  the xmlTextWriterPtr
 
2019
 * @name:  attribute name
 
2020
 * @content:  attribute content
 
2021
 *
 
2022
 * Write an xml attribute.
 
2023
 *
 
2024
 * Returns the bytes written (may be 0 because of buffering) or -1 in case of error
 
2025
 */
 
2026
int
 
2027
xmlTextWriterWriteAttribute(xmlTextWriterPtr writer, const xmlChar * name,
 
2028
                            const xmlChar * content)
 
2029
{
 
2030
    int count;
 
2031
    int sum;
 
2032
 
 
2033
    sum = 0;
 
2034
    count = xmlTextWriterStartAttribute(writer, name);
 
2035
    if (count < 0)
 
2036
        return -1;
 
2037
    sum += count;
 
2038
    count = xmlTextWriterWriteString(writer, content);
 
2039
    if (count < 0)
 
2040
        return -1;
 
2041
    sum += count;
 
2042
    count = xmlTextWriterEndAttribute(writer);
 
2043
    if (count < 0)
 
2044
        return -1;
 
2045
    sum += count;
 
2046
 
 
2047
    return sum;
 
2048
}
 
2049
 
 
2050
/**
 
2051
 * xmlTextWriterWriteFormatAttributeNS:
 
2052
 * @writer:  the xmlTextWriterPtr
 
2053
 * @prefix:  namespace prefix
 
2054
 * @name:  attribute local name
 
2055
 * @namespaceURI:  namespace URI
 
2056
 * @format:  format string (see printf)
 
2057
 * @...:  extra parameters for the format
 
2058
 *
 
2059
 * Write a formatted xml attribute.with namespace support
 
2060
 *
 
2061
 * Returns the bytes written (may be 0 because of buffering) or -1 in case of error
 
2062
 */
 
2063
int XMLCDECL
 
2064
xmlTextWriterWriteFormatAttributeNS(xmlTextWriterPtr writer,
 
2065
                                    const xmlChar * prefix,
 
2066
                                    const xmlChar * name,
 
2067
                                    const xmlChar * namespaceURI,
 
2068
                                    const char *format, ...)
 
2069
{
 
2070
    int rc;
 
2071
    va_list ap;
 
2072
 
 
2073
    va_start(ap, format);
 
2074
 
 
2075
    rc = xmlTextWriterWriteVFormatAttributeNS(writer, prefix, name,
 
2076
                                              namespaceURI, format, ap);
 
2077
 
 
2078
    va_end(ap);
 
2079
    return rc;
 
2080
}
 
2081
 
 
2082
/**
 
2083
 * xmlTextWriterWriteVFormatAttributeNS:
 
2084
 * @writer:  the xmlTextWriterPtr
 
2085
 * @prefix:  namespace prefix
 
2086
 * @name:  attribute local name
 
2087
 * @namespaceURI:  namespace URI
 
2088
 * @format:  format string (see printf)
 
2089
 * @argptr:  pointer to the first member of the variable argument list.
 
2090
 *
 
2091
 * Write a formatted xml attribute.with namespace support
 
2092
 *
 
2093
 * Returns the bytes written (may be 0 because of buffering) or -1 in case of error
 
2094
 */
 
2095
int
 
2096
xmlTextWriterWriteVFormatAttributeNS(xmlTextWriterPtr writer,
 
2097
                                     const xmlChar * prefix,
 
2098
                                     const xmlChar * name,
 
2099
                                     const xmlChar * namespaceURI,
 
2100
                                     const char *format, va_list argptr)
 
2101
{
 
2102
    int rc;
 
2103
    xmlChar *buf;
 
2104
 
 
2105
    if (writer == NULL)
 
2106
        return -1;
 
2107
 
 
2108
    buf = xmlTextWriterVSprintf(format, argptr);
 
2109
    if (buf == NULL)
 
2110
        return -1;
 
2111
 
 
2112
    rc = xmlTextWriterWriteAttributeNS(writer, prefix, name, namespaceURI,
 
2113
                                       buf);
 
2114
 
 
2115
    xmlFree(buf);
 
2116
    return rc;
 
2117
}
 
2118
 
 
2119
/**
 
2120
 * xmlTextWriterWriteAttributeNS:
 
2121
 * @writer:  the xmlTextWriterPtr
 
2122
 * @prefix:  namespace prefix
 
2123
 * @name:  attribute local name
 
2124
 * @namespaceURI:  namespace URI
 
2125
 * @content:  attribute content
 
2126
 *
 
2127
 * Write an xml attribute.
 
2128
 *
 
2129
 * Returns the bytes written (may be 0 because of buffering) or -1 in case of error
 
2130
 */
 
2131
int
 
2132
xmlTextWriterWriteAttributeNS(xmlTextWriterPtr writer,
 
2133
                              const xmlChar * prefix, const xmlChar * name,
 
2134
                              const xmlChar * namespaceURI,
 
2135
                              const xmlChar * content)
 
2136
{
 
2137
    int count;
 
2138
    int sum;
 
2139
 
 
2140
    if ((writer == NULL) || (name == NULL) || (*name == '\0'))
 
2141
        return -1;
 
2142
 
 
2143
    sum = 0;
 
2144
    count = xmlTextWriterStartAttributeNS(writer, prefix, name, namespaceURI);
 
2145
    if (count < 0)
 
2146
        return -1;
 
2147
    sum += count;
 
2148
    count = xmlTextWriterWriteString(writer, content);
 
2149
    if (count < 0)
 
2150
        return -1;
 
2151
    sum += count;
 
2152
    count = xmlTextWriterEndAttribute(writer);
 
2153
    if (count < 0)
 
2154
        return -1;
 
2155
    sum += count;
 
2156
 
 
2157
    return sum;
 
2158
}
 
2159
 
 
2160
/**
 
2161
 * xmlTextWriterWriteFormatElement:
 
2162
 * @writer:  the xmlTextWriterPtr
 
2163
 * @name:  element name
 
2164
 * @format:  format string (see printf)
 
2165
 * @...:  extra parameters for the format
 
2166
 *
 
2167
 * Write a formatted xml element.
 
2168
 *
 
2169
 * Returns the bytes written (may be 0 because of buffering) or -1 in case of error
 
2170
 */
 
2171
int XMLCDECL
 
2172
xmlTextWriterWriteFormatElement(xmlTextWriterPtr writer,
 
2173
                                const xmlChar * name, const char *format,
 
2174
                                ...)
 
2175
{
 
2176
    int rc;
 
2177
    va_list ap;
 
2178
 
 
2179
    va_start(ap, format);
 
2180
 
 
2181
    rc = xmlTextWriterWriteVFormatElement(writer, name, format, ap);
 
2182
 
 
2183
    va_end(ap);
 
2184
    return rc;
 
2185
}
 
2186
 
 
2187
/**
 
2188
 * xmlTextWriterWriteVFormatElement:
 
2189
 * @writer:  the xmlTextWriterPtr
 
2190
 * @name:  element name
 
2191
 * @format:  format string (see printf)
 
2192
 * @argptr:  pointer to the first member of the variable argument list.
 
2193
 *
 
2194
 * Write a formatted xml element.
 
2195
 *
 
2196
 * Returns the bytes written (may be 0 because of buffering) or -1 in case of error
 
2197
 */
 
2198
int
 
2199
xmlTextWriterWriteVFormatElement(xmlTextWriterPtr writer,
 
2200
                                 const xmlChar * name, const char *format,
 
2201
                                 va_list argptr)
 
2202
{
 
2203
    int rc;
 
2204
    xmlChar *buf;
 
2205
 
 
2206
    if (writer == NULL)
 
2207
        return -1;
 
2208
 
 
2209
    buf = xmlTextWriterVSprintf(format, argptr);
 
2210
    if (buf == NULL)
 
2211
        return -1;
 
2212
 
 
2213
    rc = xmlTextWriterWriteElement(writer, name, buf);
 
2214
 
 
2215
    xmlFree(buf);
 
2216
    return rc;
 
2217
}
 
2218
 
 
2219
/**
 
2220
 * xmlTextWriterWriteElement:
 
2221
 * @writer:  the xmlTextWriterPtr
 
2222
 * @name:  element name
 
2223
 * @content:  element content
 
2224
 *
 
2225
 * Write an xml element.
 
2226
 *
 
2227
 * Returns the bytes written (may be 0 because of buffering) or -1 in case of error
 
2228
 */
 
2229
int
 
2230
xmlTextWriterWriteElement(xmlTextWriterPtr writer, const xmlChar * name,
 
2231
                          const xmlChar * content)
 
2232
{
 
2233
    int count;
 
2234
    int sum;
 
2235
 
 
2236
    sum = 0;
 
2237
    count = xmlTextWriterStartElement(writer, name);
 
2238
    if (count == -1)
 
2239
        return -1;
 
2240
    sum += count;
 
2241
    count = xmlTextWriterWriteString(writer, content);
 
2242
    if (count == -1)
 
2243
        return -1;
 
2244
    sum += count;
 
2245
    count = xmlTextWriterEndElement(writer);
 
2246
    if (count == -1)
 
2247
        return -1;
 
2248
    sum += count;
 
2249
 
 
2250
    return sum;
 
2251
}
 
2252
 
 
2253
/**
 
2254
 * xmlTextWriterWriteFormatElementNS:
 
2255
 * @writer:  the xmlTextWriterPtr
 
2256
 * @prefix:  namespace prefix
 
2257
 * @name:  element local name
 
2258
 * @namespaceURI:  namespace URI
 
2259
 * @format:  format string (see printf)
 
2260
 * @...:  extra parameters for the format
 
2261
 *
 
2262
 * Write a formatted xml element with namespace support.
 
2263
 *
 
2264
 * Returns the bytes written (may be 0 because of buffering) or -1 in case of error
 
2265
 */
 
2266
int XMLCDECL
 
2267
xmlTextWriterWriteFormatElementNS(xmlTextWriterPtr writer,
 
2268
                                  const xmlChar * prefix,
 
2269
                                  const xmlChar * name,
 
2270
                                  const xmlChar * namespaceURI,
 
2271
                                  const char *format, ...)
 
2272
{
 
2273
    int rc;
 
2274
    va_list ap;
 
2275
 
 
2276
    va_start(ap, format);
 
2277
 
 
2278
    rc = xmlTextWriterWriteVFormatElementNS(writer, prefix, name,
 
2279
                                            namespaceURI, format, ap);
 
2280
 
 
2281
    va_end(ap);
 
2282
    return rc;
 
2283
}
 
2284
 
 
2285
/**
 
2286
 * xmlTextWriterWriteVFormatElementNS:
 
2287
 * @writer:  the xmlTextWriterPtr
 
2288
 * @prefix:  namespace prefix
 
2289
 * @name:  element local name
 
2290
 * @namespaceURI:  namespace URI
 
2291
 * @format:  format string (see printf)
 
2292
 * @argptr:  pointer to the first member of the variable argument list.
 
2293
 *
 
2294
 * Write a formatted xml element with namespace support.
 
2295
 *
 
2296
 * Returns the bytes written (may be 0 because of buffering) or -1 in case of error
 
2297
 */
 
2298
int
 
2299
xmlTextWriterWriteVFormatElementNS(xmlTextWriterPtr writer,
 
2300
                                   const xmlChar * prefix,
 
2301
                                   const xmlChar * name,
 
2302
                                   const xmlChar * namespaceURI,
 
2303
                                   const char *format, va_list argptr)
 
2304
{
 
2305
    int rc;
 
2306
    xmlChar *buf;
 
2307
 
 
2308
    if (writer == NULL)
 
2309
        return -1;
 
2310
 
 
2311
    buf = xmlTextWriterVSprintf(format, argptr);
 
2312
    if (buf == NULL)
 
2313
        return -1;
 
2314
 
 
2315
    rc = xmlTextWriterWriteElementNS(writer, prefix, name, namespaceURI,
 
2316
                                     buf);
 
2317
 
 
2318
    xmlFree(buf);
 
2319
    return rc;
 
2320
}
 
2321
 
 
2322
/**
 
2323
 * xmlTextWriterWriteElementNS:
 
2324
 * @writer:  the xmlTextWriterPtr
 
2325
 * @prefix:  namespace prefix
 
2326
 * @name:  element local name
 
2327
 * @namespaceURI:  namespace URI
 
2328
 * @content:  element content
 
2329
 *
 
2330
 * Write an xml element with namespace support.
 
2331
 *
 
2332
 * Returns the bytes written (may be 0 because of buffering) or -1 in case of error
 
2333
 */
 
2334
int
 
2335
xmlTextWriterWriteElementNS(xmlTextWriterPtr writer,
 
2336
                            const xmlChar * prefix, const xmlChar * name,
 
2337
                            const xmlChar * namespaceURI,
 
2338
                            const xmlChar * content)
 
2339
{
 
2340
    int count;
 
2341
    int sum;
 
2342
 
 
2343
    if ((writer == NULL) || (name == NULL) || (*name == '\0'))
 
2344
        return -1;
 
2345
 
 
2346
    sum = 0;
 
2347
    count =
 
2348
        xmlTextWriterStartElementNS(writer, prefix, name, namespaceURI);
 
2349
    if (count < 0)
 
2350
        return -1;
 
2351
    sum += count;
 
2352
    count = xmlTextWriterWriteString(writer, content);
 
2353
    if (count == -1)
 
2354
        return -1;
 
2355
    sum += count;
 
2356
    count = xmlTextWriterEndElement(writer);
 
2357
    if (count == -1)
 
2358
        return -1;
 
2359
    sum += count;
 
2360
 
 
2361
    return sum;
 
2362
}
 
2363
 
 
2364
/**
 
2365
 * xmlTextWriterStartPI:
 
2366
 * @writer:  the xmlTextWriterPtr
 
2367
 * @target:  PI target
 
2368
 *
 
2369
 * Start an xml PI.
 
2370
 *
 
2371
 * Returns the bytes written (may be 0 because of buffering) or -1 in case of error
 
2372
 */
 
2373
int
 
2374
xmlTextWriterStartPI(xmlTextWriterPtr writer, const xmlChar * target)
 
2375
{
 
2376
    int count;
 
2377
    int sum;
 
2378
    xmlLinkPtr lk;
 
2379
    xmlTextWriterStackEntry *p;
 
2380
 
 
2381
    if ((writer == NULL) || (target == NULL) || (*target == '\0'))
 
2382
        return -1;
 
2383
 
 
2384
    if (xmlStrcasecmp(target, (const xmlChar *) "xml") == 0) {
 
2385
        xmlWriterErrMsg(writer, XML_ERR_INTERNAL_ERROR,
 
2386
                        "xmlTextWriterStartPI : target name [Xx][Mm][Ll] is reserved for xml standardization!\n");
 
2387
        return -1;
 
2388
    }
 
2389
 
 
2390
    sum = 0;
 
2391
    lk = xmlListFront(writer->nodes);
 
2392
    if (lk != 0) {
 
2393
        p = (xmlTextWriterStackEntry *) xmlLinkGetData(lk);
 
2394
        if (p != 0) {
 
2395
            switch (p->state) {
 
2396
                case XML_TEXTWRITER_ATTRIBUTE:
 
2397
                    count = xmlTextWriterEndAttribute(writer);
 
2398
                    if (count < 0)
 
2399
                        return -1;
 
2400
                    sum += count;
 
2401
                    /* fallthrough */
 
2402
                case XML_TEXTWRITER_NAME:
 
2403
                    /* Output namespace declarations */
 
2404
                    count = xmlTextWriterOutputNSDecl(writer);
 
2405
                    if (count < 0)
 
2406
                        return -1;
 
2407
                    sum += count;
 
2408
                    count = xmlOutputBufferWriteString(writer->out, ">");
 
2409
                    if (count < 0)
 
2410
                        return -1;
 
2411
                    sum += count;
 
2412
                    p->state = XML_TEXTWRITER_TEXT;
 
2413
                    break;
 
2414
                case XML_TEXTWRITER_NONE:
 
2415
                case XML_TEXTWRITER_TEXT:
 
2416
                case XML_TEXTWRITER_DTD:
 
2417
                    break;
 
2418
                case XML_TEXTWRITER_PI:
 
2419
                case XML_TEXTWRITER_PI_TEXT:
 
2420
                    xmlWriterErrMsg(writer, XML_ERR_INTERNAL_ERROR,
 
2421
                                    "xmlTextWriterStartPI : nested PI!\n");
 
2422
                    return -1;
 
2423
                default:
 
2424
                    return -1;
 
2425
            }
 
2426
        }
 
2427
    }
 
2428
 
 
2429
    p = (xmlTextWriterStackEntry *)
 
2430
        xmlMalloc(sizeof(xmlTextWriterStackEntry));
 
2431
    if (p == 0) {
 
2432
        xmlWriterErrMsg(writer, XML_ERR_NO_MEMORY,
 
2433
                        "xmlTextWriterStartPI : out of memory!\n");
 
2434
        return -1;
 
2435
    }
 
2436
 
 
2437
    p->name = xmlStrdup(target);
 
2438
    if (p->name == 0) {
 
2439
        xmlWriterErrMsg(writer, XML_ERR_NO_MEMORY,
 
2440
                        "xmlTextWriterStartPI : out of memory!\n");
 
2441
        xmlFree(p);
 
2442
        return -1;
 
2443
    }
 
2444
    p->state = XML_TEXTWRITER_PI;
 
2445
 
 
2446
    xmlListPushFront(writer->nodes, p);
 
2447
 
 
2448
    count = xmlOutputBufferWriteString(writer->out, "<?");
 
2449
    if (count < 0)
 
2450
        return -1;
 
2451
    sum += count;
 
2452
    count =
 
2453
        xmlOutputBufferWriteString(writer->out, (const char *) p->name);
 
2454
    if (count < 0)
 
2455
        return -1;
 
2456
    sum += count;
 
2457
 
 
2458
    return sum;
 
2459
}
 
2460
 
 
2461
/**
 
2462
 * xmlTextWriterEndPI:
 
2463
 * @writer:  the xmlTextWriterPtr
 
2464
 *
 
2465
 * End the current xml PI.
 
2466
 *
 
2467
 * Returns the bytes written (may be 0 because of buffering) or -1 in case of error
 
2468
 */
 
2469
int
 
2470
xmlTextWriterEndPI(xmlTextWriterPtr writer)
 
2471
{
 
2472
    int count;
 
2473
    int sum;
 
2474
    xmlLinkPtr lk;
 
2475
    xmlTextWriterStackEntry *p;
 
2476
 
 
2477
    if (writer == NULL)
 
2478
        return -1;
 
2479
 
 
2480
    lk = xmlListFront(writer->nodes);
 
2481
    if (lk == 0)
 
2482
        return 0;
 
2483
 
 
2484
    p = (xmlTextWriterStackEntry *) xmlLinkGetData(lk);
 
2485
    if (p == 0)
 
2486
        return 0;
 
2487
 
 
2488
    sum = 0;
 
2489
    switch (p->state) {
 
2490
        case XML_TEXTWRITER_PI:
 
2491
        case XML_TEXTWRITER_PI_TEXT:
 
2492
            count = xmlOutputBufferWriteString(writer->out, "?>");
 
2493
            if (count < 0)
 
2494
                return -1;
 
2495
            sum += count;
 
2496
            break;
 
2497
        default:
 
2498
            return -1;
 
2499
    }
 
2500
 
 
2501
    if (writer->indent) {
 
2502
        count = xmlOutputBufferWriteString(writer->out, "\n");
 
2503
        if (count < 0)
 
2504
        return -1;
 
2505
        sum += count;
 
2506
    }
 
2507
 
 
2508
    xmlListPopFront(writer->nodes);
 
2509
    return sum;
 
2510
}
 
2511
 
 
2512
/**
 
2513
 * xmlTextWriterWriteFormatPI:
 
2514
 * @writer:  the xmlTextWriterPtr
 
2515
 * @target:  PI target
 
2516
 * @format:  format string (see printf)
 
2517
 * @...:  extra parameters for the format
 
2518
 *
 
2519
 * Write a formatted PI.
 
2520
 *
 
2521
 * Returns the bytes written (may be 0 because of buffering) or -1 in case of error
 
2522
 */
 
2523
int XMLCDECL
 
2524
xmlTextWriterWriteFormatPI(xmlTextWriterPtr writer, const xmlChar * target,
 
2525
                           const char *format, ...)
 
2526
{
 
2527
    int rc;
 
2528
    va_list ap;
 
2529
 
 
2530
    va_start(ap, format);
 
2531
 
 
2532
    rc = xmlTextWriterWriteVFormatPI(writer, target, format, ap);
 
2533
 
 
2534
    va_end(ap);
 
2535
    return rc;
 
2536
}
 
2537
 
 
2538
/**
 
2539
 * xmlTextWriterWriteVFormatPI:
 
2540
 * @writer:  the xmlTextWriterPtr
 
2541
 * @target:  PI target
 
2542
 * @format:  format string (see printf)
 
2543
 * @argptr:  pointer to the first member of the variable argument list.
 
2544
 *
 
2545
 * Write a formatted xml PI.
 
2546
 *
 
2547
 * Returns the bytes written (may be 0 because of buffering) or -1 in case of error
 
2548
 */
 
2549
int
 
2550
xmlTextWriterWriteVFormatPI(xmlTextWriterPtr writer,
 
2551
                            const xmlChar * target, const char *format,
 
2552
                            va_list argptr)
 
2553
{
 
2554
    int rc;
 
2555
    xmlChar *buf;
 
2556
 
 
2557
    if (writer == NULL)
 
2558
        return -1;
 
2559
 
 
2560
    buf = xmlTextWriterVSprintf(format, argptr);
 
2561
    if (buf == NULL)
 
2562
        return -1;
 
2563
 
 
2564
    rc = xmlTextWriterWritePI(writer, target, buf);
 
2565
 
 
2566
    xmlFree(buf);
 
2567
    return rc;
 
2568
}
 
2569
 
 
2570
/**
 
2571
 * xmlTextWriterWritePI:
 
2572
 * @writer:  the xmlTextWriterPtr
 
2573
 * @target:  PI target
 
2574
 * @content:  PI content
 
2575
 *
 
2576
 * Write an xml PI.
 
2577
 *
 
2578
 * Returns the bytes written (may be 0 because of buffering) or -1 in case of error
 
2579
 */
 
2580
int
 
2581
xmlTextWriterWritePI(xmlTextWriterPtr writer, const xmlChar * target,
 
2582
                     const xmlChar * content)
 
2583
{
 
2584
    int count;
 
2585
    int sum;
 
2586
 
 
2587
    sum = 0;
 
2588
    count = xmlTextWriterStartPI(writer, target);
 
2589
    if (count == -1)
 
2590
        return -1;
 
2591
    sum += count;
 
2592
    if (content != 0) {
 
2593
        count = xmlTextWriterWriteString(writer, content);
 
2594
        if (count == -1)
 
2595
            return -1;
 
2596
        sum += count;
 
2597
    }
 
2598
    count = xmlTextWriterEndPI(writer);
 
2599
    if (count == -1)
 
2600
        return -1;
 
2601
    sum += count;
 
2602
 
 
2603
    return sum;
 
2604
}
 
2605
 
 
2606
/**
 
2607
 * xmlTextWriterStartCDATA:
 
2608
 * @writer:  the xmlTextWriterPtr
 
2609
 *
 
2610
 * Start an xml CDATA section.
 
2611
 *
 
2612
 * Returns the bytes written (may be 0 because of buffering) or -1 in case of error
 
2613
 */
 
2614
int
 
2615
xmlTextWriterStartCDATA(xmlTextWriterPtr writer)
 
2616
{
 
2617
    int count;
 
2618
    int sum;
 
2619
    xmlLinkPtr lk;
 
2620
    xmlTextWriterStackEntry *p;
 
2621
 
 
2622
    if (writer == NULL)
 
2623
        return -1;
 
2624
 
 
2625
    sum = 0;
 
2626
    lk = xmlListFront(writer->nodes);
 
2627
    if (lk != 0) {
 
2628
        p = (xmlTextWriterStackEntry *) xmlLinkGetData(lk);
 
2629
        if (p != 0) {
 
2630
            switch (p->state) {
 
2631
                case XML_TEXTWRITER_NONE:
 
2632
                case XML_TEXTWRITER_TEXT:
 
2633
                case XML_TEXTWRITER_PI:
 
2634
                case XML_TEXTWRITER_PI_TEXT:
 
2635
                    break;
 
2636
                case XML_TEXTWRITER_ATTRIBUTE:
 
2637
                    count = xmlTextWriterEndAttribute(writer);
 
2638
                    if (count < 0)
 
2639
                        return -1;
 
2640
                    sum += count;
 
2641
                    /* fallthrough */
 
2642
                case XML_TEXTWRITER_NAME:
 
2643
                    /* Output namespace declarations */
 
2644
                    count = xmlTextWriterOutputNSDecl(writer);
 
2645
                    if (count < 0)
 
2646
                        return -1;
 
2647
                    sum += count;
 
2648
                    count = xmlOutputBufferWriteString(writer->out, ">");
 
2649
                    if (count < 0)
 
2650
                        return -1;
 
2651
                    sum += count;
 
2652
                    p->state = XML_TEXTWRITER_TEXT;
 
2653
                    break;
 
2654
                case XML_TEXTWRITER_CDATA:
 
2655
                    xmlWriterErrMsg(writer, XML_ERR_INTERNAL_ERROR,
 
2656
                                    "xmlTextWriterStartCDATA : CDATA not allowed in this context!\n");
 
2657
                    return -1;
 
2658
                default:
 
2659
                    return -1;
 
2660
            }
 
2661
        }
 
2662
    }
 
2663
 
 
2664
    p = (xmlTextWriterStackEntry *)
 
2665
        xmlMalloc(sizeof(xmlTextWriterStackEntry));
 
2666
    if (p == 0) {
 
2667
        xmlWriterErrMsg(writer, XML_ERR_NO_MEMORY,
 
2668
                        "xmlTextWriterStartCDATA : out of memory!\n");
 
2669
        return -1;
 
2670
    }
 
2671
 
 
2672
    p->name = NULL;
 
2673
    p->state = XML_TEXTWRITER_CDATA;
 
2674
 
 
2675
    xmlListPushFront(writer->nodes, p);
 
2676
 
 
2677
    count = xmlOutputBufferWriteString(writer->out, "<![CDATA[");
 
2678
    if (count < 0)
 
2679
        return -1;
 
2680
    sum += count;
 
2681
 
 
2682
    return sum;
 
2683
}
 
2684
 
 
2685
/**
 
2686
 * xmlTextWriterEndCDATA:
 
2687
 * @writer:  the xmlTextWriterPtr
 
2688
 *
 
2689
 * End an xml CDATA section.
 
2690
 *
 
2691
 * Returns the bytes written (may be 0 because of buffering) or -1 in case of error
 
2692
 */
 
2693
int
 
2694
xmlTextWriterEndCDATA(xmlTextWriterPtr writer)
 
2695
{
 
2696
    int count;
 
2697
    int sum;
 
2698
    xmlLinkPtr lk;
 
2699
    xmlTextWriterStackEntry *p;
 
2700
 
 
2701
    if (writer == NULL)
 
2702
        return -1;
 
2703
 
 
2704
    lk = xmlListFront(writer->nodes);
 
2705
    if (lk == 0)
 
2706
        return -1;
 
2707
 
 
2708
    p = (xmlTextWriterStackEntry *) xmlLinkGetData(lk);
 
2709
    if (p == 0)
 
2710
        return -1;
 
2711
 
 
2712
    sum = 0;
 
2713
    switch (p->state) {
 
2714
        case XML_TEXTWRITER_CDATA:
 
2715
            count = xmlOutputBufferWriteString(writer->out, "]]>");
 
2716
            if (count < 0)
 
2717
                return -1;
 
2718
            sum += count;
 
2719
            break;
 
2720
        default:
 
2721
            return -1;
 
2722
    }
 
2723
 
 
2724
    xmlListPopFront(writer->nodes);
 
2725
    return sum;
 
2726
}
 
2727
 
 
2728
/**
 
2729
 * xmlTextWriterWriteFormatCDATA:
 
2730
 * @writer:  the xmlTextWriterPtr
 
2731
 * @format:  format string (see printf)
 
2732
 * @...:  extra parameters for the format
 
2733
 *
 
2734
 * Write a formatted xml CDATA.
 
2735
 *
 
2736
 * Returns the bytes written (may be 0 because of buffering) or -1 in case of error
 
2737
 */
 
2738
int XMLCDECL
 
2739
xmlTextWriterWriteFormatCDATA(xmlTextWriterPtr writer, const char *format,
 
2740
                              ...)
 
2741
{
 
2742
    int rc;
 
2743
    va_list ap;
 
2744
 
 
2745
    va_start(ap, format);
 
2746
 
 
2747
    rc = xmlTextWriterWriteVFormatCDATA(writer, format, ap);
 
2748
 
 
2749
    va_end(ap);
 
2750
    return rc;
 
2751
}
 
2752
 
 
2753
/**
 
2754
 * xmlTextWriterWriteVFormatCDATA:
 
2755
 * @writer:  the xmlTextWriterPtr
 
2756
 * @format:  format string (see printf)
 
2757
 * @argptr:  pointer to the first member of the variable argument list.
 
2758
 *
 
2759
 * Write a formatted xml CDATA.
 
2760
 *
 
2761
 * Returns the bytes written (may be 0 because of buffering) or -1 in case of error
 
2762
 */
 
2763
int
 
2764
xmlTextWriterWriteVFormatCDATA(xmlTextWriterPtr writer, const char *format,
 
2765
                               va_list argptr)
 
2766
{
 
2767
    int rc;
 
2768
    xmlChar *buf;
 
2769
 
 
2770
    if (writer == NULL)
 
2771
        return -1;
 
2772
 
 
2773
    buf = xmlTextWriterVSprintf(format, argptr);
 
2774
    if (buf == NULL)
 
2775
        return -1;
 
2776
 
 
2777
    rc = xmlTextWriterWriteCDATA(writer, buf);
 
2778
 
 
2779
    xmlFree(buf);
 
2780
    return rc;
 
2781
}
 
2782
 
 
2783
/**
 
2784
 * xmlTextWriterWriteCDATA:
 
2785
 * @writer:  the xmlTextWriterPtr
 
2786
 * @content:  CDATA content
 
2787
 *
 
2788
 * Write an xml CDATA.
 
2789
 *
 
2790
 * Returns the bytes written (may be 0 because of buffering) or -1 in case of error
 
2791
 */
 
2792
int
 
2793
xmlTextWriterWriteCDATA(xmlTextWriterPtr writer, const xmlChar * content)
 
2794
{
 
2795
    int count;
 
2796
    int sum;
 
2797
 
 
2798
    sum = 0;
 
2799
    count = xmlTextWriterStartCDATA(writer);
 
2800
    if (count == -1)
 
2801
        return -1;
 
2802
    sum += count;
 
2803
    if (content != 0) {
 
2804
        count = xmlTextWriterWriteString(writer, content);
 
2805
        if (count == -1)
 
2806
            return -1;
 
2807
        sum += count;
 
2808
    }
 
2809
    count = xmlTextWriterEndCDATA(writer);
 
2810
    if (count == -1)
 
2811
        return -1;
 
2812
    sum += count;
 
2813
 
 
2814
    return sum;
 
2815
}
 
2816
 
 
2817
/**
 
2818
 * xmlTextWriterStartDTD:
 
2819
 * @writer:  the xmlTextWriterPtr
 
2820
 * @name:  the name of the DTD
 
2821
 * @pubid:  the public identifier, which is an alternative to the system identifier
 
2822
 * @sysid:  the system identifier, which is the URI of the DTD
 
2823
 *
 
2824
 * Start an xml DTD.
 
2825
 *
 
2826
 * Returns the bytes written (may be 0 because of buffering) or -1 in case of error
 
2827
 */
 
2828
int
 
2829
xmlTextWriterStartDTD(xmlTextWriterPtr writer,
 
2830
                      const xmlChar * name,
 
2831
                      const xmlChar * pubid, const xmlChar * sysid)
 
2832
{
 
2833
    int count;
 
2834
    int sum;
 
2835
    xmlLinkPtr lk;
 
2836
    xmlTextWriterStackEntry *p;
 
2837
 
 
2838
    if (writer == NULL || name == NULL || *name == '\0')
 
2839
        return -1;
 
2840
 
 
2841
    sum = 0;
 
2842
    lk = xmlListFront(writer->nodes);
 
2843
    if ((lk != NULL) && (xmlLinkGetData(lk) != NULL)) {
 
2844
        xmlWriterErrMsg(writer, XML_ERR_INTERNAL_ERROR,
 
2845
                        "xmlTextWriterStartDTD : DTD allowed only in prolog!\n");
 
2846
        return -1;
 
2847
    }
 
2848
 
 
2849
    p = (xmlTextWriterStackEntry *)
 
2850
        xmlMalloc(sizeof(xmlTextWriterStackEntry));
 
2851
    if (p == 0) {
 
2852
        xmlWriterErrMsg(writer, XML_ERR_NO_MEMORY,
 
2853
                        "xmlTextWriterStartDTD : out of memory!\n");
 
2854
        return -1;
 
2855
    }
 
2856
 
 
2857
    p->name = xmlStrdup(name);
 
2858
    if (p->name == 0) {
 
2859
        xmlWriterErrMsg(writer, XML_ERR_NO_MEMORY,
 
2860
                        "xmlTextWriterStartDTD : out of memory!\n");
 
2861
        xmlFree(p);
 
2862
        return -1;
 
2863
    }
 
2864
    p->state = XML_TEXTWRITER_DTD;
 
2865
 
 
2866
    xmlListPushFront(writer->nodes, p);
 
2867
 
 
2868
    count = xmlOutputBufferWriteString(writer->out, "<!DOCTYPE ");
 
2869
    if (count < 0)
 
2870
        return -1;
 
2871
    sum += count;
 
2872
    count = xmlOutputBufferWriteString(writer->out, (const char *) name);
 
2873
    if (count < 0)
 
2874
        return -1;
 
2875
    sum += count;
 
2876
 
 
2877
    if (pubid != 0) {
 
2878
        if (sysid == 0) {
 
2879
            xmlWriterErrMsg(writer, XML_ERR_INTERNAL_ERROR,
 
2880
                            "xmlTextWriterStartDTD : system identifier needed!\n");
 
2881
            return -1;
 
2882
        }
 
2883
 
 
2884
        if (writer->indent)
 
2885
            count = xmlOutputBufferWrite(writer->out, 1, "\n");
 
2886
        else
 
2887
            count = xmlOutputBufferWrite(writer->out, 1, " ");
 
2888
        if (count < 0)
 
2889
            return -1;
 
2890
        sum += count;
 
2891
 
 
2892
        count = xmlOutputBufferWriteString(writer->out, "PUBLIC ");
 
2893
        if (count < 0)
 
2894
            return -1;
 
2895
        sum += count;
 
2896
 
 
2897
        count = xmlOutputBufferWrite(writer->out, 1, &writer->qchar);
 
2898
        if (count < 0)
 
2899
            return -1;
 
2900
        sum += count;
 
2901
 
 
2902
        count =
 
2903
            xmlOutputBufferWriteString(writer->out, (const char *) pubid);
 
2904
        if (count < 0)
 
2905
            return -1;
 
2906
        sum += count;
 
2907
 
 
2908
        count = xmlOutputBufferWrite(writer->out, 1, &writer->qchar);
 
2909
        if (count < 0)
 
2910
            return -1;
 
2911
        sum += count;
 
2912
    }
 
2913
 
 
2914
    if (sysid != 0) {
 
2915
        if (pubid == 0) {
 
2916
            if (writer->indent)
 
2917
                count = xmlOutputBufferWrite(writer->out, 1, "\n");
 
2918
            else
 
2919
                count = xmlOutputBufferWrite(writer->out, 1, " ");
 
2920
            if (count < 0)
 
2921
                return -1;
 
2922
            sum += count;
 
2923
            count = xmlOutputBufferWriteString(writer->out, "SYSTEM ");
 
2924
            if (count < 0)
 
2925
                return -1;
 
2926
            sum += count;
 
2927
        } else {
 
2928
                        if (writer->indent)
 
2929
            count = xmlOutputBufferWriteString(writer->out, "\n       ");
 
2930
            else
 
2931
                count = xmlOutputBufferWrite(writer->out, 1, " ");
 
2932
            if (count < 0)
 
2933
                return -1;
 
2934
            sum += count;
 
2935
        }
 
2936
 
 
2937
        count = xmlOutputBufferWrite(writer->out, 1, &writer->qchar);
 
2938
        if (count < 0)
 
2939
            return -1;
 
2940
        sum += count;
 
2941
 
 
2942
        count =
 
2943
            xmlOutputBufferWriteString(writer->out, (const char *) sysid);
 
2944
        if (count < 0)
 
2945
            return -1;
 
2946
        sum += count;
 
2947
 
 
2948
        count = xmlOutputBufferWrite(writer->out, 1, &writer->qchar);
 
2949
        if (count < 0)
 
2950
            return -1;
 
2951
        sum += count;
 
2952
    }
 
2953
 
 
2954
    return sum;
 
2955
}
 
2956
 
 
2957
/**
 
2958
 * xmlTextWriterEndDTD:
 
2959
 * @writer:  the xmlTextWriterPtr
 
2960
 *
 
2961
 * End an xml DTD.
 
2962
 *
 
2963
 * Returns the bytes written (may be 0 because of buffering) or -1 in case of error
 
2964
 */
 
2965
int
 
2966
xmlTextWriterEndDTD(xmlTextWriterPtr writer)
 
2967
{
 
2968
    int loop;
 
2969
    int count;
 
2970
    int sum;
 
2971
    xmlLinkPtr lk;
 
2972
    xmlTextWriterStackEntry *p;
 
2973
 
 
2974
    if (writer == NULL)
 
2975
        return -1;
 
2976
 
 
2977
    sum = 0;
 
2978
    loop = 1;
 
2979
    while (loop) {
 
2980
        lk = xmlListFront(writer->nodes);
 
2981
        if (lk == NULL)
 
2982
            break;
 
2983
        p = (xmlTextWriterStackEntry *) xmlLinkGetData(lk);
 
2984
        if (p == 0)
 
2985
            break;
 
2986
        switch (p->state) {
 
2987
            case XML_TEXTWRITER_DTD_TEXT:
 
2988
                count = xmlOutputBufferWriteString(writer->out, "]");
 
2989
                if (count < 0)
 
2990
                    return -1;
 
2991
                sum += count;
 
2992
                /* fallthrough */
 
2993
            case XML_TEXTWRITER_DTD:
 
2994
                count = xmlOutputBufferWriteString(writer->out, ">");
 
2995
 
 
2996
                if (writer->indent) {
 
2997
                    if (count < 0)
 
2998
                        return -1;
 
2999
                    sum += count;
 
3000
                    count = xmlOutputBufferWriteString(writer->out, "\n");
 
3001
                }
 
3002
 
 
3003
                xmlListPopFront(writer->nodes);
 
3004
                break;
 
3005
            case XML_TEXTWRITER_DTD_ELEM:
 
3006
            case XML_TEXTWRITER_DTD_ELEM_TEXT:
 
3007
                count = xmlTextWriterEndDTDElement(writer);
 
3008
                break;
 
3009
            case XML_TEXTWRITER_DTD_ATTL:
 
3010
            case XML_TEXTWRITER_DTD_ATTL_TEXT:
 
3011
                count = xmlTextWriterEndDTDAttlist(writer);
 
3012
                break;
 
3013
            case XML_TEXTWRITER_DTD_ENTY:
 
3014
            case XML_TEXTWRITER_DTD_PENT:
 
3015
            case XML_TEXTWRITER_DTD_ENTY_TEXT:
 
3016
                count = xmlTextWriterEndDTDEntity(writer);
 
3017
                break;
 
3018
            case XML_TEXTWRITER_COMMENT:
 
3019
                count = xmlTextWriterEndComment(writer);
 
3020
                break;
 
3021
            default:
 
3022
                loop = 0;
 
3023
                continue;
 
3024
        }
 
3025
 
 
3026
        if (count < 0)
 
3027
            return -1;
 
3028
        sum += count;
 
3029
    }
 
3030
 
 
3031
    return sum;
 
3032
}
 
3033
 
 
3034
/**
 
3035
 * xmlTextWriterWriteFormatDTD:
 
3036
 * @writer:  the xmlTextWriterPtr
 
3037
 * @name:  the name of the DTD
 
3038
 * @pubid:  the public identifier, which is an alternative to the system identifier
 
3039
 * @sysid:  the system identifier, which is the URI of the DTD
 
3040
 * @format:  format string (see printf)
 
3041
 * @...:  extra parameters for the format
 
3042
 *
 
3043
 * Write a DTD with a formatted markup declarations part.
 
3044
 *
 
3045
 * Returns the bytes written (may be 0 because of buffering) or -1 in case of error
 
3046
 */
 
3047
int XMLCDECL
 
3048
xmlTextWriterWriteFormatDTD(xmlTextWriterPtr writer,
 
3049
                            const xmlChar * name,
 
3050
                            const xmlChar * pubid,
 
3051
                            const xmlChar * sysid, const char *format, ...)
 
3052
{
 
3053
    int rc;
 
3054
    va_list ap;
 
3055
 
 
3056
    va_start(ap, format);
 
3057
 
 
3058
    rc = xmlTextWriterWriteVFormatDTD(writer, name, pubid, sysid, format,
 
3059
                                      ap);
 
3060
 
 
3061
    va_end(ap);
 
3062
    return rc;
 
3063
}
 
3064
 
 
3065
/**
 
3066
 * xmlTextWriterWriteVFormatDTD:
 
3067
 * @writer:  the xmlTextWriterPtr
 
3068
 * @name:  the name of the DTD
 
3069
 * @pubid:  the public identifier, which is an alternative to the system identifier
 
3070
 * @sysid:  the system identifier, which is the URI of the DTD
 
3071
 * @format:  format string (see printf)
 
3072
 * @argptr:  pointer to the first member of the variable argument list.
 
3073
 *
 
3074
 * Write a DTD with a formatted markup declarations part.
 
3075
 *
 
3076
 * Returns the bytes written (may be 0 because of buffering) or -1 in case of error
 
3077
 */
 
3078
int
 
3079
xmlTextWriterWriteVFormatDTD(xmlTextWriterPtr writer,
 
3080
                             const xmlChar * name,
 
3081
                             const xmlChar * pubid,
 
3082
                             const xmlChar * sysid,
 
3083
                             const char *format, va_list argptr)
 
3084
{
 
3085
    int rc;
 
3086
    xmlChar *buf;
 
3087
 
 
3088
    if (writer == NULL)
 
3089
        return -1;
 
3090
 
 
3091
    buf = xmlTextWriterVSprintf(format, argptr);
 
3092
    if (buf == NULL)
 
3093
        return -1;
 
3094
 
 
3095
    rc = xmlTextWriterWriteDTD(writer, name, pubid, sysid, buf);
 
3096
 
 
3097
    xmlFree(buf);
 
3098
    return rc;
 
3099
}
 
3100
 
 
3101
/**
 
3102
 * xmlTextWriterWriteDTD:
 
3103
 * @writer:  the xmlTextWriterPtr
 
3104
 * @name:  the name of the DTD
 
3105
 * @pubid:  the public identifier, which is an alternative to the system identifier
 
3106
 * @sysid:  the system identifier, which is the URI of the DTD
 
3107
 * @subset:  string content of the DTD
 
3108
 *
 
3109
 * Write a DTD.
 
3110
 *
 
3111
 * Returns the bytes written (may be 0 because of buffering) or -1 in case of error
 
3112
 */
 
3113
int
 
3114
xmlTextWriterWriteDTD(xmlTextWriterPtr writer,
 
3115
                      const xmlChar * name,
 
3116
                      const xmlChar * pubid,
 
3117
                      const xmlChar * sysid, const xmlChar * subset)
 
3118
{
 
3119
    int count;
 
3120
    int sum;
 
3121
 
 
3122
    sum = 0;
 
3123
    count = xmlTextWriterStartDTD(writer, name, pubid, sysid);
 
3124
    if (count == -1)
 
3125
        return -1;
 
3126
    sum += count;
 
3127
    if (subset != 0) {
 
3128
        count = xmlTextWriterWriteString(writer, subset);
 
3129
        if (count == -1)
 
3130
            return -1;
 
3131
        sum += count;
 
3132
    }
 
3133
    count = xmlTextWriterEndDTD(writer);
 
3134
    if (count == -1)
 
3135
        return -1;
 
3136
    sum += count;
 
3137
 
 
3138
    return sum;
 
3139
}
 
3140
 
 
3141
/**
 
3142
 * xmlTextWriterStartDTDElement:
 
3143
 * @writer:  the xmlTextWriterPtr
 
3144
 * @name:  the name of the DTD element
 
3145
 *
 
3146
 * Start an xml DTD element.
 
3147
 *
 
3148
 * Returns the bytes written (may be 0 because of buffering) or -1 in case of error
 
3149
 */
 
3150
int
 
3151
xmlTextWriterStartDTDElement(xmlTextWriterPtr writer, const xmlChar * name)
 
3152
{
 
3153
    int count;
 
3154
    int sum;
 
3155
    xmlLinkPtr lk;
 
3156
    xmlTextWriterStackEntry *p;
 
3157
 
 
3158
    if (writer == NULL || name == NULL || *name == '\0')
 
3159
        return -1;
 
3160
 
 
3161
    sum = 0;
 
3162
    lk = xmlListFront(writer->nodes);
 
3163
    if (lk == 0) {
 
3164
        return -1;
 
3165
    }
 
3166
 
 
3167
    p = (xmlTextWriterStackEntry *) xmlLinkGetData(lk);
 
3168
    if (p != 0) {
 
3169
        switch (p->state) {
 
3170
            case XML_TEXTWRITER_DTD:
 
3171
                count = xmlOutputBufferWriteString(writer->out, " [");
 
3172
                if (count < 0)
 
3173
                    return -1;
 
3174
                sum += count;
 
3175
                if (writer->indent) {
 
3176
                    count = xmlOutputBufferWriteString(writer->out, "\n");
 
3177
                    if (count < 0)
 
3178
                        return -1;
 
3179
                    sum += count;
 
3180
                }
 
3181
                p->state = XML_TEXTWRITER_DTD_TEXT;
 
3182
                /* fallthrough */
 
3183
            case XML_TEXTWRITER_DTD_TEXT:
 
3184
            case XML_TEXTWRITER_NONE:
 
3185
                break;
 
3186
            default:
 
3187
                return -1;
 
3188
        }
 
3189
    }
 
3190
 
 
3191
    p = (xmlTextWriterStackEntry *)
 
3192
        xmlMalloc(sizeof(xmlTextWriterStackEntry));
 
3193
    if (p == 0) {
 
3194
        xmlWriterErrMsg(writer, XML_ERR_NO_MEMORY,
 
3195
                        "xmlTextWriterStartDTDElement : out of memory!\n");
 
3196
        return -1;
 
3197
    }
 
3198
 
 
3199
    p->name = xmlStrdup(name);
 
3200
    if (p->name == 0) {
 
3201
        xmlWriterErrMsg(writer, XML_ERR_NO_MEMORY,
 
3202
                        "xmlTextWriterStartDTDElement : out of memory!\n");
 
3203
        xmlFree(p);
 
3204
        return -1;
 
3205
    }
 
3206
    p->state = XML_TEXTWRITER_DTD_ELEM;
 
3207
 
 
3208
    xmlListPushFront(writer->nodes, p);
 
3209
 
 
3210
    if (writer->indent) {
 
3211
        count = xmlTextWriterWriteIndent(writer);
 
3212
        if (count < 0)
 
3213
            return -1;
 
3214
        sum += count;
 
3215
    }
 
3216
 
 
3217
    count = xmlOutputBufferWriteString(writer->out, "<!ELEMENT ");
 
3218
    if (count < 0)
 
3219
        return -1;
 
3220
    sum += count;
 
3221
    count = xmlOutputBufferWriteString(writer->out, (const char *) name);
 
3222
    if (count < 0)
 
3223
        return -1;
 
3224
    sum += count;
 
3225
 
 
3226
    return sum;
 
3227
}
 
3228
 
 
3229
/**
 
3230
 * xmlTextWriterEndDTDElement:
 
3231
 * @writer:  the xmlTextWriterPtr
 
3232
 *
 
3233
 * End an xml DTD element.
 
3234
 *
 
3235
 * Returns the bytes written (may be 0 because of buffering) or -1 in case of error
 
3236
 */
 
3237
int
 
3238
xmlTextWriterEndDTDElement(xmlTextWriterPtr writer)
 
3239
{
 
3240
    int count;
 
3241
    int sum;
 
3242
    xmlLinkPtr lk;
 
3243
    xmlTextWriterStackEntry *p;
 
3244
 
 
3245
    if (writer == NULL)
 
3246
        return -1;
 
3247
 
 
3248
    sum = 0;
 
3249
    lk = xmlListFront(writer->nodes);
 
3250
    if (lk == 0)
 
3251
        return -1;
 
3252
 
 
3253
    p = (xmlTextWriterStackEntry *) xmlLinkGetData(lk);
 
3254
    if (p == 0)
 
3255
        return -1;
 
3256
 
 
3257
    switch (p->state) {
 
3258
        case XML_TEXTWRITER_DTD_ELEM:
 
3259
        case XML_TEXTWRITER_DTD_ELEM_TEXT:
 
3260
            count = xmlOutputBufferWriteString(writer->out, ">");
 
3261
            if (count < 0)
 
3262
                return -1;
 
3263
            sum += count;
 
3264
            break;
 
3265
        default:
 
3266
            return -1;
 
3267
    }
 
3268
 
 
3269
    if (writer->indent) {
 
3270
        count = xmlOutputBufferWriteString(writer->out, "\n");
 
3271
        if (count < 0)
 
3272
            return -1;
 
3273
        sum += count;
 
3274
    }
 
3275
 
 
3276
    xmlListPopFront(writer->nodes);
 
3277
    return sum;
 
3278
}
 
3279
 
 
3280
/**
 
3281
 * xmlTextWriterWriteFormatDTDElement:
 
3282
 * @writer:  the xmlTextWriterPtr
 
3283
 * @name:  the name of the DTD element
 
3284
 * @format:  format string (see printf)
 
3285
 * @...:  extra parameters for the format
 
3286
 *
 
3287
 * Write a formatted DTD element.
 
3288
 *
 
3289
 * Returns the bytes written (may be 0 because of buffering) or -1 in case of error
 
3290
 */
 
3291
int XMLCDECL
 
3292
xmlTextWriterWriteFormatDTDElement(xmlTextWriterPtr writer,
 
3293
                                   const xmlChar * name,
 
3294
                                   const char *format, ...)
 
3295
{
 
3296
    int rc;
 
3297
    va_list ap;
 
3298
 
 
3299
    va_start(ap, format);
 
3300
 
 
3301
    rc = xmlTextWriterWriteVFormatDTDElement(writer, name, format, ap);
 
3302
 
 
3303
    va_end(ap);
 
3304
    return rc;
 
3305
}
 
3306
 
 
3307
/**
 
3308
 * xmlTextWriterWriteVFormatDTDElement:
 
3309
 * @writer:  the xmlTextWriterPtr
 
3310
 * @name:  the name of the DTD element
 
3311
 * @format:  format string (see printf)
 
3312
 * @argptr:  pointer to the first member of the variable argument list.
 
3313
 *
 
3314
 * Write a formatted DTD element.
 
3315
 *
 
3316
 * Returns the bytes written (may be 0 because of buffering) or -1 in case of error
 
3317
 */
 
3318
int
 
3319
xmlTextWriterWriteVFormatDTDElement(xmlTextWriterPtr writer,
 
3320
                                    const xmlChar * name,
 
3321
                                    const char *format, va_list argptr)
 
3322
{
 
3323
    int rc;
 
3324
    xmlChar *buf;
 
3325
 
 
3326
    if (writer == NULL)
 
3327
        return -1;
 
3328
 
 
3329
    buf = xmlTextWriterVSprintf(format, argptr);
 
3330
    if (buf == NULL)
 
3331
        return -1;
 
3332
 
 
3333
    rc = xmlTextWriterWriteDTDElement(writer, name, buf);
 
3334
 
 
3335
    xmlFree(buf);
 
3336
    return rc;
 
3337
}
 
3338
 
 
3339
/**
 
3340
 * xmlTextWriterWriteDTDElement:
 
3341
 * @writer:  the xmlTextWriterPtr
 
3342
 * @name:  the name of the DTD element
 
3343
 * @content:  content of the element
 
3344
 *
 
3345
 * Write a DTD element.
 
3346
 *
 
3347
 * Returns the bytes written (may be 0 because of buffering) or -1 in case of error
 
3348
 */
 
3349
int
 
3350
xmlTextWriterWriteDTDElement(xmlTextWriterPtr writer,
 
3351
                             const xmlChar * name, const xmlChar * content)
 
3352
{
 
3353
    int count;
 
3354
    int sum;
 
3355
 
 
3356
    if (content == NULL)
 
3357
        return -1;
 
3358
 
 
3359
    sum = 0;
 
3360
    count = xmlTextWriterStartDTDElement(writer, name);
 
3361
    if (count == -1)
 
3362
        return -1;
 
3363
    sum += count;
 
3364
 
 
3365
    count = xmlTextWriterWriteString(writer, content);
 
3366
    if (count == -1)
 
3367
        return -1;
 
3368
    sum += count;
 
3369
 
 
3370
    count = xmlTextWriterEndDTDElement(writer);
 
3371
    if (count == -1)
 
3372
        return -1;
 
3373
    sum += count;
 
3374
 
 
3375
    return sum;
 
3376
}
 
3377
 
 
3378
/**
 
3379
 * xmlTextWriterStartDTDAttlist:
 
3380
 * @writer:  the xmlTextWriterPtr
 
3381
 * @name:  the name of the DTD ATTLIST
 
3382
 *
 
3383
 * Start an xml DTD ATTLIST.
 
3384
 *
 
3385
 * Returns the bytes written (may be 0 because of buffering) or -1 in case of error
 
3386
 */
 
3387
int
 
3388
xmlTextWriterStartDTDAttlist(xmlTextWriterPtr writer, const xmlChar * name)
 
3389
{
 
3390
    int count;
 
3391
    int sum;
 
3392
    xmlLinkPtr lk;
 
3393
    xmlTextWriterStackEntry *p;
 
3394
 
 
3395
    if (writer == NULL || name == NULL || *name == '\0')
 
3396
        return -1;
 
3397
 
 
3398
    sum = 0;
 
3399
    lk = xmlListFront(writer->nodes);
 
3400
    if (lk == 0) {
 
3401
        return -1;
 
3402
    }
 
3403
 
 
3404
    p = (xmlTextWriterStackEntry *) xmlLinkGetData(lk);
 
3405
    if (p != 0) {
 
3406
        switch (p->state) {
 
3407
            case XML_TEXTWRITER_DTD:
 
3408
                count = xmlOutputBufferWriteString(writer->out, " [");
 
3409
                if (count < 0)
 
3410
                    return -1;
 
3411
                sum += count;
 
3412
                if (writer->indent) {
 
3413
                    count = xmlOutputBufferWriteString(writer->out, "\n");
 
3414
                    if (count < 0)
 
3415
                        return -1;
 
3416
                    sum += count;
 
3417
                }
 
3418
                p->state = XML_TEXTWRITER_DTD_TEXT;
 
3419
                /* fallthrough */
 
3420
            case XML_TEXTWRITER_DTD_TEXT:
 
3421
            case XML_TEXTWRITER_NONE:
 
3422
                break;
 
3423
            default:
 
3424
                return -1;
 
3425
        }
 
3426
    }
 
3427
 
 
3428
    p = (xmlTextWriterStackEntry *)
 
3429
        xmlMalloc(sizeof(xmlTextWriterStackEntry));
 
3430
    if (p == 0) {
 
3431
        xmlWriterErrMsg(writer, XML_ERR_NO_MEMORY,
 
3432
                        "xmlTextWriterStartDTDAttlist : out of memory!\n");
 
3433
        return -1;
 
3434
    }
 
3435
 
 
3436
    p->name = xmlStrdup(name);
 
3437
    if (p->name == 0) {
 
3438
        xmlWriterErrMsg(writer, XML_ERR_NO_MEMORY,
 
3439
                        "xmlTextWriterStartDTDAttlist : out of memory!\n");
 
3440
        xmlFree(p);
 
3441
        return -1;
 
3442
    }
 
3443
    p->state = XML_TEXTWRITER_DTD_ATTL;
 
3444
 
 
3445
    xmlListPushFront(writer->nodes, p);
 
3446
 
 
3447
    if (writer->indent) {
 
3448
        count = xmlTextWriterWriteIndent(writer);
 
3449
        if (count < 0)
 
3450
            return -1;
 
3451
        sum += count;
 
3452
    }
 
3453
 
 
3454
    count = xmlOutputBufferWriteString(writer->out, "<!ATTLIST ");
 
3455
    if (count < 0)
 
3456
        return -1;
 
3457
    sum += count;
 
3458
    count = xmlOutputBufferWriteString(writer->out, (const char *) name);
 
3459
    if (count < 0)
 
3460
        return -1;
 
3461
    sum += count;
 
3462
 
 
3463
    return sum;
 
3464
}
 
3465
 
 
3466
/**
 
3467
 * xmlTextWriterEndDTDAttlist:
 
3468
 * @writer:  the xmlTextWriterPtr
 
3469
 *
 
3470
 * End an xml DTD attribute list.
 
3471
 *
 
3472
 * Returns the bytes written (may be 0 because of buffering) or -1 in case of error
 
3473
 */
 
3474
int
 
3475
xmlTextWriterEndDTDAttlist(xmlTextWriterPtr writer)
 
3476
{
 
3477
    int count;
 
3478
    int sum;
 
3479
    xmlLinkPtr lk;
 
3480
    xmlTextWriterStackEntry *p;
 
3481
 
 
3482
    if (writer == NULL)
 
3483
        return -1;
 
3484
 
 
3485
    sum = 0;
 
3486
    lk = xmlListFront(writer->nodes);
 
3487
    if (lk == 0)
 
3488
        return -1;
 
3489
 
 
3490
    p = (xmlTextWriterStackEntry *) xmlLinkGetData(lk);
 
3491
    if (p == 0)
 
3492
        return -1;
 
3493
 
 
3494
    switch (p->state) {
 
3495
        case XML_TEXTWRITER_DTD_ATTL:
 
3496
        case XML_TEXTWRITER_DTD_ATTL_TEXT:
 
3497
            count = xmlOutputBufferWriteString(writer->out, ">");
 
3498
            if (count < 0)
 
3499
                return -1;
 
3500
            sum += count;
 
3501
            break;
 
3502
        default:
 
3503
            return -1;
 
3504
    }
 
3505
 
 
3506
    if (writer->indent) {
 
3507
        count = xmlOutputBufferWriteString(writer->out, "\n");
 
3508
        if (count < 0)
 
3509
            return -1;
 
3510
        sum += count;
 
3511
    }
 
3512
 
 
3513
    xmlListPopFront(writer->nodes);
 
3514
    return sum;
 
3515
}
 
3516
 
 
3517
/**
 
3518
 * xmlTextWriterWriteFormatDTDAttlist:
 
3519
 * @writer:  the xmlTextWriterPtr
 
3520
 * @name:  the name of the DTD ATTLIST
 
3521
 * @format:  format string (see printf)
 
3522
 * @...:  extra parameters for the format
 
3523
 *
 
3524
 * Write a formatted DTD ATTLIST.
 
3525
 *
 
3526
 * Returns the bytes written (may be 0 because of buffering) or -1 in case of error
 
3527
 */
 
3528
int XMLCDECL
 
3529
xmlTextWriterWriteFormatDTDAttlist(xmlTextWriterPtr writer,
 
3530
                                   const xmlChar * name,
 
3531
                                   const char *format, ...)
 
3532
{
 
3533
    int rc;
 
3534
    va_list ap;
 
3535
 
 
3536
    va_start(ap, format);
 
3537
 
 
3538
    rc = xmlTextWriterWriteVFormatDTDAttlist(writer, name, format, ap);
 
3539
 
 
3540
    va_end(ap);
 
3541
    return rc;
 
3542
}
 
3543
 
 
3544
/**
 
3545
 * xmlTextWriterWriteVFormatDTDAttlist:
 
3546
 * @writer:  the xmlTextWriterPtr
 
3547
 * @name:  the name of the DTD ATTLIST
 
3548
 * @format:  format string (see printf)
 
3549
 * @argptr:  pointer to the first member of the variable argument list.
 
3550
 *
 
3551
 * Write a formatted DTD ATTLIST.
 
3552
 *
 
3553
 * Returns the bytes written (may be 0 because of buffering) or -1 in case of error
 
3554
 */
 
3555
int
 
3556
xmlTextWriterWriteVFormatDTDAttlist(xmlTextWriterPtr writer,
 
3557
                                    const xmlChar * name,
 
3558
                                    const char *format, va_list argptr)
 
3559
{
 
3560
    int rc;
 
3561
    xmlChar *buf;
 
3562
 
 
3563
    if (writer == NULL)
 
3564
        return -1;
 
3565
 
 
3566
    buf = xmlTextWriterVSprintf(format, argptr);
 
3567
    if (buf == NULL)
 
3568
        return -1;
 
3569
 
 
3570
    rc = xmlTextWriterWriteDTDAttlist(writer, name, buf);
 
3571
 
 
3572
    xmlFree(buf);
 
3573
    return rc;
 
3574
}
 
3575
 
 
3576
/**
 
3577
 * xmlTextWriterWriteDTDAttlist:
 
3578
 * @writer:  the xmlTextWriterPtr
 
3579
 * @name:  the name of the DTD ATTLIST
 
3580
 * @content:  content of the ATTLIST
 
3581
 *
 
3582
 * Write a DTD ATTLIST.
 
3583
 *
 
3584
 * Returns the bytes written (may be 0 because of buffering) or -1 in case of error
 
3585
 */
 
3586
int
 
3587
xmlTextWriterWriteDTDAttlist(xmlTextWriterPtr writer,
 
3588
                             const xmlChar * name, const xmlChar * content)
 
3589
{
 
3590
    int count;
 
3591
    int sum;
 
3592
 
 
3593
    if (content == NULL)
 
3594
        return -1;
 
3595
 
 
3596
    sum = 0;
 
3597
    count = xmlTextWriterStartDTDAttlist(writer, name);
 
3598
    if (count == -1)
 
3599
        return -1;
 
3600
    sum += count;
 
3601
 
 
3602
    count = xmlTextWriterWriteString(writer, content);
 
3603
    if (count == -1)
 
3604
        return -1;
 
3605
    sum += count;
 
3606
 
 
3607
    count = xmlTextWriterEndDTDAttlist(writer);
 
3608
    if (count == -1)
 
3609
        return -1;
 
3610
    sum += count;
 
3611
 
 
3612
    return sum;
 
3613
}
 
3614
 
 
3615
/**
 
3616
 * xmlTextWriterStartDTDEntity:
 
3617
 * @writer:  the xmlTextWriterPtr
 
3618
 * @pe:  TRUE if this is a parameter entity, FALSE if not
 
3619
 * @name:  the name of the DTD ATTLIST
 
3620
 *
 
3621
 * Start an xml DTD ATTLIST.
 
3622
 *
 
3623
 * Returns the bytes written (may be 0 because of buffering) or -1 in case of error
 
3624
 */
 
3625
int
 
3626
xmlTextWriterStartDTDEntity(xmlTextWriterPtr writer,
 
3627
                            int pe, const xmlChar * name)
 
3628
{
 
3629
    int count;
 
3630
    int sum;
 
3631
    xmlLinkPtr lk;
 
3632
    xmlTextWriterStackEntry *p;
 
3633
 
 
3634
    if (writer == NULL || name == NULL || *name == '\0')
 
3635
        return -1;
 
3636
 
 
3637
    sum = 0;
 
3638
    lk = xmlListFront(writer->nodes);
 
3639
    if (lk != 0) {
 
3640
 
 
3641
        p = (xmlTextWriterStackEntry *) xmlLinkGetData(lk);
 
3642
        if (p != 0) {
 
3643
            switch (p->state) {
 
3644
                case XML_TEXTWRITER_DTD:
 
3645
                    count = xmlOutputBufferWriteString(writer->out, " [");
 
3646
                    if (count < 0)
 
3647
                        return -1;
 
3648
                    sum += count;
 
3649
                    if (writer->indent) {
 
3650
                        count =
 
3651
                            xmlOutputBufferWriteString(writer->out, "\n");
 
3652
                        if (count < 0)
 
3653
                            return -1;
 
3654
                        sum += count;
 
3655
                    }
 
3656
                    p->state = XML_TEXTWRITER_DTD_TEXT;
 
3657
                    /* fallthrough */
 
3658
                case XML_TEXTWRITER_DTD_TEXT:
 
3659
                case XML_TEXTWRITER_NONE:
 
3660
                    break;
 
3661
                default:
 
3662
                    return -1;
 
3663
            }
 
3664
        }
 
3665
    }
 
3666
 
 
3667
    p = (xmlTextWriterStackEntry *)
 
3668
        xmlMalloc(sizeof(xmlTextWriterStackEntry));
 
3669
    if (p == 0) {
 
3670
        xmlWriterErrMsg(writer, XML_ERR_NO_MEMORY,
 
3671
                        "xmlTextWriterStartDTDElement : out of memory!\n");
 
3672
        return -1;
 
3673
    }
 
3674
 
 
3675
    p->name = xmlStrdup(name);
 
3676
    if (p->name == 0) {
 
3677
        xmlWriterErrMsg(writer, XML_ERR_NO_MEMORY,
 
3678
                        "xmlTextWriterStartDTDElement : out of memory!\n");
 
3679
        xmlFree(p);
 
3680
        return -1;
 
3681
    }
 
3682
 
 
3683
    if (pe != 0)
 
3684
        p->state = XML_TEXTWRITER_DTD_PENT;
 
3685
    else
 
3686
        p->state = XML_TEXTWRITER_DTD_ENTY;
 
3687
 
 
3688
    xmlListPushFront(writer->nodes, p);
 
3689
 
 
3690
    if (writer->indent) {
 
3691
        count = xmlTextWriterWriteIndent(writer);
 
3692
        if (count < 0)
 
3693
            return -1;
 
3694
        sum += count;
 
3695
    }
 
3696
 
 
3697
    count = xmlOutputBufferWriteString(writer->out, "<!ENTITY ");
 
3698
    if (count < 0)
 
3699
        return -1;
 
3700
    sum += count;
 
3701
 
 
3702
    if (pe != 0) {
 
3703
        count = xmlOutputBufferWriteString(writer->out, "% ");
 
3704
        if (count < 0)
 
3705
            return -1;
 
3706
        sum += count;
 
3707
    }
 
3708
 
 
3709
    count = xmlOutputBufferWriteString(writer->out, (const char *) name);
 
3710
    if (count < 0)
 
3711
        return -1;
 
3712
    sum += count;
 
3713
 
 
3714
    return sum;
 
3715
}
 
3716
 
 
3717
/**
 
3718
 * xmlTextWriterEndDTDEntity:
 
3719
 * @writer:  the xmlTextWriterPtr
 
3720
 *
 
3721
 * End an xml DTD entity.
 
3722
 *
 
3723
 * Returns the bytes written (may be 0 because of buffering) or -1 in case of error
 
3724
 */
 
3725
int
 
3726
xmlTextWriterEndDTDEntity(xmlTextWriterPtr writer)
 
3727
{
 
3728
    int count;
 
3729
    int sum;
 
3730
    xmlLinkPtr lk;
 
3731
    xmlTextWriterStackEntry *p;
 
3732
 
 
3733
    if (writer == NULL)
 
3734
        return -1;
 
3735
 
 
3736
    sum = 0;
 
3737
    lk = xmlListFront(writer->nodes);
 
3738
    if (lk == 0)
 
3739
        return -1;
 
3740
 
 
3741
    p = (xmlTextWriterStackEntry *) xmlLinkGetData(lk);
 
3742
    if (p == 0)
 
3743
        return -1;
 
3744
 
 
3745
    switch (p->state) {
 
3746
        case XML_TEXTWRITER_DTD_ENTY_TEXT:
 
3747
            count = xmlOutputBufferWrite(writer->out, 1, &writer->qchar);
 
3748
            if (count < 0)
 
3749
                return -1;
 
3750
            sum += count;
 
3751
        case XML_TEXTWRITER_DTD_ENTY:
 
3752
        case XML_TEXTWRITER_DTD_PENT:
 
3753
            count = xmlOutputBufferWriteString(writer->out, ">");
 
3754
            if (count < 0)
 
3755
                return -1;
 
3756
            sum += count;
 
3757
            break;
 
3758
        default:
 
3759
            return -1;
 
3760
    }
 
3761
 
 
3762
    if (writer->indent) {
 
3763
        count = xmlOutputBufferWriteString(writer->out, "\n");
 
3764
        if (count < 0)
 
3765
            return -1;
 
3766
        sum += count;
 
3767
    }
 
3768
 
 
3769
    xmlListPopFront(writer->nodes);
 
3770
    return sum;
 
3771
}
 
3772
 
 
3773
/**
 
3774
 * xmlTextWriterWriteFormatDTDInternalEntity:
 
3775
 * @writer:  the xmlTextWriterPtr
 
3776
 * @pe:  TRUE if this is a parameter entity, FALSE if not
 
3777
 * @name:  the name of the DTD entity
 
3778
 * @format:  format string (see printf)
 
3779
 * @...:  extra parameters for the format
 
3780
 *
 
3781
 * Write a formatted DTD internal entity.
 
3782
 *
 
3783
 * Returns the bytes written (may be 0 because of buffering) or -1 in case of error
 
3784
 */
 
3785
int XMLCDECL
 
3786
xmlTextWriterWriteFormatDTDInternalEntity(xmlTextWriterPtr writer,
 
3787
                                          int pe,
 
3788
                                          const xmlChar * name,
 
3789
                                          const char *format, ...)
 
3790
{
 
3791
    int rc;
 
3792
    va_list ap;
 
3793
 
 
3794
    va_start(ap, format);
 
3795
 
 
3796
    rc = xmlTextWriterWriteVFormatDTDInternalEntity(writer, pe, name,
 
3797
                                                    format, ap);
 
3798
 
 
3799
    va_end(ap);
 
3800
    return rc;
 
3801
}
 
3802
 
 
3803
/**
 
3804
 * xmlTextWriterWriteVFormatDTDInternalEntity:
 
3805
 * @writer:  the xmlTextWriterPtr
 
3806
 * @pe:  TRUE if this is a parameter entity, FALSE if not
 
3807
 * @name:  the name of the DTD entity
 
3808
 * @format:  format string (see printf)
 
3809
 * @argptr:  pointer to the first member of the variable argument list.
 
3810
 *
 
3811
 * Write a formatted DTD internal entity.
 
3812
 *
 
3813
 * Returns the bytes written (may be 0 because of buffering) or -1 in case of error
 
3814
 */
 
3815
int
 
3816
xmlTextWriterWriteVFormatDTDInternalEntity(xmlTextWriterPtr writer,
 
3817
                                           int pe,
 
3818
                                           const xmlChar * name,
 
3819
                                           const char *format,
 
3820
                                           va_list argptr)
 
3821
{
 
3822
    int rc;
 
3823
    xmlChar *buf;
 
3824
 
 
3825
    if (writer == NULL)
 
3826
        return -1;
 
3827
 
 
3828
    buf = xmlTextWriterVSprintf(format, argptr);
 
3829
    if (buf == NULL)
 
3830
        return -1;
 
3831
 
 
3832
    rc = xmlTextWriterWriteDTDInternalEntity(writer, pe, name, buf);
 
3833
 
 
3834
    xmlFree(buf);
 
3835
    return rc;
 
3836
}
 
3837
 
 
3838
/**
 
3839
 * xmlTextWriterWriteDTDEntity:
 
3840
 * @writer:  the xmlTextWriterPtr
 
3841
 * @pe:  TRUE if this is a parameter entity, FALSE if not
 
3842
 * @name:  the name of the DTD entity
 
3843
 * @pubid:  the public identifier, which is an alternative to the system identifier
 
3844
 * @sysid:  the system identifier, which is the URI of the DTD
 
3845
 * @ndataid:  the xml notation name.
 
3846
 * @content:  content of the entity
 
3847
 *
 
3848
 * Write a DTD entity.
 
3849
 *
 
3850
 * Returns the bytes written (may be 0 because of buffering) or -1 in case of error
 
3851
 */
 
3852
int
 
3853
xmlTextWriterWriteDTDEntity(xmlTextWriterPtr writer,
 
3854
                            int pe,
 
3855
                            const xmlChar * name,
 
3856
                            const xmlChar * pubid,
 
3857
                            const xmlChar * sysid,
 
3858
                            const xmlChar * ndataid,
 
3859
                            const xmlChar * content)
 
3860
{
 
3861
    if ((content == NULL) && (pubid == NULL) && (sysid == NULL))
 
3862
        return -1;
 
3863
    if ((pe != 0) && (ndataid != NULL))
 
3864
        return -1;
 
3865
 
 
3866
    if ((pubid == NULL) && (sysid == NULL))
 
3867
        return xmlTextWriterWriteDTDInternalEntity(writer, pe, name,
 
3868
                                                   content);
 
3869
 
 
3870
    return xmlTextWriterWriteDTDExternalEntity(writer, pe, name, pubid,
 
3871
                                               sysid, ndataid);
 
3872
}
 
3873
 
 
3874
/**
 
3875
 * xmlTextWriterWriteDTDInternalEntity:
 
3876
 * @writer:  the xmlTextWriterPtr
 
3877
 * @pe:  TRUE if this is a parameter entity, FALSE if not
 
3878
 * @name:  the name of the DTD entity
 
3879
 * @content:  content of the entity
 
3880
 *
 
3881
 * Write a DTD internal entity.
 
3882
 *
 
3883
 * Returns the bytes written (may be 0 because of buffering) or -1 in case of error
 
3884
 */
 
3885
int
 
3886
xmlTextWriterWriteDTDInternalEntity(xmlTextWriterPtr writer,
 
3887
                                    int pe,
 
3888
                                    const xmlChar * name,
 
3889
                                    const xmlChar * content)
 
3890
{
 
3891
    int count;
 
3892
    int sum;
 
3893
 
 
3894
    if ((name == NULL) || (*name == '\0') || (content == NULL))
 
3895
        return -1;
 
3896
 
 
3897
    sum = 0;
 
3898
    count = xmlTextWriterStartDTDEntity(writer, pe, name);
 
3899
    if (count == -1)
 
3900
        return -1;
 
3901
    sum += count;
 
3902
 
 
3903
    count = xmlTextWriterWriteString(writer, content);
 
3904
    if (count == -1)
 
3905
        return -1;
 
3906
    sum += count;
 
3907
 
 
3908
    count = xmlTextWriterEndDTDEntity(writer);
 
3909
    if (count == -1)
 
3910
        return -1;
 
3911
    sum += count;
 
3912
 
 
3913
    return sum;
 
3914
}
 
3915
 
 
3916
/**
 
3917
 * xmlTextWriterWriteDTDExternalEntity:
 
3918
 * @writer:  the xmlTextWriterPtr
 
3919
 * @pe:  TRUE if this is a parameter entity, FALSE if not
 
3920
 * @name:  the name of the DTD entity
 
3921
 * @pubid:  the public identifier, which is an alternative to the system identifier
 
3922
 * @sysid:  the system identifier, which is the URI of the DTD
 
3923
 * @ndataid:  the xml notation name.
 
3924
 *
 
3925
 * Write a DTD external entity. The entity must have been started with xmlTextWriterStartDTDEntity
 
3926
 *
 
3927
 * Returns the bytes written (may be 0 because of buffering) or -1 in case of error
 
3928
 */
 
3929
int
 
3930
xmlTextWriterWriteDTDExternalEntity(xmlTextWriterPtr writer,
 
3931
                                    int pe,
 
3932
                                    const xmlChar * name,
 
3933
                                    const xmlChar * pubid,
 
3934
                                    const xmlChar * sysid,
 
3935
                                    const xmlChar * ndataid)
 
3936
{
 
3937
    int count;
 
3938
    int sum;
 
3939
 
 
3940
    if (((pubid == NULL) && (sysid == NULL)))
 
3941
        return -1;
 
3942
    if ((pe != 0) && (ndataid != NULL))
 
3943
        return -1;
 
3944
 
 
3945
    sum = 0;
 
3946
    count = xmlTextWriterStartDTDEntity(writer, pe, name);
 
3947
    if (count == -1)
 
3948
        return -1;
 
3949
    sum += count;
 
3950
 
 
3951
    count =
 
3952
        xmlTextWriterWriteDTDExternalEntityContents(writer, pubid, sysid,
 
3953
                                                    ndataid);
 
3954
    if (count < 0)
 
3955
        return -1;
 
3956
    sum += count;
 
3957
 
 
3958
    count = xmlTextWriterEndDTDEntity(writer);
 
3959
    if (count == -1)
 
3960
        return -1;
 
3961
    sum += count;
 
3962
 
 
3963
    return sum;
 
3964
}
 
3965
 
 
3966
/**
 
3967
 * xmlTextWriterWriteDTDExternalEntityContents:
 
3968
 * @writer:  the xmlTextWriterPtr
 
3969
 * @pubid:  the public identifier, which is an alternative to the system identifier
 
3970
 * @sysid:  the system identifier, which is the URI of the DTD
 
3971
 * @ndataid:  the xml notation name.
 
3972
 *
 
3973
 * Write the contents of a DTD external entity.
 
3974
 *
 
3975
 * Returns the bytes written (may be 0 because of buffering) or -1 in case of error
 
3976
 */
 
3977
int
 
3978
xmlTextWriterWriteDTDExternalEntityContents(xmlTextWriterPtr writer,
 
3979
                                            const xmlChar * pubid,
 
3980
                                            const xmlChar * sysid,
 
3981
                                            const xmlChar * ndataid)
 
3982
{
 
3983
    int count;
 
3984
    int sum;
 
3985
    xmlLinkPtr lk;
 
3986
    xmlTextWriterStackEntry *p;
 
3987
 
 
3988
    if (writer == NULL) {
 
3989
        xmlWriterErrMsg(writer, XML_ERR_INTERNAL_ERROR,
 
3990
                        "xmlTextWriterWriteDTDExternalEntityContents: xmlTextWriterPtr invalid!\n");
 
3991
        return -1;
 
3992
    }
 
3993
 
 
3994
    sum = 0;
 
3995
    lk = xmlListFront(writer->nodes);
 
3996
    if (lk == 0) {
 
3997
        xmlWriterErrMsg(writer, XML_ERR_INTERNAL_ERROR,
 
3998
                        "xmlTextWriterWriteDTDExternalEntityContents: you must call xmlTextWriterStartDTDEntity before the call to this function!\n");
 
3999
        return -1;
 
4000
    }
 
4001
 
 
4002
    p = (xmlTextWriterStackEntry *) xmlLinkGetData(lk);
 
4003
    if (p == 0)
 
4004
        return -1;
 
4005
 
 
4006
    switch (p->state) {
 
4007
        case XML_TEXTWRITER_DTD_ENTY:
 
4008
            break;
 
4009
        case XML_TEXTWRITER_DTD_PENT:
 
4010
            if (ndataid != NULL) {
 
4011
                xmlWriterErrMsg(writer, XML_ERR_INTERNAL_ERROR,
 
4012
                                "xmlTextWriterWriteDTDExternalEntityContents: notation not allowed with parameter entities!\n");
 
4013
                return -1;
 
4014
            }
 
4015
            break;
 
4016
        default:
 
4017
            xmlWriterErrMsg(writer, XML_ERR_INTERNAL_ERROR,
 
4018
                            "xmlTextWriterWriteDTDExternalEntityContents: you must call xmlTextWriterStartDTDEntity before the call to this function!\n");
 
4019
            return -1;
 
4020
    }
 
4021
 
 
4022
    if (pubid != 0) {
 
4023
        if (sysid == 0) {
 
4024
            xmlWriterErrMsg(writer, XML_ERR_INTERNAL_ERROR,
 
4025
                            "xmlTextWriterWriteDTDExternalEntityContents: system identifier needed!\n");
 
4026
            return -1;
 
4027
        }
 
4028
 
 
4029
        count = xmlOutputBufferWriteString(writer->out, " PUBLIC ");
 
4030
        if (count < 0)
 
4031
            return -1;
 
4032
        sum += count;
 
4033
 
 
4034
        count = xmlOutputBufferWrite(writer->out, 1, &writer->qchar);
 
4035
        if (count < 0)
 
4036
            return -1;
 
4037
        sum += count;
 
4038
 
 
4039
        count =
 
4040
            xmlOutputBufferWriteString(writer->out, (const char *) pubid);
 
4041
        if (count < 0)
 
4042
            return -1;
 
4043
        sum += count;
 
4044
 
 
4045
        count = xmlOutputBufferWrite(writer->out, 1, &writer->qchar);
 
4046
        if (count < 0)
 
4047
            return -1;
 
4048
        sum += count;
 
4049
    }
 
4050
 
 
4051
    if (sysid != 0) {
 
4052
        if (pubid == 0) {
 
4053
            count = xmlOutputBufferWriteString(writer->out, " SYSTEM");
 
4054
            if (count < 0)
 
4055
                return -1;
 
4056
            sum += count;
 
4057
        }
 
4058
 
 
4059
        count = xmlOutputBufferWriteString(writer->out, " ");
 
4060
        if (count < 0)
 
4061
            return -1;
 
4062
        sum += count;
 
4063
 
 
4064
        count = xmlOutputBufferWrite(writer->out, 1, &writer->qchar);
 
4065
        if (count < 0)
 
4066
            return -1;
 
4067
        sum += count;
 
4068
 
 
4069
        count =
 
4070
            xmlOutputBufferWriteString(writer->out, (const char *) sysid);
 
4071
        if (count < 0)
 
4072
            return -1;
 
4073
        sum += count;
 
4074
 
 
4075
        count = xmlOutputBufferWrite(writer->out, 1, &writer->qchar);
 
4076
        if (count < 0)
 
4077
            return -1;
 
4078
        sum += count;
 
4079
    }
 
4080
 
 
4081
    if (ndataid != NULL) {
 
4082
        count = xmlOutputBufferWriteString(writer->out, " NDATA ");
 
4083
        if (count < 0)
 
4084
            return -1;
 
4085
        sum += count;
 
4086
 
 
4087
        count =
 
4088
            xmlOutputBufferWriteString(writer->out,
 
4089
                                       (const char *) ndataid);
 
4090
        if (count < 0)
 
4091
            return -1;
 
4092
        sum += count;
 
4093
    }
 
4094
 
 
4095
    return sum;
 
4096
}
 
4097
 
 
4098
/**
 
4099
 * xmlTextWriterWriteDTDNotation:
 
4100
 * @writer:  the xmlTextWriterPtr
 
4101
 * @name:  the name of the xml notation
 
4102
 * @pubid:  the public identifier, which is an alternative to the system identifier
 
4103
 * @sysid:  the system identifier, which is the URI of the DTD
 
4104
 *
 
4105
 * Write a DTD entity.
 
4106
 *
 
4107
 * Returns the bytes written (may be 0 because of buffering) or -1 in case of error
 
4108
 */
 
4109
int
 
4110
xmlTextWriterWriteDTDNotation(xmlTextWriterPtr writer,
 
4111
                              const xmlChar * name,
 
4112
                              const xmlChar * pubid, const xmlChar * sysid)
 
4113
{
 
4114
    int count;
 
4115
    int sum;
 
4116
    xmlLinkPtr lk;
 
4117
    xmlTextWriterStackEntry *p;
 
4118
 
 
4119
    if (writer == NULL || name == NULL || *name == '\0')
 
4120
        return -1;
 
4121
 
 
4122
    sum = 0;
 
4123
    lk = xmlListFront(writer->nodes);
 
4124
    if (lk == 0) {
 
4125
        return -1;
 
4126
    }
 
4127
 
 
4128
    p = (xmlTextWriterStackEntry *) xmlLinkGetData(lk);
 
4129
    if (p != 0) {
 
4130
        switch (p->state) {
 
4131
            case XML_TEXTWRITER_DTD:
 
4132
                count = xmlOutputBufferWriteString(writer->out, " [");
 
4133
                if (count < 0)
 
4134
                    return -1;
 
4135
                sum += count;
 
4136
                if (writer->indent) {
 
4137
                    count = xmlOutputBufferWriteString(writer->out, "\n");
 
4138
                    if (count < 0)
 
4139
                        return -1;
 
4140
                    sum += count;
 
4141
                }
 
4142
                p->state = XML_TEXTWRITER_DTD_TEXT;
 
4143
                /* fallthrough */
 
4144
            case XML_TEXTWRITER_DTD_TEXT:
 
4145
                break;
 
4146
            default:
 
4147
                return -1;
 
4148
        }
 
4149
    }
 
4150
 
 
4151
    if (writer->indent) {
 
4152
        count = xmlTextWriterWriteIndent(writer);
 
4153
        if (count < 0)
 
4154
            return -1;
 
4155
        sum += count;
 
4156
    }
 
4157
 
 
4158
    count = xmlOutputBufferWriteString(writer->out, "<!NOTATION ");
 
4159
    if (count < 0)
 
4160
        return -1;
 
4161
    sum += count;
 
4162
    count = xmlOutputBufferWriteString(writer->out, (const char *) name);
 
4163
    if (count < 0)
 
4164
        return -1;
 
4165
    sum += count;
 
4166
 
 
4167
    if (pubid != 0) {
 
4168
        count = xmlOutputBufferWriteString(writer->out, " PUBLIC ");
 
4169
        if (count < 0)
 
4170
            return -1;
 
4171
        sum += count;
 
4172
        count = xmlOutputBufferWrite(writer->out, 1, &writer->qchar);
 
4173
        if (count < 0)
 
4174
            return -1;
 
4175
        sum += count;
 
4176
        count =
 
4177
            xmlOutputBufferWriteString(writer->out, (const char *) pubid);
 
4178
        if (count < 0)
 
4179
            return -1;
 
4180
        sum += count;
 
4181
        count = xmlOutputBufferWrite(writer->out, 1, &writer->qchar);
 
4182
        if (count < 0)
 
4183
            return -1;
 
4184
        sum += count;
 
4185
    }
 
4186
 
 
4187
    if (sysid != 0) {
 
4188
        if (pubid == 0) {
 
4189
            count = xmlOutputBufferWriteString(writer->out, " SYSTEM");
 
4190
            if (count < 0)
 
4191
                return -1;
 
4192
            sum += count;
 
4193
        }
 
4194
        count = xmlOutputBufferWriteString(writer->out, " ");
 
4195
        if (count < 0)
 
4196
            return -1;
 
4197
        sum += count;
 
4198
        count = xmlOutputBufferWrite(writer->out, 1, &writer->qchar);
 
4199
        if (count < 0)
 
4200
            return -1;
 
4201
        sum += count;
 
4202
        count =
 
4203
            xmlOutputBufferWriteString(writer->out, (const char *) sysid);
 
4204
        if (count < 0)
 
4205
            return -1;
 
4206
        sum += count;
 
4207
        count = xmlOutputBufferWrite(writer->out, 1, &writer->qchar);
 
4208
        if (count < 0)
 
4209
            return -1;
 
4210
        sum += count;
 
4211
    }
 
4212
 
 
4213
    count = xmlOutputBufferWriteString(writer->out, ">");
 
4214
    if (count < 0)
 
4215
        return -1;
 
4216
    sum += count;
 
4217
 
 
4218
    return sum;
 
4219
}
 
4220
 
 
4221
/**
 
4222
 * xmlTextWriterFlush:
 
4223
 * @writer:  the xmlTextWriterPtr
 
4224
 *
 
4225
 * Flush the output buffer.
 
4226
 *
 
4227
 * Returns the bytes written (may be 0 because of buffering) or -1 in case of error
 
4228
 */
 
4229
int
 
4230
xmlTextWriterFlush(xmlTextWriterPtr writer)
 
4231
{
 
4232
    int count;
 
4233
 
 
4234
    if (writer == NULL)
 
4235
        return -1;
 
4236
 
 
4237
    if (writer->out == NULL)
 
4238
        count = 0;
 
4239
    else
 
4240
        count = xmlOutputBufferFlush(writer->out);
 
4241
 
 
4242
    return count;
 
4243
}
 
4244
 
 
4245
/**
 
4246
 * misc
 
4247
 */
 
4248
 
 
4249
/**
 
4250
 * xmlFreeTextWriterStackEntry:
 
4251
 * @lk:  the xmlLinkPtr
 
4252
 *
 
4253
 * Free callback for the xmlList.
 
4254
 */
 
4255
static void
 
4256
xmlFreeTextWriterStackEntry(xmlLinkPtr lk)
 
4257
{
 
4258
    xmlTextWriterStackEntry *p;
 
4259
 
 
4260
    p = (xmlTextWriterStackEntry *) xmlLinkGetData(lk);
 
4261
    if (p == 0)
 
4262
        return;
 
4263
 
 
4264
    if (p->name != 0)
 
4265
        xmlFree(p->name);
 
4266
    xmlFree(p);
 
4267
}
 
4268
 
 
4269
/**
 
4270
 * xmlCmpTextWriterStackEntry:
 
4271
 * @data0:  the first data
 
4272
 * @data1:  the second data
 
4273
 *
 
4274
 * Compare callback for the xmlList.
 
4275
 *
 
4276
 * Returns -1, 0, 1
 
4277
 */
 
4278
static int
 
4279
xmlCmpTextWriterStackEntry(const void *data0, const void *data1)
 
4280
{
 
4281
    xmlTextWriterStackEntry *p0;
 
4282
    xmlTextWriterStackEntry *p1;
 
4283
 
 
4284
    if (data0 == data1)
 
4285
        return 0;
 
4286
 
 
4287
    if (data0 == 0)
 
4288
        return -1;
 
4289
 
 
4290
    if (data1 == 0)
 
4291
        return 1;
 
4292
 
 
4293
    p0 = (xmlTextWriterStackEntry *) data0;
 
4294
    p1 = (xmlTextWriterStackEntry *) data1;
 
4295
 
 
4296
    return xmlStrcmp(p0->name, p1->name);
 
4297
}
 
4298
 
 
4299
/**
 
4300
 * misc
 
4301
 */
 
4302
 
 
4303
/**
 
4304
 * xmlTextWriterOutputNSDecl:
 
4305
 * @writer:  the xmlTextWriterPtr
 
4306
 *
 
4307
 * Output the current namespace declarations.
 
4308
 */
 
4309
static int
 
4310
xmlTextWriterOutputNSDecl(xmlTextWriterPtr writer)
 
4311
{
 
4312
    xmlLinkPtr lk;
 
4313
    xmlTextWriterNsStackEntry *np;
 
4314
    int count;
 
4315
    int sum;
 
4316
 
 
4317
    sum = 0;
 
4318
    while (!xmlListEmpty(writer->nsstack)) {
 
4319
        xmlChar *namespaceURI = NULL;
 
4320
        xmlChar *prefix = NULL;
 
4321
 
 
4322
        lk = xmlListFront(writer->nsstack);
 
4323
        np = (xmlTextWriterNsStackEntry *) xmlLinkGetData(lk);
 
4324
 
 
4325
        if (np != 0) {
 
4326
            namespaceURI = xmlStrdup(np->uri);
 
4327
            prefix = xmlStrdup(np->prefix);
 
4328
        }
 
4329
 
 
4330
        xmlListPopFront(writer->nsstack);
 
4331
 
 
4332
        if (np != 0) {
 
4333
            count = xmlTextWriterWriteAttribute(writer, prefix, namespaceURI);
 
4334
            xmlFree(namespaceURI);
 
4335
            xmlFree(prefix);
 
4336
 
 
4337
            if (count < 0) {
 
4338
                xmlListDelete(writer->nsstack);
 
4339
                writer->nsstack = NULL;
 
4340
                return -1;
 
4341
            }
 
4342
            sum += count;
 
4343
        }
 
4344
    }
 
4345
    return sum;
 
4346
}
 
4347
 
 
4348
/**
 
4349
 * xmlFreeTextWriterNsStackEntry:
 
4350
 * @lk:  the xmlLinkPtr
 
4351
 *
 
4352
 * Free callback for the xmlList.
 
4353
 */
 
4354
static void
 
4355
xmlFreeTextWriterNsStackEntry(xmlLinkPtr lk)
 
4356
{
 
4357
    xmlTextWriterNsStackEntry *p;
 
4358
 
 
4359
    p = (xmlTextWriterNsStackEntry *) xmlLinkGetData(lk);
 
4360
    if (p == 0)
 
4361
        return;
 
4362
 
 
4363
    if (p->prefix != 0)
 
4364
        xmlFree(p->prefix);
 
4365
    if (p->uri != 0)
 
4366
        xmlFree(p->uri);
 
4367
 
 
4368
    xmlFree(p);
 
4369
}
 
4370
 
 
4371
/**
 
4372
 * xmlCmpTextWriterNsStackEntry:
 
4373
 * @data0:  the first data
 
4374
 * @data1:  the second data
 
4375
 *
 
4376
 * Compare callback for the xmlList.
 
4377
 *
 
4378
 * Returns -1, 0, 1
 
4379
 */
 
4380
static int
 
4381
xmlCmpTextWriterNsStackEntry(const void *data0, const void *data1)
 
4382
{
 
4383
    xmlTextWriterNsStackEntry *p0;
 
4384
    xmlTextWriterNsStackEntry *p1;
 
4385
    int rc;
 
4386
 
 
4387
    if (data0 == data1)
 
4388
        return 0;
 
4389
 
 
4390
    if (data0 == 0)
 
4391
        return -1;
 
4392
 
 
4393
    if (data1 == 0)
 
4394
        return 1;
 
4395
 
 
4396
    p0 = (xmlTextWriterNsStackEntry *) data0;
 
4397
    p1 = (xmlTextWriterNsStackEntry *) data1;
 
4398
 
 
4399
    rc = xmlStrcmp(p0->prefix, p1->prefix);
 
4400
 
 
4401
    if ((rc != 0) || (p0->elem != p1->elem))
 
4402
        rc = -1;
 
4403
 
 
4404
    return rc;
 
4405
}
 
4406
 
 
4407
/**
 
4408
 * xmlTextWriterWriteDocCallback:
 
4409
 * @context:  the xmlBufferPtr
 
4410
 * @str:  the data to write
 
4411
 * @len:  the length of the data
 
4412
 *
 
4413
 * Write callback for the xmlOutputBuffer with target xmlBuffer
 
4414
 *
 
4415
 * Returns -1, 0, 1
 
4416
 */
 
4417
static int
 
4418
xmlTextWriterWriteDocCallback(void *context, const xmlChar * str, int len)
 
4419
{
 
4420
    xmlParserCtxtPtr ctxt = (xmlParserCtxtPtr) context;
 
4421
    int rc;
 
4422
 
 
4423
    if ((rc = xmlParseChunk(ctxt, (const char *) str, len, 0)) != 0) {
 
4424
        xmlWriterErrMsgInt(NULL, XML_ERR_INTERNAL_ERROR,
 
4425
                        "xmlTextWriterWriteDocCallback : XML error %d !\n",
 
4426
                        rc);
 
4427
        return -1;
 
4428
    }
 
4429
 
 
4430
    return len;
 
4431
}
 
4432
 
 
4433
/**
 
4434
 * xmlTextWriterCloseDocCallback:
 
4435
 * @context:  the xmlBufferPtr
 
4436
 *
 
4437
 * Close callback for the xmlOutputBuffer with target xmlBuffer
 
4438
 *
 
4439
 * Returns -1, 0, 1
 
4440
 */
 
4441
static int
 
4442
xmlTextWriterCloseDocCallback(void *context)
 
4443
{
 
4444
    xmlParserCtxtPtr ctxt = (xmlParserCtxtPtr) context;
 
4445
    int rc;
 
4446
 
 
4447
    if ((rc = xmlParseChunk(ctxt, NULL, 0, 1)) != 0) {
 
4448
        xmlWriterErrMsgInt(NULL, XML_ERR_INTERNAL_ERROR,
 
4449
                        "xmlTextWriterWriteDocCallback : XML error %d !\n",
 
4450
                        rc);
 
4451
        return -1;
 
4452
    }
 
4453
 
 
4454
    return 0;
 
4455
}
 
4456
 
 
4457
/**
 
4458
 * xmlTextWriterVSprintf:
 
4459
 * @format:  see printf
 
4460
 * @argptr:  pointer to the first member of the variable argument list.
 
4461
 *
 
4462
 * Utility function for formatted output
 
4463
 *
 
4464
 * Returns a new xmlChar buffer with the data or NULL on error. This buffer must be freed.
 
4465
 */
 
4466
static xmlChar *
 
4467
xmlTextWriterVSprintf(const char *format, va_list argptr)
 
4468
{
 
4469
    int size;
 
4470
    int count;
 
4471
    xmlChar *buf;
 
4472
    va_list locarg;
 
4473
 
 
4474
    size = BUFSIZ;
 
4475
    buf = (xmlChar *) xmlMalloc(size);
 
4476
    if (buf == NULL) {
 
4477
        xmlWriterErrMsg(NULL, XML_ERR_NO_MEMORY,
 
4478
                        "xmlTextWriterVSprintf : out of memory!\n");
 
4479
        return NULL;
 
4480
    }
 
4481
 
 
4482
    VA_COPY(locarg, argptr);
 
4483
    while (((count = vsnprintf((char *) buf, size, format, locarg)) < 0)
 
4484
           || (count == size - 1) || (count == size) || (count > size)) {
 
4485
        va_end(locarg);
 
4486
        xmlFree(buf);
 
4487
        size += BUFSIZ;
 
4488
        buf = (xmlChar *) xmlMalloc(size);
 
4489
        if (buf == NULL) {
 
4490
            xmlWriterErrMsg(NULL, XML_ERR_NO_MEMORY,
 
4491
                            "xmlTextWriterVSprintf : out of memory!\n");
 
4492
            return NULL;
 
4493
        }
 
4494
        VA_COPY(locarg, argptr);
 
4495
    }
 
4496
    va_end(locarg);
 
4497
 
 
4498
    return buf;
 
4499
}
 
4500
 
 
4501
/**
 
4502
 * xmlTextWriterStartDocumentCallback:
 
4503
 * @ctx: the user data (XML parser context)
 
4504
 *
 
4505
 * called at the start of document processing.
 
4506
 */
 
4507
static void
 
4508
xmlTextWriterStartDocumentCallback(void *ctx)
 
4509
{
 
4510
    xmlParserCtxtPtr ctxt = (xmlParserCtxtPtr) ctx;
 
4511
    xmlDocPtr doc;
 
4512
 
 
4513
    if (ctxt->html) {
 
4514
#ifdef LIBXML_HTML_ENABLED
 
4515
        if (ctxt->myDoc == NULL)
 
4516
            ctxt->myDoc = htmlNewDocNoDtD(NULL, NULL);
 
4517
        if (ctxt->myDoc == NULL) {
 
4518
            if ((ctxt->sax != NULL) && (ctxt->sax->error != NULL))
 
4519
                ctxt->sax->error(ctxt->userData,
 
4520
                                 "SAX.startDocument(): out of memory\n");
 
4521
            ctxt->errNo = XML_ERR_NO_MEMORY;
 
4522
            ctxt->instate = XML_PARSER_EOF;
 
4523
            ctxt->disableSAX = 1;
 
4524
            return;
 
4525
        }
 
4526
#else
 
4527
        xmlWriterErrMsg(NULL, XML_ERR_INTERNAL_ERROR,
 
4528
                        "libxml2 built without HTML support\n");
 
4529
        ctxt->errNo = XML_ERR_INTERNAL_ERROR;
 
4530
        ctxt->instate = XML_PARSER_EOF;
 
4531
        ctxt->disableSAX = 1;
 
4532
        return;
 
4533
#endif
 
4534
    } else {
 
4535
        doc = ctxt->myDoc;
 
4536
        if (doc == NULL)
 
4537
            doc = ctxt->myDoc = xmlNewDoc(ctxt->version);
 
4538
        if (doc != NULL) {
 
4539
            if (doc->children == NULL) {
 
4540
                if (ctxt->encoding != NULL)
 
4541
                    doc->encoding = xmlStrdup(ctxt->encoding);
 
4542
                else
 
4543
                    doc->encoding = NULL;
 
4544
                doc->standalone = ctxt->standalone;
 
4545
            }
 
4546
        } else {
 
4547
            if ((ctxt->sax != NULL) && (ctxt->sax->error != NULL))
 
4548
                ctxt->sax->error(ctxt->userData,
 
4549
                                 "SAX.startDocument(): out of memory\n");
 
4550
            ctxt->errNo = XML_ERR_NO_MEMORY;
 
4551
            ctxt->instate = XML_PARSER_EOF;
 
4552
            ctxt->disableSAX = 1;
 
4553
            return;
 
4554
        }
 
4555
    }
 
4556
    if ((ctxt->myDoc != NULL) && (ctxt->myDoc->URL == NULL) &&
 
4557
        (ctxt->input != NULL) && (ctxt->input->filename != NULL)) {
 
4558
        ctxt->myDoc->URL =
 
4559
            xmlCanonicPath((const xmlChar *) ctxt->input->filename);
 
4560
        if (ctxt->myDoc->URL == NULL)
 
4561
            ctxt->myDoc->URL =
 
4562
                xmlStrdup((const xmlChar *) ctxt->input->filename);
 
4563
    }
 
4564
}
 
4565
 
 
4566
/**
 
4567
 * xmlTextWriterSetIndent:
 
4568
 * @writer:  the xmlTextWriterPtr
 
4569
 * @indent:  do indentation?
 
4570
 *
 
4571
 * Set indentation output. indent = 0 do not indentation. indent > 0 do indentation.
 
4572
 *
 
4573
 * Returns -1 on error or 0 otherwise.
 
4574
 */
 
4575
int
 
4576
xmlTextWriterSetIndent(xmlTextWriterPtr writer, int indent)
 
4577
{
 
4578
    if ((writer == NULL) || (indent < 0))
 
4579
        return -1;
 
4580
 
 
4581
    writer->indent = indent;
 
4582
    writer->doindent = 1;
 
4583
 
 
4584
    return 0;
 
4585
}
 
4586
 
 
4587
/**
 
4588
 * xmlTextWriterSetIndentString:
 
4589
 * @writer:  the xmlTextWriterPtr
 
4590
 * @str:  the xmlChar string
 
4591
 *
 
4592
 * Set string indentation.
 
4593
 *
 
4594
 * Returns -1 on error or 0 otherwise.
 
4595
 */
 
4596
int
 
4597
xmlTextWriterSetIndentString(xmlTextWriterPtr writer, const xmlChar * str)
 
4598
{
 
4599
    if ((writer == NULL) || (!str))
 
4600
        return -1;
 
4601
 
 
4602
    if (writer->ichar != NULL)
 
4603
        xmlFree(writer->ichar);
 
4604
    writer->ichar = xmlStrdup(str);
 
4605
 
 
4606
    if (!writer->ichar)
 
4607
        return -1;
 
4608
    else
 
4609
        return 0;
 
4610
}
 
4611
 
 
4612
/**
 
4613
 * xmlTextWriterSetQuoteChar:
 
4614
 * @writer:  the xmlTextWriterPtr
 
4615
 * @quotechar:  the quote character
 
4616
 *
 
4617
 * Set the character used for quoting attributes.
 
4618
 *
 
4619
 * Returns -1 on error or 0 otherwise.
 
4620
 */
 
4621
int
 
4622
xmlTextWriterSetQuoteChar(xmlTextWriterPtr writer, xmlChar quotechar)
 
4623
{
 
4624
    if ((writer == NULL) || ((quotechar != '\'') && (quotechar != '"')))
 
4625
        return -1;
 
4626
 
 
4627
    writer->qchar = quotechar;
 
4628
 
 
4629
    return 0;
 
4630
}
 
4631
 
 
4632
/**
 
4633
 * xmlTextWriterWriteIndent:
 
4634
 * @writer:  the xmlTextWriterPtr
 
4635
 *
 
4636
 * Write indent string.
 
4637
 *
 
4638
 * Returns -1 on error or the number of strings written.
 
4639
 */
 
4640
static int
 
4641
xmlTextWriterWriteIndent(xmlTextWriterPtr writer)
 
4642
{
 
4643
    int lksize;
 
4644
    int i;
 
4645
    int ret;
 
4646
 
 
4647
    lksize = xmlListSize(writer->nodes);
 
4648
    if (lksize < 1)
 
4649
        return (-1);            /* list is empty */
 
4650
    for (i = 0; i < (lksize - 1); i++) {
 
4651
        ret = xmlOutputBufferWriteString(writer->out,
 
4652
                                         (const char *) writer->ichar);
 
4653
        if (ret == -1)
 
4654
            return (-1);
 
4655
    }
 
4656
 
 
4657
    return (lksize - 1);
 
4658
}
 
4659
 
 
4660
/**
 
4661
 * xmlTextWriterHandleStateDependencies:
 
4662
 * @writer:  the xmlTextWriterPtr
 
4663
 * @p:  the xmlTextWriterStackEntry
 
4664
 *
 
4665
 * Write state dependent strings.
 
4666
 *
 
4667
 * Returns -1 on error or the number of characters written.
 
4668
 */
 
4669
static int
 
4670
xmlTextWriterHandleStateDependencies(xmlTextWriterPtr writer,
 
4671
                                     xmlTextWriterStackEntry * p)
 
4672
{
 
4673
    int count;
 
4674
    int sum;
 
4675
    char extra[3];
 
4676
 
 
4677
    if (writer == NULL)
 
4678
        return -1;
 
4679
 
 
4680
    if (p == NULL)
 
4681
        return 0;
 
4682
 
 
4683
    sum = 0;
 
4684
    extra[0] = extra[1] = extra[2] = '\0';
 
4685
    if (p != 0) {
 
4686
        sum = 0;
 
4687
        switch (p->state) {
 
4688
            case XML_TEXTWRITER_NAME:
 
4689
                /* Output namespace declarations */
 
4690
                count = xmlTextWriterOutputNSDecl(writer);
 
4691
                if (count < 0)
 
4692
                    return -1;
 
4693
                sum += count;
 
4694
                extra[0] = '>';
 
4695
                p->state = XML_TEXTWRITER_TEXT;
 
4696
                break;
 
4697
            case XML_TEXTWRITER_PI:
 
4698
                extra[0] = ' ';
 
4699
                p->state = XML_TEXTWRITER_PI_TEXT;
 
4700
                break;
 
4701
            case XML_TEXTWRITER_DTD:
 
4702
                extra[0] = ' ';
 
4703
                extra[1] = '[';
 
4704
                p->state = XML_TEXTWRITER_DTD_TEXT;
 
4705
                break;
 
4706
            case XML_TEXTWRITER_DTD_ELEM:
 
4707
                extra[0] = ' ';
 
4708
                p->state = XML_TEXTWRITER_DTD_ELEM_TEXT;
 
4709
                break;
 
4710
            case XML_TEXTWRITER_DTD_ATTL:
 
4711
                extra[0] = ' ';
 
4712
                p->state = XML_TEXTWRITER_DTD_ATTL_TEXT;
 
4713
                break;
 
4714
            case XML_TEXTWRITER_DTD_ENTY:
 
4715
            case XML_TEXTWRITER_DTD_PENT:
 
4716
                extra[0] = ' ';
 
4717
                extra[1] = writer->qchar;
 
4718
                p->state = XML_TEXTWRITER_DTD_ENTY_TEXT;
 
4719
                break;
 
4720
            default:
 
4721
                break;
 
4722
        }
 
4723
    }
 
4724
 
 
4725
    if (*extra != '\0') {
 
4726
        count = xmlOutputBufferWriteString(writer->out, extra);
 
4727
        if (count < 0)
 
4728
            return -1;
 
4729
        sum += count;
 
4730
    }
 
4731
 
 
4732
    return sum;
 
4733
}
 
4734
 
 
4735
#define bottom_xmlwriter
 
4736
#include "elfgcchack.h"
 
4737
#endif