From e248819673c1abd6da37258dbebb2afe94d1c46d Mon Sep 17 00:00:00 2001 From: Daniel Veillard Date: Thu, 4 Jan 2001 10:54:22 +0000 Subject: [PATCH] - encoding.c xmlIO.c: Fixing the problem reported by Marc Sanfacon Daniel --- ChangeLog | 5 +++ encoding.c | 17 ++++++-- xmlIO.c | 117 +++++++++++++++++++++++++++++------------------------ 3 files changed, 84 insertions(+), 55 deletions(-) diff --git a/ChangeLog b/ChangeLog index 96ff252b..ea27bc0a 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,8 @@ +Thu Jan 4 11:46:40 CET 2001 Daniel Veillard + + * encoding.c xmlIO.c: Fixing the problem reported by Marc Sanfacon + on large files + Wed Jan 3 21:51:13 CET 2001 Daniel Veillard * xmlIO.c: fixed xmlParserInputBufferCreateMem doc diff --git a/encoding.c b/encoding.c index 643d7f88..fab241e6 100644 --- a/encoding.c +++ b/encoding.c @@ -1812,7 +1812,7 @@ xmlCharEncInFunc(xmlCharEncodingHandler *handler, xmlBufferPtr out, return(0); written = out->size - out->use; if (toconv * 2 >= written) { - xmlBufferGrow(out, toconv * 2); + xmlBufferGrow(out, out->size + toconv * 2); written = out->size - out->use - 1; } if (handler->input != NULL) { @@ -1886,6 +1886,7 @@ xmlCharEncOutFunc(xmlCharEncodingHandler *handler, xmlBufferPtr out, xmlBufferPtr in) { int ret = -2; int written; + int writtentot = 0; int toconv; int output = 0; @@ -1937,6 +1938,7 @@ retry: in->content, &toconv); xmlBufferShrink(in, toconv); out->use += written; + writtentot += written; out->content[out->use] = 0; } #ifdef LIBXML_ICONV_ENABLED @@ -1945,8 +1947,17 @@ retry: &written, in->content, &toconv); xmlBufferShrink(in, toconv); out->use += written; + writtentot += written; out->content[out->use] = 0; - if (ret == -1) ret = -3; + if (ret == -1) { + if (written > 0) { + /* + * Can be a limitation of iconv + */ + goto retry; + } + ret = -3; + } } #endif /* LIBXML_ICONV_ENABLED */ else { @@ -1971,11 +1982,11 @@ retry: xmlGenericError(xmlGenericErrorContext, "output conversion failed by lack of space\n"); break; +#endif case -3: xmlGenericError(xmlGenericErrorContext,"converted %d bytes to %d bytes of output %d left\n", toconv, written, in->use); break; -#endif case -2: { int len = in->use; const xmlChar *utf = (const xmlChar *) in->content; diff --git a/xmlIO.c b/xmlIO.c index e2fff08b..a7c288ca 100644 --- a/xmlIO.c +++ b/xmlIO.c @@ -1377,71 +1377,84 @@ xmlParserInputBufferRead(xmlParserInputBufferPtr in, int len) { */ int xmlOutputBufferWrite(xmlOutputBufferPtr out, int len, const char *buf) { - int nbchars = 0, ret; + 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 chunk; /* number of byte curreent processed from buf */ if (len < 0) return(0); - /* - * first handle encoding stuff. - */ - if (out->encoder != NULL) { - /* - * Store the data in the incoming raw buffer - */ - if (out->conv == NULL) { - out->conv = xmlBufferCreate(); - } - xmlBufferAdd(out->buffer, (const xmlChar *) buf, len); - - if (out->buffer->use < MINLEN) - return(0); + do { + chunk = len; + if (chunk > 4 * MINLEN) + chunk = 4 * MINLEN; /* - * convert as much as possible to the parser reading buffer. + * first handle encoding stuff. */ - nbchars = xmlCharEncOutFunc(out->encoder, out->conv, out->buffer); - if (nbchars < 0) { - xmlGenericError(xmlGenericErrorContext, - "xmlOutputBufferWrite: encoder error\n"); - return(-1); + if (out->encoder != NULL) { + /* + * Store the data in the incoming raw buffer + */ + if (out->conv == NULL) { + out->conv = xmlBufferCreate(); + } + xmlBufferAdd(out->buffer, (const xmlChar *) buf, chunk); + + if ((out->buffer->use < MINLEN) && (chunk == len)) + goto done; + + /* + * convert as much as possible to the parser reading buffer. + */ + ret = xmlCharEncOutFunc(out->encoder, out->conv, out->buffer); + if (ret < 0) { + xmlGenericError(xmlGenericErrorContext, + "xmlOutputBufferWrite: encoder error\n"); + return(-1); + } + nbchars = out->conv->use; + } else { + xmlBufferAdd(out->buffer, (const xmlChar *) buf, chunk); + nbchars = out->buffer->use; } - nbchars = out->conv->use; - } else { - xmlBufferAdd(out->buffer, (const xmlChar *) buf, len); - nbchars = out->buffer->use; - } - if (nbchars < MINLEN) - return(0); + buf += chunk; + len -= chunk; - if (!out->writecallback) - return(nbchars); + 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 *)out->conv->content, nbchars); - if (ret >= 0) - xmlBufferShrink(out->conv, nbchars); - } else { - ret = out->writecallback(out->context, - (const char *)out->buffer->content, nbchars); - if (ret >= 0) - xmlBufferShrink(out->buffer, nbchars); - } - if (ret < 0) { - xmlGenericError(xmlGenericErrorContext, - "I/O: error %d writing %d bytes\n", ret, nbchars); - return(ret); - } - out->written += ret; + if (out->writecallback) { + /* + * second write the stuff to the I/O channel + */ + if (out->encoder != NULL) { + ret = out->writecallback(out->context, + (const char *)out->conv->content, nbchars); + if (ret >= 0) + xmlBufferShrink(out->conv, nbchars); + } else { + ret = out->writecallback(out->context, + (const char *)out->buffer->content, nbchars); + if (ret >= 0) + xmlBufferShrink(out->buffer, nbchars); + } + if (ret < 0) { + xmlGenericError(xmlGenericErrorContext, + "I/O: error %d writing %d bytes\n", ret, nbchars); + return(ret); + } + out->written += ret; + } + written += nbchars; + } while (len > 0); +done: #ifdef DEBUG_INPUT xmlGenericError(xmlGenericErrorContext, - "I/O: wrote %d chars\n", ret); + "I/O: wrote %d chars\n", written); #endif - return(nbchars); + return(written); } /**