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