diff options
Diffstat (limited to 'gnulib-local/lib/libxml/xmlIO.c')
-rw-r--r-- | gnulib-local/lib/libxml/xmlIO.c | 666 |
1 files changed, 501 insertions, 165 deletions
diff --git a/gnulib-local/lib/libxml/xmlIO.c b/gnulib-local/lib/libxml/xmlIO.c index 90db848..8b13184 100644 --- a/gnulib-local/lib/libxml/xmlIO.c +++ b/gnulib-local/lib/libxml/xmlIO.c @@ -35,11 +35,18 @@ #ifdef HAVE_ZLIB_H #include <zlib.h> #endif +#ifdef HAVE_LZMA_H +#include <lzma.h> +#endif -#ifdef WIN32 +#if defined(WIN32) || defined(_WIN32) #include <windows.h> #endif +#if defined(_WIN32_WCE) +#include <winnls.h> /* for CP_UTF8 */ +#endif + /* Figure a portable way to know if a file is a directory. */ #ifndef HAVE_STAT # ifdef HAVE__STAT @@ -89,6 +96,9 @@ #endif #include <libxml/globals.h> +#include "buf.h" +#include "enc.h" + /* #define VERBOSE_FAILURE */ /* #define DEBUG_EXTERNAL_ENTITIES */ /* #define DEBUG_INPUT */ @@ -131,11 +141,14 @@ typedef struct _xmlOutputCallback { static xmlOutputCallback xmlOutputCallbackTable[MAX_OUTPUT_CALLBACK]; static int xmlOutputCallbackNr = 0; static int xmlOutputCallbackInitialized = 0; + +xmlOutputBufferPtr +xmlAllocOutputBufferInternal(xmlCharEncodingHandlerPtr encoder); #endif /* LIBXML_OUTPUT_ENABLED */ /************************************************************************ * * - * Tree memory error handler * + * Tree memory error handler * * * ************************************************************************/ @@ -418,7 +431,7 @@ __xmlIOErr(int domain, int code, const char *extra) idx = 0; if (code >= XML_IO_UNKNOWN) idx = code - XML_IO_UNKNOWN; if (idx >= (sizeof(IOerr) / sizeof(IOerr[0]))) idx = 0; - + __xmlSimpleError(domain, code, NULL, IOerr[idx], extra); } @@ -470,12 +483,12 @@ __xmlLoaderErr(void *ctx, const char *msg, const char *filename) XML_IO_LOAD_ERROR, level, NULL, 0, filename, NULL, NULL, 0, 0, msg, filename); - + } /************************************************************************ * * - * Tree memory error handler * + * Tree memory error handler * * * ************************************************************************/ /** @@ -497,7 +510,7 @@ xmlNormalizeWindowsPath(const xmlChar *path) * xmlCleanupInputCallbacks: * * clears the entire input callback table. this includes the - * compiled-in I/O. + * compiled-in I/O. */ void xmlCleanupInputCallbacks(void) @@ -522,7 +535,7 @@ xmlCleanupInputCallbacks(void) * xmlPopInputCallbacks: * * Clear the top input callback from the input stack. this includes the - * compiled-in I/O. + * compiled-in I/O. * * Returns the number of input callback registered or -1 in case of error. */ @@ -534,7 +547,7 @@ xmlPopInputCallbacks(void) if (xmlInputCallbackNr <= 0) return(-1); - + xmlInputCallbackNr--; xmlInputCallbackTable[xmlInputCallbackNr].matchcallback = NULL; xmlInputCallbackTable[xmlInputCallbackNr].opencallback = NULL; @@ -549,7 +562,7 @@ xmlPopInputCallbacks(void) * xmlCleanupOutputCallbacks: * * clears the entire output callback table. this includes the - * compiled-in I/O callbacks. + * compiled-in I/O callbacks. */ void xmlCleanupOutputCallbacks(void) @@ -606,6 +619,34 @@ xmlWrapOpenUtf8(const char *path,int mode) return fd; } +#ifdef HAVE_ZLIB_H +static gzFile +xmlWrapGzOpenUtf8(const char *path, const char *mode) +{ + gzFile fd; + wchar_t *wPath; + + fd = gzopen (path, mode); + if (fd) + return fd; + + wPath = __xmlIOWin32UTF8ToWChar(path); + if(wPath) + { + int d, m = (strstr(mode, "r") ? O_RDONLY : O_RDWR); +#ifdef _O_BINARY + m |= (strstr(mode, "b") ? _O_BINARY : 0); +#endif + d = _wopen(wPath, m); + if (d >= 0) + fd = gzdopen(d, mode); + xmlFree(wPath); + } + + return fd; +} +#endif + /** * xmlWrapStatUtf8: * @path: the path in utf-8 encoding @@ -672,7 +713,10 @@ typedef int (* xmlWrapStatFunc) (const char *f, struct stat *s); static xmlWrapStatFunc xmlWrapStat = xmlWrapStatNative; typedef FILE* (* xmlWrapOpenFunc)(const char *f,int mode); static xmlWrapOpenFunc xmlWrapOpen = xmlWrapOpenNative; - +#ifdef HAVE_ZLIB_H +typedef gzFile (* xmlWrapGzOpenFunc) (const char *f, const char *mode); +static xmlWrapGzOpenFunc xmlWrapGzOpen = gzopen; +#endif /** * xmlInitPlatformSpecificIo: * @@ -692,9 +736,15 @@ xmlInitPlatformSpecificIo(void) if(GetVersionEx(&osvi) && (osvi.dwPlatformId == VER_PLATFORM_WIN32_NT)) { xmlWrapStat = xmlWrapStatUtf8; xmlWrapOpen = xmlWrapOpenUtf8; +#ifdef HAVE_ZLIB_H + xmlWrapGzOpen = xmlWrapGzOpenUtf8; +#endif } else { xmlWrapStat = xmlWrapStatNative; xmlWrapOpen = xmlWrapOpenNative; +#ifdef HAVE_ZLIB_H + xmlWrapGzOpen = gzopen; +#endif } xmlPlatformIoInitialized = 1; @@ -721,13 +771,21 @@ int xmlCheckFilename (const char *path) { #ifdef HAVE_STAT - struct stat stat_buffer; + struct stat stat_buffer; #endif - if (path == NULL) - return(0); + if (path == NULL) + return(0); #ifdef HAVE_STAT #if defined(_WIN32) || defined (__DJGPP__) && !defined (__CYGWIN__) + /* + * On Windows stat and wstat do not work with long pathname, + * which start with '\\?\' + */ + if ((path[0] == '\\') && (path[1] == '\\') && (path[2] == '?') && + (path[3] == '\\') ) + return 1; + if (xmlWrapStat(path, &stat_buffer) == -1) return 0; #else @@ -742,7 +800,14 @@ xmlCheckFilename (const char *path) return 1; } -static int +/** + * xmlNop: + * + * No Operation function, does nothing, no input + * + * Returns zero + */ +int xmlNop(void) { return(0); } @@ -829,7 +894,7 @@ xmlFileMatch (const char *filename ATTRIBUTE_UNUSED) { */ static void * xmlFileOpen_real (const char *filename) { - const char *path = NULL; + const char *path = filename; FILE *fd; if (filename == NULL) @@ -840,23 +905,27 @@ xmlFileOpen_real (const char *filename) { return((void *) fd); } - if (!xmlStrncasecmp(BAD_CAST filename, BAD_CAST "file://localhost/", 17)) + if (!xmlStrncasecmp(BAD_CAST filename, BAD_CAST "file://localhost/", 17)) { #if defined (_WIN32) || defined (__DJGPP__) && !defined(__CYGWIN__) path = &filename[17]; #else path = &filename[16]; #endif - else if (!xmlStrncasecmp(BAD_CAST filename, BAD_CAST "file:///", 8)) { + } else if (!xmlStrncasecmp(BAD_CAST filename, BAD_CAST "file:///", 8)) { #if defined (_WIN32) || defined (__DJGPP__) && !defined(__CYGWIN__) path = &filename[8]; #else path = &filename[7]; #endif - } else - path = filename; + } else if (!xmlStrncasecmp(BAD_CAST filename, BAD_CAST "file:/", 6)) { + /* lots of generators seems to lazy to read RFC 1738 */ +#if defined (_WIN32) || defined (__DJGPP__) && !defined(__CYGWIN__) + path = &filename[6]; +#else + path = &filename[5]; +#endif + } - if (path == NULL) - return(NULL); if (!xmlCheckFilename(path)) return(NULL); @@ -883,13 +952,15 @@ xmlFileOpen (const char *filename) { char *unescaped; void *retval; - unescaped = xmlURIUnescapeString(filename, 0, NULL); - if (unescaped != NULL) { - retval = xmlFileOpen_real(unescaped); - xmlFree(unescaped); - } else { - retval = xmlFileOpen_real(filename); + retval = xmlFileOpen_real(filename); + if (retval == NULL) { + unescaped = xmlURIUnescapeString(filename, 0, NULL); + if (unescaped != NULL) { + retval = xmlFileOpen_real(unescaped); + xmlFree(unescaped); + } } + return retval; } @@ -925,7 +996,7 @@ xmlFileOpenW (const char *filename) { #else path = &filename[7]; #endif - } else + } else path = filename; if (path == NULL) @@ -934,7 +1005,7 @@ xmlFileOpenW (const char *filename) { #if defined(_WIN32) || defined (__DJGPP__) && !defined (__CYGWIN__) fd = xmlWrapOpen(path, 1); #else - fd = fopen(path, "wb"); + fd = fopen(path, "wb"); #endif /* WIN32 */ if (fd == NULL) xmlIOErr(0, path); @@ -955,7 +1026,7 @@ xmlFileOpenW (const char *filename) { int xmlFileRead (void * context, char * buffer, int len) { int ret; - if ((context == NULL) || (buffer == NULL)) + if ((context == NULL) || (buffer == NULL)) return(-1); ret = fread(&buffer[0], 1, len, (FILE *) context); if (ret < 0) xmlIOErr(0, "fread()"); @@ -977,7 +1048,7 @@ static int xmlFileWrite (void * context, const char * buffer, int len) { int items; - if ((context == NULL) || (buffer == NULL)) + if ((context == NULL) || (buffer == NULL)) return(-1); items = fwrite(&buffer[0], len, 1, (FILE *) context); if ((items == 0) && (ferror((FILE *) context))) { @@ -1092,7 +1163,12 @@ xmlGzfileOpen_real (const char *filename) { gzFile fd; if (!strcmp(filename, "-")) { - fd = gzdopen(dup(0), "rb"); + int duped_fd = dup(fileno(stdin)); + fd = gzdopen(duped_fd, "rb"); + if (fd == Z_NULL && duped_fd >= 0) { + close(duped_fd); /* gzdOpen() does not close on failure */ + } + return((void *) fd); } @@ -1108,7 +1184,7 @@ xmlGzfileOpen_real (const char *filename) { #else path = &filename[7]; #endif - } else + } else path = filename; if (path == NULL) @@ -1116,7 +1192,11 @@ xmlGzfileOpen_real (const char *filename) { if (!xmlCheckFilename(path)) return(NULL); +#if defined(_WIN32) || defined (__DJGPP__) && !defined (__CYGWIN__) + fd = xmlWrapGzOpen(path, "rb"); +#else fd = gzopen(path, "rb"); +#endif return((void *) fd); } @@ -1162,7 +1242,12 @@ xmlGzfileOpenW (const char *filename, int compression) { snprintf(mode, sizeof(mode), "wb%d", compression); if (!strcmp(filename, "-")) { - fd = gzdopen(dup(1), mode); + int duped_fd = dup(fileno(stdout)); + fd = gzdopen(duped_fd, "rb"); + if (fd == Z_NULL && duped_fd >= 0) { + close(duped_fd); /* gzdOpen() does not close on failure */ + } + return((void *) fd); } @@ -1178,13 +1263,17 @@ xmlGzfileOpenW (const char *filename, int compression) { #else path = &filename[7]; #endif - } else + } else path = filename; if (path == NULL) return(NULL); +#if defined(_WIN32) || defined (__DJGPP__) && !defined (__CYGWIN__) + fd = xmlWrapGzOpen(path, mode); +#else fd = gzopen(path, mode); +#endif return((void *) fd); } #endif /* LIBXML_OUTPUT_ENABLED */ @@ -1245,6 +1334,125 @@ xmlGzfileClose (void * context) { } #endif /* HAVE_ZLIB_H */ +#ifdef LIBXML_LZMA_ENABLED +/************************************************************************ + * * + * I/O for compressed file accesses * + * * + ************************************************************************/ +#include "xzlib.h" +/** + * xmlXzfileMatch: + * @filename: the URI for matching + * + * input from compressed file test + * + * Returns 1 if matches, 0 otherwise + */ +static int +xmlXzfileMatch (const char *filename ATTRIBUTE_UNUSED) { + return(1); +} + +/** + * xmlXzFileOpen_real: + * @filename: the URI for matching + * + * input from compressed file open + * if @filename is " " then the standard input is used + * + * Returns an I/O context or NULL in case of error + */ +static void * +xmlXzfileOpen_real (const char *filename) { + const char *path = NULL; + xzFile fd; + + if (!strcmp(filename, "-")) { + fd = __libxml2_xzdopen(dup(fileno(stdin)), "rb"); + return((void *) fd); + } + + if (!xmlStrncasecmp(BAD_CAST filename, BAD_CAST "file://localhost/", 17)) { + path = &filename[16]; + } else if (!xmlStrncasecmp(BAD_CAST filename, BAD_CAST "file:///", 8)) { + path = &filename[7]; + } else if (!xmlStrncasecmp(BAD_CAST filename, BAD_CAST "file:/", 6)) { + /* lots of generators seems to lazy to read RFC 1738 */ + path = &filename[5]; + } else + path = filename; + + if (path == NULL) + return(NULL); + if (!xmlCheckFilename(path)) + return(NULL); + + fd = __libxml2_xzopen(path, "rb"); + return((void *) fd); +} + +/** + * xmlXzfileOpen: + * @filename: the URI for matching + * + * Wrapper around xmlXzfileOpen_real that try it with an unescaped + * version of @filename, if this fails fallback to @filename + * + * Returns a handler or NULL in case or failure + */ +static void * +xmlXzfileOpen (const char *filename) { + char *unescaped; + void *retval; + + retval = xmlXzfileOpen_real(filename); + if (retval == NULL) { + unescaped = xmlURIUnescapeString(filename, 0, NULL); + if (unescaped != NULL) { + retval = xmlXzfileOpen_real(unescaped); + } + xmlFree(unescaped); + } + + return retval; +} + +/** + * xmlXzfileRead: + * @context: the I/O context + * @buffer: where to drop data + * @len: number of bytes to write + * + * Read @len bytes to @buffer from the compressed I/O channel. + * + * Returns the number of bytes written + */ +static int +xmlXzfileRead (void * context, char * buffer, int len) { + int ret; + + ret = __libxml2_xzread((xzFile) context, &buffer[0], len); + if (ret < 0) xmlIOErr(0, "xzread()"); + return(ret); +} + +/** + * xmlXzfileClose: + * @context: the I/O context + * + * Close a compressed I/O channel + */ +static int +xmlXzfileClose (void * context) { + int ret; + + ret = (__libxml2_xzclose((xzFile) context) == LZMA_OK ) ? 0 : -1; + if (ret < 0) xmlIOErr(0, "xzclose()"); + return(ret); +} +#endif /* LIBXML_LZMA_ENABLED */ + #ifdef LIBXML_HTTP_ENABLED /************************************************************************ * * @@ -1306,7 +1514,7 @@ append_reverse_ulong( xmlZMemBuff * buff, unsigned long data ) { /* ** This is plagiarized from putLong in gzio.c (zlib source) where - ** the number "4" is hardcoded. If zlib is ever patched to + ** the number "4" is hardcoded. If zlib is ever patched to ** support 64 bit file sizes, this code would need to be patched ** as well. */ @@ -1358,7 +1566,7 @@ xmlFreeZMemBuff( xmlZMemBuffPtr buff ) { * * Create a memory buffer to hold the compressed XML document. The * compressed document in memory will end up being identical to what - * would be created if gzopen/gzwrite/gzclose were being used to + * would be created if gzopen/gzwrite/gzclose were being used to * write the document to disk. The code for the header/trailer data to * the compression is plagiarized from the zlib source files. */ @@ -1407,7 +1615,7 @@ xmlCreateZMemBuff( int compression ) { buff->crc = crc32( 0L, NULL, 0 ); hdr_lgth = snprintf( (char *)buff->zbuff, buff->size, "%c%c%c%c%c%c%c%c%c%c", - GZ_MAGIC1, GZ_MAGIC2, Z_DEFLATED, + GZ_MAGIC1, GZ_MAGIC2, Z_DEFLATED, 0, 0, 0, 0, 0, 0, LXML_ZLIB_OS_CODE ); buff->zctrl.next_out = buff->zbuff + hdr_lgth; buff->zctrl.avail_out = buff->size - hdr_lgth; @@ -1445,11 +1653,11 @@ xmlZMemBuffExtend( xmlZMemBuffPtr buff, size_t ext_amt ) { new_size = buff->size + ext_amt; #ifdef DEBUG_HTTP - if ( cur_used > new_size ) + if ( cur_used > new_size ) xmlGenericError( xmlGenericErrorContext, "xmlZMemBuffExtend: %s\n%s %d bytes.\n", "Buffer overwrite detected during compressed memory", - "buffer extension. Overflowed by", + "buffer extension. Overflowed by", (cur_used - new_size ) ); #endif @@ -1587,7 +1795,7 @@ xmlZMemBuffGetContent( xmlZMemBuffPtr buff, char ** data_ref ) { "Error flushing zlib buffers. Error code", z_err ); xmlIOErr(XML_IO_WRITE, (const char *) msg); } - + return ( zlgth ); } #endif /* LIBXML_OUTPUT_ENABLED */ @@ -1707,7 +1915,7 @@ xmlIOHTTPOpenW(const char *post_uri, int compression) { /* Any character conversions should have been done before this */ - ctxt->doc_buff = xmlAllocOutputBuffer(NULL); + ctxt->doc_buff = xmlAllocOutputBufferInternal(NULL); } if (ctxt->doc_buff == NULL) { @@ -1718,7 +1926,7 @@ xmlIOHTTPOpenW(const char *post_uri, int compression) return (ctxt); } #endif /* LIBXML_OUTPUT_ENABLED */ - + #ifdef LIBXML_OUTPUT_ENABLED /** * xmlIOHTTPDfltOpenW @@ -1746,7 +1954,7 @@ xmlIOHTTPDfltOpenW( const char * post_uri ) { * * Returns the number of bytes written */ -int +int xmlIOHTTPRead(void * context, char * buffer, int len) { if ((buffer == NULL) || (len < 0)) return(-1); return(xmlNanoHTTPRead(context, &buffer[0], len)); @@ -1766,7 +1974,7 @@ xmlIOHTTPRead(void * context, char * buffer, int len) { */ static int -xmlIOHTTPWrite( void * context, const char * buffer, int len ) { +xmlIOHTTPWrite( void * context, const char * buffer, int len ) { xmlIOHTTPWriteCtxtPtr ctxt = context; @@ -1778,7 +1986,7 @@ xmlIOHTTPWrite( void * context, const char * buffer, int len ) { /* Use gzwrite or fwrite as previously setup in the open call */ #ifdef HAVE_ZLIB_H - if ( ctxt->compression > 0 ) + if ( ctxt->compression > 0 ) len = xmlZMemBuffAppend( ctxt->doc_buff, buffer, len ); else @@ -1853,8 +2061,8 @@ xmlIOHTTPCloseWrite( void * context, const char * http_mthd ) { /* Pull the data out of the memory output buffer */ xmlOutputBufferPtr dctxt = ctxt->doc_buff; - http_content = (char *)dctxt->buffer->content; - content_lgth = dctxt->buffer->use; + http_content = (char *) xmlBufContent(dctxt->buffer); + content_lgth = xmlBufUse(dctxt->buffer); } if ( http_content == NULL ) { @@ -1869,7 +2077,7 @@ xmlIOHTTPCloseWrite( void * context, const char * http_mthd ) { else { http_ctxt = xmlNanoHTTPMethod( ctxt->uri, http_mthd, http_content, - &content_type, content_encoding, + &content_type, content_encoding, content_lgth ); if ( http_ctxt != NULL ) { @@ -1888,7 +2096,7 @@ xmlIOHTTPCloseWrite( void * context, const char * http_mthd ) { /* ** Since either content or reply may be gzipped, - ** dump them to separate files instead of the + ** dump them to separate files instead of the ** standard error context. */ @@ -2025,7 +2233,7 @@ xmlIOFTPOpen (const char *filename) { * * Returns the number of bytes written */ -int +int xmlIOFTPRead(void * context, char * buffer, int len) { if ((buffer == NULL) || (len < 0)) return(-1); return(xmlNanoFTPRead(context, &buffer[0], len)); @@ -2088,7 +2296,7 @@ int xmlRegisterOutputCallbacks(xmlOutputMatchCallback matchFunc, xmlOutputOpenCallback openFunc, xmlOutputWriteCallback writeFunc, xmlOutputCloseCallback closeFunc) { - if (xmlOutputCallbackNr >= MAX_INPUT_CALLBACK) { + if (xmlOutputCallbackNr >= MAX_OUTPUT_CALLBACK) { return(-1); } xmlOutputCallbackTable[xmlOutputCallbackNr].matchcallback = matchFunc; @@ -2120,6 +2328,10 @@ xmlRegisterDefaultInputCallbacks(void) { xmlRegisterInputCallbacks(xmlGzfileMatch, xmlGzfileOpen, xmlGzfileRead, xmlGzfileClose); #endif /* HAVE_ZLIB_H */ +#ifdef LIBXML_LZMA_ENABLED + xmlRegisterInputCallbacks(xmlXzfileMatch, xmlXzfileOpen, + xmlXzfileRead, xmlXzfileClose); +#endif /* LIBXML_LZMA_ENABLED */ #ifdef LIBXML_HTTP_ENABLED xmlRegisterInputCallbacks(xmlIOHTTPMatch, xmlIOHTTPOpen, @@ -2217,15 +2429,15 @@ xmlAllocParserInputBuffer(xmlCharEncoding enc) { return(NULL); } memset(ret, 0, (size_t) sizeof(xmlParserInputBuffer)); - ret->buffer = xmlBufferCreateSize(2 * xmlDefaultBufferSize); + ret->buffer = xmlBufCreateSize(2 * xmlDefaultBufferSize); if (ret->buffer == NULL) { xmlFree(ret); return(NULL); } - ret->buffer->alloc = XML_BUFFER_ALLOC_DOUBLEIT; + xmlBufSetAllocationScheme(ret->buffer, XML_BUFFER_ALLOC_DOUBLEIT); ret->encoder = xmlGetCharEncodingHandler(enc); if (ret->encoder != NULL) - ret->raw = xmlBufferCreateSize(2 * xmlDefaultBufferSize); + ret->raw = xmlBufCreateSize(2 * xmlDefaultBufferSize); else ret->raw = NULL; ret->readcallback = NULL; @@ -2256,19 +2468,80 @@ xmlAllocOutputBuffer(xmlCharEncodingHandlerPtr encoder) { return(NULL); } memset(ret, 0, (size_t) sizeof(xmlOutputBuffer)); - ret->buffer = xmlBufferCreate(); + ret->buffer = xmlBufCreate(); + if (ret->buffer == NULL) { + xmlFree(ret); + return(NULL); + } + + /* try to avoid a performance problem with Windows realloc() */ + if (xmlBufGetAllocationScheme(ret->buffer) == XML_BUFFER_ALLOC_EXACT) + xmlBufSetAllocationScheme(ret->buffer, XML_BUFFER_ALLOC_DOUBLEIT); + + ret->encoder = encoder; + if (encoder != NULL) { + ret->conv = xmlBufCreateSize(4000); + if (ret->conv == NULL) { + xmlFree(ret); + return(NULL); + } + + /* + * This call is designed to initiate the encoder state + */ + xmlCharEncOutput(ret, 1); + } else + ret->conv = NULL; + ret->writecallback = NULL; + ret->closecallback = NULL; + ret->context = NULL; + ret->written = 0; + + return(ret); +} + +/** + * xmlAllocOutputBufferInternal: + * @encoder: the encoding converter or NULL + * + * Create a buffered parser output + * + * Returns the new parser output or NULL + */ +xmlOutputBufferPtr +xmlAllocOutputBufferInternal(xmlCharEncodingHandlerPtr encoder) { + xmlOutputBufferPtr ret; + + ret = (xmlOutputBufferPtr) xmlMalloc(sizeof(xmlOutputBuffer)); + if (ret == NULL) { + xmlIOErrMemory("creating output buffer"); + return(NULL); + } + memset(ret, 0, (size_t) sizeof(xmlOutputBuffer)); + ret->buffer = xmlBufCreate(); if (ret->buffer == NULL) { xmlFree(ret); return(NULL); } - ret->buffer->alloc = XML_BUFFER_ALLOC_DOUBLEIT; + + + /* + * For conversion buffers we use the special IO handling + */ + xmlBufSetAllocationScheme(ret->buffer, XML_BUFFER_ALLOC_IO); + ret->encoder = encoder; if (encoder != NULL) { - ret->conv = xmlBufferCreateSize(4000); + ret->conv = xmlBufCreateSize(4000); + if (ret->conv == NULL) { + xmlFree(ret); + return(NULL); + } + /* * This call is designed to initiate the encoder state */ - xmlCharEncOutFunc(encoder, ret->conv, NULL); + xmlCharEncOutput(ret, 1); } else ret->conv = NULL; ret->writecallback = NULL; @@ -2278,6 +2551,7 @@ xmlAllocOutputBuffer(xmlCharEncodingHandlerPtr encoder) { return(ret); } + #endif /* LIBXML_OUTPUT_ENABLED */ /** @@ -2291,7 +2565,7 @@ xmlFreeParserInputBuffer(xmlParserInputBufferPtr in) { if (in == NULL) return; if (in->raw) { - xmlBufferFree(in->raw); + xmlBufFree(in->raw); in->raw = NULL; } if (in->encoder != NULL) { @@ -2301,7 +2575,7 @@ xmlFreeParserInputBuffer(xmlParserInputBufferPtr in) { in->closecallback(in->context); } if (in->buffer != NULL) { - xmlBufferFree(in->buffer); + xmlBufFree(in->buffer); in->buffer = NULL; } @@ -2333,14 +2607,14 @@ xmlOutputBufferClose(xmlOutputBufferPtr out) } written = out->written; if (out->conv) { - xmlBufferFree(out->conv); + xmlBufFree(out->conv); out->conv = NULL; } if (out->encoder != NULL) { xmlCharEncCloseFunc(out->encoder); } if (out->buffer != NULL) { - xmlBufferFree(out->buffer); + xmlBufFree(out->buffer); out->buffer = NULL; } @@ -2392,6 +2666,9 @@ __xmlParserInputBufferCreateFilename(const char *URI, xmlCharEncoding enc) { #ifdef HAVE_ZLIB_H if ((xmlInputCallbackTable[i].opencallback == xmlGzfileOpen) && (strcmp(URI, "-") != 0)) { +#if defined(ZLIB_VERNUM) && ZLIB_VERNUM >= 0x1230 + ret->compressed = !gzdirect(context); +#else if (((z_stream *)context)->avail_in > 4) { char *cptr, buff4[4]; cptr = (char *) ((z_stream *)context)->next_in; @@ -2403,6 +2680,13 @@ __xmlParserInputBufferCreateFilename(const char *URI, xmlCharEncoding enc) { gzrewind(context); } } +#endif + } +#endif +#ifdef LIBXML_LZMA_ENABLED + if ((xmlInputCallbackTable[i].opencallback == xmlXzfileOpen) && + (strcmp(URI, "-") != 0)) { + ret->compressed = __libxml2_xzcompressed(context); } #endif } @@ -2478,7 +2762,7 @@ __xmlOutputBufferCreateFilename(const char *URI, if ((compression > 0) && (compression <= 9) && (is_file_uri == 1)) { context = xmlGzfileOpenW(unescaped, compression); if (context != NULL) { - ret = xmlAllocOutputBuffer(encoder); + ret = xmlAllocOutputBufferInternal(encoder); if (ret != NULL) { ret->context = context; ret->writecallback = xmlGzfileWrite; @@ -2515,7 +2799,7 @@ __xmlOutputBufferCreateFilename(const char *URI, if ((compression > 0) && (compression <= 9) && (is_file_uri == 1)) { context = xmlGzfileOpenW(URI, compression); if (context != NULL) { - ret = xmlAllocOutputBuffer(encoder); + ret = xmlAllocOutputBufferInternal(encoder); if (ret != NULL) { ret->context = context; ret->writecallback = xmlGzfileWrite; @@ -2548,7 +2832,7 @@ __xmlOutputBufferCreateFilename(const char *URI, /* * Allocate the Output buffer front-end. */ - ret = xmlAllocOutputBuffer(encoder); + ret = xmlAllocOutputBufferInternal(encoder); if (ret != NULL) { ret->context = context; ret->writecallback = xmlOutputCallbackTable[i].writecallback; @@ -2585,7 +2869,7 @@ xmlOutputBufferCreateFilename(const char *URI, /** * xmlParserInputBufferCreateFile: - * @file: a FILE* + * @file: a FILE* * @enc: the charset encoding if known * * Create a buffered parser input for the progressive parsing of a FILE * @@ -2615,7 +2899,7 @@ xmlParserInputBufferCreateFile(FILE *file, xmlCharEncoding enc) { #ifdef LIBXML_OUTPUT_ENABLED /** * xmlOutputBufferCreateFile: - * @file: a FILE* + * @file: a FILE* * @encoder: the encoding converter or NULL * * Create a buffered output for the progressive saving to a FILE * @@ -2632,7 +2916,7 @@ xmlOutputBufferCreateFile(FILE *file, xmlCharEncodingHandlerPtr encoder) { if (file == NULL) return(NULL); - ret = xmlAllocOutputBuffer(encoder); + ret = xmlAllocOutputBufferInternal(encoder); if (ret != NULL) { ret->context = file; ret->writecallback = xmlFileWrite; @@ -2666,6 +2950,39 @@ xmlOutputBufferCreateBuffer(xmlBufferPtr buffer, return(ret); } +/** + * xmlOutputBufferGetContent: + * @out: an xmlOutputBufferPtr + * + * Gives a pointer to the data currently held in the output buffer + * + * Returns a pointer to the data or NULL in case of error + */ +const xmlChar * +xmlOutputBufferGetContent(xmlOutputBufferPtr out) { + if ((out == NULL) || (out->buffer == NULL)) + return(NULL); + + return(xmlBufContent(out->buffer)); +} + +/** + * xmlOutputBufferGetSize: + * @out: an xmlOutputBufferPtr + * + * Gives the length of the data currently held in the output buffer + * + * Returns 0 in case or error or no data is held, the size otherwise + */ +size_t +xmlOutputBufferGetSize(xmlOutputBufferPtr out) { + if ((out == NULL) || (out->buffer == NULL)) + return(0); + + return(xmlBufUse(out->buffer)); +} + + #endif /* LIBXML_OUTPUT_ENABLED */ /** @@ -2718,7 +3035,7 @@ xmlParserInputBufferCreateMem(const char *mem, int size, xmlCharEncoding enc) { ret->context = (void *) mem; ret->readcallback = (xmlInputReadCallback) xmlNop; ret->closecallback = NULL; - errcode = xmlBufferAdd(ret->buffer, (const xmlChar *) mem, size); + errcode = xmlBufAdd(ret->buffer, (const xmlChar *) mem, size); if (errcode != 0) { xmlFree(ret); return(NULL); @@ -2755,14 +3072,14 @@ xmlParserInputBufferCreateStatic(const char *mem, int size, return(NULL); } memset(ret, 0, (size_t) sizeof(xmlParserInputBuffer)); - ret->buffer = xmlBufferCreateStatic((void *)mem, (size_t) size); + ret->buffer = xmlBufCreateStatic((void *)mem, (size_t) size); if (ret->buffer == NULL) { xmlFree(ret); return(NULL); } ret->encoder = xmlGetCharEncodingHandler(enc); if (ret->encoder != NULL) - ret->raw = xmlBufferCreateSize(2 * xmlDefaultBufferSize); + ret->raw = xmlBufCreateSize(2 * xmlDefaultBufferSize); else ret->raw = NULL; ret->compressed = -1; @@ -2779,7 +3096,7 @@ xmlParserInputBufferCreateStatic(const char *mem, int size, * @fd: a file descriptor number * @encoder: the encoding converter or NULL * - * Create a buffered output for the progressive saving + * Create a buffered output for the progressive saving * to a file descriptor * * Returns the new parser output or NULL @@ -2790,7 +3107,7 @@ xmlOutputBufferCreateFd(int fd, xmlCharEncodingHandlerPtr encoder) { if (fd < 0) return(NULL); - ret = xmlAllocOutputBuffer(encoder); + ret = xmlAllocOutputBufferInternal(encoder); if (ret != NULL) { ret->context = (void *) (long) fd; ret->writecallback = xmlFdWrite; @@ -2851,7 +3168,7 @@ xmlOutputBufferCreateIO(xmlOutputWriteCallback iowrite, if (iowrite == NULL) return(NULL); - ret = xmlAllocOutputBuffer(encoder); + ret = xmlAllocOutputBufferInternal(encoder); if (ret != NULL) { ret->context = (void *) ioctx; ret->writecallback = iowrite; @@ -2931,33 +3248,33 @@ xmlParserInputBufferPush(xmlParserInputBufferPtr in, * Store the data in the incoming raw buffer */ if (in->raw == NULL) { - in->raw = xmlBufferCreate(); + in->raw = xmlBufCreate(); } - ret = xmlBufferAdd(in->raw, (const xmlChar *) buf, len); + ret = xmlBufAdd(in->raw, (const xmlChar *) buf, len); if (ret != 0) return(-1); /* * convert as much as possible to the parser reading buffer. */ - use = in->raw->use; - nbchars = xmlCharEncInFunc(in->encoder, in->buffer, in->raw); + use = xmlBufUse(in->raw); + nbchars = xmlCharEncInput(in, 1); if (nbchars < 0) { xmlIOErr(XML_IO_ENCODER, NULL); in->error = XML_IO_ENCODER; return(-1); } - in->rawconsumed += (use - in->raw->use); + in->rawconsumed += (use - xmlBufUse(in->raw)); } else { nbchars = len; - ret = xmlBufferAdd(in->buffer, (xmlChar *) buf, nbchars); + ret = xmlBufAdd(in->buffer, (xmlChar *) buf, nbchars); if (ret != 0) return(-1); } #ifdef DEBUG_INPUT xmlGenericError(xmlGenericErrorContext, "I/O: pushed %d chars, buffer %d/%d\n", - nbchars, in->buffer->use, in->buffer->size); + nbchars, xmlBufUse(in->buffer), xmlBufLength(in->buffer)); #endif return(nbchars); } @@ -2995,29 +3312,23 @@ xmlParserInputBufferGrow(xmlParserInputBufferPtr in, int len) { char *buffer = NULL; int res = 0; int nbchars = 0; - int buffree; - unsigned int needSize; if ((in == NULL) || (in->error)) return(-1); if ((len <= MINLEN) && (len != 4)) len = MINLEN; - buffree = in->buffer->size - in->buffer->use; - if (buffree <= 0) { + if (xmlBufAvail(in->buffer) <= 0) { xmlIOErr(XML_IO_BUFFER_FULL, NULL); in->error = XML_IO_BUFFER_FULL; return(-1); } - needSize = in->buffer->use + len + 1; - if (needSize > in->buffer->size){ - if (!xmlBufferResize(in->buffer, needSize)){ - xmlIOErrMemory("growing input buffer"); - in->error = XML_ERR_NO_MEMORY; - return(-1); - } + if (xmlBufGrow(in->buffer, len + 1) < 0) { + xmlIOErrMemory("growing input buffer"); + in->error = XML_ERR_NO_MEMORY; + return(-1); } - buffer = (char *)&in->buffer->content[in->buffer->use]; + buffer = (char *)xmlBufEnd(in->buffer); /* * Call the read method for this I/O type. @@ -3034,6 +3345,17 @@ xmlParserInputBufferGrow(xmlParserInputBufferPtr in, int len) { if (res < 0) { return(-1); } + + /* + * try to establish compressed status of input if not done already + */ + if (in->compressed == -1) { +#ifdef LIBXML_LZMA_ENABLED + if (in->readcallback == xmlXzfileRead) + in->compressed = __libxml2_xzcompressed(in->context); +#endif + } + len = res; if (in->encoder != NULL) { unsigned int use; @@ -3042,32 +3364,31 @@ xmlParserInputBufferGrow(xmlParserInputBufferPtr in, int len) { * Store the data in the incoming raw buffer */ if (in->raw == NULL) { - in->raw = xmlBufferCreate(); + in->raw = xmlBufCreate(); } - res = xmlBufferAdd(in->raw, (const xmlChar *) buffer, len); + res = xmlBufAdd(in->raw, (const xmlChar *) buffer, len); if (res != 0) return(-1); /* * convert as much as possible to the parser reading buffer. */ - use = in->raw->use; - nbchars = xmlCharEncInFunc(in->encoder, in->buffer, in->raw); + use = xmlBufUse(in->raw); + nbchars = xmlCharEncInput(in, 1); if (nbchars < 0) { xmlIOErr(XML_IO_ENCODER, NULL); in->error = XML_IO_ENCODER; return(-1); } - in->rawconsumed += (use - in->raw->use); + in->rawconsumed += (use - xmlBufUse(in->raw)); } else { nbchars = len; - in->buffer->use += nbchars; - buffer[nbchars] = 0; + xmlBufAddLen(in->buffer, nbchars); } #ifdef DEBUG_INPUT xmlGenericError(xmlGenericErrorContext, - "I/O: read %d chars, buffer %d/%d\n", - nbchars, in->buffer->use, in->buffer->size); + "I/O: read %d chars, buffer %d\n", + nbchars, xmlBufUse(in->buffer)); #endif return(nbchars); } @@ -3089,8 +3410,7 @@ xmlParserInputBufferRead(xmlParserInputBufferPtr in, int len) { if ((in == NULL) || (in->error)) return(-1); if (in->readcallback != NULL) return(xmlParserInputBufferGrow(in, len)); - else if ((in->buffer != NULL) && - (in->buffer->alloc == XML_BUFFER_ALLOC_IMMUTABLE)) + else if (xmlBufGetAllocationScheme(in->buffer) == XML_BUFFER_ALLOC_IMMUTABLE) return(0); else return(-1); @@ -3135,30 +3455,30 @@ xmlOutputBufferWrite(xmlOutputBufferPtr out, int len, const char *buf) { * Store the data in the incoming raw buffer */ if (out->conv == NULL) { - out->conv = xmlBufferCreate(); + out->conv = xmlBufCreate(); } - ret = xmlBufferAdd(out->buffer, (const xmlChar *) buf, chunk); + ret = xmlBufAdd(out->buffer, (const xmlChar *) buf, chunk); if (ret != 0) return(-1); - if ((out->buffer->use < MINLEN) && (chunk == len)) + if ((xmlBufUse(out->buffer) < MINLEN) && (chunk == len)) goto done; /* * convert as much as possible to the parser reading buffer. */ - ret = xmlCharEncOutFunc(out->encoder, out->conv, out->buffer); + ret = xmlCharEncOutput(out, 0); if ((ret < 0) && (ret != -3)) { xmlIOErr(XML_IO_ENCODER, NULL); out->error = XML_IO_ENCODER; return(-1); } - nbchars = out->conv->use; + nbchars = xmlBufUse(out->conv); } else { - ret = xmlBufferAdd(out->buffer, (const xmlChar *) buf, chunk); + ret = xmlBufAdd(out->buffer, (const xmlChar *) buf, chunk); if (ret != 0) return(-1); - nbchars = out->buffer->use; + nbchars = xmlBufUse(out->buffer); } buf += chunk; len -= chunk; @@ -3171,15 +3491,15 @@ xmlOutputBufferWrite(xmlOutputBufferPtr out, int len, const char *buf) { * second write the stuff to the I/O channel */ if (out->encoder != NULL) { - ret = out->writecallback(out->context, - (const char *)out->conv->content, nbchars); + ret = out->writecallback(out->context, + (const char *)xmlBufContent(out->conv), nbchars); if (ret >= 0) - xmlBufferShrink(out->conv, ret); + xmlBufShrink(out->conv, ret); } else { - ret = out->writecallback(out->context, - (const char *)out->buffer->content, nbchars); + ret = out->writecallback(out->context, + (const char *)xmlBufContent(out->buffer), nbchars); if (ret >= 0) - xmlBufferShrink(out->buffer, ret); + xmlBufShrink(out->buffer, ret); } if (ret < 0) { xmlIOErr(XML_IO_WRITE, NULL); @@ -3221,9 +3541,9 @@ xmlEscapeContent(unsigned char* out, int *outlen, const unsigned char* inend; inend = in + (*inlen); - + while ((in < inend) && (out < outend)) { - if (*in == '<') { + if (*in == '<') { if (outend - out < 4) break; *out++ = '&'; *out++ = 'l'; @@ -3253,7 +3573,7 @@ xmlEscapeContent(unsigned char* out, int *outlen, *out++ = (unsigned char) *in; } ++in; - } + } *outlen = out - outstart; *inlen = in - base; return(0); @@ -3287,7 +3607,8 @@ xmlOutputBufferWriteEscape(xmlOutputBufferPtr out, const xmlChar *str, if ((out == NULL) || (out->error) || (str == NULL) || (out->buffer == NULL) || - (out->buffer->alloc == XML_BUFFER_ALLOC_IMMUTABLE)) return(-1); + (xmlBufGetAllocationScheme(out->buffer) == XML_BUFFER_ALLOC_IMMUTABLE)) + return(-1); len = strlen((const char *)str); if (len < 0) return(0); if (out->error) return(-1); @@ -3300,7 +3621,18 @@ xmlOutputBufferWriteEscape(xmlOutputBufferPtr out, const xmlChar *str, * how many bytes to consume and how many bytes to store. */ cons = len; - chunk = (out->buffer->size - out->buffer->use) - 1; + chunk = xmlBufAvail(out->buffer) - 1; + + /* + * 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) + return(-1); + oldwritten = -1; + continue; + } /* * first handle encoding stuff. @@ -3310,36 +3642,33 @@ xmlOutputBufferWriteEscape(xmlOutputBufferPtr out, const xmlChar *str, * Store the data in the incoming raw buffer */ if (out->conv == NULL) { - out->conv = xmlBufferCreate(); + out->conv = xmlBufCreate(); } - ret = escaping(out->buffer->content + out->buffer->use , + ret = escaping(xmlBufEnd(out->buffer) , &chunk, str, &cons); if ((ret < 0) || (chunk == 0)) /* chunk==0 => nothing done */ return(-1); - out->buffer->use += chunk; - out->buffer->content[out->buffer->use] = 0; + xmlBufAddLen(out->buffer, chunk); - if ((out->buffer->use < MINLEN) && (cons == len)) + if ((xmlBufUse(out->buffer) < MINLEN) && (cons == len)) goto done; /* * convert as much as possible to the output buffer. */ - ret = xmlCharEncOutFunc(out->encoder, out->conv, out->buffer); + ret = xmlCharEncOutput(out, 0); if ((ret < 0) && (ret != -3)) { xmlIOErr(XML_IO_ENCODER, NULL); out->error = XML_IO_ENCODER; return(-1); } - nbchars = out->conv->use; + nbchars = xmlBufUse(out->conv); } else { - ret = escaping(out->buffer->content + out->buffer->use , - &chunk, str, &cons); + ret = escaping(xmlBufEnd(out->buffer), &chunk, str, &cons); if ((ret < 0) || (chunk == 0)) /* chunk==0 => nothing done */ return(-1); - out->buffer->use += chunk; - out->buffer->content[out->buffer->use] = 0; - nbchars = out->buffer->use; + xmlBufAddLen(out->buffer, chunk); + nbchars = xmlBufUse(out->buffer); } str += cons; len -= cons; @@ -3352,15 +3681,15 @@ xmlOutputBufferWriteEscape(xmlOutputBufferPtr out, const xmlChar *str, * second write the stuff to the I/O channel */ if (out->encoder != NULL) { - ret = out->writecallback(out->context, - (const char *)out->conv->content, nbchars); + ret = out->writecallback(out->context, + (const char *)xmlBufContent(out->conv), nbchars); if (ret >= 0) - xmlBufferShrink(out->conv, ret); + xmlBufShrink(out->conv, ret); } else { - ret = out->writecallback(out->context, - (const char *)out->buffer->content, nbchars); + ret = out->writecallback(out->context, + (const char *)xmlBufContent(out->buffer), nbchars); if (ret >= 0) - xmlBufferShrink(out->buffer, ret); + xmlBufShrink(out->buffer, ret); } if (ret < 0) { xmlIOErr(XML_IO_WRITE, NULL); @@ -3368,8 +3697,8 @@ xmlOutputBufferWriteEscape(xmlOutputBufferPtr out, const xmlChar *str, return(ret); } out->written += ret; - } else if (out->buffer->size - out->buffer->use < MINLEN) { - xmlBufferResize(out->buffer, out->buffer->size + MINLEN); + } else if (xmlBufAvail(out->buffer) < MINLEN) { + xmlBufGrow(out->buffer, MINLEN); } written += nbchars; } while ((len > 0) && (oldwritten != written)); @@ -3398,7 +3727,7 @@ done: int xmlOutputBufferWriteString(xmlOutputBufferPtr out, const char *str) { int len; - + if ((out == NULL) || (out->error)) return(-1); if (str == NULL) return(-1); @@ -3427,14 +3756,16 @@ xmlOutputBufferFlush(xmlOutputBufferPtr out) { */ if ((out->conv != NULL) && (out->encoder != NULL)) { /* - * convert as much as possible to the parser reading buffer. + * convert as much as possible to the parser output buffer. */ - nbchars = xmlCharEncOutFunc(out->encoder, out->conv, out->buffer); - if (nbchars < 0) { - xmlIOErr(XML_IO_ENCODER, NULL); - out->error = XML_IO_ENCODER; - return(-1); - } + do { + nbchars = xmlCharEncOutput(out, 0); + if (nbchars < 0) { + xmlIOErr(XML_IO_ENCODER, NULL); + out->error = XML_IO_ENCODER; + return(-1); + } + } while (nbchars); } /* @@ -3443,14 +3774,16 @@ xmlOutputBufferFlush(xmlOutputBufferPtr out) { if ((out->conv != NULL) && (out->encoder != NULL) && (out->writecallback != NULL)) { ret = out->writecallback(out->context, - (const char *)out->conv->content, out->conv->use); + (const char *)xmlBufContent(out->conv), + xmlBufUse(out->conv)); if (ret >= 0) - xmlBufferShrink(out->conv, ret); + xmlBufShrink(out->conv, ret); } else if (out->writecallback != NULL) { ret = out->writecallback(out->context, - (const char *)out->buffer->content, out->buffer->use); + (const char *)xmlBufContent(out->buffer), + xmlBufUse(out->buffer)); if (ret >= 0) - xmlBufferShrink(out->buffer, ret); + xmlBufShrink(out->buffer, ret); } if (ret < 0) { xmlIOErr(XML_IO_FLUSH, NULL); @@ -3480,7 +3813,6 @@ xmlParserGetDirectory(const char *filename) { char *ret = NULL; char dir[1024]; char *cur; - char sep = '/'; #ifdef _WIN32_WCE /* easy way by now ... wince does not have dirs! */ return NULL; @@ -3490,18 +3822,21 @@ xmlParserGetDirectory(const char *filename) { xmlRegisterDefaultInputCallbacks(); if (filename == NULL) return(NULL); + #if defined(WIN32) && !defined(__CYGWIN__) - sep = '\\'; +# define IS_XMLPGD_SEP(ch) ((ch=='/')||(ch=='\\')) +#else +# define IS_XMLPGD_SEP(ch) (ch=='/') #endif strncpy(dir, filename, 1023); dir[1023] = 0; cur = &dir[strlen(dir)]; while (cur > dir) { - if (*cur == sep) break; + if (IS_XMLPGD_SEP(*cur)) break; cur --; } - if (*cur == sep) { + if (IS_XMLPGD_SEP(*cur)) { if (cur == dir) dir[1] = 0; else *cur = 0; ret = xmlMemStrdup(dir); @@ -3512,6 +3847,7 @@ xmlParserGetDirectory(const char *filename) { } } return(ret); +#undef IS_XMLPGD_SEP } /**************************************************************** @@ -3612,9 +3948,9 @@ static int xmlNoNetExists(const char *URL) { #else path = &URL[7]; #endif - } else + } else path = URL; - + return xmlCheckFilename(path); } @@ -3632,7 +3968,7 @@ static int xmlNoNetExists(const char *URL) { * * Returns a new allocated URL, or NULL. */ -xmlChar * +static xmlChar * xmlResolveResourceFromCatalog(const char *URL, const char *ID, xmlParserCtxtPtr ctxt) { xmlChar *resource = NULL; @@ -3802,9 +4138,9 @@ xmlLoadExternalEntity(const char *URL, const char *ID, } /************************************************************************ - * * - * Disabling Network access * - * * + * * + * Disabling Network access * + * * ************************************************************************/ /** |