diff --git a/xmlIO.c b/xmlIO.c index 8e934a69..a3f6e81d 100644 --- a/xmlIO.c +++ b/xmlIO.c @@ -2452,130 +2452,38 @@ xmlEscapeContent(unsigned char* out, int *outlen, int xmlOutputBufferWriteEscape(xmlOutputBufferPtr out, const xmlChar *str, xmlCharEncodingOutputFunc escaping) { - int nbchars = 0; /* number of chars to output to I/O */ - int ret; /* return from function call */ - int written = 0; /* number of char written to I/O so far */ - int oldwritten=0;/* loop guard */ - int chunk; /* number of byte currently processed from str */ - int len; /* number of bytes in str */ - int cons; /* byte from str consumed */ + int ret; + int written = 0; + int len; - if ((out == NULL) || (out->error) || (str == NULL) || - (out->buffer == NULL)) + if ((out == NULL) || (out->error) || (str == NULL)) return(-1); len = strlen((const char *)str); - if (len < 0) return(0); - if (out->error) return(-1); - if (escaping == NULL) escaping = xmlEscapeContent; + if (escaping == NULL) + escaping = xmlEscapeContent; - do { - oldwritten = written; + while (len > 0) { + xmlChar buf[1024]; + int c_out; + int c_in; - /* - * how many bytes to consume and how many bytes to store. - */ - cons = len; - chunk = xmlBufAvail(out->buffer); + c_out = 1024; + c_in = len; - /* - * make sure we have enough room to save first, if this is - * not the case force a flush, but make sure we stay in the loop - */ - if (chunk < 40) { - if (xmlBufGrow(out->buffer, 100) < 0) { - out->error = XML_ERR_NO_MEMORY; - return(-1); - } - oldwritten = -1; - continue; - } + ret = escaping(buf, &c_out, str, &c_in); + if (ret < 0) { + out->error = XML_ERR_NO_MEMORY; + return(-1); + } + str += c_in; + len -= c_in; - /* - * first handle encoding stuff. - */ - if (out->encoder != NULL) { - /* - * Store the data in the incoming raw buffer - */ - if (out->conv == NULL) { - out->conv = xmlBufCreate(); - if (out->conv == NULL) { - out->error = XML_ERR_NO_MEMORY; - return(-1); - } - } - ret = escaping(xmlBufEnd(out->buffer) , - &chunk, str, &cons); - if (ret < 0) { - out->error = XML_ERR_NO_MEMORY; - return(-1); - } - xmlBufAddLen(out->buffer, chunk); + ret = xmlOutputBufferWrite(out, c_out, (char *) buf); + if (ret < 0) + return(ret); + written += ret; + } - if ((xmlBufUse(out->buffer) < MINLEN) && (cons == len)) - goto done; - - /* - * convert as much as possible to the output buffer. - */ - ret = xmlCharEncOutput(out, 0); - if (ret < 0) - return(-1); - if (out->writecallback) - nbchars = xmlBufUse(out->conv); - else - nbchars = ret >= 0 ? ret : 0; - } else { - ret = escaping(xmlBufEnd(out->buffer), &chunk, str, &cons); - if (ret < 0) { - out->error = XML_ERR_NO_MEMORY; - return(-1); - } - xmlBufAddLen(out->buffer, chunk); - if (out->writecallback) - nbchars = xmlBufUse(out->buffer); - else - nbchars = chunk; - } - str += cons; - len -= cons; - - if (out->writecallback) { - if ((nbchars < MINLEN) && (len <= 0)) - goto done; - - /* - * second write the stuff to the I/O channel - */ - if (out->encoder != NULL) { - ret = out->writecallback(out->context, - (const char *)xmlBufContent(out->conv), nbchars); - if (ret >= 0) - xmlBufShrink(out->conv, ret); - } else { - ret = out->writecallback(out->context, - (const char *)xmlBufContent(out->buffer), nbchars); - if (ret >= 0) - xmlBufShrink(out->buffer, ret); - } - if (ret < 0) { - out->error = (ret == -1) ? XML_IO_WRITE : -ret; - return(-1); - } - if (out->written > INT_MAX - ret) - out->written = INT_MAX; - else - out->written += ret; - } else if (xmlBufAvail(out->buffer) < MINLEN) { - if (xmlBufGrow(out->buffer, MINLEN) < 0) { - out->error = XML_ERR_NO_MEMORY; - return(-1); - } - } - written += nbchars; - } while ((len > 0) && (oldwritten != written)); - -done: return(written); } diff --git a/xmlsave.c b/xmlsave.c index 0772ba33..dd3d6d2c 100644 --- a/xmlsave.c +++ b/xmlsave.c @@ -31,6 +31,9 @@ #define XHTML_NS_NAME BAD_CAST "http://www.w3.org/1999/xhtml" +#define XML_ESCAPE_ATTR (1u << 0) +#define XML_ESCAPE_NON_ASCII (1u << 1) + struct _xmlSaveCtxt { void *_private; int type; @@ -124,9 +127,9 @@ xmlSaveErr(xmlOutputBufferPtr out, int code, xmlNodePtr node, * Special escaping routines * * * ************************************************************************/ -static unsigned char * -xmlSerializeHexCharRef(unsigned char *out, int val) { - unsigned char *ptr; +static char * +xmlSerializeHexCharRef(char *out, int val) { + char *ptr; *out++ = '&'; *out++ = '#'; @@ -165,104 +168,112 @@ xmlSerializeHexCharRef(unsigned char *out, int val) { return(out); } -/** - * xmlEscapeEntities: - * @out: a pointer to an array of bytes to store the result - * @outlen: the length of @out - * @in: a pointer to an array of unescaped UTF-8 bytes - * @inlen: the length of @in - * - * Take a block of UTF-8 chars in and escape them. Used when there is no - * encoding specified. - * - * Returns 0 if success, or -1 otherwise - * The value of @inlen after return is the number of octets consumed - * if the return value is positive, else unpredictable. - * The value of @outlen after return is the number of octets consumed. - */ -static int -xmlEscapeEntities(unsigned char* out, int *outlen, - const xmlChar* in, int *inlen) { - unsigned char* outstart = out; - const unsigned char* base = in; - unsigned char* outend = out + *outlen; - const unsigned char* inend; - int val; +static void +xmlSerializeText(xmlOutputBufferPtr buf, const xmlChar *string, + unsigned flags) { + char tmp[12]; + const char *base, *cur; - inend = in + (*inlen); + if (string == NULL) + return; - while ((in < inend) && (out < outend)) { - if (*in == '<') { - if (outend - out < 4) break; - *out++ = '&'; - *out++ = 'l'; - *out++ = 't'; - *out++ = ';'; - in++; - continue; - } else if (*in == '>') { - if (outend - out < 4) break; - *out++ = '&'; - *out++ = 'g'; - *out++ = 't'; - *out++ = ';'; - in++; - continue; - } else if (*in == '&') { - if (outend - out < 5) break; - *out++ = '&'; - *out++ = 'a'; - *out++ = 'm'; - *out++ = 'p'; - *out++ = ';'; - in++; - continue; - } else if (*in == 0xD) { - if (outend - out < 5) break; - *out++ = '&'; - *out++ = '#'; - *out++ = 'x'; - *out++ = 'D'; - *out++ = ';'; - in++; - } else if (((*in >= 0x20) && (*in < 0x80)) || - (*in == 0xA) || (*in == 0x9)) { - /* - * default case, just copy ! - */ - *out++ = *in++; - continue; - } else if (*in < 0x80) { - /* invalid control char */ - if (outend - out < 8) break; - out = xmlSerializeHexCharRef(out, 0xFFFD); - in++; - } else { - int len; + base = cur = (const char *) string; - if (outend - out < 11) break; + while (*cur != 0) { + const char *repl = NULL; + int replSize = 0; + int c = (unsigned char) *cur; - len = inend - in; - val = xmlGetUTF8Char(in, &len); + if ((c >= 0x80) && (flags & XML_ESCAPE_NON_ASCII)) { + int val = 0, l = 4; + if (base != cur) + xmlOutputBufferWrite(buf, cur - base, base); + + val = xmlGetUTF8Char((const xmlChar *) cur, &l); if (val < 0) { val = 0xFFFD; - in++; + cur++; } else { if (!IS_CHAR(val)) val = 0xFFFD; - in += len; + cur += l; } - /* - * We could do multiple things here. Just save as a char ref - */ - out = xmlSerializeHexCharRef(out, val); - } + xmlSerializeHexCharRef(tmp, val); + xmlOutputBufferWriteString(buf, tmp); + base = cur; + + continue; + } + + switch (c) { + case '\t': + if (flags & XML_ESCAPE_ATTR) { + repl = " "; + replSize = 4; + } + break; + + case '\n': + if (flags & XML_ESCAPE_ATTR) { + repl = " "; + replSize = 5; + } + break; + + case '\r': + if ((flags & XML_ESCAPE_NON_ASCII) && + ((flags & XML_ESCAPE_ATTR) == 0)) + repl = " "; + else + repl = " "; + replSize = 5; + break; + + case '"': + if (flags & XML_ESCAPE_ATTR) { + repl = "&#quot;"; + replSize = 6; + } + break; + + case '<': + repl = "<"; + replSize = 4; + break; + + case '>': + repl = ">"; + replSize = 4; + break; + + case '&': + repl = "&"; + replSize = 5; + break; + + default: + if (c < 0x20) { + repl = "�"; + replSize = 8; + } + break; + } + + if (repl == NULL) { + cur++; + } else { + if (base != cur) + xmlOutputBufferWrite(buf, cur - base, base); + xmlOutputBufferWrite(buf, replSize, repl); + cur++; + base = cur; + } } - *outlen = out - outstart; - *inlen = in - base; - return(0); + + if (base != cur) + xmlOutputBufferWrite(buf, cur - base, base); } /************************************************************************ @@ -313,9 +324,6 @@ xmlSaveCtxtInit(xmlSaveCtxtPtr ctxt, int options) { if (ctxt == NULL) return; - if ((ctxt->encoding == NULL) && (ctxt->escape == NULL)) - ctxt->escape = xmlEscapeEntities; - xmlSaveSetIndentString(ctxt, xmlTreeIndentString); if (options & XML_SAVE_FORMAT) @@ -376,7 +384,6 @@ xmlNewSaveCtxt(const char *encoding, int options) return(NULL); } ret->encoding = xmlStrdup((const xmlChar *)encoding); - ret->escape = NULL; } xmlSaveCtxtInit(ret, options); @@ -389,25 +396,33 @@ xmlNewSaveCtxt(const char *encoding, int options) * Dumping XML tree content to a simple buffer * * * ************************************************************************/ + +static void +xmlSaveWriteText(xmlSaveCtxt *ctxt, const xmlChar *text, unsigned flags) { + if (ctxt->encoding == NULL) + flags |= XML_ESCAPE_NON_ASCII; + + xmlSerializeText(ctxt->buf, text, flags); +} + /** - * xmlAttrSerializeContent: - * @buf: the XML buffer output - * @doc: the document + * xmlSaveWriteAttrContent: + * @ctxt: save context * @attr: the attribute pointer * * Serialize the attribute in the buffer */ static void -xmlAttrSerializeContent(xmlOutputBufferPtr buf, xmlAttrPtr attr) +xmlSaveWriteAttrContent(xmlSaveCtxt *ctxt, xmlAttrPtr attr) { xmlNodePtr children; + xmlOutputBufferPtr buf = ctxt->buf; children = attr->children; while (children != NULL) { switch (children->type) { case XML_TEXT_NODE: - xmlBufAttrSerializeTxtContent(buf, attr->doc, - children->content); + xmlSaveWriteText(ctxt, children->content, XML_ESCAPE_ATTR); break; case XML_ENTITY_REF_NODE: xmlOutputBufferWrite(buf, 1, "&"); @@ -899,9 +914,14 @@ xmlOutputBufferWriteWSNonSig(xmlSaveCtxtPtr ctxt, int extra) * If @ctxt is supplied, @buf should be its buffer. */ static void -xmlNsDumpOutput(xmlOutputBufferPtr buf, xmlDocPtr doc, xmlNsPtr cur, - xmlSaveCtxtPtr ctxt) { +xmlNsDumpOutput(xmlOutputBufferPtr buf, xmlNsPtr cur, xmlSaveCtxtPtr ctxt) { + unsigned escapeFlags = XML_ESCAPE_ATTR; + if ((cur == NULL) || (buf == NULL)) return; + + if ((ctxt == NULL) || (ctxt->encoding == NULL)) + escapeFlags |= XML_ESCAPE_NON_ASCII; + if ((cur->type == XML_LOCAL_NAMESPACE) && (cur->href != NULL)) { if (xmlStrEqual(cur->prefix, BAD_CAST "xml")) return; @@ -918,7 +938,7 @@ xmlNsDumpOutput(xmlOutputBufferPtr buf, xmlDocPtr doc, xmlNsPtr cur, } else xmlOutputBufferWrite(buf, 5, "xmlns"); xmlOutputBufferWrite(buf, 2, "=\""); - xmlBufAttrSerializeTxtContent(buf, doc, cur->href); + xmlSerializeText(buf, cur->href, escapeFlags); xmlOutputBufferWrite(buf, 1, "\""); } } @@ -932,9 +952,9 @@ xmlNsDumpOutput(xmlOutputBufferPtr buf, xmlDocPtr doc, xmlNsPtr cur, * Should be called in the context of attribute dumps. */ static void -xmlNsListDumpOutputCtxt(xmlSaveCtxtPtr ctxt, xmlDocPtr doc, xmlNsPtr cur) { +xmlNsListDumpOutputCtxt(xmlSaveCtxtPtr ctxt, xmlNsPtr cur) { while (cur != NULL) { - xmlNsDumpOutput(ctxt->buf, doc, cur, ctxt); + xmlNsDumpOutput(ctxt->buf, cur, ctxt); cur = cur->next; } } @@ -950,7 +970,7 @@ xmlNsListDumpOutputCtxt(xmlSaveCtxtPtr ctxt, xmlDocPtr doc, xmlNsPtr cur) { void xmlNsListDumpOutput(xmlOutputBufferPtr buf, xmlNsPtr cur) { while (cur != NULL) { - xmlNsDumpOutput(buf, NULL, cur, NULL); + xmlNsDumpOutput(buf, cur, NULL); cur = cur->next; } } @@ -1045,7 +1065,7 @@ xmlAttrDumpOutput(xmlSaveCtxtPtr ctxt, xmlAttrPtr cur) { } else #endif { - xmlAttrSerializeContent(buf, cur); + xmlSaveWriteAttrContent(ctxt, cur); } xmlOutputBufferWrite(buf, 1, "\""); } @@ -1059,7 +1079,6 @@ xmlAttrDumpOutput(xmlSaveCtxtPtr ctxt, xmlAttrPtr cur) { */ static int htmlNodeDumpOutputInternal(xmlSaveCtxtPtr ctxt, xmlNodePtr cur) { - const xmlChar *oldenc = NULL; const xmlChar *oldctxtenc = ctxt->encoding; const xmlChar *encoding = ctxt->encoding; xmlOutputBufferPtr buf = ctxt->buf; @@ -1069,14 +1088,8 @@ htmlNodeDumpOutputInternal(xmlSaveCtxtPtr ctxt, xmlNodePtr cur) { xmlInitParser(); doc = cur->doc; - if (doc != NULL) { - oldenc = doc->encoding; - if (ctxt->encoding != NULL) { - doc->encoding = BAD_CAST ctxt->encoding; - } else if (doc->encoding != NULL) { - encoding = doc->encoding; - } - } + if ((encoding == NULL) && (doc != NULL)) + encoding = doc->encoding; if ((encoding != NULL) && (doc != NULL)) htmlSetMetaEncoding(doc, (const xmlChar *) encoding); @@ -1086,10 +1099,8 @@ htmlNodeDumpOutputInternal(xmlSaveCtxtPtr ctxt, xmlNodePtr cur) { encoding = BAD_CAST "HTML"; if ((encoding != NULL) && (oldctxtenc == NULL) && (buf->encoder == NULL) && (buf->conv == NULL)) { - if (xmlSaveSwitchEncoding(ctxt, (const char*) encoding) < 0) { - doc->encoding = oldenc; + if (xmlSaveSwitchEncoding(ctxt, (const char*) encoding) < 0) return(-1); - } switched_encoding = 1; } if (ctxt->options & XML_SAVE_FORMAT) @@ -1104,8 +1115,6 @@ htmlNodeDumpOutputInternal(xmlSaveCtxtPtr ctxt, xmlNodePtr cur) { if ((switched_encoding) && (oldctxtenc == NULL)) { xmlSaveClearEncoding(ctxt); } - if (doc != NULL) - doc->encoding = oldenc; return(0); } #endif @@ -1182,7 +1191,7 @@ xmlNodeDumpOutputInternal(xmlSaveCtxtPtr ctxt, xmlNodePtr cur) { } xmlOutputBufferWriteString(buf, (const char *)cur->name); if (cur->nsDef) - xmlNsListDumpOutputCtxt(ctxt, cur->doc, cur->nsDef); + xmlNsListDumpOutputCtxt(ctxt, cur->nsDef); for (attr = cur->properties; attr != NULL; attr = attr->next) xmlAttrDumpOutput(ctxt, attr); @@ -1235,7 +1244,15 @@ xmlNodeDumpOutputInternal(xmlSaveCtxtPtr ctxt, xmlNodePtr cur) { if (cur->content == NULL) break; if (cur->name != xmlStringTextNoenc) { - xmlOutputBufferWriteEscape(buf, cur->content, ctxt->escape); + if (ctxt->escape) + xmlOutputBufferWriteEscape(buf, cur->content, + ctxt->escape); +#ifdef TEST_OUTPUT_BUFFER_WRITE_ESCAPE + else if (ctxt->encoding) + xmlOutputBufferWriteEscape(buf, cur->content, NULL); +#endif + else + xmlSaveWriteText(ctxt, cur->content, /* flags */ 0); } else { /* * Disable escaping, needed for XSLT @@ -1316,7 +1333,7 @@ xmlNodeDumpOutputInternal(xmlSaveCtxtPtr ctxt, xmlNodePtr cur) { break; case XML_NAMESPACE_DECL: - xmlNsDumpOutput(buf, NULL, (xmlNsPtr) cur, ctxt); + xmlNsDumpOutput(buf, (xmlNsPtr) cur, ctxt); break; default: @@ -1377,10 +1394,8 @@ xmlDocContentDumpOutput(xmlSaveCtxtPtr ctxt, xmlDocPtr cur) { xmlDtdPtr dtd; int is_xhtml = 0; #endif - const xmlChar *oldenc = cur->encoding; const xmlChar *oldctxtenc = ctxt->encoding; const xmlChar *encoding = ctxt->encoding; - xmlCharEncodingOutputFunc oldescape = ctxt->escape; xmlOutputBufferPtr buf = ctxt->buf; xmlCharEncoding enc; int switched_encoding = 0; @@ -1391,11 +1406,8 @@ xmlDocContentDumpOutput(xmlSaveCtxtPtr ctxt, xmlDocPtr cur) { (cur->type != XML_DOCUMENT_NODE)) return(-1); - if (ctxt->encoding != NULL) { - cur->encoding = BAD_CAST ctxt->encoding; - } else if (cur->encoding != NULL) { + if (ctxt->encoding == NULL) encoding = cur->encoding; - } if (((cur->type == XML_HTML_DOCUMENT_NODE) && ((ctxt->options & XML_SAVE_AS_XML) == 0) && @@ -1411,7 +1423,6 @@ xmlDocContentDumpOutput(xmlSaveCtxtPtr ctxt, xmlDocPtr cur) { if ((encoding != NULL) && (oldctxtenc == NULL) && (buf->encoder == NULL) && (buf->conv == NULL)) { if (xmlSaveSwitchEncoding(ctxt, (const char*) encoding) < 0) { - cur->encoding = oldenc; return(-1); } } @@ -1421,8 +1432,6 @@ xmlDocContentDumpOutput(xmlSaveCtxtPtr ctxt, xmlDocPtr cur) { else htmlDocContentDumpFormatOutput(buf, cur, (const char *)encoding, 0); - if (ctxt->encoding != NULL) - cur->encoding = oldenc; return(0); #else return(-1); @@ -1442,14 +1451,10 @@ xmlDocContentDumpOutput(xmlSaveCtxtPtr ctxt, xmlDocPtr cur) { * document since we output the XMLDecl the conversion * must be done to not generate not well formed documents. */ - if (xmlSaveSwitchEncoding(ctxt, (const char*) encoding) < 0) { - cur->encoding = oldenc; + if (xmlSaveSwitchEncoding(ctxt, (const char*) encoding) < 0) return(-1); - } switched_encoding = 1; } - if (ctxt->escape == xmlEscapeEntities) - ctxt->escape = NULL; } @@ -1512,9 +1517,7 @@ xmlDocContentDumpOutput(xmlSaveCtxtPtr ctxt, xmlDocPtr cur) { */ if ((switched_encoding) && (oldctxtenc == NULL)) { xmlSaveClearEncoding(ctxt); - ctxt->escape = oldescape; } - cur->encoding = oldenc; return(0); } @@ -1641,7 +1644,7 @@ xhtmlAttrListDumpOutput(xmlSaveCtxtPtr ctxt, xmlAttrPtr cur) { (xmlStrEqual(parent->name, BAD_CAST "frame")) || (xmlStrEqual(parent->name, BAD_CAST "iframe")))) { xmlOutputBufferWrite(buf, 5, " id=\""); - xmlAttrSerializeContent(buf, name); + xmlSaveWriteAttrContent(ctxt, name); xmlOutputBufferWrite(buf, 1, "\""); } } @@ -1650,12 +1653,12 @@ xhtmlAttrListDumpOutput(xmlSaveCtxtPtr ctxt, xmlAttrPtr cur) { */ if ((lang != NULL) && (xml_lang == NULL)) { xmlOutputBufferWrite(buf, 11, " xml:lang=\""); - xmlAttrSerializeContent(buf, lang); + xmlSaveWriteAttrContent(ctxt, lang); xmlOutputBufferWrite(buf, 1, "\""); } else if ((xml_lang != NULL) && (lang == NULL)) { xmlOutputBufferWrite(buf, 7, " lang=\""); - xmlAttrSerializeContent(buf, xml_lang); + xmlSaveWriteAttrContent(ctxt, xml_lang); xmlOutputBufferWrite(buf, 1, "\""); } } @@ -1693,7 +1696,7 @@ xhtmlNodeDumpOutput(xmlSaveCtxtPtr ctxt, xmlNodePtr cur) { break; case XML_NAMESPACE_DECL: - xmlNsDumpOutput(buf, NULL, (xmlNsPtr) cur, ctxt); + xmlNsDumpOutput(buf, (xmlNsPtr) cur, ctxt); break; case XML_DTD_NODE: @@ -1745,7 +1748,7 @@ xhtmlNodeDumpOutput(xmlSaveCtxtPtr ctxt, xmlNodePtr cur) { xmlOutputBufferWriteString(buf, (const char *)cur->name); if (cur->nsDef) - xmlNsListDumpOutputCtxt(ctxt, cur->doc, cur->nsDef); + xmlNsListDumpOutputCtxt(ctxt, cur->nsDef); if ((xmlStrEqual(cur->name, BAD_CAST "html") && (cur->ns == NULL) && (cur->nsDef == NULL))) { /* @@ -1870,7 +1873,11 @@ xhtmlNodeDumpOutput(xmlSaveCtxtPtr ctxt, xmlNodePtr cur) { break; if ((cur->name == xmlStringText) || (cur->name != xmlStringTextNoenc)) { - xmlOutputBufferWriteEscape(buf, cur->content, ctxt->escape); + if (ctxt->escape) + xmlOutputBufferWriteEscape(buf, cur->content, + ctxt->escape); + else + xmlSaveWriteText(ctxt, cur->content, /* flags */ 0); } else { /* * Disable escaping, needed for XSLT @@ -2313,88 +2320,11 @@ void xmlBufAttrSerializeTxtContent(xmlOutputBufferPtr buf, xmlDocPtr doc, const xmlChar *string) { - const xmlChar *base, *cur; + int flags = XML_ESCAPE_ATTR; - if (string == NULL) - return; - base = cur = string; - while (*cur != 0) { - if (*cur == '\n') { - if (base != cur) - xmlOutputBufferWrite(buf, cur - base, (const char *) base); - xmlOutputBufferWrite(buf, 5, " "); - cur++; - base = cur; - } else if (*cur == '\r') { - if (base != cur) - xmlOutputBufferWrite(buf, cur - base, (const char *) base); - xmlOutputBufferWrite(buf, 5, " "); - cur++; - base = cur; - } else if (*cur == '\t') { - if (base != cur) - xmlOutputBufferWrite(buf, cur - base, (const char *) base); - xmlOutputBufferWrite(buf, 4, " "); - cur++; - base = cur; - } else if (*cur == '"') { - if (base != cur) - xmlOutputBufferWrite(buf, cur - base, (const char *) base); - xmlOutputBufferWrite(buf, 6, """); - cur++; - base = cur; - } else if (*cur == '<') { - if (base != cur) - xmlOutputBufferWrite(buf, cur - base, (const char *) base); - xmlOutputBufferWrite(buf, 4, "<"); - cur++; - base = cur; - } else if (*cur == '>') { - if (base != cur) - xmlOutputBufferWrite(buf, cur - base, (const char *) base); - xmlOutputBufferWrite(buf, 4, ">"); - cur++; - base = cur; - } else if (*cur == '&') { - if (base != cur) - xmlOutputBufferWrite(buf, cur - base, (const char *) base); - xmlOutputBufferWrite(buf, 5, "&"); - cur++; - base = cur; - } else if ((*cur >= 0x80) && (cur[1] != 0) && - ((doc == NULL) || (doc->encoding == NULL))) { - /* - * We assume we have UTF-8 content. - */ - unsigned char tmp[12]; - int val = 0, l = 4; - - if (base != cur) - xmlOutputBufferWrite(buf, cur - base, (const char *) base); - - val = xmlGetUTF8Char(cur, &l); - if (val < 0) { - val = 0xFFFD; - cur++; - } else { - if (!IS_CHAR(val)) - val = 0xFFFD; - cur += l; - } - - /* - * We could do multiple things here. Just save - * as a char ref - */ - xmlSerializeHexCharRef(tmp, val); - xmlOutputBufferWriteString(buf, (const char *) tmp); - base = cur; - } else { - cur++; - } - } - if (base != cur) - xmlOutputBufferWrite(buf, cur - base, (const char *) base); + if ((doc == NULL) || (doc->encoding == NULL)) + flags |= XML_ESCAPE_NON_ASCII; + xmlSerializeText(buf, string, flags); } /** @@ -2799,7 +2729,6 @@ xmlDocFormatDump(FILE *f, xmlDocPtr cur, int format) { res = xmlOpenCharEncodingHandler(encoding, /* output */ 1, &handler); if (res != XML_ERR_OK) { xmlFree((char *) cur->encoding); - cur->encoding = NULL; encoding = NULL; } }