Coverage Report

Created: 2025-07-07 10:01

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