#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
#endif
#include <libxml/globals.h>
+#include "buf.h"
+#include "enc.h"
+
/* #define VERBOSE_FAILURE */
/* #define DEBUG_EXTERNAL_ENTITIES */
/* #define DEBUG_INPUT */
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 *
* *
************************************************************************/
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);
}
XML_IO_LOAD_ERROR, level, NULL, 0,
filename, NULL, NULL, 0, 0,
msg, filename);
-
+
}
/************************************************************************
* *
- * Tree memory error handler *
+ * Tree memory error handler *
* *
************************************************************************/
/**
* xmlCleanupInputCallbacks:
*
* clears the entire input callback table. this includes the
- * compiled-in I/O.
+ * compiled-in I/O.
*/
void
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.
*/
if (xmlInputCallbackNr <= 0)
return(-1);
-
+
xmlInputCallbackNr--;
xmlInputCallbackTable[xmlInputCallbackNr].matchcallback = NULL;
xmlInputCallbackTable[xmlInputCallbackNr].opencallback = NULL;
* xmlCleanupOutputCallbacks:
*
* clears the entire output callback table. this includes the
- * compiled-in I/O callbacks.
+ * compiled-in I/O callbacks.
*/
void
xmlCleanupOutputCallbacks(void)
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
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:
*
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;
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
return 1;
}
-static int
+/**
+ * xmlNop:
+ *
+ * No Operation function, does nothing, no input
+ *
+ * Returns zero
+ */
+int
xmlNop(void) {
return(0);
}
*/
static void *
xmlFileOpen_real (const char *filename) {
- const char *path = NULL;
+ const char *path = filename;
FILE *fd;
if (filename == NULL)
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);
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;
}
#else
path = &filename[7];
#endif
- } else
+ } else
path = filename;
if (path == NULL)
#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);
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()");
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))) {
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);
}
#else
path = &filename[7];
#endif
- } else
+ } else
path = filename;
if (path == NULL)
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);
}
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);
}
#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 */
}
#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
/************************************************************************
* *
/*
** 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.
*/
*
* 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.
*/
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;
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
"Error flushing zlib buffers. Error code", z_err );
xmlIOErr(XML_IO_WRITE, (const char *) msg);
}
-
+
return ( zlgth );
}
#endif /* LIBXML_OUTPUT_ENABLED */
{
/* Any character conversions should have been done before this */
- ctxt->doc_buff = xmlAllocOutputBuffer(NULL);
+ ctxt->doc_buff = xmlAllocOutputBufferInternal(NULL);
}
if (ctxt->doc_buff == NULL) {
return (ctxt);
}
#endif /* LIBXML_OUTPUT_ENABLED */
-
+
#ifdef LIBXML_OUTPUT_ENABLED
/**
* xmlIOHTTPDfltOpenW
*
* 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));
*/
static int
-xmlIOHTTPWrite( void * context, const char * buffer, int len ) {
+xmlIOHTTPWrite( void * context, const char * buffer, int len ) {
xmlIOHTTPWriteCtxtPtr ctxt = context;
/* 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
/* 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 ) {
else {
http_ctxt = xmlNanoHTTPMethod( ctxt->uri, http_mthd, http_content,
- &content_type, content_encoding,
+ &content_type, content_encoding,
content_lgth );
if ( http_ctxt != NULL ) {
/*
** 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.
*/
*
* 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));
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;
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,
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;
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;
return(ret);
}
+
#endif /* LIBXML_OUTPUT_ENABLED */
/**
if (in == NULL) return;
if (in->raw) {
- xmlBufferFree(in->raw);
+ xmlBufFree(in->raw);
in->raw = NULL;
}
if (in->encoder != NULL) {
in->closecallback(in->context);
}
if (in->buffer != NULL) {
- xmlBufferFree(in->buffer);
+ xmlBufFree(in->buffer);
in->buffer = NULL;
}
}
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;
}
#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;
gzrewind(context);
}
}
+#endif
+ }
+#endif
+#ifdef LIBXML_LZMA_ENABLED
+ if ((xmlInputCallbackTable[i].opencallback == xmlXzfileOpen) &&
+ (strcmp(URI, "-") != 0)) {
+ ret->compressed = __libxml2_xzcompressed(context);
}
#endif
}
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;
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;
/*
* Allocate the Output buffer front-end.
*/
- ret = xmlAllocOutputBuffer(encoder);
+ ret = xmlAllocOutputBufferInternal(encoder);
if (ret != NULL) {
ret->context = context;
ret->writecallback = xmlOutputCallbackTable[i].writecallback;
/**
* 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 *
#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 *
if (file == NULL) return(NULL);
- ret = xmlAllocOutputBuffer(encoder);
+ ret = xmlAllocOutputBufferInternal(encoder);
if (ret != NULL) {
ret->context = file;
ret->writecallback = xmlFileWrite;
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 */
/**
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);
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;
* @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
if (fd < 0) return(NULL);
- ret = xmlAllocOutputBuffer(encoder);
+ ret = xmlAllocOutputBufferInternal(encoder);
if (ret != NULL) {
ret->context = (void *) (long) fd;
ret->writecallback = xmlFdWrite;
if (iowrite == NULL) return(NULL);
- ret = xmlAllocOutputBuffer(encoder);
+ ret = xmlAllocOutputBufferInternal(encoder);
if (ret != NULL) {
ret->context = (void *) ioctx;
ret->writecallback = iowrite;
* 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);
}
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.
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;
* 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);
}
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);
* 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;
* 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);
const unsigned char* inend;
inend = in + (*inlen);
-
+
while ((in < inend) && (out < outend)) {
- if (*in == '<') {
+ if (*in == '<') {
if (outend - out < 4) break;
*out++ = '&';
*out++ = 'l';
*out++ = (unsigned char) *in;
}
++in;
- }
+ }
*outlen = out - outstart;
*inlen = in - base;
return(0);
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);
* 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.
* 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;
* 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);
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));
int
xmlOutputBufferWriteString(xmlOutputBufferPtr out, const char *str) {
int len;
-
+
if ((out == NULL) || (out->error)) return(-1);
if (str == NULL)
return(-1);
*/
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);
}
/*
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);
char *ret = NULL;
char dir[1024];
char *cur;
- char sep = '/';
#ifdef _WIN32_WCE /* easy way by now ... wince does not have dirs! */
return NULL;
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);
}
}
return(ret);
+#undef IS_XMLPGD_SEP
}
/****************************************************************
#else
path = &URL[7];
#endif
- } else
+ } else
path = URL;
-
+
return xmlCheckFilename(path);
}
*
* Returns a new allocated URL, or NULL.
*/
-xmlChar *
+static xmlChar *
xmlResolveResourceFromCatalog(const char *URL, const char *ID,
xmlParserCtxtPtr ctxt) {
xmlChar *resource = NULL;
}
/************************************************************************
- * *
- * Disabling Network access *
- * *
+ * *
+ * Disabling Network access *
+ * *
************************************************************************/
/**