1999-07-27 23:52:06 +04:00
/*
* xmlIO . c : implementation of the I / O interfaces used by the parser
*
* See Copyright for the status of this software .
*
* Daniel . Veillard @ w3 . org
2000-11-25 12:54:49 +03:00
*
* 14 Nov 2000 ht - for VMS , truncated name of long functions to under 32 char
1999-07-27 23:52:06 +04:00
*/
1999-09-22 13:46:25 +04:00
# ifdef WIN32
1999-12-22 14:30:41 +03:00
# include "win32config.h"
1999-09-22 13:46:25 +04:00
# else
1999-07-27 23:52:06 +04:00
# include "config.h"
1999-09-22 13:46:25 +04:00
# endif
1999-07-27 23:52:06 +04:00
1999-09-22 13:46:25 +04:00
# include <stdio.h>
# include <string.h>
# ifdef HAVE_SYS_TYPES_H
1999-07-27 23:52:06 +04:00
# include <sys/types.h>
1999-09-22 13:46:25 +04:00
# endif
# ifdef HAVE_SYS_STAT_H
1999-07-27 23:52:06 +04:00
# include <sys/stat.h>
1999-09-22 13:46:25 +04:00
# endif
# ifdef HAVE_FCNTL_H
1999-07-27 23:52:06 +04:00
# include <fcntl.h>
1999-09-22 13:46:25 +04:00
# endif
1999-07-27 23:52:06 +04:00
# ifdef HAVE_UNISTD_H
# include <unistd.h>
# endif
1999-09-22 13:46:25 +04:00
# ifdef HAVE_STDLIB_H
# include <stdlib.h>
# endif
1999-07-27 23:52:06 +04:00
# ifdef HAVE_ZLIB_H
# include <zlib.h>
# endif
2000-04-03 23:48:13 +04:00
# include <libxml/xmlmemory.h>
# include <libxml/parser.h>
# include <libxml/parserInternals.h>
# include <libxml/xmlIO.h>
# include <libxml/nanohttp.h>
# include <libxml/nanoftp.h>
2000-10-25 23:56:55 +04:00
# include <libxml/xmlerror.h>
1999-07-27 23:52:06 +04:00
2000-11-25 12:54:49 +03:00
# ifdef VMS
# define xmlRegisterDefaultInputCallbacks xmlRegisterDefInputCallbacks
# define xmlRegisterDefaultOutputCallbacks xmlRegisterDefOutputCallbacks
# endif
1999-07-27 23:52:06 +04:00
/* #define VERBOSE_FAILURE */
1999-08-30 01:02:19 +04:00
/* #define DEBUG_EXTERNAL_ENTITIES */
2000-06-29 03:40:59 +04:00
/* #define DEBUG_INPUT */
1999-07-27 23:52:06 +04:00
# ifdef DEBUG_INPUT
# define MINLEN 40
# else
# define MINLEN 4000
# endif
2000-04-07 21:00:24 +04:00
/*
* Input I / O callback sets
*/
typedef struct _xmlInputCallback {
xmlInputMatchCallback matchcallback ;
xmlInputOpenCallback opencallback ;
xmlInputReadCallback readcallback ;
xmlInputCloseCallback closecallback ;
} xmlInputCallback ;
# define MAX_INPUT_CALLBACK 15
xmlInputCallback xmlInputCallbackTable [ MAX_INPUT_CALLBACK ] ;
int xmlInputCallbackNr = 0 ;
int xmlInputCallbackInitialized = 0 ;
2000-06-29 03:40:59 +04:00
/*
* Output I / O callback sets
*/
typedef struct _xmlOutputCallback {
xmlOutputMatchCallback matchcallback ;
xmlOutputOpenCallback opencallback ;
xmlOutputWriteCallback writecallback ;
xmlOutputCloseCallback closecallback ;
} xmlOutputCallback ;
# define MAX_OUTPUT_CALLBACK 15
xmlOutputCallback xmlOutputCallbackTable [ MAX_OUTPUT_CALLBACK ] ;
int xmlOutputCallbackNr = 0 ;
int xmlOutputCallbackInitialized = 0 ;
2000-04-07 21:00:24 +04:00
/************************************************************************
* *
* Standard I / O for file accesses *
* *
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
2000-07-22 00:32:03 +04:00
int
xmlNop ( void ) {
return ( 0 ) ;
}
2000-04-07 21:00:24 +04:00
/**
* xmlFdMatch :
* @ filename : the URI for matching
*
* input from file descriptor
*
* Returns 1 if matches , 0 otherwise
*/
int
xmlFdMatch ( const char * filename ) {
return ( 1 ) ;
}
/**
* xmlFdOpen :
* @ filename : the URI for matching
*
* input from file descriptor , supports compressed input
* if @ filename is " " then the standard input is used
*
* Returns an I / O context or NULL in case of error
*/
void *
xmlFdOpen ( const char * filename ) {
const char * path = NULL ;
int fd ;
if ( ! strcmp ( filename , " - " ) ) {
fd = 0 ;
return ( ( void * ) fd ) ;
}
if ( ! strncmp ( filename , " file://localhost " , 16 ) )
path = & filename [ 16 ] ;
else if ( ! strncmp ( filename , " file:/// " , 8 ) )
path = & filename [ 8 ] ;
else if ( filename [ 0 ] = = ' / ' )
path = filename ;
if ( path = = NULL )
return ( NULL ) ;
# ifdef WIN32
fd = _open ( filename , O_RDONLY | _O_BINARY ) ;
# else
fd = open ( filename , O_RDONLY ) ;
# endif
return ( ( void * ) fd ) ;
}
2000-06-29 03:40:59 +04:00
/**
* xmlFdOpenW :
* @ filename : the URI for matching
*
* input from file descriptor ,
* if @ filename is " - " then the standard output is used
*
* Returns an I / O context or NULL in case of error
*/
void *
xmlFdOpenW ( const char * filename ) {
const char * path = NULL ;
int fd ;
if ( ! strcmp ( filename , " - " ) ) {
fd = 1 ;
return ( ( void * ) fd ) ;
}
if ( ! strncmp ( filename , " file://localhost " , 16 ) )
path = & filename [ 16 ] ;
else if ( ! strncmp ( filename , " file:/// " , 8 ) )
path = & filename [ 8 ] ;
else if ( filename [ 0 ] = = ' / ' )
path = filename ;
if ( path = = NULL )
return ( NULL ) ;
fd = open ( filename , O_WRONLY ) ;
return ( ( void * ) fd ) ;
}
2000-04-07 21:00:24 +04:00
/**
* xmlFdRead :
* @ context : the I / O context
* @ buffer : where to drop data
2000-06-29 03:40:59 +04:00
* @ len : number of bytes to read
2000-04-07 21:00:24 +04:00
*
* Read @ len bytes to @ buffer from the I / O channel .
*
* Returns the number of bytes written
*/
int
xmlFdRead ( void * context , char * buffer , int len ) {
return ( read ( ( int ) context , & buffer [ 0 ] , len ) ) ;
}
2000-06-29 03:40:59 +04:00
/**
* xmlFdWrite :
* @ context : the I / O context
* @ buffer : where to get data
* @ len : number of bytes to write
*
* Write @ len bytes from @ buffer to the I / O channel .
*
* Returns the number of bytes written
*/
int
xmlFdWrite ( void * context , const char * buffer , int len ) {
return ( write ( ( int ) context , & buffer [ 0 ] , len ) ) ;
}
2000-04-07 21:00:24 +04:00
/**
* xmlFdClose :
* @ context : the I / O context
*
* Close an I / O channel
*/
void
xmlFdClose ( void * context ) {
close ( ( int ) context ) ;
}
/**
* xmlFileMatch :
* @ filename : the URI for matching
*
* input from FILE *
*
* Returns 1 if matches , 0 otherwise
*/
int
xmlFileMatch ( const char * filename ) {
return ( 1 ) ;
}
/**
* xmlFileOpen :
* @ filename : the URI for matching
*
* input from FILE * , supports compressed input
* if @ filename is " " then the standard input is used
*
* Returns an I / O context or NULL in case of error
*/
void *
xmlFileOpen ( const char * filename ) {
const char * path = NULL ;
FILE * fd ;
if ( ! strcmp ( filename , " - " ) ) {
fd = stdin ;
return ( ( void * ) fd ) ;
}
if ( ! strncmp ( filename , " file://localhost " , 16 ) )
path = & filename [ 16 ] ;
else if ( ! strncmp ( filename , " file:/// " , 8 ) )
path = & filename [ 8 ] ;
else
path = filename ;
if ( path = = NULL )
return ( NULL ) ;
# ifdef WIN32
fd = fopen ( path , " rb " ) ;
# else
fd = fopen ( path , " r " ) ;
# endif /* WIN32 */
return ( ( void * ) fd ) ;
}
2000-06-29 03:40:59 +04:00
/**
* xmlFileOpenW :
* @ filename : the URI for matching
*
* output to from FILE * ,
* if @ filename is " - " then the standard output is used
*
* Returns an I / O context or NULL in case of error
*/
void *
xmlFileOpenW ( const char * filename ) {
const char * path = NULL ;
FILE * fd ;
if ( ! strcmp ( filename , " - " ) ) {
fd = stdout ;
return ( ( void * ) fd ) ;
}
if ( ! strncmp ( filename , " file://localhost " , 16 ) )
path = & filename [ 16 ] ;
else if ( ! strncmp ( filename , " file:/// " , 8 ) )
path = & filename [ 8 ] ;
else
path = filename ;
if ( path = = NULL )
return ( NULL ) ;
fd = fopen ( path , " w " ) ;
return ( ( void * ) fd ) ;
}
2000-04-07 21:00:24 +04:00
/**
* xmlFileRead :
* @ context : the I / O context
* @ buffer : where to drop data
* @ len : number of bytes to write
*
* Read @ len bytes to @ buffer from the I / O channel .
*
* Returns the number of bytes written
*/
int
xmlFileRead ( void * context , char * buffer , int len ) {
return ( fread ( & buffer [ 0 ] , 1 , len , ( FILE * ) context ) ) ;
}
2000-06-29 03:40:59 +04:00
/**
* xmlFileWrite :
* @ context : the I / O context
* @ buffer : where to drop data
* @ len : number of bytes to write
*
* Write @ len bytes from @ buffer to the I / O channel .
*
* Returns the number of bytes written
*/
int
xmlFileWrite ( void * context , const char * buffer , int len ) {
return ( fwrite ( & buffer [ 0 ] , 1 , len , ( FILE * ) context ) ) ;
}
2000-04-07 21:00:24 +04:00
/**
* xmlFileClose :
* @ context : the I / O context
*
* Close an I / O channel
*/
void
xmlFileClose ( void * context ) {
fclose ( ( FILE * ) context ) ;
}
2000-10-22 20:56:02 +04:00
/**
* xmlFileFlush :
* @ context : the I / O context
*
* Flush an I / O channel
*/
void
xmlFileFlush ( void * context ) {
fflush ( ( FILE * ) context ) ;
}
2000-04-07 21:00:24 +04:00
# ifdef HAVE_ZLIB_H
/************************************************************************
* *
* I / O for compressed file accesses *
* *
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
/**
* xmlGzfileMatch :
* @ filename : the URI for matching
*
* input from compressed file test
*
* Returns 1 if matches , 0 otherwise
*/
int
xmlGzfileMatch ( const char * filename ) {
return ( 1 ) ;
}
/**
* xmlGzfileOpen :
* @ 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
*/
void *
xmlGzfileOpen ( const char * filename ) {
const char * path = NULL ;
gzFile fd ;
if ( ! strcmp ( filename , " - " ) ) {
2000-10-13 03:26:32 +04:00
fd = gzdopen ( fileno ( stdin ) , " rb " ) ;
2000-04-07 21:00:24 +04:00
return ( ( void * ) fd ) ;
}
if ( ! strncmp ( filename , " file://localhost " , 16 ) )
path = & filename [ 16 ] ;
else if ( ! strncmp ( filename , " file:/// " , 8 ) )
path = & filename [ 8 ] ;
else
path = filename ;
2000-10-13 03:26:32 +04:00
fd = gzopen ( filename , " rb " ) ;
2000-04-07 21:00:24 +04:00
return ( ( void * ) fd ) ;
}
2000-06-29 03:40:59 +04:00
/**
* xmlGzfileOpenW :
* @ filename : the URI for matching
* @ compression : the compression factor ( 0 - 9 included )
*
* 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
*/
void *
xmlGzfileOpenW ( const char * filename , int compression ) {
const char * path = NULL ;
char mode [ 15 ] ;
gzFile fd ;
2000-10-13 03:26:32 +04:00
sprintf ( mode , " wb%d " , compression ) ;
2000-06-29 03:40:59 +04:00
if ( ! strcmp ( filename , " - " ) ) {
fd = gzdopen ( 1 , mode ) ;
return ( ( void * ) fd ) ;
}
if ( ! strncmp ( filename , " file://localhost " , 16 ) )
path = & filename [ 16 ] ;
else if ( ! strncmp ( filename , " file:/// " , 8 ) )
path = & filename [ 8 ] ;
else
path = filename ;
fd = gzopen ( filename , mode ) ;
return ( ( void * ) fd ) ;
}
2000-04-07 21:00:24 +04:00
/**
* xmlGzfileRead :
* @ 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
*/
int
xmlGzfileRead ( void * context , char * buffer , int len ) {
return ( gzread ( ( gzFile ) context , & buffer [ 0 ] , len ) ) ;
}
2000-06-29 03:40:59 +04:00
/**
* xmlGzfileWrite :
* @ context : the I / O context
* @ buffer : where to drop data
* @ len : number of bytes to write
*
* Write @ len bytes from @ buffer to the compressed I / O channel .
*
* Returns the number of bytes written
*/
int
xmlGzfileWrite ( void * context , const char * buffer , int len ) {
return ( gzwrite ( ( gzFile ) context , ( char * ) & buffer [ 0 ] , len ) ) ;
}
2000-04-07 21:00:24 +04:00
/**
* xmlGzfileClose :
* @ context : the I / O context
*
* Close a compressed I / O channel
*/
void
xmlGzfileClose ( void * context ) {
gzclose ( ( gzFile ) context ) ;
}
# endif /* HAVE_ZLIB_H */
# ifdef LIBXML_HTTP_ENABLED
/************************************************************************
* *
* I / O for HTTP file accesses *
* *
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
/**
* xmlIOHTTPMatch :
* @ filename : the URI for matching
*
* check if the URI matches an HTTP one
*
* Returns 1 if matches , 0 otherwise
*/
int
xmlIOHTTPMatch ( const char * filename ) {
if ( ! strncmp ( filename , " http:// " , 7 ) )
return ( 1 ) ;
return ( 0 ) ;
}
/**
* xmlIOHTTPOpen :
* @ filename : the URI for matching
*
* open an HTTP I / O channel
*
* Returns an I / O context or NULL in case of error
*/
void *
xmlIOHTTPOpen ( const char * filename ) {
return ( xmlNanoHTTPOpen ( filename , NULL ) ) ;
}
/**
* xmlIOHTTPRead :
* @ context : the I / O context
* @ buffer : where to drop data
* @ len : number of bytes to write
*
* Read @ len bytes to @ buffer from the I / O channel .
*
* Returns the number of bytes written
*/
int
xmlIOHTTPRead ( void * context , char * buffer , int len ) {
return ( xmlNanoHTTPRead ( context , & buffer [ 0 ] , len ) ) ;
}
/**
* xmlIOHTTPClose :
* @ context : the I / O context
*
* Close an HTTP I / O channel
*/
void
xmlIOHTTPClose ( void * context ) {
xmlNanoHTTPClose ( context ) ;
}
# endif /* LIBXML_HTTP_ENABLED */
# ifdef LIBXML_FTP_ENABLED
/************************************************************************
* *
* I / O for FTP file accesses *
* *
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
/**
* xmlIOFTPMatch :
* @ filename : the URI for matching
*
* check if the URI matches an FTP one
*
* Returns 1 if matches , 0 otherwise
*/
int
xmlIOFTPMatch ( const char * filename ) {
if ( ! strncmp ( filename , " ftp:// " , 6 ) )
return ( 1 ) ;
return ( 0 ) ;
}
/**
* xmlIOFTPOpen :
* @ filename : the URI for matching
*
* open an FTP I / O channel
*
* Returns an I / O context or NULL in case of error
*/
void *
xmlIOFTPOpen ( const char * filename ) {
return ( xmlNanoFTPOpen ( filename ) ) ;
}
/**
* xmlIOFTPRead :
* @ context : the I / O context
* @ buffer : where to drop data
* @ len : number of bytes to write
*
* Read @ len bytes to @ buffer from the I / O channel .
*
* Returns the number of bytes written
*/
int
xmlIOFTPRead ( void * context , char * buffer , int len ) {
return ( xmlNanoFTPRead ( context , & buffer [ 0 ] , len ) ) ;
}
/**
* xmlIOFTPClose :
* @ context : the I / O context
*
* Close an FTP I / O channel
*/
void
xmlIOFTPClose ( void * context ) {
xmlNanoFTPClose ( context ) ;
}
# endif /* LIBXML_FTP_ENABLED */
/**
* xmlRegisterInputCallbacks :
* @ match : the xmlInputMatchCallback
* @ open : the xmlInputOpenCallback
* @ read : the xmlInputReadCallback
* @ close : the xmlInputCloseCallback
*
* Register a new set of I / O callback for handling parser input .
*
* Returns the registered handler number or - 1 in case of error
*/
int
xmlRegisterInputCallbacks ( xmlInputMatchCallback match ,
xmlInputOpenCallback open , xmlInputReadCallback read ,
xmlInputCloseCallback close ) {
if ( xmlInputCallbackNr > = MAX_INPUT_CALLBACK ) {
return ( - 1 ) ;
}
xmlInputCallbackTable [ xmlInputCallbackNr ] . matchcallback = match ;
xmlInputCallbackTable [ xmlInputCallbackNr ] . opencallback = open ;
xmlInputCallbackTable [ xmlInputCallbackNr ] . readcallback = read ;
xmlInputCallbackTable [ xmlInputCallbackNr ] . closecallback = close ;
return ( xmlInputCallbackNr + + ) ;
}
2000-06-29 03:40:59 +04:00
/**
* xmlRegisterOutputCallbacks :
* @ match : the xmlOutputMatchCallback
* @ open : the xmlOutputOpenCallback
* @ write : the xmlOutputWriteCallback
* @ close : the xmlOutputCloseCallback
*
* Register a new set of I / O callback for handling output .
*
* Returns the registered handler number or - 1 in case of error
*/
int
xmlRegisterOutputCallbacks ( xmlOutputMatchCallback match ,
xmlOutputOpenCallback open , xmlOutputWriteCallback write ,
xmlOutputCloseCallback close ) {
if ( xmlOutputCallbackNr > = MAX_INPUT_CALLBACK ) {
return ( - 1 ) ;
}
xmlOutputCallbackTable [ xmlOutputCallbackNr ] . matchcallback = match ;
xmlOutputCallbackTable [ xmlOutputCallbackNr ] . opencallback = open ;
xmlOutputCallbackTable [ xmlOutputCallbackNr ] . writecallback = write ;
xmlOutputCallbackTable [ xmlOutputCallbackNr ] . closecallback = close ;
return ( xmlOutputCallbackNr + + ) ;
}
2000-04-07 21:00:24 +04:00
/**
* xmlRegisterDefaultInputCallbacks :
*
* Registers the default compiled - in I / O handlers .
*/
void
2000-11-25 12:54:49 +03:00
# ifdef VMS
xmlRegisterDefInputCallbacks
# else
xmlRegisterDefaultInputCallbacks
# endif
( void ) {
2000-10-04 16:40:27 +04:00
if ( xmlInputCallbackInitialized )
return ;
2000-04-07 21:00:24 +04:00
xmlRegisterInputCallbacks ( xmlFileMatch , xmlFileOpen ,
xmlFileRead , xmlFileClose ) ;
# ifdef HAVE_ZLIB_H
xmlRegisterInputCallbacks ( xmlGzfileMatch , xmlGzfileOpen ,
xmlGzfileRead , xmlGzfileClose ) ;
# endif /* HAVE_ZLIB_H */
# ifdef LIBXML_HTTP_ENABLED
xmlRegisterInputCallbacks ( xmlIOHTTPMatch , xmlIOHTTPOpen ,
xmlIOHTTPRead , xmlIOHTTPClose ) ;
# endif /* LIBXML_HTTP_ENABLED */
# ifdef LIBXML_FTP_ENABLED
xmlRegisterInputCallbacks ( xmlIOFTPMatch , xmlIOFTPOpen ,
xmlIOFTPRead , xmlIOFTPClose ) ;
# endif /* LIBXML_FTP_ENABLED */
2000-10-04 16:40:27 +04:00
xmlInputCallbackInitialized = 1 ;
2000-04-07 21:00:24 +04:00
}
2000-06-29 03:40:59 +04:00
/**
* xmlRegisterDefaultOutputCallbacks :
*
* Registers the default compiled - in I / O handlers .
*/
void
2000-11-25 12:54:49 +03:00
# ifdef VMS
xmlRegisterDefOutputCallbacks
# else
xmlRegisterDefaultOutputCallbacks
# endif
( void ) {
2000-10-04 16:40:27 +04:00
if ( xmlOutputCallbackInitialized )
return ;
2000-06-29 03:40:59 +04:00
xmlRegisterOutputCallbacks ( xmlFileMatch , xmlFileOpenW ,
xmlFileWrite , xmlFileClose ) ;
/*********************************
No way a - priori to distinguish between gzipped files from
uncompressed ones except opening if existing then closing
and saving with same compression ratio . . . a pain .
# ifdef HAVE_ZLIB_H
xmlRegisterOutputCallbacks ( xmlGzfileMatch , xmlGzfileOpen ,
xmlGzfileWrite , xmlGzfileClose ) ;
# endif
No HTTP PUT support yet , patches welcome
# ifdef LIBXML_HTTP_ENABLED
xmlRegisterOutputCallbacks ( xmlIOHTTPMatch , xmlIOHTTPOpen ,
xmlIOHTTPWrite , xmlIOHTTPClose ) ;
# endif
Nor FTP PUT . . . .
# ifdef LIBXML_FTP_ENABLED
xmlRegisterOutputCallbacks ( xmlIOFTPMatch , xmlIOFTPOpen ,
xmlIOFTPWrite , xmlIOFTPClose ) ;
# endif
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
2000-10-04 16:40:27 +04:00
xmlOutputCallbackInitialized = 1 ;
2000-06-29 03:40:59 +04:00
}
1999-07-27 23:52:06 +04:00
/**
* xmlAllocParserInputBuffer :
* @ enc : the charset encoding if known
*
* Create a buffered parser input for progressive parsing
*
* Returns the new parser input or NULL
*/
xmlParserInputBufferPtr
xmlAllocParserInputBuffer ( xmlCharEncoding enc ) {
xmlParserInputBufferPtr ret ;
1999-09-03 02:04:43 +04:00
ret = ( xmlParserInputBufferPtr ) xmlMalloc ( sizeof ( xmlParserInputBuffer ) ) ;
1999-07-27 23:52:06 +04:00
if ( ret = = NULL ) {
2000-10-25 23:56:55 +04:00
xmlGenericError ( xmlGenericErrorContext ,
" xmlAllocParserInputBuffer : out of memory! \n " ) ;
1999-07-27 23:52:06 +04:00
return ( NULL ) ;
}
memset ( ret , 0 , ( size_t ) sizeof ( xmlParserInputBuffer ) ) ;
ret - > buffer = xmlBufferCreate ( ) ;
1999-12-28 19:35:14 +03:00
if ( ret - > buffer = = NULL ) {
xmlFree ( ret ) ;
return ( NULL ) ;
}
ret - > buffer - > alloc = XML_BUFFER_ALLOC_DOUBLEIT ;
1999-07-27 23:52:06 +04:00
ret - > encoder = xmlGetCharEncodingHandler ( enc ) ;
revamped the encoding support, added iconv support, so now libxml if
* encoding.[ch], xmlIO.[ch], parser.c, configure.in : revamped
the encoding support, added iconv support, so now libxml if
compiled with iconv automatically support japanese encodings
among others. Work based on initial patch from Yuan-Chen Cheng
I may have broken binary compat in the encoding handler
registration scheme, but that was so utterly broken I don't
expect anybody to have used this feature until now.
* parserInternals.h: fixup on the CHAR range macro
* xml-error.h, parser.c: catch URL/URI errors using the uri.c
code.
* tree.[ch]: added xmlBufferGrow(), was needed for iconv
* uri.c: added xmlParseURI() I can't believe I forgot to
implement this one in 2.0 !!!
* SAX.c: moved doc->encoding update in the endDocument() call.
* TODO: updated.
Iconv rules :-)
Daniel
2000-05-03 18:20:55 +04:00
if ( ret - > encoder ! = NULL )
ret - > raw = xmlBufferCreate ( ) ;
else
ret - > raw = NULL ;
2000-04-07 21:00:24 +04:00
ret - > readcallback = NULL ;
ret - > closecallback = NULL ;
ret - > context = NULL ;
1999-07-27 23:52:06 +04:00
return ( ret ) ;
}
2000-06-29 03:40:59 +04:00
/**
* xmlAllocOutputBuffer :
* @ encoder : the encoding converter or NULL
*
* Create a buffered parser output
*
* Returns the new parser output or NULL
*/
xmlOutputBufferPtr
xmlAllocOutputBuffer ( xmlCharEncodingHandlerPtr encoder ) {
xmlOutputBufferPtr ret ;
ret = ( xmlOutputBufferPtr ) xmlMalloc ( sizeof ( xmlOutputBuffer ) ) ;
if ( ret = = NULL ) {
2000-10-25 23:56:55 +04:00
xmlGenericError ( xmlGenericErrorContext ,
" xmlAllocOutputBuffer : out of memory! \n " ) ;
2000-06-29 03:40:59 +04:00
return ( NULL ) ;
}
memset ( ret , 0 , ( size_t ) sizeof ( xmlOutputBuffer ) ) ;
ret - > buffer = xmlBufferCreate ( ) ;
if ( ret - > buffer = = NULL ) {
xmlFree ( ret ) ;
return ( NULL ) ;
}
ret - > buffer - > alloc = XML_BUFFER_ALLOC_DOUBLEIT ;
ret - > encoder = encoder ;
if ( encoder ! = NULL ) {
ret - > conv = xmlBufferCreateSize ( 4000 ) ;
/*
* This call is designed to initiate the encoder state
*/
xmlCharEncOutFunc ( encoder , ret - > conv , NULL ) ;
} else
ret - > conv = NULL ;
ret - > writecallback = NULL ;
ret - > closecallback = NULL ;
ret - > context = NULL ;
ret - > written = 0 ;
return ( ret ) ;
}
1999-07-27 23:52:06 +04:00
/**
* xmlFreeParserInputBuffer :
* @ in : a buffered parser input
*
* Free up the memory used by a buffered parser input
*/
void
xmlFreeParserInputBuffer ( xmlParserInputBufferPtr in ) {
revamped the encoding support, added iconv support, so now libxml if
* encoding.[ch], xmlIO.[ch], parser.c, configure.in : revamped
the encoding support, added iconv support, so now libxml if
compiled with iconv automatically support japanese encodings
among others. Work based on initial patch from Yuan-Chen Cheng
I may have broken binary compat in the encoding handler
registration scheme, but that was so utterly broken I don't
expect anybody to have used this feature until now.
* parserInternals.h: fixup on the CHAR range macro
* xml-error.h, parser.c: catch URL/URI errors using the uri.c
code.
* tree.[ch]: added xmlBufferGrow(), was needed for iconv
* uri.c: added xmlParseURI() I can't believe I forgot to
implement this one in 2.0 !!!
* SAX.c: moved doc->encoding update in the endDocument() call.
* TODO: updated.
Iconv rules :-)
Daniel
2000-05-03 18:20:55 +04:00
if ( in - > raw ) {
xmlBufferFree ( in - > raw ) ;
in - > raw = NULL ;
}
if ( in - > encoder ! = NULL ) {
xmlCharEncCloseFunc ( in - > encoder ) ;
1999-07-27 23:52:06 +04:00
}
2000-04-07 21:00:24 +04:00
if ( in - > closecallback ! = NULL ) {
in - > closecallback ( in - > context ) ;
}
revamped the encoding support, added iconv support, so now libxml if
* encoding.[ch], xmlIO.[ch], parser.c, configure.in : revamped
the encoding support, added iconv support, so now libxml if
compiled with iconv automatically support japanese encodings
among others. Work based on initial patch from Yuan-Chen Cheng
I may have broken binary compat in the encoding handler
registration scheme, but that was so utterly broken I don't
expect anybody to have used this feature until now.
* parserInternals.h: fixup on the CHAR range macro
* xml-error.h, parser.c: catch URL/URI errors using the uri.c
code.
* tree.[ch]: added xmlBufferGrow(), was needed for iconv
* uri.c: added xmlParseURI() I can't believe I forgot to
implement this one in 2.0 !!!
* SAX.c: moved doc->encoding update in the endDocument() call.
* TODO: updated.
Iconv rules :-)
Daniel
2000-05-03 18:20:55 +04:00
if ( in - > buffer ! = NULL ) {
xmlBufferFree ( in - > buffer ) ;
in - > buffer = NULL ;
}
2000-04-07 21:00:24 +04:00
1999-07-27 23:52:06 +04:00
memset ( in , 0xbe , ( size_t ) sizeof ( xmlParserInputBuffer ) ) ;
1999-09-03 02:04:43 +04:00
xmlFree ( in ) ;
1999-07-27 23:52:06 +04:00
}
2000-06-29 03:40:59 +04:00
/**
* xmlOutputBufferClose :
* @ out : a buffered output
*
* flushes and close the output I / O channel
* and free up all the associated resources
*
* Returns the number of byte written or - 1 in case of error .
*/
int
xmlOutputBufferClose ( xmlOutputBufferPtr out ) {
int written ;
if ( out = = NULL )
return ( - 1 ) ;
2000-11-25 03:48:47 +03:00
if ( out - > writecallback ! = NULL )
xmlOutputBufferFlush ( out ) ;
2000-06-29 03:40:59 +04:00
if ( out - > closecallback ! = NULL ) {
out - > closecallback ( out - > context ) ;
}
written = out - > written ;
if ( out - > conv ) {
xmlBufferFree ( out - > conv ) ;
out - > conv = NULL ;
}
if ( out - > encoder ! = NULL ) {
xmlCharEncCloseFunc ( out - > encoder ) ;
}
if ( out - > buffer ! = NULL ) {
xmlBufferFree ( out - > buffer ) ;
out - > buffer = NULL ;
}
memset ( out , 0xbe , ( size_t ) sizeof ( xmlOutputBuffer ) ) ;
xmlFree ( out ) ;
return ( written ) ;
}
1999-07-27 23:52:06 +04:00
/**
* xmlParserInputBufferCreateFilename :
2000-04-07 21:00:24 +04:00
* @ URI : a C string containing the URI or filename
1999-07-27 23:52:06 +04:00
* @ enc : the charset encoding if known
*
* Create a buffered parser input for the progressive parsing of a file
* If filename is " -' then we use stdin as the input.
* Automatic support for ZLIB / Compress compressed document is provided
* by default if found at compile - time .
2000-03-14 21:30:20 +03:00
* Do an encoding check if enc = = XML_CHAR_ENCODING_NONE
1999-07-27 23:52:06 +04:00
*
* Returns the new parser input or NULL
*/
xmlParserInputBufferPtr
2000-11-25 12:54:49 +03:00
# ifdef VMS
xmlParserInputBufferCreateFname
# else
xmlParserInputBufferCreateFilename
# endif
( const char * URI , xmlCharEncoding enc ) {
1999-07-27 23:52:06 +04:00
xmlParserInputBufferPtr ret ;
2000-04-07 21:00:24 +04:00
int i ;
void * context = NULL ;
1999-07-27 23:52:06 +04:00
2000-04-07 21:00:24 +04:00
if ( xmlInputCallbackInitialized = = 0 )
xmlRegisterDefaultInputCallbacks ( ) ;
1999-07-27 23:52:06 +04:00
2000-04-07 21:00:24 +04:00
if ( URI = = NULL ) return ( NULL ) ;
/*
* Try to find one of the input accept method accepting taht scheme
* Go in reverse to give precedence to user defined handlers .
*/
for ( i = xmlInputCallbackNr - 1 ; i > = 0 ; i - - ) {
if ( ( xmlInputCallbackTable [ i ] . matchcallback ! = NULL ) & &
( xmlInputCallbackTable [ i ] . matchcallback ( URI ) ! = 0 ) ) {
context = xmlInputCallbackTable [ i ] . opencallback ( URI ) ;
if ( context ! = NULL )
break ;
1999-07-27 23:52:06 +04:00
}
2000-04-07 21:00:24 +04:00
}
if ( context = = NULL ) {
return ( NULL ) ;
1999-07-27 23:52:06 +04:00
}
2000-03-14 21:30:20 +03:00
/*
* Allocate the Input buffer front - end .
*/
1999-07-27 23:52:06 +04:00
ret = xmlAllocParserInputBuffer ( enc ) ;
if ( ret ! = NULL ) {
2000-04-07 21:00:24 +04:00
ret - > context = context ;
ret - > readcallback = xmlInputCallbackTable [ i ] . readcallback ;
ret - > closecallback = xmlInputCallbackTable [ i ] . closecallback ;
1999-07-27 23:52:06 +04:00
}
return ( ret ) ;
}
2000-06-29 03:40:59 +04:00
/**
* xmlOutputBufferCreateFilename :
* @ URI : a C string containing the URI or filename
* @ encoder : the encoding converter or NULL
* @ compression : the compression ration ( 0 none , 9 max ) .
*
* Create a buffered output for the progressive saving of a file
* If filename is " -' then we use stdout as the output.
* Automatic support for ZLIB / Compress compressed document is provided
* by default if found at compile - time .
* TODO : currently if compression is set , the library only support
* writing to a local file .
*
* Returns the new output or NULL
*/
xmlOutputBufferPtr
xmlOutputBufferCreateFilename ( const char * URI ,
xmlCharEncodingHandlerPtr encoder ,
int compression ) {
xmlOutputBufferPtr ret ;
int i ;
void * context = NULL ;
if ( xmlOutputCallbackInitialized = = 0 )
xmlRegisterDefaultOutputCallbacks ( ) ;
if ( URI = = NULL ) return ( NULL ) ;
# ifdef HAVE_ZLIB_H
if ( ( compression > 0 ) & & ( compression < = 9 ) ) {
context = xmlGzfileOpenW ( URI , compression ) ;
if ( context ! = NULL ) {
ret = xmlAllocOutputBuffer ( encoder ) ;
if ( ret ! = NULL ) {
ret - > context = context ;
ret - > writecallback = xmlGzfileWrite ;
ret - > closecallback = xmlGzfileClose ;
}
return ( ret ) ;
}
}
# endif
/*
* Try to find one of the output accept method accepting taht scheme
* Go in reverse to give precedence to user defined handlers .
*/
for ( i = xmlOutputCallbackNr - 1 ; i > = 0 ; i - - ) {
if ( ( xmlOutputCallbackTable [ i ] . matchcallback ! = NULL ) & &
( xmlOutputCallbackTable [ i ] . matchcallback ( URI ) ! = 0 ) ) {
context = xmlOutputCallbackTable [ i ] . opencallback ( URI ) ;
if ( context ! = NULL )
break ;
}
}
if ( context = = NULL ) {
return ( NULL ) ;
}
/*
* Allocate the Output buffer front - end .
*/
ret = xmlAllocOutputBuffer ( encoder ) ;
if ( ret ! = NULL ) {
ret - > context = context ;
ret - > writecallback = xmlOutputCallbackTable [ i ] . writecallback ;
ret - > closecallback = xmlOutputCallbackTable [ i ] . closecallback ;
}
return ( ret ) ;
}
1999-07-27 23:52:06 +04:00
/**
* xmlParserInputBufferCreateFile :
* @ file : a FILE *
* @ enc : the charset encoding if known
*
* Create a buffered parser input for the progressive parsing of a FILE *
* buffered C I / O
*
* Returns the new parser input or NULL
*/
xmlParserInputBufferPtr
xmlParserInputBufferCreateFile ( FILE * file , xmlCharEncoding enc ) {
xmlParserInputBufferPtr ret ;
2000-04-07 21:00:24 +04:00
if ( xmlInputCallbackInitialized = = 0 )
xmlRegisterDefaultInputCallbacks ( ) ;
1999-07-27 23:52:06 +04:00
if ( file = = NULL ) return ( NULL ) ;
ret = xmlAllocParserInputBuffer ( enc ) ;
2000-04-07 21:00:24 +04:00
if ( ret ! = NULL ) {
ret - > context = file ;
ret - > readcallback = xmlFileRead ;
2000-10-22 20:56:02 +04:00
ret - > closecallback = xmlFileFlush ;
2000-04-07 21:00:24 +04:00
}
1999-07-27 23:52:06 +04:00
return ( ret ) ;
}
2000-06-29 03:40:59 +04:00
/**
* xmlOutputBufferCreateFile :
* @ file : a FILE *
* @ encoder : the encoding converter or NULL
*
* Create a buffered output for the progressive saving to a FILE *
* buffered C I / O
*
* Returns the new parser output or NULL
*/
xmlOutputBufferPtr
xmlOutputBufferCreateFile ( FILE * file , xmlCharEncodingHandlerPtr encoder ) {
xmlOutputBufferPtr ret ;
if ( xmlOutputCallbackInitialized = = 0 )
xmlRegisterDefaultOutputCallbacks ( ) ;
if ( file = = NULL ) return ( NULL ) ;
ret = xmlAllocOutputBuffer ( encoder ) ;
if ( ret ! = NULL ) {
ret - > context = file ;
ret - > writecallback = xmlFileWrite ;
2000-10-22 20:56:02 +04:00
ret - > closecallback = xmlFileFlush ;
2000-06-29 03:40:59 +04:00
}
return ( ret ) ;
}
1999-07-27 23:52:06 +04:00
/**
* xmlParserInputBufferCreateFd :
* @ fd : a file descriptor number
* @ enc : the charset encoding if known
*
* Create a buffered parser input for the progressive parsing for the input
* from a file descriptor
*
* Returns the new parser input or NULL
*/
xmlParserInputBufferPtr
xmlParserInputBufferCreateFd ( int fd , xmlCharEncoding enc ) {
xmlParserInputBufferPtr ret ;
if ( fd < 0 ) return ( NULL ) ;
ret = xmlAllocParserInputBuffer ( enc ) ;
2000-04-07 21:00:24 +04:00
if ( ret ! = NULL ) {
ret - > context = ( void * ) fd ;
ret - > readcallback = xmlFdRead ;
ret - > closecallback = xmlFdClose ;
}
1999-07-27 23:52:06 +04:00
return ( ret ) ;
}
2000-07-22 00:32:03 +04:00
/**
* xmlParserInputBufferCreateMem :
* @ mem : the memory input
* @ size : the length of the memory block
* @ enc : the charset encoding if known
*
* Create a buffered parser input for the progressive parsing for the input
* from a file descriptor
*
* Returns the new parser input or NULL
*/
xmlParserInputBufferPtr
xmlParserInputBufferCreateMem ( const char * mem , int size , xmlCharEncoding enc ) {
xmlParserInputBufferPtr ret ;
if ( size < = 0 ) return ( NULL ) ;
if ( mem = = NULL ) return ( NULL ) ;
ret = xmlAllocParserInputBuffer ( enc ) ;
if ( ret ! = NULL ) {
ret - > context = ( void * ) mem ;
ret - > readcallback = ( xmlInputReadCallback ) xmlNop ;
ret - > closecallback = NULL ;
xmlBufferAdd ( ret - > buffer , ( const xmlChar * ) mem , size ) ;
}
return ( ret ) ;
}
2000-06-29 03:40:59 +04:00
/**
* xmlOutputBufferCreateFd :
* @ fd : a file descriptor number
* @ encoder : the encoding converter or NULL
*
* Create a buffered output for the progressive saving
* to a file descriptor
*
* Returns the new parser output or NULL
*/
xmlOutputBufferPtr
xmlOutputBufferCreateFd ( int fd , xmlCharEncodingHandlerPtr encoder ) {
xmlOutputBufferPtr ret ;
if ( fd < 0 ) return ( NULL ) ;
ret = xmlAllocOutputBuffer ( encoder ) ;
if ( ret ! = NULL ) {
ret - > context = ( void * ) fd ;
ret - > writecallback = xmlFdWrite ;
ret - > closecallback = xmlFdClose ;
}
return ( ret ) ;
}
2000-04-12 17:27:38 +04:00
/**
* xmlParserInputBufferCreateIO :
* @ ioread : an I / O read function
* @ ioclose : an I / O close function
* @ ioctx : an I / O handler
* @ enc : the charset encoding if known
*
* Create a buffered parser input for the progressive parsing for the input
2000-06-29 03:40:59 +04:00
* from an I / O handler
2000-04-12 17:27:38 +04:00
*
* Returns the new parser input or NULL
*/
xmlParserInputBufferPtr
xmlParserInputBufferCreateIO ( xmlInputReadCallback ioread ,
xmlInputCloseCallback ioclose , void * ioctx , xmlCharEncoding enc ) {
xmlParserInputBufferPtr ret ;
if ( ioread = = NULL ) return ( NULL ) ;
ret = xmlAllocParserInputBuffer ( enc ) ;
if ( ret ! = NULL ) {
ret - > context = ( void * ) ioctx ;
ret - > readcallback = ioread ;
ret - > closecallback = ioclose ;
}
return ( ret ) ;
}
2000-06-29 03:40:59 +04:00
/**
* xmlOutputBufferCreateIO :
* @ iowrite : an I / O write function
* @ ioclose : an I / O close function
* @ ioctx : an I / O handler
* @ enc : the charset encoding if known
*
* Create a buffered output for the progressive saving
* to an I / O handler
*
* Returns the new parser output or NULL
*/
xmlOutputBufferPtr
xmlOutputBufferCreateIO ( xmlOutputWriteCallback iowrite ,
xmlOutputCloseCallback ioclose , void * ioctx ,
xmlCharEncodingHandlerPtr encoder ) {
xmlOutputBufferPtr ret ;
if ( iowrite = = NULL ) return ( NULL ) ;
ret = xmlAllocOutputBuffer ( encoder ) ;
if ( ret ! = NULL ) {
ret - > context = ( void * ) ioctx ;
ret - > writecallback = iowrite ;
ret - > closecallback = ioclose ;
}
return ( ret ) ;
}
1999-11-17 20:32:38 +03:00
/**
* xmlParserInputBufferPush :
* @ in : a buffered parser input
* @ len : the size in bytes of the array .
2000-06-29 03:40:59 +04:00
* @ buf : an char array
1999-11-17 20:32:38 +03:00
*
* Push the content of the arry in the input buffer
* This routine handle the I18N transcoding to internal UTF - 8
* This is used when operating the parser in progressive ( push ) mode .
*
* Returns the number of chars read and stored in the buffer , or - 1
* in case of error .
*/
int
2000-10-25 23:56:55 +04:00
xmlParserInputBufferPush ( xmlParserInputBufferPtr in ,
int len , const char * buf ) {
1999-11-17 20:32:38 +03:00
int nbchars = 0 ;
if ( len < 0 ) return ( 0 ) ;
if ( in - > encoder ! = NULL ) {
revamped the encoding support, added iconv support, so now libxml if
* encoding.[ch], xmlIO.[ch], parser.c, configure.in : revamped
the encoding support, added iconv support, so now libxml if
compiled with iconv automatically support japanese encodings
among others. Work based on initial patch from Yuan-Chen Cheng
I may have broken binary compat in the encoding handler
registration scheme, but that was so utterly broken I don't
expect anybody to have used this feature until now.
* parserInternals.h: fixup on the CHAR range macro
* xml-error.h, parser.c: catch URL/URI errors using the uri.c
code.
* tree.[ch]: added xmlBufferGrow(), was needed for iconv
* uri.c: added xmlParseURI() I can't believe I forgot to
implement this one in 2.0 !!!
* SAX.c: moved doc->encoding update in the endDocument() call.
* TODO: updated.
Iconv rules :-)
Daniel
2000-05-03 18:20:55 +04:00
/*
* Store the data in the incoming raw buffer
*/
if ( in - > raw = = NULL ) {
in - > raw = xmlBufferCreate ( ) ;
1999-11-17 20:32:38 +03:00
}
revamped the encoding support, added iconv support, so now libxml if
* encoding.[ch], xmlIO.[ch], parser.c, configure.in : revamped
the encoding support, added iconv support, so now libxml if
compiled with iconv automatically support japanese encodings
among others. Work based on initial patch from Yuan-Chen Cheng
I may have broken binary compat in the encoding handler
registration scheme, but that was so utterly broken I don't
expect anybody to have used this feature until now.
* parserInternals.h: fixup on the CHAR range macro
* xml-error.h, parser.c: catch URL/URI errors using the uri.c
code.
* tree.[ch]: added xmlBufferGrow(), was needed for iconv
* uri.c: added xmlParseURI() I can't believe I forgot to
implement this one in 2.0 !!!
* SAX.c: moved doc->encoding update in the endDocument() call.
* TODO: updated.
Iconv rules :-)
Daniel
2000-05-03 18:20:55 +04:00
xmlBufferAdd ( in - > raw , ( const xmlChar * ) buf , len ) ;
1999-11-17 20:32:38 +03:00
/*
revamped the encoding support, added iconv support, so now libxml if
* encoding.[ch], xmlIO.[ch], parser.c, configure.in : revamped
the encoding support, added iconv support, so now libxml if
compiled with iconv automatically support japanese encodings
among others. Work based on initial patch from Yuan-Chen Cheng
I may have broken binary compat in the encoding handler
registration scheme, but that was so utterly broken I don't
expect anybody to have used this feature until now.
* parserInternals.h: fixup on the CHAR range macro
* xml-error.h, parser.c: catch URL/URI errors using the uri.c
code.
* tree.[ch]: added xmlBufferGrow(), was needed for iconv
* uri.c: added xmlParseURI() I can't believe I forgot to
implement this one in 2.0 !!!
* SAX.c: moved doc->encoding update in the endDocument() call.
* TODO: updated.
Iconv rules :-)
Daniel
2000-05-03 18:20:55 +04:00
* convert as much as possible to the parser reading buffer .
1999-11-17 20:32:38 +03:00
*/
revamped the encoding support, added iconv support, so now libxml if
* encoding.[ch], xmlIO.[ch], parser.c, configure.in : revamped
the encoding support, added iconv support, so now libxml if
compiled with iconv automatically support japanese encodings
among others. Work based on initial patch from Yuan-Chen Cheng
I may have broken binary compat in the encoding handler
registration scheme, but that was so utterly broken I don't
expect anybody to have used this feature until now.
* parserInternals.h: fixup on the CHAR range macro
* xml-error.h, parser.c: catch URL/URI errors using the uri.c
code.
* tree.[ch]: added xmlBufferGrow(), was needed for iconv
* uri.c: added xmlParseURI() I can't believe I forgot to
implement this one in 2.0 !!!
* SAX.c: moved doc->encoding update in the endDocument() call.
* TODO: updated.
Iconv rules :-)
Daniel
2000-05-03 18:20:55 +04:00
nbchars = xmlCharEncInFunc ( in - > encoder , in - > buffer , in - > raw ) ;
2000-03-14 21:30:20 +03:00
if ( nbchars < 0 ) {
2000-10-25 23:56:55 +04:00
xmlGenericError ( xmlGenericErrorContext ,
" xmlParserInputBufferPush: encoder error \n " ) ;
2000-03-14 21:30:20 +03:00
return ( - 1 ) ;
}
1999-12-28 19:35:14 +03:00
} else {
nbchars = len ;
xmlBufferAdd ( in - > buffer , ( xmlChar * ) buf , nbchars ) ;
1999-11-17 20:32:38 +03:00
}
# ifdef DEBUG_INPUT
2000-10-25 23:56:55 +04:00
xmlGenericError ( xmlGenericErrorContext ,
" I/O: pushed %d chars, buffer %d/%d \n " ,
1999-11-17 20:32:38 +03:00
nbchars , in - > buffer - > use , in - > buffer - > size ) ;
# endif
return ( nbchars ) ;
}
1999-07-27 23:52:06 +04:00
/**
* xmlParserInputBufferGrow :
* @ in : a buffered parser input
* @ len : indicative value of the amount of chars to read
*
* Grow up the content of the input buffer , the old data are preserved
* This routine handle the I18N transcoding to internal UTF - 8
1999-11-17 20:32:38 +03:00
* This routine is used when operating the parser in normal ( pull ) mode
revamped the encoding support, added iconv support, so now libxml if
* encoding.[ch], xmlIO.[ch], parser.c, configure.in : revamped
the encoding support, added iconv support, so now libxml if
compiled with iconv automatically support japanese encodings
among others. Work based on initial patch from Yuan-Chen Cheng
I may have broken binary compat in the encoding handler
registration scheme, but that was so utterly broken I don't
expect anybody to have used this feature until now.
* parserInternals.h: fixup on the CHAR range macro
* xml-error.h, parser.c: catch URL/URI errors using the uri.c
code.
* tree.[ch]: added xmlBufferGrow(), was needed for iconv
* uri.c: added xmlParseURI() I can't believe I forgot to
implement this one in 2.0 !!!
* SAX.c: moved doc->encoding update in the endDocument() call.
* TODO: updated.
Iconv rules :-)
Daniel
2000-05-03 18:20:55 +04:00
*
* TODO : one should be able to remove one extra copy by copying directy
* onto in - > buffer or in - > raw
1999-07-27 23:52:06 +04:00
*
* Returns the number of chars read and stored in the buffer , or - 1
* in case of error .
*/
int
xmlParserInputBufferGrow ( xmlParserInputBufferPtr in , int len ) {
char * buffer = NULL ;
int res = 0 ;
int nbchars = 0 ;
int buffree ;
if ( ( len < = MINLEN ) & & ( len ! = 4 ) )
len = MINLEN ;
buffree = in - > buffer - > size - in - > buffer - > use ;
if ( buffree < = 0 ) {
2000-10-25 23:56:55 +04:00
xmlGenericError ( xmlGenericErrorContext ,
" xmlParserInputBufferGrow : buffer full ! \n " ) ;
1999-07-27 23:52:06 +04:00
return ( 0 ) ;
}
if ( len > buffree )
len = buffree ;
2000-07-14 18:49:25 +04:00
buffer = ( char * ) xmlMalloc ( ( len + 1 ) * sizeof ( char ) ) ;
1999-07-27 23:52:06 +04:00
if ( buffer = = NULL ) {
2000-10-25 23:56:55 +04:00
xmlGenericError ( xmlGenericErrorContext ,
" xmlParserInputBufferGrow : out of memory ! \n " ) ;
1999-07-27 23:52:06 +04:00
return ( - 1 ) ;
}
2000-04-07 21:00:24 +04:00
/*
* Call the read method for this I / O type .
*/
if ( in - > readcallback ! = NULL ) {
res = in - > readcallback ( in - > context , & buffer [ 0 ] , len ) ;
1999-07-27 23:52:06 +04:00
} else {
2000-10-25 23:56:55 +04:00
xmlGenericError ( xmlGenericErrorContext ,
" xmlParserInputBufferGrow : no input ! \n " ) ;
1999-09-03 02:04:43 +04:00
xmlFree ( buffer ) ;
1999-07-27 23:52:06 +04:00
return ( - 1 ) ;
}
if ( res < 0 ) {
perror ( " read error " ) ;
1999-09-03 02:04:43 +04:00
xmlFree ( buffer ) ;
1999-07-27 23:52:06 +04:00
return ( - 1 ) ;
}
2000-06-29 03:40:59 +04:00
len = res ;
1999-07-27 23:52:06 +04:00
if ( in - > encoder ! = NULL ) {
revamped the encoding support, added iconv support, so now libxml if
* encoding.[ch], xmlIO.[ch], parser.c, configure.in : revamped
the encoding support, added iconv support, so now libxml if
compiled with iconv automatically support japanese encodings
among others. Work based on initial patch from Yuan-Chen Cheng
I may have broken binary compat in the encoding handler
registration scheme, but that was so utterly broken I don't
expect anybody to have used this feature until now.
* parserInternals.h: fixup on the CHAR range macro
* xml-error.h, parser.c: catch URL/URI errors using the uri.c
code.
* tree.[ch]: added xmlBufferGrow(), was needed for iconv
* uri.c: added xmlParseURI() I can't believe I forgot to
implement this one in 2.0 !!!
* SAX.c: moved doc->encoding update in the endDocument() call.
* TODO: updated.
Iconv rules :-)
Daniel
2000-05-03 18:20:55 +04:00
/*
* Store the data in the incoming raw buffer
*/
if ( in - > raw = = NULL ) {
in - > raw = xmlBufferCreate ( ) ;
1999-07-27 23:52:06 +04:00
}
revamped the encoding support, added iconv support, so now libxml if
* encoding.[ch], xmlIO.[ch], parser.c, configure.in : revamped
the encoding support, added iconv support, so now libxml if
compiled with iconv automatically support japanese encodings
among others. Work based on initial patch from Yuan-Chen Cheng
I may have broken binary compat in the encoding handler
registration scheme, but that was so utterly broken I don't
expect anybody to have used this feature until now.
* parserInternals.h: fixup on the CHAR range macro
* xml-error.h, parser.c: catch URL/URI errors using the uri.c
code.
* tree.[ch]: added xmlBufferGrow(), was needed for iconv
* uri.c: added xmlParseURI() I can't believe I forgot to
implement this one in 2.0 !!!
* SAX.c: moved doc->encoding update in the endDocument() call.
* TODO: updated.
Iconv rules :-)
Daniel
2000-05-03 18:20:55 +04:00
xmlBufferAdd ( in - > raw , ( const xmlChar * ) buffer , len ) ;
2000-03-14 21:30:20 +03:00
/*
revamped the encoding support, added iconv support, so now libxml if
* encoding.[ch], xmlIO.[ch], parser.c, configure.in : revamped
the encoding support, added iconv support, so now libxml if
compiled with iconv automatically support japanese encodings
among others. Work based on initial patch from Yuan-Chen Cheng
I may have broken binary compat in the encoding handler
registration scheme, but that was so utterly broken I don't
expect anybody to have used this feature until now.
* parserInternals.h: fixup on the CHAR range macro
* xml-error.h, parser.c: catch URL/URI errors using the uri.c
code.
* tree.[ch]: added xmlBufferGrow(), was needed for iconv
* uri.c: added xmlParseURI() I can't believe I forgot to
implement this one in 2.0 !!!
* SAX.c: moved doc->encoding update in the endDocument() call.
* TODO: updated.
Iconv rules :-)
Daniel
2000-05-03 18:20:55 +04:00
* convert as much as possible to the parser reading buffer .
2000-03-14 21:30:20 +03:00
*/
revamped the encoding support, added iconv support, so now libxml if
* encoding.[ch], xmlIO.[ch], parser.c, configure.in : revamped
the encoding support, added iconv support, so now libxml if
compiled with iconv automatically support japanese encodings
among others. Work based on initial patch from Yuan-Chen Cheng
I may have broken binary compat in the encoding handler
registration scheme, but that was so utterly broken I don't
expect anybody to have used this feature until now.
* parserInternals.h: fixup on the CHAR range macro
* xml-error.h, parser.c: catch URL/URI errors using the uri.c
code.
* tree.[ch]: added xmlBufferGrow(), was needed for iconv
* uri.c: added xmlParseURI() I can't believe I forgot to
implement this one in 2.0 !!!
* SAX.c: moved doc->encoding update in the endDocument() call.
* TODO: updated.
Iconv rules :-)
Daniel
2000-05-03 18:20:55 +04:00
nbchars = xmlCharEncInFunc ( in - > encoder , in - > buffer , in - > raw ) ;
if ( nbchars < 0 ) {
2000-10-25 23:56:55 +04:00
xmlGenericError ( xmlGenericErrorContext ,
" xmlParserInputBufferGrow: encoder error \n " ) ;
revamped the encoding support, added iconv support, so now libxml if
* encoding.[ch], xmlIO.[ch], parser.c, configure.in : revamped
the encoding support, added iconv support, so now libxml if
compiled with iconv automatically support japanese encodings
among others. Work based on initial patch from Yuan-Chen Cheng
I may have broken binary compat in the encoding handler
registration scheme, but that was so utterly broken I don't
expect anybody to have used this feature until now.
* parserInternals.h: fixup on the CHAR range macro
* xml-error.h, parser.c: catch URL/URI errors using the uri.c
code.
* tree.[ch]: added xmlBufferGrow(), was needed for iconv
* uri.c: added xmlParseURI() I can't believe I forgot to
implement this one in 2.0 !!!
* SAX.c: moved doc->encoding update in the endDocument() call.
* TODO: updated.
Iconv rules :-)
Daniel
2000-05-03 18:20:55 +04:00
return ( - 1 ) ;
2000-03-14 21:30:20 +03:00
}
1999-07-27 23:52:06 +04:00
} else {
2000-06-29 03:40:59 +04:00
nbchars = len ;
1999-07-27 23:52:06 +04:00
buffer [ nbchars ] = 0 ;
1999-09-24 02:19:22 +04:00
xmlBufferAdd ( in - > buffer , ( xmlChar * ) buffer , nbchars ) ;
1999-07-27 23:52:06 +04:00
}
# ifdef DEBUG_INPUT
2000-10-25 23:56:55 +04:00
xmlGenericError ( xmlGenericErrorContext ,
" I/O: read %d chars, buffer %d/%d \n " ,
1999-07-27 23:52:06 +04:00
nbchars , in - > buffer - > use , in - > buffer - > size ) ;
# endif
1999-09-03 02:04:43 +04:00
xmlFree ( buffer ) ;
1999-07-27 23:52:06 +04:00
return ( nbchars ) ;
}
/**
* xmlParserInputBufferRead :
* @ in : a buffered parser input
* @ len : indicative value of the amount of chars to read
*
* Refresh the content of the input buffer , the old data are considered
* consumed
* This routine handle the I18N transcoding to internal UTF - 8
*
* Returns the number of chars read and stored in the buffer , or - 1
* in case of error .
*/
int
xmlParserInputBufferRead ( xmlParserInputBufferPtr in , int len ) {
/* xmlBufferEmpty(in->buffer); */
2000-04-07 21:00:24 +04:00
if ( in - > readcallback ! = NULL )
1999-12-28 19:35:14 +03:00
return ( xmlParserInputBufferGrow ( in , len ) ) ;
else
2000-06-29 03:40:59 +04:00
return ( - 1 ) ;
}
/**
* xmlOutputBufferWrite :
* @ out : a buffered parser output
* @ len : the size in bytes of the array .
* @ buf : an char array
*
* Write the content of the array in the output I / O buffer
* This routine handle the I18N transcoding from internal UTF - 8
* The buffer is lossless , i . e . will store in case of partial
* or delayed writes .
*
* Returns the number of chars immediately written , or - 1
* in case of error .
*/
int
xmlOutputBufferWrite ( xmlOutputBufferPtr out , int len , const char * buf ) {
int nbchars = 0 , ret ;
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 ) ;
/*
* convert as much as possible to the parser reading buffer .
*/
nbchars = xmlCharEncOutFunc ( out - > encoder , out - > conv , out - > buffer ) ;
if ( nbchars < 0 ) {
2000-10-25 23:56:55 +04:00
xmlGenericError ( xmlGenericErrorContext ,
" xmlOutputBufferWrite: encoder error \n " ) ;
2000-06-29 03:40:59 +04:00
return ( - 1 ) ;
}
nbchars = out - > conv - > use ;
} else {
xmlBufferAdd ( out - > buffer , ( const xmlChar * ) buf , len ) ;
nbchars = out - > buffer - > use ;
}
if ( nbchars < MINLEN )
return ( 0 ) ;
2000-12-27 13:46:47 +03:00
if ( ! out - > writecallback )
return ( nbchars ) ;
2000-06-29 03:40:59 +04:00
/*
* 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 ) {
2000-10-25 23:56:55 +04:00
xmlGenericError ( xmlGenericErrorContext ,
" I/O: error %d writing %d bytes \n " , ret , nbchars ) ;
2000-06-29 03:40:59 +04:00
return ( ret ) ;
}
out - > written + = ret ;
# ifdef DEBUG_INPUT
2000-10-25 23:56:55 +04:00
xmlGenericError ( xmlGenericErrorContext ,
" I/O: wrote %d chars \n " , ret ) ;
2000-06-29 03:40:59 +04:00
# endif
return ( nbchars ) ;
}
/**
* xmlOutputBufferWriteString :
* @ out : a buffered parser output
* @ str : a zero terminated C string
*
* Write the content of the string in the output I / O buffer
* This routine handle the I18N transcoding from internal UTF - 8
* The buffer is lossless , i . e . will store in case of partial
* or delayed writes .
*
* Returns the number of chars immediately written , or - 1
* in case of error .
*/
int
xmlOutputBufferWriteString ( xmlOutputBufferPtr out , const char * str ) {
int len ;
if ( str = = NULL )
return ( - 1 ) ;
len = strlen ( str ) ;
if ( len > 0 )
return ( xmlOutputBufferWrite ( out , len , str ) ) ;
return ( len ) ;
}
/**
* xmlOutputBufferFlush :
* @ out : a buffered output
*
* flushes the output I / O channel
*
* Returns the number of byte written or - 1 in case of error .
*/
int
xmlOutputBufferFlush ( xmlOutputBufferPtr out ) {
2000-12-27 13:46:47 +03:00
int nbchars = 0 , ret = 0 ;
2000-06-29 03:40:59 +04:00
/*
* first handle encoding stuff .
*/
if ( ( out - > conv ! = NULL ) & & ( out - > encoder ! = NULL ) ) {
/*
* convert as much as possible to the parser reading buffer .
*/
nbchars = xmlCharEncOutFunc ( out - > encoder , out - > conv , out - > buffer ) ;
if ( nbchars < 0 ) {
2000-10-25 23:56:55 +04:00
xmlGenericError ( xmlGenericErrorContext ,
" xmlOutputBufferWrite: encoder error \n " ) ;
2000-06-29 03:40:59 +04:00
return ( - 1 ) ;
}
}
/*
* second flush the stuff to the I / O channel
*/
2000-12-27 13:46:47 +03:00
if ( ( out - > conv ! = NULL ) & & ( out - > encoder ! = NULL ) & &
( out - > writecallback ! = NULL ) ) {
2000-06-29 03:40:59 +04:00
ret = out - > writecallback ( out - > context ,
( const char * ) out - > conv - > content , out - > conv - > use ) ;
if ( ret > = 0 )
xmlBufferShrink ( out - > conv , ret ) ;
2000-12-27 13:46:47 +03:00
} else if ( out - > writecallback ! = NULL ) {
2000-06-29 03:40:59 +04:00
ret = out - > writecallback ( out - > context ,
( const char * ) out - > buffer - > content , out - > buffer - > use ) ;
if ( ret > = 0 )
xmlBufferShrink ( out - > buffer , ret ) ;
}
if ( ret < 0 ) {
2000-10-25 23:56:55 +04:00
xmlGenericError ( xmlGenericErrorContext ,
" I/O: error %d flushing %d bytes \n " , ret , nbchars ) ;
2000-06-29 03:40:59 +04:00
return ( ret ) ;
}
out - > written + = ret ;
# ifdef DEBUG_INPUT
2000-10-25 23:56:55 +04:00
xmlGenericError ( xmlGenericErrorContext ,
" I/O: flushed %d chars \n " , ret ) ;
2000-06-29 03:40:59 +04:00
# endif
return ( ret ) ;
1999-07-27 23:52:06 +04:00
}
1999-08-10 23:04:08 +04:00
/*
* xmlParserGetDirectory :
* @ filename : the path to a file
*
* lookup the directory for that file
*
* Returns a new allocated string containing the directory , or NULL .
*/
char *
xmlParserGetDirectory ( const char * filename ) {
char * ret = NULL ;
char dir [ 1024 ] ;
char * cur ;
char sep = ' / ' ;
2000-04-07 21:00:24 +04:00
if ( xmlInputCallbackInitialized = = 0 )
xmlRegisterDefaultInputCallbacks ( ) ;
1999-08-10 23:04:08 +04:00
if ( filename = = NULL ) return ( NULL ) ;
# ifdef WIN32
sep = ' \\ ' ;
# endif
strncpy ( dir , filename , 1023 ) ;
dir [ 1023 ] = 0 ;
cur = & dir [ strlen ( dir ) ] ;
while ( cur > dir ) {
if ( * cur = = sep ) break ;
cur - - ;
}
if ( * cur = = sep ) {
if ( cur = = dir ) dir [ 1 ] = 0 ;
else * cur = 0 ;
1999-09-03 02:04:43 +04:00
ret = xmlMemStrdup ( dir ) ;
1999-08-10 23:04:08 +04:00
} else {
if ( getcwd ( dir , 1024 ) ! = NULL ) {
dir [ 1023 ] = 0 ;
1999-09-03 02:04:43 +04:00
ret = xmlMemStrdup ( dir ) ;
1999-08-10 23:04:08 +04:00
}
}
return ( ret ) ;
}
1999-08-30 01:02:19 +04:00
/****************************************************************
* *
* External entities loading *
* *
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
/*
* xmlDefaultExternalEntityLoader :
* @ URL : the URL for the entity to load
* @ ID : the System ID for the entity to load
2000-01-03 14:08:02 +03:00
* @ ctxt : the context in which the entity is called or NULL
1999-08-30 01:02:19 +04:00
*
* By default we don ' t load external entitites , yet .
*
* Returns a new allocated xmlParserInputPtr , or NULL .
*/
static
xmlParserInputPtr
xmlDefaultExternalEntityLoader ( const char * URL , const char * ID ,
2000-01-03 14:08:02 +03:00
xmlParserCtxtPtr ctxt ) {
xmlParserInputPtr ret = NULL ;
2000-09-10 20:14:55 +04:00
1999-08-30 01:02:19 +04:00
# ifdef DEBUG_EXTERNAL_ENTITIES
2000-10-25 23:56:55 +04:00
xmlGenericError ( xmlGenericErrorContext ,
" xmlDefaultExternalEntityLoader(%s, xxx) \n " , URL ) ;
1999-08-30 01:02:19 +04:00
# endif
2000-01-03 14:08:02 +03:00
if ( URL = = NULL ) {
if ( ( ctxt - > sax ! = NULL ) & & ( ctxt - > sax - > warning ! = NULL ) )
2000-10-25 23:56:55 +04:00
ctxt - > sax - > warning ( ctxt ,
" failed to load external entity \" %s \" \n " , ID ) ;
2000-01-03 14:08:02 +03:00
return ( NULL ) ;
}
ret = xmlNewInputFromFile ( ctxt , URL ) ;
if ( ret = = NULL ) {
if ( ( ctxt - > sax ! = NULL ) & & ( ctxt - > sax - > warning ! = NULL ) )
2000-10-25 23:56:55 +04:00
ctxt - > sax - > warning ( ctxt ,
" failed to load external entity \" %s \" \n " , URL ) ;
2000-01-03 14:08:02 +03:00
}
return ( ret ) ;
1999-08-30 01:02:19 +04:00
}
static xmlExternalEntityLoader xmlCurrentExternalEntityLoader =
xmlDefaultExternalEntityLoader ;
/*
* xmlSetExternalEntityLoader :
* @ f : the new entity resolver function
*
* Changes the defaultexternal entity resolver function for the application
*/
void
xmlSetExternalEntityLoader ( xmlExternalEntityLoader f ) {
xmlCurrentExternalEntityLoader = f ;
}
/*
* xmlGetExternalEntityLoader :
*
* Get the default external entity resolver function for the application
*
* Returns the xmlExternalEntityLoader function pointer
*/
xmlExternalEntityLoader
xmlGetExternalEntityLoader ( void ) {
return ( xmlCurrentExternalEntityLoader ) ;
}
/*
* xmlLoadExternalEntity :
* @ URL : the URL for the entity to load
* @ ID : the System ID for the entity to load
2000-01-03 14:08:02 +03:00
* @ ctxt : the context in which the entity is called or NULL
1999-08-30 01:02:19 +04:00
*
* Load an external entity , note that the use of this function for
* unparsed entities may generate problems
* TODO : a more generic External entitiy API must be designed
*
* Returns the xmlParserInputPtr or NULL
*/
xmlParserInputPtr
xmlLoadExternalEntity ( const char * URL , const char * ID ,
2000-01-03 14:08:02 +03:00
xmlParserCtxtPtr ctxt ) {
return ( xmlCurrentExternalEntityLoader ( URL , ID , ctxt ) ) ;
1999-08-30 01:02:19 +04:00
}