Annotation of embedaddon/libxml2/xmlwriter.c, revision 1.1.1.2

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

FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>