Coverage Report

Created: 2025-07-18 06:10

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