2001-02-23 20:55:21 +03:00
/*
* xmlIO . c : implementation of the I / O interfaces used by the parser
*
* See Copyright for the status of this software .
*
2001-08-20 04:08:40 +04:00
* daniel @ veillard . com
2001-02-23 20:55:21 +03:00
*/
2002-03-18 22:37:11 +03:00
# define IN_LIBXML
2001-04-21 20:57:29 +04:00
# include "libxml.h"
2001-02-23 20:55:21 +03:00
# include <string.h>
2022-03-02 02:29:17 +03:00
# include <stdlib.h>
2001-02-23 20:55:21 +03:00
# include <errno.h>
# ifdef HAVE_SYS_STAT_H
# include <sys/stat.h>
# endif
# ifdef HAVE_FCNTL_H
# include <fcntl.h>
# endif
# ifdef HAVE_UNISTD_H
# include <unistd.h>
# endif
2017-11-13 19:08:38 +03:00
# ifdef LIBXML_ZLIB_ENABLED
2001-02-23 20:55:21 +03:00
# include <zlib.h>
# endif
2017-11-13 19:08:38 +03:00
# ifdef LIBXML_LZMA_ENABLED
2011-09-18 18:59:13 +04:00
# include <lzma.h>
# endif
2001-02-23 20:55:21 +03:00
2022-03-01 00:42:10 +03:00
# if defined(_WIN32)
2017-10-09 01:20:01 +03:00
# define WIN32_LEAN_AND_MEAN
2006-04-27 12:15:20 +04:00
# include <windows.h>
2022-03-30 02:07:51 +03:00
# include <io.h>
# include <direct.h>
2006-04-27 12:15:20 +04:00
# endif
2023-09-20 18:54:48 +03:00
# include <libxml/xmlIO.h>
2001-02-23 20:55:21 +03:00
# include <libxml/xmlmemory.h>
2001-07-08 22:35:48 +04:00
# include <libxml/uri.h>
2001-02-23 20:55:21 +03:00
# include <libxml/nanohttp.h>
2024-06-11 03:15:18 +03:00
# include <libxml/parserInternals.h>
2001-02-23 20:55:21 +03:00
# include <libxml/xmlerror.h>
2001-05-10 19:34:11 +04:00
# ifdef LIBXML_CATALOG_ENABLED
# include <libxml/catalog.h>
# endif
2001-02-23 20:55:21 +03:00
2022-08-26 02:22:33 +03:00
# include "private/buf.h"
# include "private/enc.h"
# include "private/error.h"
# include "private/io.h"
2012-07-16 10:22:54 +04:00
2001-07-23 23:10:52 +04:00
/* #define VERBOSE_FAILURE */
2001-02-23 20:55:21 +03:00
# define MINLEN 4000
2023-12-23 06:03:41 +03:00
# ifndef STDOUT_FILENO
# define STDOUT_FILENO 1
# endif
2023-12-19 21:36:35 +03:00
# ifndef S_ISDIR
# ifdef _S_ISDIR
# define S_ISDIR(x) _S_ISDIR(x)
# elif defined(S_IFDIR)
# ifdef S_IFMT
# define S_ISDIR(m) (((m) & S_IFMT) == S_IFDIR)
# elif defined(_S_IFMT)
# define S_ISDIR(m) (((m) & _S_IFMT) == S_IFDIR)
# endif
# endif
# endif
2001-02-23 20:55:21 +03:00
/*
* Input I / O callback sets
*/
typedef struct _xmlInputCallback {
xmlInputMatchCallback matchcallback ;
xmlInputOpenCallback opencallback ;
xmlInputReadCallback readcallback ;
xmlInputCloseCallback closecallback ;
} xmlInputCallback ;
2023-12-19 15:33:59 +03:00
/* This dummy function only marks default IO in the callback table */
static int
xmlIODefaultMatch ( const char * filename ) ;
# define MAX_INPUT_CALLBACK 10
2001-02-23 20:55:21 +03:00
2023-12-20 22:11:09 +03:00
static xmlInputCallback xmlInputCallbackTable [ MAX_INPUT_CALLBACK ] ;
static int xmlInputCallbackNr ;
2001-02-23 20:55:21 +03:00
2003-09-29 17:20:24 +04:00
# ifdef LIBXML_OUTPUT_ENABLED
2001-02-23 20:55:21 +03:00
/*
* Output I / O callback sets
*/
typedef struct _xmlOutputCallback {
xmlOutputMatchCallback matchcallback ;
xmlOutputOpenCallback opencallback ;
xmlOutputWriteCallback writecallback ;
xmlOutputCloseCallback closecallback ;
} xmlOutputCallback ;
2023-12-19 15:33:59 +03:00
# define MAX_OUTPUT_CALLBACK 10
2001-02-23 20:55:21 +03:00
2023-12-20 22:11:09 +03:00
static xmlOutputCallback xmlOutputCallbackTable [ MAX_OUTPUT_CALLBACK ] ;
static int xmlOutputCallbackNr ;
2003-09-29 17:20:24 +04:00
# endif /* LIBXML_OUTPUT_ENABLED */
2001-02-23 20:55:21 +03:00
2003-10-08 15:54:57 +04:00
/************************************************************************
* *
2023-12-20 22:01:19 +03:00
* Error handling *
2003-10-08 15:54:57 +04:00
* *
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
/**
2024-06-10 17:39:57 +03:00
* xmlIOErr :
2003-10-08 15:54:57 +04:00
* @ code : the error number
*
2024-06-10 17:39:57 +03:00
* Convert errno to xmlParserErrors .
*
* Returns an xmlParserErrors code .
2003-10-08 15:54:57 +04:00
*/
2024-06-10 17:39:57 +03:00
static int
xmlIOErr ( int err )
2003-10-08 15:54:57 +04:00
{
2024-06-10 17:39:57 +03:00
int code ;
2003-10-08 15:54:57 +04:00
2024-06-10 17:39:57 +03:00
if ( err = = 0 ) code = XML_IO_UNKNOWN ;
2003-10-08 15:54:57 +04:00
# ifdef EACCES
2024-06-10 17:39:57 +03:00
else if ( err = = EACCES ) code = XML_IO_EACCES ;
2003-10-08 15:54:57 +04:00
# endif
# ifdef EAGAIN
2024-06-10 17:39:57 +03:00
else if ( err = = EAGAIN ) code = XML_IO_EAGAIN ;
2003-10-08 15:54:57 +04:00
# endif
# ifdef EBADF
2024-06-10 17:39:57 +03:00
else if ( err = = EBADF ) code = XML_IO_EBADF ;
2003-10-08 15:54:57 +04:00
# endif
# ifdef EBADMSG
2024-06-10 17:39:57 +03:00
else if ( err = = EBADMSG ) code = XML_IO_EBADMSG ;
2003-10-08 15:54:57 +04:00
# endif
# ifdef EBUSY
2024-06-10 17:39:57 +03:00
else if ( err = = EBUSY ) code = XML_IO_EBUSY ;
2003-10-08 15:54:57 +04:00
# endif
# ifdef ECANCELED
2024-06-10 17:39:57 +03:00
else if ( err = = ECANCELED ) code = XML_IO_ECANCELED ;
2003-10-08 15:54:57 +04:00
# endif
# ifdef ECHILD
2024-06-10 17:39:57 +03:00
else if ( err = = ECHILD ) code = XML_IO_ECHILD ;
2003-10-08 15:54:57 +04:00
# endif
# ifdef EDEADLK
2024-06-10 17:39:57 +03:00
else if ( err = = EDEADLK ) code = XML_IO_EDEADLK ;
2003-10-08 15:54:57 +04:00
# endif
# ifdef EDOM
2024-06-10 17:39:57 +03:00
else if ( err = = EDOM ) code = XML_IO_EDOM ;
2003-10-08 15:54:57 +04:00
# endif
# ifdef EEXIST
2024-06-10 17:39:57 +03:00
else if ( err = = EEXIST ) code = XML_IO_EEXIST ;
2003-10-08 15:54:57 +04:00
# endif
# ifdef EFAULT
2024-06-10 17:39:57 +03:00
else if ( err = = EFAULT ) code = XML_IO_EFAULT ;
2003-10-08 15:54:57 +04:00
# endif
# ifdef EFBIG
2024-06-10 17:39:57 +03:00
else if ( err = = EFBIG ) code = XML_IO_EFBIG ;
2003-10-08 15:54:57 +04:00
# endif
# ifdef EINPROGRESS
2024-06-10 17:39:57 +03:00
else if ( err = = EINPROGRESS ) code = XML_IO_EINPROGRESS ;
2003-10-08 15:54:57 +04:00
# endif
# ifdef EINTR
2024-06-10 17:39:57 +03:00
else if ( err = = EINTR ) code = XML_IO_EINTR ;
2003-10-08 15:54:57 +04:00
# endif
# ifdef EINVAL
2024-06-10 17:39:57 +03:00
else if ( err = = EINVAL ) code = XML_IO_EINVAL ;
2003-10-08 15:54:57 +04:00
# endif
# ifdef EIO
2024-06-10 17:39:57 +03:00
else if ( err = = EIO ) code = XML_IO_EIO ;
2003-10-08 15:54:57 +04:00
# endif
# ifdef EISDIR
2024-06-10 17:39:57 +03:00
else if ( err = = EISDIR ) code = XML_IO_EISDIR ;
2003-10-08 15:54:57 +04:00
# endif
# ifdef EMFILE
2024-06-10 17:39:57 +03:00
else if ( err = = EMFILE ) code = XML_IO_EMFILE ;
2003-10-08 15:54:57 +04:00
# endif
# ifdef EMLINK
2024-06-10 17:39:57 +03:00
else if ( err = = EMLINK ) code = XML_IO_EMLINK ;
2003-10-08 15:54:57 +04:00
# endif
# ifdef EMSGSIZE
2024-06-10 17:39:57 +03:00
else if ( err = = EMSGSIZE ) code = XML_IO_EMSGSIZE ;
2003-10-08 15:54:57 +04:00
# endif
# ifdef ENAMETOOLONG
2024-06-10 17:39:57 +03:00
else if ( err = = ENAMETOOLONG ) code = XML_IO_ENAMETOOLONG ;
2003-10-08 15:54:57 +04:00
# endif
# ifdef ENFILE
2024-06-10 17:39:57 +03:00
else if ( err = = ENFILE ) code = XML_IO_ENFILE ;
2003-10-08 15:54:57 +04:00
# endif
# ifdef ENODEV
2024-06-10 17:39:57 +03:00
else if ( err = = ENODEV ) code = XML_IO_ENODEV ;
2003-10-08 15:54:57 +04:00
# endif
# ifdef ENOENT
2024-06-10 17:39:57 +03:00
else if ( err = = ENOENT ) code = XML_IO_ENOENT ;
2003-10-08 15:54:57 +04:00
# endif
# ifdef ENOEXEC
2024-06-10 17:39:57 +03:00
else if ( err = = ENOEXEC ) code = XML_IO_ENOEXEC ;
2003-10-08 15:54:57 +04:00
# endif
# ifdef ENOLCK
2024-06-10 17:39:57 +03:00
else if ( err = = ENOLCK ) code = XML_IO_ENOLCK ;
2003-10-08 15:54:57 +04:00
# endif
# ifdef ENOMEM
2024-06-10 17:39:57 +03:00
else if ( err = = ENOMEM ) code = XML_IO_ENOMEM ;
2003-10-08 15:54:57 +04:00
# endif
# ifdef ENOSPC
2024-06-10 17:39:57 +03:00
else if ( err = = ENOSPC ) code = XML_IO_ENOSPC ;
2003-10-08 15:54:57 +04:00
# endif
# ifdef ENOSYS
2024-06-10 17:39:57 +03:00
else if ( err = = ENOSYS ) code = XML_IO_ENOSYS ;
2003-10-08 15:54:57 +04:00
# endif
# ifdef ENOTDIR
2024-06-10 17:39:57 +03:00
else if ( err = = ENOTDIR ) code = XML_IO_ENOTDIR ;
2003-10-08 15:54:57 +04:00
# endif
# ifdef ENOTEMPTY
2024-06-10 17:39:57 +03:00
else if ( err = = ENOTEMPTY ) code = XML_IO_ENOTEMPTY ;
2003-10-08 15:54:57 +04:00
# endif
# ifdef ENOTSUP
2024-06-10 17:39:57 +03:00
else if ( err = = ENOTSUP ) code = XML_IO_ENOTSUP ;
2003-10-08 15:54:57 +04:00
# endif
# ifdef ENOTTY
2024-06-10 17:39:57 +03:00
else if ( err = = ENOTTY ) code = XML_IO_ENOTTY ;
2003-10-08 15:54:57 +04:00
# endif
# ifdef ENXIO
2024-06-10 17:39:57 +03:00
else if ( err = = ENXIO ) code = XML_IO_ENXIO ;
2003-10-08 15:54:57 +04:00
# endif
# ifdef EPERM
2024-06-10 17:39:57 +03:00
else if ( err = = EPERM ) code = XML_IO_EPERM ;
2003-10-08 15:54:57 +04:00
# endif
# ifdef EPIPE
2024-06-10 17:39:57 +03:00
else if ( err = = EPIPE ) code = XML_IO_EPIPE ;
2003-10-08 15:54:57 +04:00
# endif
# ifdef ERANGE
2024-06-10 17:39:57 +03:00
else if ( err = = ERANGE ) code = XML_IO_ERANGE ;
2003-10-08 15:54:57 +04:00
# endif
# ifdef EROFS
2024-06-10 17:39:57 +03:00
else if ( err = = EROFS ) code = XML_IO_EROFS ;
2003-10-08 15:54:57 +04:00
# endif
# ifdef ESPIPE
2024-06-10 17:39:57 +03:00
else if ( err = = ESPIPE ) code = XML_IO_ESPIPE ;
2003-10-08 15:54:57 +04:00
# endif
# ifdef ESRCH
2024-06-10 17:39:57 +03:00
else if ( err = = ESRCH ) code = XML_IO_ESRCH ;
2003-10-08 15:54:57 +04:00
# endif
# ifdef ETIMEDOUT
2024-06-10 17:39:57 +03:00
else if ( err = = ETIMEDOUT ) code = XML_IO_ETIMEDOUT ;
2003-10-08 15:54:57 +04:00
# endif
# ifdef EXDEV
2024-06-10 17:39:57 +03:00
else if ( err = = EXDEV ) code = XML_IO_EXDEV ;
2003-10-10 23:36:36 +04:00
# endif
# ifdef ENOTSOCK
2024-06-10 17:39:57 +03:00
else if ( err = = ENOTSOCK ) code = XML_IO_ENOTSOCK ;
2003-10-10 23:36:36 +04:00
# endif
# ifdef EISCONN
2024-06-10 17:39:57 +03:00
else if ( err = = EISCONN ) code = XML_IO_EISCONN ;
2003-10-10 23:36:36 +04:00
# endif
# ifdef ECONNREFUSED
2024-06-10 17:39:57 +03:00
else if ( err = = ECONNREFUSED ) code = XML_IO_ECONNREFUSED ;
2003-10-10 23:36:36 +04:00
# endif
# ifdef ETIMEDOUT
2024-06-10 17:39:57 +03:00
else if ( err = = ETIMEDOUT ) code = XML_IO_ETIMEDOUT ;
2003-10-10 23:36:36 +04:00
# endif
# ifdef ENETUNREACH
2024-06-10 17:39:57 +03:00
else if ( err = = ENETUNREACH ) code = XML_IO_ENETUNREACH ;
2003-10-10 23:36:36 +04:00
# endif
# ifdef EADDRINUSE
2024-06-10 17:39:57 +03:00
else if ( err = = EADDRINUSE ) code = XML_IO_EADDRINUSE ;
2003-10-10 23:36:36 +04:00
# endif
# ifdef EINPROGRESS
2024-06-10 17:39:57 +03:00
else if ( err = = EINPROGRESS ) code = XML_IO_EINPROGRESS ;
2003-10-10 23:36:36 +04:00
# endif
# ifdef EALREADY
2024-06-10 17:39:57 +03:00
else if ( err = = EALREADY ) code = XML_IO_EALREADY ;
2003-10-10 23:36:36 +04:00
# endif
# ifdef EAFNOSUPPORT
2024-06-10 17:39:57 +03:00
else if ( err = = EAFNOSUPPORT ) code = XML_IO_EAFNOSUPPORT ;
2003-10-08 15:54:57 +04:00
# endif
2024-06-10 17:39:57 +03:00
else code = XML_IO_UNKNOWN ;
2023-12-19 17:41:37 +03:00
return ( code ) ;
2003-10-10 23:36:36 +04:00
}
2003-10-08 15:54:57 +04:00
/************************************************************************
* *
2023-12-20 22:01:19 +03:00
* Standard I / O for file accesses *
2003-10-08 15:54:57 +04:00
* *
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
2002-09-10 15:13:43 +04:00
2023-12-20 22:01:19 +03:00
# if defined(_WIN32)
2020-02-11 13:32:23 +03:00
/**
2023-12-20 22:01:19 +03:00
* __xmlIOWin32UTF8ToWChar :
* @ u8String : uft - 8 string
2020-02-11 13:32:23 +03:00
*
2023-12-20 22:01:19 +03:00
* Convert a string from utf - 8 to wchar ( WINDOWS ONLY ! )
2020-02-11 13:32:23 +03:00
*/
2023-12-20 22:01:19 +03:00
static wchar_t *
__xmlIOWin32UTF8ToWChar ( const char * u8String )
2020-02-11 13:32:23 +03:00
{
2023-12-20 22:01:19 +03:00
wchar_t * wString = NULL ;
2023-12-23 02:00:15 +03:00
int i ;
2020-02-11 13:32:23 +03:00
2023-12-20 22:01:19 +03:00
if ( u8String ) {
int wLen =
MultiByteToWideChar ( CP_UTF8 , MB_ERR_INVALID_CHARS , u8String ,
- 1 , NULL , 0 ) ;
if ( wLen ) {
wString = xmlMalloc ( wLen * sizeof ( wchar_t ) ) ;
if ( wString ) {
if ( MultiByteToWideChar
( CP_UTF8 , 0 , u8String , - 1 , wString , wLen ) = = 0 ) {
xmlFree ( wString ) ;
wString = NULL ;
}
}
2023-12-23 02:00:15 +03:00
/*
* Convert to backward slash
*/
for ( i = 0 ; wString [ i ] ! = 0 ; i + + ) {
if ( wString [ i ] = = ' / ' )
wString [ i ] = ' \\ ' ;
}
2023-12-20 22:01:19 +03:00
}
}
2020-02-11 13:32:23 +03:00
2023-12-20 22:01:19 +03:00
return wString ;
2020-02-11 13:32:23 +03:00
}
2006-09-01 13:56:07 +04:00
# endif
2023-12-20 22:01:19 +03:00
/**
* xmlNormalizeWindowsPath :
* @ path : the input file path
*
2023-12-23 06:03:41 +03:00
* DEPRECATED : This never really worked .
2023-12-20 22:01:19 +03:00
*
2023-12-23 06:03:41 +03:00
* Returns a copy of path .
2023-12-20 22:01:19 +03:00
*/
xmlChar *
xmlNormalizeWindowsPath ( const xmlChar * path )
{
2023-12-23 06:03:41 +03:00
return xmlStrdup ( path ) ;
2023-12-20 22:01:19 +03:00
}
2001-02-23 20:55:21 +03:00
/**
2002-12-11 17:23:49 +03:00
* xmlCheckFilename :
2001-02-23 20:55:21 +03:00
* @ path : the path to check
*
2023-12-19 21:36:35 +03:00
* DEPRECATED : Internal function , don ' t use .
2001-02-23 20:55:21 +03:00
*
* if stat is not available on the target machine ,
* returns 1. if stat fails , returns 0 ( if calling
* stat on the filename fails , it can ' t be right ) .
* if stat succeeds and the file is a directory ,
2002-10-14 15:15:18 +04:00
* returns 2. otherwise returns 1.
2001-02-23 20:55:21 +03:00
*/
2002-10-14 15:15:18 +04:00
int
2023-12-23 06:03:41 +03:00
xmlCheckFilename ( const char * path )
2001-02-23 20:55:21 +03:00
{
2006-09-01 13:56:07 +04:00
# ifdef HAVE_STAT
2022-03-01 01:22:50 +03:00
# if defined(_WIN32)
2017-10-09 16:35:32 +03:00
struct _stat stat_buffer ;
# else
2012-09-07 08:14:00 +04:00
struct stat stat_buffer ;
2017-10-09 16:35:32 +03:00
# endif
2023-12-23 06:03:41 +03:00
int res ;
2006-05-03 00:34:38 +04:00
# endif
2023-12-23 06:03:41 +03:00
2012-09-07 08:14:00 +04:00
if ( path = = NULL )
return ( 0 ) ;
2006-08-30 17:11:36 +04:00
2001-02-23 20:55:21 +03:00
# ifdef HAVE_STAT
2022-03-01 01:22:50 +03:00
# if defined(_WIN32)
2023-12-23 06:03:41 +03:00
{
wchar_t * wpath ;
2012-09-07 08:14:00 +04:00
2023-12-23 06:03:41 +03:00
/*
* 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 ;
wpath = __xmlIOWin32UTF8ToWChar ( path ) ;
if ( wpath = = NULL )
return ( 0 ) ;
res = _wstat ( wpath , & stat_buffer ) ;
xmlFree ( wpath ) ;
}
2006-09-01 13:56:07 +04:00
# else
2023-12-23 06:03:41 +03:00
res = stat ( path , & stat_buffer ) ;
2006-09-01 13:56:07 +04:00
# endif
2023-12-23 06:03:41 +03:00
if ( res < 0 )
return 0 ;
2002-10-14 15:15:18 +04:00
# ifdef S_ISDIR
2006-04-27 12:15:20 +04:00
if ( S_ISDIR ( stat_buffer . st_mode ) )
2002-10-14 15:15:18 +04:00
return 2 ;
2006-09-01 13:56:07 +04:00
# endif
2006-04-27 12:15:20 +04:00
# endif /* HAVE_STAT */
2023-12-23 06:03:41 +03:00
2001-02-23 20:55:21 +03:00
return 1 ;
}
2023-12-23 02:00:15 +03:00
static int
xmlConvertUriToPath ( const char * uri , char * * out ) {
const char * escaped ;
char * unescaped ;
* out = NULL ;
if ( ! xmlStrncasecmp ( BAD_CAST uri , BAD_CAST " file://localhost/ " , 17 ) ) {
escaped = & uri [ 16 ] ;
} else if ( ! xmlStrncasecmp ( BAD_CAST uri , BAD_CAST " file:/// " , 8 ) ) {
escaped = & uri [ 7 ] ;
} else if ( ! xmlStrncasecmp ( BAD_CAST uri , BAD_CAST " file:/ " , 6 ) ) {
/* lots of generators seems to lazy to read RFC 1738 */
escaped = & uri [ 5 ] ;
} else {
return ( 1 ) ;
}
# ifdef _WIN32
/* Ignore slash like in file:///C:/file.txt */
escaped + = 1 ;
# endif
unescaped = xmlURIUnescapeString ( escaped , 0 , NULL ) ;
if ( unescaped = = NULL )
return ( - 1 ) ;
* out = unescaped ;
return ( 0 ) ;
}
2023-12-19 21:36:35 +03:00
/**
* xmlFdOpen :
* @ filename : the URI for matching
* @ out : pointer to resulting context
*
* Returns an xmlParserErrors code
*/
static int
2023-12-23 06:03:41 +03:00
xmlFdOpen ( const char * filename , int write , int * out ) {
2023-12-23 02:00:15 +03:00
char * fromUri = NULL ;
2023-12-23 06:03:41 +03:00
int flags ;
2023-12-19 21:36:35 +03:00
int fd ;
int ret ;
2023-12-23 06:03:41 +03:00
* out = - 1 ;
2023-12-19 21:36:35 +03:00
if ( filename = = NULL )
return ( XML_ERR_ARGUMENT ) ;
2023-12-23 02:00:15 +03:00
if ( xmlConvertUriToPath ( filename , & fromUri ) < 0 )
return ( XML_ERR_NO_MEMORY ) ;
2023-12-19 21:36:35 +03:00
2023-12-23 02:00:15 +03:00
if ( fromUri ! = NULL )
filename = fromUri ;
2023-12-19 21:36:35 +03:00
# if defined(_WIN32)
{
wchar_t * wpath ;
wpath = __xmlIOWin32UTF8ToWChar ( filename ) ;
2023-12-23 02:00:15 +03:00
if ( wpath = = NULL ) {
xmlFree ( fromUri ) ;
2023-12-19 21:36:35 +03:00
return ( XML_ERR_NO_MEMORY ) ;
2023-12-23 02:00:15 +03:00
}
2023-12-23 06:03:41 +03:00
if ( write )
flags = _O_WRONLY | _O_CREAT | _O_TRUNC ;
else
flags = _O_RDONLY ;
fd = _wopen ( wpath , flags | _O_BINARY , 0777 ) ;
2023-12-19 21:36:35 +03:00
xmlFree ( wpath ) ;
}
# else
2023-12-23 06:03:41 +03:00
if ( write )
flags = O_WRONLY | O_CREAT | O_TRUNC ;
else
flags = O_RDONLY ;
fd = open ( filename , flags , 0777 ) ;
2023-12-19 21:36:35 +03:00
# endif /* WIN32 */
if ( fd < 0 ) {
/*
* Windows and possibly other platforms return EINVAL
* for invalid filenames .
*/
if ( ( errno = = ENOENT ) | | ( errno = = EINVAL ) ) {
ret = XML_IO_ENOENT ;
} else {
2024-06-10 17:39:57 +03:00
ret = xmlIOErr ( errno ) ;
2023-12-19 21:36:35 +03:00
}
} else {
2023-12-23 06:03:41 +03:00
* out = fd ;
2023-12-19 21:36:35 +03:00
ret = XML_ERR_OK ;
}
2023-12-23 02:00:15 +03:00
xmlFree ( fromUri ) ;
2023-12-19 21:36:35 +03:00
return ( ret ) ;
}
2001-02-23 20:55:21 +03:00
/**
* xmlFdRead :
* @ context : the I / O context
* @ buffer : where to drop data
* @ len : number of bytes to read
*
* Read @ len bytes to @ buffer from the I / O channel .
*
2023-12-24 19:59:02 +03:00
* Returns the number of bytes read
2001-02-23 20:55:21 +03:00
*/
2001-03-24 20:00:36 +03:00
static int
2023-12-24 19:59:02 +03:00
xmlFdRead ( void * context , char * buffer , int len ) {
int fd = ( int ) ( ptrdiff_t ) context ;
int ret = 0 ;
int bytes ;
while ( len > 0 ) {
bytes = read ( fd , buffer , len ) ;
if ( bytes < 0 ) {
/*
* If we already got some bytes , return them without
* raising an error .
*/
if ( ret > 0 )
break ;
2024-06-10 17:39:57 +03:00
return ( - xmlIOErr ( errno ) ) ;
2023-12-24 19:59:02 +03:00
}
if ( bytes = = 0 )
break ;
ret + = bytes ;
buffer + = bytes ;
len - = bytes ;
}
2003-10-08 15:54:57 +04:00
return ( ret ) ;
2001-02-23 20:55:21 +03:00
}
2003-09-29 17:20:24 +04:00
# ifdef LIBXML_OUTPUT_ENABLED
2001-02-23 20:55:21 +03: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
*/
2001-03-24 20:00:36 +03:00
static int
2023-12-24 19:59:02 +03:00
xmlFdWrite ( void * context , const char * buffer , int len ) {
int fd = ( int ) ( ptrdiff_t ) context ;
2005-10-28 18:54:17 +04:00
int ret = 0 ;
2023-12-24 19:59:02 +03:00
int bytes ;
while ( len > 0 ) {
bytes = write ( fd , buffer , len ) ;
if ( bytes < 0 )
2024-06-10 17:39:57 +03:00
return ( - xmlIOErr ( errno ) ) ;
2023-12-24 19:59:02 +03:00
ret + = bytes ;
buffer + = bytes ;
len - = bytes ;
2005-10-28 18:54:17 +04:00
}
2023-12-24 19:59:02 +03:00
2003-10-08 15:54:57 +04:00
return ( ret ) ;
2001-02-23 20:55:21 +03:00
}
2003-09-29 17:20:24 +04:00
# endif /* LIBXML_OUTPUT_ENABLED */
2001-02-23 20:55:21 +03:00
/**
* xmlFdClose :
* @ context : the I / O context
*
* Close an I / O channel
2001-07-23 23:10:52 +04:00
*
* Returns 0 in case of success and error code otherwise
2001-02-23 20:55:21 +03:00
*/
2001-07-23 23:10:52 +04:00
static int
2001-02-23 20:55:21 +03:00
xmlFdClose ( void * context ) {
2003-10-08 15:54:57 +04:00
int ret ;
2023-12-25 01:56:57 +03:00
2017-10-09 14:37:42 +03:00
ret = close ( ( int ) ( ptrdiff_t ) context ) ;
2023-12-25 01:56:57 +03:00
if ( ret < 0 )
2024-06-10 17:39:57 +03:00
return ( xmlIOErr ( errno ) ) ;
2023-12-25 01:56:57 +03:00
return ( XML_ERR_OK ) ;
2001-02-23 20:55:21 +03:00
}
/**
* xmlFileMatch :
* @ filename : the URI for matching
*
2023-12-19 21:36:35 +03:00
* DEPRECATED : Internal function , don ' t use .
2001-02-23 20:55:21 +03:00
*
* Returns 1 if matches , 0 otherwise
*/
2002-05-01 22:32:28 +04:00
int
2001-03-26 20:28:29 +04:00
xmlFileMatch ( const char * filename ATTRIBUTE_UNUSED ) {
2001-02-23 20:55:21 +03:00
return ( 1 ) ;
}
/**
2023-12-23 06:03:41 +03:00
* xmlFileOpenSafe :
2001-02-23 20:55:21 +03:00
* @ filename : the URI for matching
2023-12-19 17:41:37 +03:00
* @ out : pointer to resulting context
2001-02-23 20:55:21 +03:00
*
2023-12-23 06:03:41 +03:00
* input from FILE *
2001-02-23 20:55:21 +03:00
*
* Returns an I / O context or NULL in case of error
*/
2023-12-19 17:41:37 +03:00
static int
2023-12-23 06:03:41 +03:00
xmlFileOpenSafe ( const char * filename , int write , void * * out ) {
char * fromUri = NULL ;
2006-09-01 13:56:07 +04:00
FILE * fd ;
2023-12-19 17:41:37 +03:00
int ret = XML_ERR_OK ;
2001-02-23 20:55:21 +03:00
2023-12-19 17:41:37 +03:00
* out = NULL ;
2004-11-04 02:25:47 +03:00
if ( filename = = NULL )
2023-12-19 17:41:37 +03:00
return ( XML_ERR_ARGUMENT ) ;
2004-11-04 02:25:47 +03:00
2023-12-23 06:03:41 +03:00
if ( xmlConvertUriToPath ( filename , & fromUri ) < 0 )
return ( XML_ERR_NO_MEMORY ) ;
if ( fromUri ! = NULL )
filename = fromUri ;
2001-02-23 20:55:21 +03:00
2022-03-01 01:22:50 +03:00
# if defined(_WIN32)
2023-12-23 06:03:41 +03:00
{
wchar_t * wpath ;
wpath = __xmlIOWin32UTF8ToWChar ( filename ) ;
if ( wpath = = NULL ) {
xmlFree ( fromUri ) ;
return ( XML_ERR_NO_MEMORY ) ;
}
fd = _wfopen ( wpath , write ? L " wb " : L " rb " ) ;
xmlFree ( wpath ) ;
}
2006-09-01 13:56:07 +04:00
# else
2023-12-23 06:03:41 +03:00
fd = fopen ( filename , write ? " wb " : " rb " ) ;
2001-02-23 20:55:21 +03:00
# endif /* WIN32 */
2023-12-19 17:41:37 +03:00
if ( fd = = NULL ) {
/*
* Windows and possibly other platforms return EINVAL
* for invalid filenames .
*/
if ( ( errno = = ENOENT ) | | ( errno = = EINVAL ) ) {
ret = XML_IO_ENOENT ;
} else {
/*
* This error won ' t be forwarded to the parser context
* which will report it a second time .
*/
2024-06-10 17:39:57 +03:00
ret = xmlIOErr ( errno ) ;
2023-12-19 17:41:37 +03:00
}
}
* out = fd ;
2023-12-23 06:03:41 +03:00
xmlFree ( fromUri ) ;
2023-12-19 17:41:37 +03:00
return ( ret ) ;
2001-02-23 20:55:21 +03:00
}
2023-12-19 17:41:37 +03:00
/**
* xmlFileOpen :
* @ filename : the URI for matching
*
2023-12-19 21:36:35 +03:00
* DEPRECATED : Internal function , don ' t use .
2023-12-19 17:41:37 +03:00
*
* Returns an IO context or NULL in case or failure
*/
void *
xmlFileOpen ( const char * filename ) {
void * context ;
2023-12-23 06:03:41 +03:00
xmlFileOpenSafe ( filename , 0 , & context ) ;
2023-12-19 17:41:37 +03:00
return ( context ) ;
}
2001-02-23 20:55:21 +03:00
/**
* xmlFileRead :
* @ context : the I / O context
* @ buffer : where to drop data
* @ len : number of bytes to write
*
2023-12-19 21:36:35 +03:00
* DEPRECATED : Internal function , don ' t use .
2001-02-23 20:55:21 +03:00
*
2023-12-24 19:59:02 +03:00
* Returns the number of bytes read or < 0 in case of failure
2001-02-23 20:55:21 +03:00
*/
2002-05-01 22:32:28 +04:00
int
2023-12-24 19:59:02 +03:00
xmlFileRead ( void * context , char * buffer , int len ) {
FILE * file = context ;
size_t bytes ;
2009-08-11 19:51:22 +04:00
if ( ( context = = NULL ) | | ( buffer = = NULL ) )
2004-11-05 20:22:25 +03:00
return ( - 1 ) ;
2023-12-24 19:59:02 +03:00
/*
* The C standard doesn ' t mandate that fread sets errno , only
* POSIX does . The Windows documentation isn ' t really clear .
* Set errno to zero which will be reported as unknown error
* if fread fails without setting errno .
*/
errno = 0 ;
bytes = fread ( buffer , 1 , len , file ) ;
if ( ( bytes < ( size_t ) len ) & & ( ferror ( file ) ) )
2024-06-10 17:39:57 +03:00
return ( - xmlIOErr ( errno ) ) ;
2023-12-24 19:59:02 +03:00
return ( len ) ;
2001-02-23 20:55:21 +03:00
}
2003-09-29 17:20:24 +04:00
# ifdef LIBXML_OUTPUT_ENABLED
2001-02-23 20:55:21 +03: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
*/
2001-03-24 20:00:36 +03:00
static int
2023-12-24 19:59:02 +03:00
xmlFileWrite ( void * context , const char * buffer , int len ) {
FILE * file = context ;
size_t bytes ;
2002-12-17 21:33:01 +03:00
2009-08-11 19:51:22 +04:00
if ( ( context = = NULL ) | | ( buffer = = NULL ) )
2004-11-05 20:22:25 +03:00
return ( - 1 ) ;
2023-12-24 19:59:02 +03:00
errno = 0 ;
bytes = fwrite ( buffer , 1 , len , file ) ;
if ( bytes < ( size_t ) len )
2024-06-10 17:39:57 +03:00
return ( - xmlIOErr ( errno ) ) ;
2023-12-24 19:59:02 +03:00
return ( len ) ;
2001-02-23 20:55:21 +03:00
}
2003-09-29 17:20:24 +04:00
# endif /* LIBXML_OUTPUT_ENABLED */
2001-02-23 20:55:21 +03:00
/**
2023-12-25 01:56:57 +03:00
* xmlFileFlush :
2001-02-23 20:55:21 +03:00
* @ context : the I / O context
*
2023-12-25 01:56:57 +03:00
* Flush an I / O channel
2001-02-23 20:55:21 +03:00
*/
2023-12-25 01:56:57 +03:00
static int
xmlFileFlush ( void * context ) {
FILE * file = context ;
2001-10-30 13:32:36 +03:00
2023-12-25 01:56:57 +03:00
if ( file = = NULL )
2004-11-04 02:25:47 +03:00
return ( - 1 ) ;
2023-12-25 01:56:57 +03:00
if ( fflush ( file ) ! = 0 )
2024-06-10 17:39:57 +03:00
return ( xmlIOErr ( errno ) ) ;
2023-12-25 01:56:57 +03:00
return ( XML_ERR_OK ) ;
2001-02-23 20:55:21 +03:00
}
/**
2023-12-25 01:56:57 +03:00
* xmlFileClose :
2001-02-23 20:55:21 +03:00
* @ context : the I / O context
*
2023-12-25 01:56:57 +03:00
* DEPRECATED : Internal function , don ' t use .
*
* Returns 0 or - 1 an error code case of error
2001-02-23 20:55:21 +03:00
*/
2023-12-25 01:56:57 +03:00
int
xmlFileClose ( void * context ) {
FILE * file = context ;
2004-11-04 02:25:47 +03:00
if ( context = = NULL )
return ( - 1 ) ;
2023-12-25 01:56:57 +03:00
if ( file = = stdin )
return ( 0 ) ;
if ( ( file = = stdout ) | | ( file = = stderr ) )
return ( xmlFileFlush ( file ) ) ;
if ( fclose ( file ) ! = 0 )
2024-06-10 17:39:57 +03:00
return ( xmlIOErr ( errno ) ) ;
2023-12-25 01:56:57 +03:00
return ( 0 ) ;
2001-02-23 20:55:21 +03:00
}
2005-11-09 11:56:26 +03:00
# ifdef LIBXML_OUTPUT_ENABLED
/**
* xmlBufferWrite :
* @ context : the xmlBuffer
* @ buffer : the data to write
* @ len : number of bytes to write
*
* Write @ len bytes from @ buffer to the xml buffer
*
2023-12-10 19:50:22 +03:00
* Returns the number of bytes written or a negative xmlParserErrors
* value .
2005-11-09 11:56:26 +03:00
*/
static int
xmlBufferWrite ( void * context , const char * buffer , int len ) {
int ret ;
ret = xmlBufferAdd ( ( xmlBufferPtr ) context , ( const xmlChar * ) buffer , len ) ;
if ( ret ! = 0 )
2023-12-10 19:50:22 +03:00
return ( - XML_ERR_NO_MEMORY ) ;
2005-11-09 11:56:26 +03:00
return ( len ) ;
}
# endif
2017-11-13 19:08:38 +03:00
# ifdef LIBXML_ZLIB_ENABLED
2001-02-23 20:55:21 +03:00
/************************************************************************
* *
* I / O for compressed file accesses *
* *
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
/**
* 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 .
*
2017-06-18 00:20:38 +03:00
* Returns the number of bytes read .
2001-02-23 20:55:21 +03:00
*/
2001-03-24 20:00:36 +03:00
static int
2001-02-23 20:55:21 +03:00
xmlGzfileRead ( void * context , char * buffer , int len ) {
2003-10-08 15:54:57 +04:00
int ret ;
ret = gzread ( ( gzFile ) context , & buffer [ 0 ] , len ) ;
2024-06-10 17:39:57 +03:00
if ( ret < 0 )
return ( - XML_IO_UNKNOWN ) ;
2003-10-08 15:54:57 +04:00
return ( ret ) ;
2001-02-23 20:55:21 +03:00
}
2003-09-29 17:20:24 +04:00
# ifdef LIBXML_OUTPUT_ENABLED
2001-02-23 20:55:21 +03: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
*/
2001-03-24 20:00:36 +03:00
static int
2001-02-23 20:55:21 +03:00
xmlGzfileWrite ( void * context , const char * buffer , int len ) {
2003-10-08 15:54:57 +04:00
int ret ;
ret = gzwrite ( ( gzFile ) context , ( char * ) & buffer [ 0 ] , len ) ;
2024-06-10 17:39:57 +03:00
if ( ret < 0 )
return ( - XML_IO_UNKNOWN ) ;
2003-10-08 15:54:57 +04:00
return ( ret ) ;
2001-02-23 20:55:21 +03:00
}
2003-09-29 17:20:24 +04:00
# endif /* LIBXML_OUTPUT_ENABLED */
2001-02-23 20:55:21 +03:00
/**
* xmlGzfileClose :
* @ context : the I / O context
*
* Close a compressed I / O channel
*/
2001-07-23 23:10:52 +04:00
static int
2001-02-23 20:55:21 +03:00
xmlGzfileClose ( void * context ) {
2024-06-10 17:39:57 +03:00
if ( gzclose ( ( gzFile ) context ) ! = Z_OK )
return ( XML_IO_UNKNOWN ) ;
return ( 0 ) ;
2001-02-23 20:55:21 +03:00
}
2017-11-13 19:08:38 +03:00
# endif /* LIBXML_ZLIB_ENABLED */
2001-02-23 20:55:21 +03:00
2011-09-18 18:59:13 +04:00
/************************************************************************
* *
* I / O for compressed file accesses *
* *
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
2023-12-23 06:03:41 +03:00
# ifdef LIBXML_LZMA_ENABLED
2011-09-18 18:59:13 +04:00
2023-12-23 06:03:41 +03:00
# include "private/xzlib.h"
2011-09-18 18:59:13 +04:00
/**
* 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 ;
2012-01-26 12:56:22 +04:00
ret = __libxml2_xzread ( ( xzFile ) context , & buffer [ 0 ] , len ) ;
2024-06-10 17:39:57 +03:00
if ( ret < 0 )
return ( - XML_IO_UNKNOWN ) ;
2011-09-18 18:59:13 +04:00
return ( ret ) ;
}
/**
* xmlXzfileClose :
* @ context : the I / O context
*
* Close a compressed I / O channel
*/
static int
xmlXzfileClose ( void * context ) {
2024-06-10 17:39:57 +03:00
if ( __libxml2_xzclose ( ( xzFile ) context ) ! = LZMA_OK )
return ( XML_IO_UNKNOWN ) ;
return ( 0 ) ;
2011-09-18 18:59:13 +04:00
}
2015-11-03 10:46:29 +03:00
# endif /* LIBXML_LZMA_ENABLED */
2011-09-18 18:59:13 +04:00
2001-02-23 20:55:21 +03:00
/************************************************************************
* *
* I / O for HTTP file accesses *
* *
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
2001-07-23 23:10:52 +04:00
2023-12-21 20:09:42 +03:00
# ifdef LIBXML_HTTP_ENABLED
2001-02-23 20:55:21 +03:00
/**
* xmlIOHTTPMatch :
* @ filename : the URI for matching
*
2023-12-21 20:09:42 +03:00
* DEPRECATED : Internal function , don ' t use .
*
2001-02-23 20:55:21 +03:00
* check if the URI matches an HTTP one
*
* Returns 1 if matches , 0 otherwise
*/
2002-05-01 22:32:28 +04:00
int
2001-02-23 20:55:21 +03:00
xmlIOHTTPMatch ( const char * filename ) {
2002-05-01 22:32:28 +04:00
if ( ! xmlStrncasecmp ( BAD_CAST filename , BAD_CAST " http:// " , 7 ) )
2001-02-23 20:55:21 +03:00
return ( 1 ) ;
return ( 0 ) ;
}
/**
* xmlIOHTTPOpen :
* @ filename : the URI for matching
*
2023-12-21 20:09:42 +03:00
* DEPRECATED : Internal function , don ' t use .
*
2001-02-23 20:55:21 +03:00
* open an HTTP I / O channel
*
* Returns an I / O context or NULL in case of error
*/
2002-05-01 22:32:28 +04:00
void *
2001-02-23 20:55:21 +03:00
xmlIOHTTPOpen ( const char * filename ) {
return ( xmlNanoHTTPOpen ( filename , NULL ) ) ;
}
2003-09-29 17:20:24 +04:00
# ifdef LIBXML_OUTPUT_ENABLED
2001-07-23 23:10:52 +04:00
/**
2002-12-11 17:23:49 +03:00
* xmlIOHTTPOpenW :
2001-07-23 23:10:52 +04:00
* @ post_uri : The destination URI for the document
* @ compression : The compression desired for the document .
*
2023-12-21 20:09:42 +03:00
* DEPRECATED : Support for HTTP POST has been removed .
2001-07-23 23:10:52 +04:00
*
2023-12-21 20:09:42 +03:00
* Returns NULL .
2001-07-23 23:10:52 +04:00
*/
void *
2023-12-21 20:09:42 +03:00
xmlIOHTTPOpenW ( const char * post_uri ATTRIBUTE_UNUSED ,
int compression ATTRIBUTE_UNUSED )
2002-01-18 19:23:55 +03:00
{
2023-12-21 20:09:42 +03:00
return ( NULL ) ;
2001-07-23 23:10:52 +04:00
}
2003-09-29 17:20:24 +04:00
# endif /* LIBXML_OUTPUT_ENABLED */
2008-09-01 17:08:57 +04:00
2001-02-23 20:55:21 +03:00
/**
* xmlIOHTTPRead :
* @ context : the I / O context
* @ buffer : where to drop data
* @ len : number of bytes to write
*
2023-12-21 20:09:42 +03:00
* DEPRECATED : Internal function , don ' t use .
*
2001-02-23 20:55:21 +03:00
* Read @ len bytes to @ buffer from the I / O channel .
*
* Returns the number of bytes written
*/
2009-08-11 19:51:22 +04:00
int
2001-02-23 20:55:21 +03:00
xmlIOHTTPRead ( void * context , char * buffer , int len ) {
2004-11-08 14:54:28 +03:00
if ( ( buffer = = NULL ) | | ( len < 0 ) ) return ( - 1 ) ;
2001-02-23 20:55:21 +03:00
return ( xmlNanoHTTPRead ( context , & buffer [ 0 ] , len ) ) ;
}
/**
* xmlIOHTTPClose :
* @ context : the I / O context
*
2023-12-21 20:09:42 +03:00
* DEPRECATED : Internal function , don ' t use .
*
2001-02-23 20:55:21 +03:00
* Close an HTTP I / O channel
2002-12-11 17:23:49 +03:00
*
* Returns 0
2001-02-23 20:55:21 +03:00
*/
2002-05-01 22:32:28 +04:00
int
2001-02-23 20:55:21 +03:00
xmlIOHTTPClose ( void * context ) {
xmlNanoHTTPClose ( context ) ;
2001-07-23 23:10:52 +04:00
return 0 ;
2001-02-23 20:55:21 +03:00
}
# endif /* LIBXML_HTTP_ENABLED */
2023-12-20 22:01:19 +03:00
/************************************************************************
* *
* Input / output buffers *
* *
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
2001-02-23 20:55:21 +03:00
2023-12-19 15:33:59 +03:00
static int
xmlIODefaultMatch ( const char * filename ATTRIBUTE_UNUSED ) {
return ( 1 ) ;
}
2023-12-19 17:41:37 +03:00
/**
* xmlInputDefaultOpen :
* @ buf : input buffer to be filled
* @ filename : filename or URI
2024-06-11 00:57:52 +03:00
* @ flags : XML_INPUT flags
2023-12-19 17:41:37 +03:00
*
* Returns an xmlParserErrors code .
*/
2023-12-19 15:33:59 +03:00
static int
2024-06-11 00:57:52 +03:00
xmlInputDefaultOpen ( xmlParserInputBufferPtr buf , const char * filename ,
2024-06-11 01:00:32 +03:00
int flags ) {
2023-12-19 17:41:37 +03:00
int ret ;
2023-12-23 06:03:41 +03:00
int fd ;
2023-12-19 17:41:37 +03:00
2024-06-11 01:00:32 +03:00
/* Avoid unused variable warning */
( void ) flags ;
2023-12-19 15:33:59 +03:00
# ifdef LIBXML_HTTP_ENABLED
if ( xmlIOHTTPMatch ( filename ) ) {
2024-06-11 19:11:51 +03:00
if ( ( flags & XML_INPUT_NETWORK ) = = 0 )
return ( XML_IO_NETWORK_ATTEMPT ) ;
2023-12-19 15:33:59 +03:00
buf - > context = xmlIOHTTPOpen ( filename ) ;
if ( buf - > context ! = NULL ) {
buf - > readcallback = xmlIOHTTPRead ;
buf - > closecallback = xmlIOHTTPClose ;
return ( XML_ERR_OK ) ;
}
}
# endif /* LIBXML_HTTP_ENABLED */
2023-12-23 06:03:41 +03:00
if ( ! xmlFileMatch ( filename ) )
return ( XML_IO_ENOENT ) ;
2023-12-19 15:33:59 +03:00
# ifdef LIBXML_LZMA_ENABLED
2024-06-11 01:00:32 +03:00
if ( flags & XML_INPUT_UNZIP ) {
2023-12-23 06:03:41 +03:00
xzFile xzStream ;
ret = xmlFdOpen ( filename , 0 , & fd ) ;
if ( ret ! = XML_ERR_OK )
return ( ret ) ;
2023-12-19 15:33:59 +03:00
2023-12-23 06:03:41 +03:00
xzStream = __libxml2_xzdopen ( filename , fd , " rb " ) ;
if ( xzStream = = NULL ) {
close ( fd ) ;
} else {
if ( __libxml2_xzcompressed ( xzStream ) > 0 ) {
buf - > context = xzStream ;
2023-12-19 19:05:08 +03:00
buf - > readcallback = xmlXzfileRead ;
buf - > closecallback = xmlXzfileClose ;
2023-12-23 06:03:41 +03:00
buf - > compressed = 1 ;
2023-12-19 15:33:59 +03:00
2023-12-19 19:05:08 +03:00
return ( XML_ERR_OK ) ;
}
2023-12-23 06:03:41 +03:00
xmlXzfileClose ( xzStream ) ;
2023-12-19 15:33:59 +03:00
}
}
# endif /* LIBXML_LZMA_ENABLED */
# ifdef LIBXML_ZLIB_ENABLED
2024-06-11 01:00:32 +03:00
if ( flags & XML_INPUT_UNZIP ) {
2023-12-23 06:03:41 +03:00
gzFile gzStream ;
2023-12-19 15:33:59 +03:00
2023-12-23 06:03:41 +03:00
ret = xmlFdOpen ( filename , 0 , & fd ) ;
if ( ret ! = XML_ERR_OK )
return ( ret ) ;
gzStream = gzdopen ( fd , " rb " ) ;
if ( gzStream = = NULL ) {
close ( fd ) ;
} else {
2023-12-19 19:05:08 +03:00
char buff4 [ 4 ] ;
2023-12-19 15:33:59 +03:00
2023-12-23 06:03:41 +03:00
if ( ( gzread ( gzStream , buff4 , 4 ) > 0 ) & &
( gzdirect ( gzStream ) = = 0 ) ) {
gzrewind ( gzStream ) ;
2023-12-19 19:05:08 +03:00
2023-12-23 06:03:41 +03:00
buf - > context = gzStream ;
2023-12-19 19:05:08 +03:00
buf - > readcallback = xmlGzfileRead ;
buf - > closecallback = xmlGzfileClose ;
buf - > compressed = 1 ;
return ( XML_ERR_OK ) ;
2023-12-19 15:33:59 +03:00
}
2023-12-23 06:03:41 +03:00
xmlGzfileClose ( gzStream ) ;
2023-12-19 15:33:59 +03:00
}
}
# endif /* LIBXML_ZLIB_ENABLED */
2023-12-23 06:03:41 +03:00
ret = xmlFdOpen ( filename , 0 , & fd ) ;
if ( ret ! = XML_ERR_OK )
return ( ret ) ;
2023-12-19 15:33:59 +03:00
2023-12-23 06:03:41 +03:00
buf - > context = ( void * ) ( ptrdiff_t ) fd ;
buf - > readcallback = xmlFdRead ;
buf - > closecallback = xmlFdClose ;
return ( XML_ERR_OK ) ;
2023-12-19 15:33:59 +03:00
}
# ifdef LIBXML_OUTPUT_ENABLED
2023-12-19 17:41:37 +03:00
/**
* xmlOutputDefaultOpen :
* @ buf : input buffer to be filled
* @ filename : filename or URI
* @ compression : compression level or 0
* @ is_file_uri : whether filename is a file URI
*
* Returns an xmlParserErrors code .
*/
2023-12-19 15:33:59 +03:00
static int
xmlOutputDefaultOpen ( xmlOutputBufferPtr buf , const char * filename ,
2023-12-23 06:03:41 +03:00
int compression ) {
int fd ;
2023-12-19 15:33:59 +03:00
( void ) compression ;
2001-02-23 20:55:21 +03:00
2023-12-23 06:03:41 +03:00
if ( ! strcmp ( filename , " - " ) ) {
fd = dup ( STDOUT_FILENO ) ;
if ( fd < 0 )
2024-06-10 17:39:57 +03:00
return ( xmlIOErr ( errno ) ) ;
2023-12-23 06:03:41 +03:00
} else {
int ret ;
ret = xmlFdOpen ( filename , /* write */ 1 , & fd ) ;
if ( ret ! = XML_ERR_OK )
return ( ret ) ;
2023-12-19 15:33:59 +03:00
}
2023-12-23 06:03:41 +03:00
# ifdef LIBXML_ZLIB_ENABLED
if ( ( compression > 0 ) & & ( compression < = 9 ) ) {
gzFile gzStream ;
char mode [ 15 ] ;
2023-12-19 15:33:59 +03:00
2023-12-23 06:03:41 +03:00
snprintf ( mode , sizeof ( mode ) , " wb%d " , compression ) ;
gzStream = gzdopen ( fd , mode ) ;
if ( gzStream = = NULL ) {
close ( fd ) ;
2024-06-10 17:39:57 +03:00
return ( XML_IO_UNKNOWN ) ;
2023-12-19 15:33:59 +03:00
}
2023-12-23 06:03:41 +03:00
buf - > context = gzStream ;
buf - > writecallback = xmlGzfileWrite ;
buf - > closecallback = xmlGzfileClose ;
return ( XML_ERR_OK ) ;
2023-12-19 15:33:59 +03:00
}
2023-12-23 06:03:41 +03:00
# endif /* LIBXML_ZLIB_ENABLED */
2023-12-19 15:33:59 +03:00
2023-12-23 06:03:41 +03:00
buf - > context = ( void * ) ( ptrdiff_t ) fd ;
buf - > writecallback = xmlFdWrite ;
buf - > closecallback = xmlFdClose ;
return ( XML_ERR_OK ) ;
2001-02-23 20:55:21 +03:00
}
2001-07-23 23:10:52 +04:00
# endif
2001-02-23 20:55:21 +03:00
/**
* xmlAllocParserInputBuffer :
2023-12-10 19:50:22 +03:00
* @ enc : the charset encoding if known ( deprecated )
*
* Create a buffered parser input for progressive parsing .
2001-02-23 20:55:21 +03:00
*
2023-12-10 19:50:22 +03:00
* The encoding argument is deprecated and should be set to
* XML_CHAR_ENCODING_NONE . The encoding can be changed with
* xmlSwitchEncoding or xmlSwitchEncodingName later on .
2001-02-23 20:55:21 +03:00
*
* Returns the new parser input or NULL
*/
xmlParserInputBufferPtr
xmlAllocParserInputBuffer ( xmlCharEncoding enc ) {
xmlParserInputBufferPtr ret ;
ret = ( xmlParserInputBufferPtr ) xmlMalloc ( sizeof ( xmlParserInputBuffer ) ) ;
if ( ret = = NULL ) {
return ( NULL ) ;
}
2022-09-01 02:18:30 +03:00
memset ( ret , 0 , sizeof ( xmlParserInputBuffer ) ) ;
2012-07-16 10:22:54 +04:00
ret - > buffer = xmlBufCreateSize ( 2 * xmlDefaultBufferSize ) ;
2001-02-23 20:55:21 +03:00
if ( ret - > buffer = = NULL ) {
xmlFree ( ret ) ;
return ( NULL ) ;
}
2012-07-16 10:22:54 +04:00
xmlBufSetAllocationScheme ( ret - > buffer , XML_BUFFER_ALLOC_DOUBLEIT ) ;
2023-12-10 19:50:22 +03:00
if ( enc ! = XML_CHAR_ENCODING_NONE ) {
if ( xmlLookupCharEncodingHandler ( enc , & ret - > encoder ) ! = 0 ) {
/* We can't handle errors properly here. */
xmlFreeParserInputBuffer ( ret ) ;
return ( NULL ) ;
}
}
2001-02-23 20:55:21 +03:00
if ( ret - > encoder ! = NULL )
2012-07-16 10:22:54 +04:00
ret - > raw = xmlBufCreateSize ( 2 * xmlDefaultBufferSize ) ;
2001-02-23 20:55:21 +03:00
else
ret - > raw = NULL ;
ret - > readcallback = NULL ;
ret - > closecallback = NULL ;
ret - > context = NULL ;
2003-09-08 05:57:30 +04:00
ret - > compressed = - 1 ;
2004-02-11 16:25:26 +03:00
ret - > rawconsumed = 0 ;
2001-02-23 20:55:21 +03:00
return ( ret ) ;
}
2003-09-29 17:20:24 +04:00
# ifdef LIBXML_OUTPUT_ENABLED
2001-02-23 20:55:21 +03: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 ) {
return ( NULL ) ;
}
2022-09-01 02:18:30 +03:00
memset ( ret , 0 , sizeof ( xmlOutputBuffer ) ) ;
2012-07-16 10:22:54 +04:00
ret - > buffer = xmlBufCreate ( ) ;
2001-02-23 20:55:21 +03:00
if ( ret - > buffer = = NULL ) {
xmlFree ( ret ) ;
return ( NULL ) ;
}
2024-03-18 16:20:19 +03:00
xmlBufSetAllocationScheme ( ret - > buffer , XML_BUFFER_ALLOC_IO ) ;
2009-03-23 22:32:04 +03:00
2008-09-01 17:08:57 +04:00
ret - > encoder = encoder ;
if ( encoder ! = NULL ) {
2012-07-16 10:22:54 +04:00
ret - > conv = xmlBufCreateSize ( 4000 ) ;
2008-09-01 17:08:57 +04:00
if ( ret - > conv = = NULL ) {
2019-07-09 10:11:01 +03:00
xmlBufFree ( ret - > buffer ) ;
2008-09-01 17:08:57 +04:00
xmlFree ( ret ) ;
return ( NULL ) ;
}
/*
* This call is designed to initiate the encoder state
*/
2012-07-16 10:22:54 +04:00
xmlCharEncOutput ( ret , 1 ) ;
2008-09-01 17:08:57 +04:00
} 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 ) {
return ( NULL ) ;
}
2022-09-01 02:18:30 +03:00
memset ( ret , 0 , sizeof ( xmlOutputBuffer ) ) ;
2012-07-16 10:22:54 +04:00
ret - > buffer = xmlBufCreate ( ) ;
2008-09-01 17:08:57 +04:00
if ( ret - > buffer = = NULL ) {
xmlFree ( ret ) ;
return ( NULL ) ;
}
2008-08-30 16:52:26 +04:00
/*
* For conversion buffers we use the special IO handling
*/
2012-07-16 10:22:54 +04:00
xmlBufSetAllocationScheme ( ret - > buffer , XML_BUFFER_ALLOC_IO ) ;
2008-08-30 16:52:26 +04:00
2001-02-23 20:55:21 +03:00
ret - > encoder = encoder ;
if ( encoder ! = NULL ) {
2012-07-16 10:22:54 +04:00
ret - > conv = xmlBufCreateSize ( 4000 ) ;
2008-08-30 16:52:26 +04:00
if ( ret - > conv = = NULL ) {
2019-05-20 14:26:08 +03:00
xmlBufFree ( ret - > buffer ) ;
2008-08-30 16:52:26 +04:00
xmlFree ( ret ) ;
return ( NULL ) ;
}
2001-02-23 20:55:21 +03:00
/*
* This call is designed to initiate the encoder state
*/
2012-07-16 10:22:54 +04:00
xmlCharEncOutput ( ret , 1 ) ;
2001-02-23 20:55:21 +03:00
} else
ret - > conv = NULL ;
ret - > writecallback = NULL ;
ret - > closecallback = NULL ;
ret - > context = NULL ;
ret - > written = 0 ;
return ( ret ) ;
}
2008-09-01 17:08:57 +04:00
2003-09-29 17:20:24 +04:00
# endif /* LIBXML_OUTPUT_ENABLED */
2001-02-23 20:55:21 +03:00
/**
* xmlFreeParserInputBuffer :
* @ in : a buffered parser input
*
* Free up the memory used by a buffered parser input
*/
void
xmlFreeParserInputBuffer ( xmlParserInputBufferPtr in ) {
2003-09-17 23:36:25 +04:00
if ( in = = NULL ) return ;
2001-02-23 20:55:21 +03:00
if ( in - > raw ) {
2012-07-16 10:22:54 +04:00
xmlBufFree ( in - > raw ) ;
2001-02-23 20:55:21 +03:00
in - > raw = NULL ;
}
if ( in - > encoder ! = NULL ) {
xmlCharEncCloseFunc ( in - > encoder ) ;
}
if ( in - > closecallback ! = NULL ) {
in - > closecallback ( in - > context ) ;
}
if ( in - > buffer ! = NULL ) {
2012-07-16 10:22:54 +04:00
xmlBufFree ( in - > buffer ) ;
2001-02-23 20:55:21 +03:00
in - > buffer = NULL ;
}
xmlFree ( in ) ;
}
2003-09-29 17:20:24 +04:00
# ifdef LIBXML_OUTPUT_ENABLED
2001-02-23 20:55:21 +03:00
/**
* xmlOutputBufferClose :
* @ out : a buffered output
*
* flushes and close the output I / O channel
* and free up all the associated resources
*
2024-01-05 22:31:10 +03:00
* Returns the number of byte written or a negative xmlParserErrors
* code in case of error .
2001-02-23 20:55:21 +03:00
*/
int
2003-10-08 23:19:10 +04:00
xmlOutputBufferClose ( xmlOutputBufferPtr out )
{
2023-12-25 01:56:57 +03:00
int ret ;
2001-02-23 20:55:21 +03:00
if ( out = = NULL )
2003-10-08 23:19:10 +04:00
return ( - 1 ) ;
2023-12-25 01:56:57 +03:00
2001-02-23 20:55:21 +03:00
if ( out - > writecallback ! = NULL )
2003-10-08 23:19:10 +04:00
xmlOutputBufferFlush ( out ) ;
2023-12-25 01:56:57 +03:00
2001-02-23 20:55:21 +03:00
if ( out - > closecallback ! = NULL ) {
2023-12-25 01:56:57 +03:00
int code = out - > closecallback ( out - > context ) ;
if ( ( code ! = XML_ERR_OK ) & & ( out - > error = = XML_ERR_OK ) ) {
if ( code < 0 )
out - > error = XML_IO_UNKNOWN ;
else
out - > error = code ;
}
2001-02-23 20:55:21 +03:00
}
2023-12-25 01:56:57 +03:00
if ( out - > error ! = XML_ERR_OK )
2024-01-05 22:31:10 +03:00
ret = - out - > error ;
2023-12-25 01:56:57 +03:00
else
ret = out - > written ;
2001-02-23 20:55:21 +03:00
if ( out - > conv ) {
2012-07-16 10:22:54 +04:00
xmlBufFree ( out - > conv ) ;
2003-10-08 23:19:10 +04:00
out - > conv = NULL ;
2001-02-23 20:55:21 +03:00
}
if ( out - > encoder ! = NULL ) {
xmlCharEncCloseFunc ( out - > encoder ) ;
}
if ( out - > buffer ! = NULL ) {
2012-07-16 10:22:54 +04:00
xmlBufFree ( out - > buffer ) ;
2003-10-08 23:19:10 +04:00
out - > buffer = NULL ;
2001-02-23 20:55:21 +03:00
}
xmlFree ( out ) ;
2023-12-25 01:56:57 +03:00
return ( ret ) ;
2001-02-23 20:55:21 +03:00
}
2003-09-29 17:20:24 +04:00
# endif /* LIBXML_OUTPUT_ENABLED */
2001-02-23 20:55:21 +03:00
2023-12-19 17:41:37 +03:00
/**
2024-06-11 00:57:52 +03:00
* xmlParserInputBufferCreateUrl :
2023-12-19 17:41:37 +03:00
* @ URI : the filename or URI
* @ enc : encoding enum ( deprecated )
2024-06-11 00:57:52 +03:00
* @ flags : XML_INPUT flags
2023-12-19 17:41:37 +03:00
* @ out : pointer to resulting input buffer
*
* Returns an xmlParserErrors code .
*/
2024-06-10 19:51:56 +03:00
int
2024-06-11 00:57:52 +03:00
xmlParserInputBufferCreateUrl ( const char * URI , xmlCharEncoding enc ,
int flags , xmlParserInputBufferPtr * out ) {
2023-12-19 17:41:37 +03:00
xmlParserInputBufferPtr buf ;
int ret ;
int i ;
2001-02-23 20:55:21 +03:00
2023-12-19 17:41:37 +03:00
* out = NULL ;
if ( URI = = NULL )
return ( XML_ERR_ARGUMENT ) ;
2001-02-23 20:55:21 +03:00
2023-12-19 15:33:59 +03:00
/*
* Allocate the Input buffer front - end .
*/
2023-12-19 17:41:37 +03:00
buf = xmlAllocParserInputBuffer ( enc ) ;
if ( buf = = NULL )
return ( XML_ERR_NO_MEMORY ) ;
2023-12-19 15:33:59 +03:00
2001-02-23 20:55:21 +03:00
/*
2001-12-31 19:16:02 +03:00
* Try to find one of the input accept method accepting that scheme
2001-02-23 20:55:21 +03:00
* Go in reverse to give precedence to user defined handlers .
2001-07-08 22:35:48 +04:00
*/
2023-12-19 17:41:37 +03:00
ret = XML_IO_ENOENT ;
2023-12-19 15:33:59 +03:00
for ( i = xmlInputCallbackNr - 1 ; i > = 0 ; i - - ) {
xmlInputCallback * cb = & xmlInputCallbackTable [ i ] ;
if ( cb - > matchcallback = = xmlIODefaultMatch ) {
2024-06-11 00:57:52 +03:00
ret = xmlInputDefaultOpen ( buf , URI , flags ) ;
2023-12-19 15:33:59 +03:00
2023-12-19 17:41:37 +03:00
if ( ( ret = = XML_ERR_OK ) | | ( ret ! = XML_IO_ENOENT ) )
2023-12-19 15:33:59 +03:00
break ;
} else if ( ( cb - > matchcallback ! = NULL ) & &
( cb - > matchcallback ( URI ) ! = 0 ) ) {
2023-12-19 17:41:37 +03:00
buf - > context = cb - > opencallback ( URI ) ;
if ( buf - > context ! = NULL ) {
buf - > readcallback = cb - > readcallback ;
buf - > closecallback = cb - > closecallback ;
ret = XML_ERR_OK ;
2023-12-19 15:33:59 +03:00
break ;
}
}
2001-02-23 20:55:21 +03:00
}
2023-12-19 17:41:37 +03:00
if ( ret ! = XML_ERR_OK ) {
xmlFreeParserInputBuffer ( buf ) ;
* out = NULL ;
return ( ret ) ;
2001-02-23 20:55:21 +03:00
}
2023-12-19 17:41:37 +03:00
* out = buf ;
return ( ret ) ;
}
xmlParserInputBufferPtr
__xmlParserInputBufferCreateFilename ( const char * URI , xmlCharEncoding enc ) {
xmlParserInputBufferPtr ret ;
2024-06-11 00:57:52 +03:00
xmlParserInputBufferCreateUrl ( URI , enc , 0 , & ret ) ;
2001-02-23 20:55:21 +03:00
return ( ret ) ;
}
/**
2004-06-02 20:18:40 +04:00
* xmlParserInputBufferCreateFilename :
2001-02-23 20:55:21 +03:00
* @ URI : a C string containing the URI or filename
2004-06-02 20:18:40 +04:00
* @ enc : the charset encoding if known
2001-02-23 20:55:21 +03:00
*
2004-06-02 20:18:40 +04:00
* Create a buffered parser input for the progressive parsing of a file
2001-02-23 20:55:21 +03:00
* Automatic support for ZLIB / Compress compressed document is provided
* by default if found at compile - time .
2004-06-02 20:18:40 +04:00
* Do an encoding check if enc = = XML_CHAR_ENCODING_NONE
2001-02-23 20:55:21 +03:00
*
2004-06-02 20:18:40 +04:00
* Returns the new parser input or NULL
2001-02-23 20:55:21 +03:00
*/
2004-06-02 20:18:40 +04:00
xmlParserInputBufferPtr
xmlParserInputBufferCreateFilename ( const char * URI , xmlCharEncoding enc ) {
2024-06-10 19:51:56 +03:00
xmlParserInputBufferPtr ret ;
2023-12-19 17:41:37 +03:00
if ( xmlParserInputBufferCreateFilenameValue ! = NULL )
return ( xmlParserInputBufferCreateFilenameValue ( URI , enc ) ) ;
2024-06-11 00:57:52 +03:00
xmlParserInputBufferCreateUrl ( URI , enc , 0 , & ret ) ;
2024-06-10 19:51:56 +03:00
return ( ret ) ;
2004-06-02 20:18:40 +04:00
}
# ifdef LIBXML_OUTPUT_ENABLED
2004-06-08 14:16:42 +04:00
xmlOutputBufferPtr
2004-06-02 20:18:40 +04:00
__xmlOutputBufferCreateFilename ( const char * URI ,
2001-02-23 20:55:21 +03:00
xmlCharEncodingHandlerPtr encoder ,
2023-12-19 15:33:59 +03:00
int compression ) {
2001-02-23 20:55:21 +03:00
xmlOutputBufferPtr ret ;
2004-05-09 06:58:44 +04:00
xmlURIPtr puri ;
2001-08-15 12:47:42 +04:00
int i = 0 ;
2004-05-09 06:58:44 +04:00
char * unescaped = NULL ;
2001-07-23 23:10:52 +04:00
2023-12-23 02:00:15 +03:00
if ( URI = = NULL )
return ( NULL ) ;
2001-02-23 20:55:21 +03:00
2004-05-09 06:58:44 +04:00
puri = xmlParseURI ( URI ) ;
if ( puri ! = NULL ) {
2023-12-23 02:00:15 +03:00
/*
* try to limit the damages of the URI unescaping code .
*/
if ( puri - > scheme = = NULL ) {
unescaped = xmlURIUnescapeString ( URI , 0 , NULL ) ;
if ( unescaped = = NULL ) {
xmlFreeURI ( puri ) ;
return ( NULL ) ;
}
URI = unescaped ;
2023-12-19 15:33:59 +03:00
}
2023-12-23 02:00:15 +03:00
xmlFreeURI ( puri ) ;
2004-05-09 06:58:44 +04:00
}
2001-08-15 12:47:42 +04:00
/*
2023-12-19 15:33:59 +03:00
* Allocate the Output buffer front - end .
2001-08-15 12:47:42 +04:00
*/
2023-12-19 15:33:59 +03:00
ret = xmlAllocOutputBufferInternal ( encoder ) ;
2023-12-23 02:00:15 +03:00
if ( ret = = NULL ) {
xmlFree ( unescaped ) ;
2023-12-19 15:33:59 +03:00
return ( NULL ) ;
2023-12-23 02:00:15 +03:00
}
2001-02-23 20:55:21 +03:00
/*
2023-12-19 15:33:59 +03:00
* Try to find one of the output accept method accepting that scheme
* Go in reverse to give precedence to user defined handlers .
2001-02-23 20:55:21 +03:00
*/
2023-12-19 15:33:59 +03:00
for ( i = xmlOutputCallbackNr - 1 ; i > = 0 ; i - - ) {
xmlOutputCallback * cb = & xmlOutputCallbackTable [ i ] ;
int code ;
if ( cb - > matchcallback = = xmlIODefaultMatch ) {
2023-12-23 06:03:41 +03:00
code = xmlOutputDefaultOpen ( ret , URI , compression ) ;
2023-12-19 15:33:59 +03:00
/* TODO: Handle other errors */
if ( code = = XML_ERR_OK )
break ;
} else if ( ( cb - > matchcallback ! = NULL ) & &
( cb - > matchcallback ( URI ) ! = 0 ) ) {
ret - > context = cb - > opencallback ( URI ) ;
if ( ret - > context ! = NULL ) {
ret - > writecallback = cb - > writecallback ;
ret - > closecallback = cb - > closecallback ;
break ;
}
}
2001-02-23 20:55:21 +03:00
}
2001-07-23 23:10:52 +04:00
2023-12-19 15:33:59 +03:00
if ( ret - > context = = NULL ) {
xmlOutputBufferClose ( ret ) ;
2023-12-23 02:00:15 +03:00
ret = NULL ;
2001-02-23 20:55:21 +03:00
}
2023-12-23 02:00:15 +03:00
xmlFree ( unescaped ) ;
2001-02-23 20:55:21 +03:00
return ( ret ) ;
}
2004-06-02 20:18:40 +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 ATTRIBUTE_UNUSED ) {
if ( ( xmlOutputBufferCreateFilenameValue ) ) {
return xmlOutputBufferCreateFilenameValue ( URI , encoder , compression ) ;
}
return __xmlOutputBufferCreateFilename ( URI , encoder , compression ) ;
}
2003-09-29 17:20:24 +04:00
# endif /* LIBXML_OUTPUT_ENABLED */
2001-02-23 20:55:21 +03:00
/**
* xmlParserInputBufferCreateFile :
2009-08-11 19:51:22 +04:00
* @ file : a FILE *
2023-12-10 19:50:22 +03:00
* @ enc : the charset encoding if known ( deprecated )
2001-02-23 20:55:21 +03:00
*
* Create a buffered parser input for the progressive parsing of a FILE *
* buffered C I / O
*
2023-12-10 19:50:22 +03:00
* The encoding argument is deprecated and should be set to
* XML_CHAR_ENCODING_NONE . The encoding can be changed with
* xmlSwitchEncoding or xmlSwitchEncodingName later on .
*
2001-02-23 20:55:21 +03:00
* Returns the new parser input or NULL
*/
xmlParserInputBufferPtr
xmlParserInputBufferCreateFile ( FILE * file , xmlCharEncoding enc ) {
xmlParserInputBufferPtr ret ;
if ( file = = NULL ) return ( NULL ) ;
ret = xmlAllocParserInputBuffer ( enc ) ;
if ( ret ! = NULL ) {
ret - > context = file ;
ret - > readcallback = xmlFileRead ;
2023-12-25 01:56:57 +03:00
ret - > closecallback = NULL ;
2001-02-23 20:55:21 +03:00
}
return ( ret ) ;
}
2003-09-29 17:20:24 +04:00
# ifdef LIBXML_OUTPUT_ENABLED
2001-02-23 20:55:21 +03:00
/**
* xmlOutputBufferCreateFile :
2009-08-11 19:51:22 +04:00
* @ file : a FILE *
2001-02-23 20:55:21 +03:00
* @ 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 ( file = = NULL ) return ( NULL ) ;
2008-09-01 17:08:57 +04:00
ret = xmlAllocOutputBufferInternal ( encoder ) ;
2001-02-23 20:55:21 +03:00
if ( ret ! = NULL ) {
ret - > context = file ;
ret - > writecallback = xmlFileWrite ;
ret - > closecallback = xmlFileFlush ;
}
return ( ret ) ;
}
2005-11-09 11:56:26 +03:00
/**
* xmlOutputBufferCreateBuffer :
* @ buffer : a xmlBufferPtr
* @ encoder : the encoding converter or NULL
*
* Create a buffered output for the progressive saving to a xmlBuffer
*
* Returns the new parser output or NULL
*/
xmlOutputBufferPtr
xmlOutputBufferCreateBuffer ( xmlBufferPtr buffer ,
xmlCharEncodingHandlerPtr encoder ) {
xmlOutputBufferPtr ret ;
if ( buffer = = NULL ) return ( NULL ) ;
2017-11-09 19:47:47 +03:00
ret = xmlOutputBufferCreateIO ( xmlBufferWrite , NULL , ( void * ) buffer ,
encoder ) ;
2005-11-09 11:56:26 +03:00
return ( ret ) ;
}
2012-08-06 07:16:30 +04:00
/**
* 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 ) {
2023-12-10 19:50:22 +03:00
if ( ( out = = NULL ) | | ( out - > buffer = = NULL ) | | ( out - > error ! = 0 ) )
2012-08-06 07:16:30 +04:00
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 ) {
2023-12-10 19:50:22 +03:00
if ( ( out = = NULL ) | | ( out - > buffer = = NULL ) | | ( out - > error ! = 0 ) )
2012-08-06 07:16:30 +04:00
return ( 0 ) ;
return ( xmlBufUse ( out - > buffer ) ) ;
}
2003-09-29 17:20:24 +04:00
# endif /* LIBXML_OUTPUT_ENABLED */
2001-02-23 20:55:21 +03:00
/**
* xmlParserInputBufferCreateFd :
* @ fd : a file descriptor number
2023-12-10 19:50:22 +03:00
* @ enc : the charset encoding if known ( deprecated )
2001-02-23 20:55:21 +03:00
*
* Create a buffered parser input for the progressive parsing for the input
* from a file descriptor
*
2023-12-10 19:50:22 +03:00
* The encoding argument is deprecated and should be set to
* XML_CHAR_ENCODING_NONE . The encoding can be changed with
* xmlSwitchEncoding or xmlSwitchEncodingName later on .
*
2001-02-23 20:55:21 +03:00
* Returns the new parser input or NULL
*/
xmlParserInputBufferPtr
xmlParserInputBufferCreateFd ( int fd , xmlCharEncoding enc ) {
xmlParserInputBufferPtr ret ;
if ( fd < 0 ) return ( NULL ) ;
ret = xmlAllocParserInputBuffer ( enc ) ;
if ( ret ! = NULL ) {
2017-10-09 14:37:42 +03:00
ret - > context = ( void * ) ( ptrdiff_t ) fd ;
2001-02-23 20:55:21 +03:00
ret - > readcallback = xmlFdRead ;
}
return ( ret ) ;
}
2023-08-08 16:21:28 +03:00
typedef struct {
2023-12-13 01:51:32 +03:00
char * mem ;
const char * cur ;
2023-08-08 16:21:28 +03:00
size_t size ;
} xmlMemIOCtxt ;
static int
xmlMemRead ( void * vctxt , char * buf , int size ) {
xmlMemIOCtxt * ctxt = vctxt ;
if ( ( size_t ) size > ctxt - > size )
size = ctxt - > size ;
2023-12-13 01:51:32 +03:00
memcpy ( buf , ctxt - > cur , size ) ;
ctxt - > cur + = size ;
2023-08-08 16:21:28 +03:00
ctxt - > size - = size ;
return size ;
}
static int
xmlMemClose ( void * vctxt ) {
2023-12-13 01:51:32 +03:00
xmlMemIOCtxt * ctxt = vctxt ;
2023-12-27 20:33:30 +03:00
if ( ctxt - > mem ! = NULL )
2023-12-13 01:51:32 +03:00
xmlFree ( ctxt - > mem ) ;
xmlFree ( ctxt ) ;
2023-08-08 16:21:28 +03:00
return ( 0 ) ;
}
2024-05-20 14:58:22 +03:00
/**
* xmlNewInputBufferMemory :
* @ mem : memory buffer
* @ size : size of buffer
* @ flags : flags
* @ enc : the charset encoding if known ( deprecated )
*
* Create an input buffer for memory .
*
* Returns the new input buffer or NULL .
*/
2023-12-27 20:33:30 +03:00
xmlParserInputBufferPtr
xmlNewInputBufferMemory ( const void * mem , size_t size , int flags ,
xmlCharEncoding enc ) {
xmlParserInputBufferPtr ret ;
xmlMemIOCtxt * ctxt ;
char * copy = NULL ;
if ( ( flags & XML_INPUT_BUF_STATIC ) = = 0 ) {
if ( size + 1 = = 0 )
return ( NULL ) ;
copy = xmlMalloc ( size + 1 ) ;
if ( copy = = NULL )
return ( NULL ) ;
memcpy ( copy , mem , size ) ;
copy [ size ] = 0 ;
mem = copy ;
}
ret = xmlAllocParserInputBuffer ( enc ) ;
if ( ret = = NULL ) {
xmlFree ( copy ) ;
return ( NULL ) ;
}
ctxt = xmlMalloc ( sizeof ( * ctxt ) ) ;
if ( ctxt = = NULL ) {
xmlFreeParserInputBuffer ( ret ) ;
xmlFree ( copy ) ;
return ( NULL ) ;
}
ctxt - > mem = copy ;
ctxt - > cur = mem ;
ctxt - > size = size ;
ret - > context = ctxt ;
ret - > readcallback = xmlMemRead ;
ret - > closecallback = xmlMemClose ;
return ( ret ) ;
}
2001-02-23 20:55:21 +03:00
/**
* xmlParserInputBufferCreateMem :
* @ mem : the memory input
* @ size : the length of the memory block
2023-12-10 19:50:22 +03:00
* @ enc : the charset encoding if known ( deprecated )
2001-02-23 20:55:21 +03:00
*
2023-12-13 01:51:32 +03:00
* Create a parser input buffer for parsing from a memory area .
*
* This function makes a copy of the whole input buffer . If you are sure
* that the contents of the buffer will remain valid until the document
* was parsed , you can avoid the copy by using
* xmlParserInputBufferCreateStatic .
2001-02-23 20:55:21 +03:00
*
2023-12-10 19:50:22 +03:00
* The encoding argument is deprecated and should be set to
* XML_CHAR_ENCODING_NONE . The encoding can be changed with
* xmlSwitchEncoding or xmlSwitchEncodingName later on .
*
2023-12-13 01:51:32 +03:00
* Returns the new parser input or NULL in case of error .
2001-02-23 20:55:21 +03:00
*/
xmlParserInputBufferPtr
xmlParserInputBufferCreateMem ( const char * mem , int size , xmlCharEncoding enc ) {
2023-12-27 20:33:30 +03:00
if ( ( mem = = NULL ) | | ( size < 0 ) )
2023-12-13 01:51:32 +03:00
return ( NULL ) ;
2001-02-23 20:55:21 +03:00
2023-12-27 20:33:30 +03:00
return ( xmlNewInputBufferMemory ( mem , size , 0 , enc ) ) ;
2001-02-23 20:55:21 +03:00
}
2003-09-18 17:35:51 +04:00
/**
* xmlParserInputBufferCreateStatic :
* @ mem : the memory input
* @ size : the length of the memory block
* @ enc : the charset encoding if known
*
2023-12-13 01:51:32 +03:00
* Create a parser input buffer for parsing from a memory area .
2003-09-18 17:35:51 +04:00
*
2023-12-13 01:51:32 +03:00
* This functions assumes that the contents of the input buffer remain
* valid until the document was parsed . Use xmlParserInputBufferCreateMem
* otherwise .
*
* The encoding argument is deprecated and should be set to
* XML_CHAR_ENCODING_NONE . The encoding can be changed with
* xmlSwitchEncoding or xmlSwitchEncodingName later on .
*
* Returns the new parser input or NULL in case of error .
2003-09-18 17:35:51 +04:00
*/
xmlParserInputBufferPtr
xmlParserInputBufferCreateStatic ( const char * mem , int size ,
xmlCharEncoding enc ) {
2023-12-27 20:33:30 +03:00
if ( ( mem = = NULL ) | | ( size < 0 ) )
2023-12-13 01:51:32 +03:00
return ( NULL ) ;
2023-12-27 20:33:30 +03:00
return ( xmlNewInputBufferMemory ( mem , size , XML_INPUT_BUF_STATIC , enc ) ) ;
2003-09-18 17:35:51 +04:00
}
2023-08-08 16:21:28 +03:00
typedef struct {
2023-12-27 20:33:30 +03:00
const char * str ;
2023-08-08 16:21:28 +03:00
} xmlStringIOCtxt ;
static int
xmlStringRead ( void * vctxt , char * buf , int size ) {
xmlStringIOCtxt * ctxt = vctxt ;
2023-12-27 20:33:30 +03:00
const char * zero ;
2023-08-08 16:21:28 +03:00
size_t len ;
zero = memchr ( ctxt - > str , 0 , size ) ;
len = zero ? zero - ctxt - > str : size ;
memcpy ( buf , ctxt - > str , len ) ;
ctxt - > str + = len ;
return ( len ) ;
}
static int
xmlStringClose ( void * vctxt ) {
xmlFree ( vctxt ) ;
return ( 0 ) ;
}
2024-05-20 14:58:22 +03:00
/**
* xmlNewInputBufferString :
* @ str : C string
* @ flags : flags
*
* Create an input buffer for a null - teriminated C string .
*
* Returns the new input buffer or NULL .
*/
2023-08-08 16:21:28 +03:00
xmlParserInputBufferPtr
2023-12-27 20:33:30 +03:00
xmlNewInputBufferString ( const char * str , int flags ) {
2023-08-08 16:21:28 +03:00
xmlParserInputBufferPtr ret ;
xmlStringIOCtxt * ctxt ;
2023-12-27 20:33:30 +03:00
if ( ( flags & XML_INPUT_BUF_STATIC ) = = 0 )
return ( xmlNewInputBufferMemory ( str , strlen ( str ) , flags ,
XML_CHAR_ENCODING_NONE ) ) ;
2023-08-08 16:21:28 +03:00
ret = xmlAllocParserInputBuffer ( XML_CHAR_ENCODING_NONE ) ;
if ( ret = = NULL )
return ( NULL ) ;
ctxt = xmlMalloc ( sizeof ( * ctxt ) ) ;
if ( ctxt = = NULL ) {
xmlFreeParserInputBuffer ( ret ) ;
return ( NULL ) ;
}
2023-12-27 20:33:30 +03:00
2023-08-08 16:21:28 +03:00
ctxt - > str = str ;
ret - > context = ctxt ;
ret - > readcallback = xmlStringRead ;
ret - > closecallback = xmlStringClose ;
return ( ret ) ;
}
2003-09-29 17:20:24 +04:00
# ifdef LIBXML_OUTPUT_ENABLED
2001-02-23 20:55:21 +03:00
/**
* xmlOutputBufferCreateFd :
* @ fd : a file descriptor number
* @ encoder : the encoding converter or NULL
*
2009-08-11 19:51:22 +04:00
* Create a buffered output for the progressive saving
2001-02-23 20:55:21 +03:00
* to a file descriptor
*
* Returns the new parser output or NULL
*/
xmlOutputBufferPtr
xmlOutputBufferCreateFd ( int fd , xmlCharEncodingHandlerPtr encoder ) {
xmlOutputBufferPtr ret ;
if ( fd < 0 ) return ( NULL ) ;
2008-09-01 17:08:57 +04:00
ret = xmlAllocOutputBufferInternal ( encoder ) ;
2001-02-23 20:55:21 +03:00
if ( ret ! = NULL ) {
2017-10-09 14:37:42 +03:00
ret - > context = ( void * ) ( ptrdiff_t ) fd ;
2001-02-23 20:55:21 +03:00
ret - > writecallback = xmlFdWrite ;
2002-02-07 19:39:11 +03:00
ret - > closecallback = NULL ;
2001-02-23 20:55:21 +03:00
}
return ( ret ) ;
}
2003-09-29 17:20:24 +04:00
# endif /* LIBXML_OUTPUT_ENABLED */
2001-02-23 20:55:21 +03:00
/**
* xmlParserInputBufferCreateIO :
* @ ioread : an I / O read function
* @ ioclose : an I / O close function
* @ ioctx : an I / O handler
2023-12-10 19:50:22 +03:00
* @ enc : the charset encoding if known ( deprecated )
2001-02-23 20:55:21 +03:00
*
* Create a buffered parser input for the progressive parsing for the input
* from an I / O handler
*
2023-12-10 19:50:22 +03:00
* The encoding argument is deprecated and should be set to
* XML_CHAR_ENCODING_NONE . The encoding can be changed with
* xmlSwitchEncoding or xmlSwitchEncodingName later on .
*
2001-02-23 20:55:21 +03: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 ) ;
}
2003-09-29 17:20:24 +04:00
# ifdef LIBXML_OUTPUT_ENABLED
2001-02-23 20:55:21 +03:00
/**
* xmlOutputBufferCreateIO :
* @ iowrite : an I / O write function
* @ ioclose : an I / O close function
* @ ioctx : an I / O handler
2002-01-22 21:15:52 +03:00
* @ encoder : the charset encoding if known
2001-02-23 20:55:21 +03:00
*
* 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 ) ;
2008-09-01 17:08:57 +04:00
ret = xmlAllocOutputBufferInternal ( encoder ) ;
2001-02-23 20:55:21 +03:00
if ( ret ! = NULL ) {
ret - > context = ( void * ) ioctx ;
ret - > writecallback = iowrite ;
ret - > closecallback = ioclose ;
}
return ( ret ) ;
}
2003-09-29 17:20:24 +04:00
# endif /* LIBXML_OUTPUT_ENABLED */
2001-02-23 20:55:21 +03:00
2004-06-08 14:16:42 +04:00
/**
* xmlParserInputBufferCreateFilenameDefault :
* @ func : function pointer to the new ParserInputBufferCreateFilenameFunc
*
2024-06-11 04:51:43 +03:00
* DEPRECATED : Use xmlCtxtSetResourceLoader or similar functions .
*
2004-06-08 14:16:42 +04:00
* Registers a callback for URI input file handling
*
* Returns the old value of the registration function
*/
xmlParserInputBufferCreateFilenameFunc
2024-06-10 19:50:28 +03:00
xmlParserInputBufferCreateFilenameDefault (
xmlParserInputBufferCreateFilenameFunc func )
2004-06-08 14:16:42 +04:00
{
2024-06-10 19:50:28 +03:00
xmlParserInputBufferCreateFilenameFunc old ;
old = xmlParserInputBufferCreateFilenameValue ;
if ( old = = NULL )
old = __xmlParserInputBufferCreateFilename ;
2004-06-08 14:16:42 +04:00
2024-06-10 19:50:28 +03:00
if ( func = = __xmlParserInputBufferCreateFilename )
func = NULL ;
2004-06-08 14:16:42 +04:00
xmlParserInputBufferCreateFilenameValue = func ;
return ( old ) ;
}
/**
* xmlOutputBufferCreateFilenameDefault :
* @ func : function pointer to the new OutputBufferCreateFilenameFunc
*
* Registers a callback for URI output file handling
*
* Returns the old value of the registration function
*/
xmlOutputBufferCreateFilenameFunc
xmlOutputBufferCreateFilenameDefault ( xmlOutputBufferCreateFilenameFunc func )
{
xmlOutputBufferCreateFilenameFunc old = xmlOutputBufferCreateFilenameValue ;
# ifdef LIBXML_OUTPUT_ENABLED
if ( old = = NULL ) {
old = __xmlOutputBufferCreateFilename ;
}
# endif
xmlOutputBufferCreateFilenameValue = func ;
return ( old ) ;
}
2001-02-23 20:55:21 +03:00
/**
* xmlParserInputBufferPush :
* @ in : a buffered parser input
* @ len : the size in bytes of the array .
* @ buf : an char array
*
* 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
xmlParserInputBufferPush ( xmlParserInputBufferPtr in ,
int len , const char * buf ) {
int nbchars = 0 ;
2004-07-31 20:24:01 +04:00
int ret ;
2001-02-23 20:55:21 +03:00
if ( len < 0 ) return ( 0 ) ;
2003-10-08 22:58:28 +04:00
if ( ( in = = NULL ) | | ( in - > error ) ) return ( - 1 ) ;
2001-02-23 20:55:21 +03:00
if ( in - > encoder ! = NULL ) {
/*
* Store the data in the incoming raw buffer
*/
if ( in - > raw = = NULL ) {
2012-07-16 10:22:54 +04:00
in - > raw = xmlBufCreate ( ) ;
2023-04-30 19:25:09 +03:00
if ( in - > raw = = NULL ) {
in - > error = XML_ERR_NO_MEMORY ;
return ( - 1 ) ;
}
2001-02-23 20:55:21 +03:00
}
2012-07-16 10:22:54 +04:00
ret = xmlBufAdd ( in - > raw , ( const xmlChar * ) buf , len ) ;
2023-04-30 19:25:09 +03:00
if ( ret ! = 0 ) {
in - > error = XML_ERR_NO_MEMORY ;
2004-07-31 20:24:01 +04:00
return ( - 1 ) ;
2023-04-30 19:25:09 +03:00
}
2001-02-23 20:55:21 +03:00
/*
* convert as much as possible to the parser reading buffer .
*/
2023-08-08 16:21:31 +03:00
nbchars = xmlCharEncInput ( in ) ;
2023-04-30 19:25:09 +03:00
if ( nbchars < 0 )
2001-02-23 20:55:21 +03:00
return ( - 1 ) ;
} else {
nbchars = len ;
2012-07-16 10:22:54 +04:00
ret = xmlBufAdd ( in - > buffer , ( xmlChar * ) buf , nbchars ) ;
2023-04-30 19:25:09 +03:00
if ( ret ! = 0 ) {
in - > error = XML_ERR_NO_MEMORY ;
2004-07-31 20:24:01 +04:00
return ( - 1 ) ;
2023-04-30 19:25:09 +03:00
}
2001-02-23 20:55:21 +03:00
}
return ( nbchars ) ;
}
2002-03-05 23:28:20 +03:00
/**
* endOfInput :
*
* When reading from an Input channel indicated end of file or error
* don ' t reread from it again .
*/
static int
endOfInput ( void * context ATTRIBUTE_UNUSED ,
char * buffer ATTRIBUTE_UNUSED ,
int len ATTRIBUTE_UNUSED ) {
return ( 0 ) ;
}
2001-02-23 20:55:21 +03: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
* This routine is used when operating the parser in normal ( pull ) mode
*
2001-12-31 19:16:02 +03:00
* TODO : one should be able to remove one extra copy by copying directly
2001-02-23 20:55:21 +03:00
* onto in - > buffer or in - > raw
*
* Returns the number of chars read and stored in the buffer , or - 1
* in case of error .
*/
int
xmlParserInputBufferGrow ( xmlParserInputBufferPtr in , int len ) {
2022-11-13 19:55:28 +03:00
xmlBufPtr buf ;
2001-02-23 20:55:21 +03:00
int res = 0 ;
2003-10-08 22:58:28 +04:00
if ( ( in = = NULL ) | | ( in - > error ) ) return ( - 1 ) ;
2003-08-19 19:01:28 +04:00
if ( ( len < = MINLEN ) & & ( len ! = 4 ) )
2001-02-23 20:55:21 +03:00
len = MINLEN ;
2003-08-19 19:01:28 +04:00
2022-11-13 19:55:28 +03:00
if ( in - > encoder = = NULL ) {
if ( in - > readcallback = = NULL )
return ( 0 ) ;
buf = in - > buffer ;
} else {
if ( in - > raw = = NULL ) {
in - > raw = xmlBufCreate ( ) ;
}
buf = in - > raw ;
2001-02-23 20:55:21 +03:00
}
/*
* Call the read method for this I / O type .
*/
if ( in - > readcallback ! = NULL ) {
2022-11-13 19:55:28 +03:00
if ( xmlBufGrow ( buf , len + 1 ) < 0 ) {
in - > error = XML_ERR_NO_MEMORY ;
return ( - 1 ) ;
}
res = in - > readcallback ( in - > context , ( char * ) xmlBufEnd ( buf ) , len ) ;
2002-03-05 23:28:20 +03:00
if ( res < = 0 )
in - > readcallback = endOfInput ;
2023-04-30 19:25:09 +03:00
if ( res < 0 ) {
2023-12-19 21:52:28 +03:00
if ( res = = - 1 )
in - > error = XML_IO_UNKNOWN ;
else
in - > error = - res ;
2022-11-13 19:55:28 +03:00
return ( - 1 ) ;
2023-04-30 19:25:09 +03:00
}
2022-11-13 19:55:28 +03:00
2023-04-30 19:25:09 +03:00
if ( xmlBufAddLen ( buf , res ) < 0 ) {
in - > error = XML_ERR_NO_MEMORY ;
2023-01-22 16:52:06 +03:00
return ( - 1 ) ;
2023-04-30 19:25:09 +03:00
}
2001-02-23 20:55:21 +03:00
}
2013-05-10 10:01:46 +04:00
/*
* try to establish compressed status of input if not done already
*/
if ( in - > compressed = = - 1 ) {
2015-11-03 10:46:29 +03:00
# ifdef LIBXML_LZMA_ENABLED
2013-05-10 10:01:46 +04:00
if ( in - > readcallback = = xmlXzfileRead )
in - > compressed = __libxml2_xzcompressed ( in - > context ) ;
# endif
}
2001-02-23 20:55:21 +03:00
if ( in - > encoder ! = NULL ) {
2023-08-08 16:21:31 +03:00
res = xmlCharEncInput ( in ) ;
2023-04-30 19:25:09 +03:00
if ( res < 0 )
2001-02-23 20:55:21 +03:00
return ( - 1 ) ;
}
2022-11-13 19:55:28 +03:00
return ( res ) ;
2001-02-23 20:55:21 +03:00
}
/**
* 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 ) {
2022-11-13 18:30:46 +03:00
return ( xmlParserInputBufferGrow ( in , len ) ) ;
2001-02-23 20:55:21 +03:00
}
2003-09-29 17:20:24 +04:00
# ifdef LIBXML_OUTPUT_ENABLED
2001-02-23 20:55:21 +03:00
/**
* 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 ; /* number of chars to output to I/O */
int ret ; /* return from function call */
int written = 0 ; /* number of char written to I/O so far */
2019-09-30 18:04:54 +03:00
int chunk ; /* number of byte current processed from buf */
2001-02-23 20:55:21 +03:00
2003-10-08 22:58:28 +04:00
if ( ( out = = NULL ) | | ( out - > error ) ) return ( - 1 ) ;
2001-02-23 20:55:21 +03:00
if ( len < 0 ) return ( 0 ) ;
2003-10-08 22:58:28 +04:00
if ( out - > error ) return ( - 1 ) ;
2001-02-23 20:55:21 +03:00
do {
chunk = len ;
if ( chunk > 4 * MINLEN )
chunk = 4 * MINLEN ;
/*
* first handle encoding stuff .
*/
if ( out - > encoder ! = NULL ) {
/*
* Store the data in the incoming raw buffer
*/
if ( out - > conv = = NULL ) {
2012-07-16 10:22:54 +04:00
out - > conv = xmlBufCreate ( ) ;
2023-12-10 19:50:22 +03:00
if ( out - > conv = = NULL ) {
out - > error = XML_ERR_NO_MEMORY ;
return ( - 1 ) ;
}
2001-02-23 20:55:21 +03:00
}
2012-07-16 10:22:54 +04:00
ret = xmlBufAdd ( out - > buffer , ( const xmlChar * ) buf , chunk ) ;
2024-02-01 13:51:58 +03:00
if ( ret ! = 0 ) {
out - > error = XML_ERR_NO_MEMORY ;
2004-07-31 20:24:01 +04:00
return ( - 1 ) ;
2024-02-01 13:51:58 +03:00
}
2001-02-23 20:55:21 +03:00
2012-07-16 10:22:54 +04:00
if ( ( xmlBufUse ( out - > buffer ) < MINLEN ) & & ( chunk = = len ) )
2001-02-23 20:55:21 +03:00
goto done ;
/*
* convert as much as possible to the parser reading buffer .
*/
2012-07-16 10:22:54 +04:00
ret = xmlCharEncOutput ( out , 0 ) ;
2023-12-10 19:50:22 +03:00
if ( ret < 0 )
2001-02-23 20:55:21 +03:00
return ( - 1 ) ;
2021-07-27 17:12:54 +03:00
if ( out - > writecallback )
nbchars = xmlBufUse ( out - > conv ) ;
else
nbchars = ret > = 0 ? ret : 0 ;
2001-02-23 20:55:21 +03:00
} else {
2012-07-16 10:22:54 +04:00
ret = xmlBufAdd ( out - > buffer , ( const xmlChar * ) buf , chunk ) ;
2024-03-06 17:21:49 +03:00
if ( ret ! = 0 ) {
out - > error = XML_ERR_NO_MEMORY ;
2004-07-31 20:24:01 +04:00
return ( - 1 ) ;
2024-03-06 17:21:49 +03:00
}
2021-07-27 17:12:54 +03:00
if ( out - > writecallback )
nbchars = xmlBufUse ( out - > buffer ) ;
else
nbchars = chunk ;
2001-02-23 20:55:21 +03:00
}
buf + = chunk ;
len - = chunk ;
if ( out - > writecallback ) {
2019-05-15 13:47:28 +03:00
if ( ( nbchars < MINLEN ) & & ( len < = 0 ) )
goto done ;
2001-02-23 20:55:21 +03:00
/*
* second write the stuff to the I / O channel
*/
if ( out - > encoder ! = NULL ) {
2009-08-11 19:51:22 +04:00
ret = out - > writecallback ( out - > context ,
2012-07-16 10:22:54 +04:00
( const char * ) xmlBufContent ( out - > conv ) , nbchars ) ;
2001-02-23 20:55:21 +03:00
if ( ret > = 0 )
2012-07-16 10:22:54 +04:00
xmlBufShrink ( out - > conv , ret ) ;
2001-02-23 20:55:21 +03:00
} else {
2009-08-11 19:51:22 +04:00
ret = out - > writecallback ( out - > context ,
2012-07-16 10:22:54 +04:00
( const char * ) xmlBufContent ( out - > buffer ) , nbchars ) ;
2001-02-23 20:55:21 +03:00
if ( ret > = 0 )
2012-07-16 10:22:54 +04:00
xmlBufShrink ( out - > buffer , ret ) ;
2001-02-23 20:55:21 +03:00
}
if ( ret < 0 ) {
2024-06-10 17:21:12 +03:00
out - > error = ( ret = = - 1 ) ? XML_IO_WRITE : - ret ;
2004-05-13 18:31:25 +04:00
return ( ret ) ;
}
2019-10-14 17:56:59 +03:00
if ( out - > written > INT_MAX - ret )
out - > written = INT_MAX ;
else
out - > written + = ret ;
2004-05-13 18:31:25 +04:00
}
written + = nbchars ;
} while ( len > 0 ) ;
done :
return ( written ) ;
}
/**
* xmlEscapeContent :
* @ out : a pointer to an array of bytes to store the result
* @ outlen : the length of @ out
* @ in : a pointer to an array of unescaped UTF - 8 bytes
* @ inlen : the length of @ in
*
* Take a block of UTF - 8 chars in and escape them .
* Returns 0 if success , or - 1 otherwise
* The value of @ inlen after return is the number of octets consumed
* if the return value is positive , else unpredictable .
* The value of @ outlen after return is the number of octets consumed .
*/
static int
xmlEscapeContent ( unsigned char * out , int * outlen ,
const xmlChar * in , int * inlen ) {
unsigned char * outstart = out ;
const unsigned char * base = in ;
unsigned char * outend = out + * outlen ;
const unsigned char * inend ;
inend = in + ( * inlen ) ;
2009-08-11 19:51:22 +04:00
2004-05-13 18:31:25 +04:00
while ( ( in < inend ) & & ( out < outend ) ) {
2012-09-11 09:26:36 +04:00
if ( * in = = ' < ' ) {
2004-05-13 18:31:25 +04:00
if ( outend - out < 4 ) break ;
* out + + = ' & ' ;
* out + + = ' l ' ;
* out + + = ' t ' ;
* out + + = ' ; ' ;
} else if ( * in = = ' > ' ) {
if ( outend - out < 4 ) break ;
* out + + = ' & ' ;
* out + + = ' g ' ;
* out + + = ' t ' ;
* out + + = ' ; ' ;
} else if ( * in = = ' & ' ) {
if ( outend - out < 5 ) break ;
* out + + = ' & ' ;
* out + + = ' a ' ;
* out + + = ' m ' ;
* out + + = ' p ' ;
* out + + = ' ; ' ;
} else if ( * in = = ' \r ' ) {
if ( outend - out < 5 ) break ;
* out + + = ' & ' ;
* out + + = ' # ' ;
* out + + = ' 1 ' ;
* out + + = ' 3 ' ;
* out + + = ' ; ' ;
} else {
2022-09-01 02:18:30 +03:00
* out + + = * in ;
2004-05-13 18:31:25 +04:00
}
+ + in ;
2009-08-11 19:51:22 +04:00
}
2004-05-13 18:31:25 +04:00
* outlen = out - outstart ;
* inlen = in - base ;
return ( 0 ) ;
}
/**
* xmlOutputBufferWriteEscape :
* @ out : a buffered parser output
* @ str : a zero terminated UTF - 8 string
2004-05-14 07:25:14 +04:00
* @ escaping : an optional escaping function ( or NULL )
2004-05-13 18:31:25 +04:00
*
* Write the content of the string in the output I / O buffer
2019-09-30 18:04:54 +03:00
* This routine escapes the characters and then handle the I18N
2004-05-13 18:31:25 +04:00
* 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
2004-05-14 07:25:14 +04:00
xmlOutputBufferWriteEscape ( xmlOutputBufferPtr out , const xmlChar * str ,
xmlCharEncodingOutputFunc escaping ) {
2004-05-13 18:31:25 +04:00
int nbchars = 0 ; /* number of chars to output to I/O */
int ret ; /* return from function call */
int written = 0 ; /* number of char written to I/O so far */
2004-08-31 16:15:36 +04:00
int oldwritten = 0 ; /* loop guard */
2004-05-13 18:31:25 +04:00
int chunk ; /* number of byte currently processed from str */
int len ; /* number of bytes in str */
int cons ; /* byte from str consumed */
2004-11-05 13:03:46 +03:00
if ( ( out = = NULL ) | | ( out - > error ) | | ( str = = NULL ) | |
2022-11-15 00:27:58 +03:00
( out - > buffer = = NULL ) )
2012-07-16 10:22:54 +04:00
return ( - 1 ) ;
2004-05-14 07:25:14 +04:00
len = strlen ( ( const char * ) str ) ;
2004-05-13 18:31:25 +04:00
if ( len < 0 ) return ( 0 ) ;
if ( out - > error ) return ( - 1 ) ;
2004-05-14 07:25:14 +04:00
if ( escaping = = NULL ) escaping = xmlEscapeContent ;
2004-05-13 18:31:25 +04:00
do {
2004-08-31 16:15:36 +04:00
oldwritten = written ;
2004-05-13 18:31:25 +04:00
/*
* how many bytes to consume and how many bytes to store .
*/
cons = len ;
2022-05-26 04:13:07 +03:00
chunk = xmlBufAvail ( out - > buffer ) ;
2004-05-13 18:31:25 +04:00
2008-02-16 13:08:14 +03:00
/*
* 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 ) {
2024-03-06 17:21:49 +03:00
if ( xmlBufGrow ( out - > buffer , 100 ) < 0 ) {
out - > error = XML_ERR_NO_MEMORY ;
2008-08-30 16:52:26 +04:00
return ( - 1 ) ;
2024-03-06 17:21:49 +03:00
}
2008-08-30 16:52:26 +04:00
oldwritten = - 1 ;
continue ;
2008-02-16 13:08:14 +03:00
}
2004-05-13 18:31:25 +04:00
/*
* first handle encoding stuff .
*/
if ( out - > encoder ! = NULL ) {
/*
* Store the data in the incoming raw buffer
*/
if ( out - > conv = = NULL ) {
2012-07-16 10:22:54 +04:00
out - > conv = xmlBufCreate ( ) ;
2024-03-06 17:21:49 +03:00
if ( out - > conv = = NULL ) {
out - > error = XML_ERR_NO_MEMORY ;
return ( - 1 ) ;
}
2004-05-13 18:31:25 +04:00
}
2012-07-16 10:22:54 +04:00
ret = escaping ( xmlBufEnd ( out - > buffer ) ,
2004-05-14 07:25:14 +04:00
& chunk , str , & cons ) ;
2024-03-06 17:21:49 +03:00
if ( ret < 0 ) {
out - > error = XML_ERR_NO_MEMORY ;
return ( - 1 ) ;
}
2012-07-16 10:22:54 +04:00
xmlBufAddLen ( out - > buffer , chunk ) ;
2004-05-13 18:31:25 +04:00
2012-07-16 10:22:54 +04:00
if ( ( xmlBufUse ( out - > buffer ) < MINLEN ) & & ( cons = = len ) )
2004-05-13 18:31:25 +04:00
goto done ;
/*
* convert as much as possible to the output buffer .
*/
2012-07-16 10:22:54 +04:00
ret = xmlCharEncOutput ( out , 0 ) ;
2023-12-10 19:50:22 +03:00
if ( ret < 0 )
2004-05-13 18:31:25 +04:00
return ( - 1 ) ;
2021-07-27 17:12:54 +03:00
if ( out - > writecallback )
nbchars = xmlBufUse ( out - > conv ) ;
else
nbchars = ret > = 0 ? ret : 0 ;
2004-05-13 18:31:25 +04:00
} else {
2012-07-16 10:22:54 +04:00
ret = escaping ( xmlBufEnd ( out - > buffer ) , & chunk , str , & cons ) ;
2024-03-06 17:21:49 +03:00
if ( ret < 0 ) {
out - > error = XML_ERR_NO_MEMORY ;
return ( - 1 ) ;
}
2012-07-16 10:22:54 +04:00
xmlBufAddLen ( out - > buffer , chunk ) ;
2021-07-27 17:12:54 +03:00
if ( out - > writecallback )
nbchars = xmlBufUse ( out - > buffer ) ;
else
nbchars = chunk ;
2004-05-13 18:31:25 +04:00
}
str + = cons ;
len - = cons ;
if ( out - > writecallback ) {
2019-05-15 13:47:28 +03:00
if ( ( nbchars < MINLEN ) & & ( len < = 0 ) )
goto done ;
2004-05-13 18:31:25 +04:00
/*
* second write the stuff to the I / O channel
*/
if ( out - > encoder ! = NULL ) {
2009-08-11 19:51:22 +04:00
ret = out - > writecallback ( out - > context ,
2012-07-16 10:22:54 +04:00
( const char * ) xmlBufContent ( out - > conv ) , nbchars ) ;
2004-05-13 18:31:25 +04:00
if ( ret > = 0 )
2012-07-16 10:22:54 +04:00
xmlBufShrink ( out - > conv , ret ) ;
2004-05-13 18:31:25 +04:00
} else {
2009-08-11 19:51:22 +04:00
ret = out - > writecallback ( out - > context ,
2012-07-16 10:22:54 +04:00
( const char * ) xmlBufContent ( out - > buffer ) , nbchars ) ;
2004-05-13 18:31:25 +04:00
if ( ret > = 0 )
2012-07-16 10:22:54 +04:00
xmlBufShrink ( out - > buffer , ret ) ;
2004-05-13 18:31:25 +04:00
}
if ( ret < 0 ) {
2024-06-10 17:21:12 +03:00
out - > error = ( ret = = - 1 ) ? XML_IO_WRITE : - ret ;
2024-03-06 17:21:49 +03:00
return ( - 1 ) ;
2001-02-23 20:55:21 +03:00
}
2019-10-14 17:56:59 +03:00
if ( out - > written > INT_MAX - ret )
out - > written = INT_MAX ;
else
out - > written + = ret ;
2012-07-16 10:22:54 +04:00
} else if ( xmlBufAvail ( out - > buffer ) < MINLEN ) {
2024-03-06 17:21:49 +03:00
if ( xmlBufGrow ( out - > buffer , MINLEN ) < 0 ) {
out - > error = XML_ERR_NO_MEMORY ;
return ( - 1 ) ;
}
2001-02-23 20:55:21 +03:00
}
written + = nbchars ;
2004-08-31 16:15:36 +04:00
} while ( ( len > 0 ) & & ( oldwritten ! = written ) ) ;
2001-02-23 20:55:21 +03:00
done :
return ( written ) ;
}
/**
* 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 ;
2009-08-11 19:51:22 +04:00
2003-10-08 22:58:28 +04:00
if ( ( out = = NULL ) | | ( out - > error ) ) return ( - 1 ) ;
2001-02-23 20:55:21 +03:00
if ( str = = NULL )
return ( - 1 ) ;
len = strlen ( str ) ;
if ( len > 0 )
return ( xmlOutputBufferWrite ( out , len , str ) ) ;
return ( len ) ;
}
2024-02-16 17:42:38 +03:00
/**
* xmlOutputBufferWriteQuotedString :
* @ buf : output buffer
* @ string : the string to add
*
* routine which manage and grows an output buffer . This one writes
* a quoted or double quoted # xmlChar string , checking first if it holds
* quote or double - quotes internally
*/
void
xmlOutputBufferWriteQuotedString ( xmlOutputBufferPtr buf ,
const xmlChar * string ) {
const xmlChar * cur , * base ;
if ( ( buf = = NULL ) | | ( buf - > error ) )
return ;
if ( xmlStrchr ( string , ' \" ' ) ) {
if ( xmlStrchr ( string , ' \' ' ) ) {
xmlOutputBufferWrite ( buf , 1 , " \" " ) ;
base = cur = string ;
while ( * cur ! = 0 ) {
if ( * cur = = ' " ' ) {
if ( base ! = cur )
xmlOutputBufferWrite ( buf , cur - base ,
( const char * ) base ) ;
xmlOutputBufferWrite ( buf , 6 , " " " ) ;
cur + + ;
base = cur ;
}
else {
cur + + ;
}
}
if ( base ! = cur )
xmlOutputBufferWrite ( buf , cur - base , ( const char * ) base ) ;
xmlOutputBufferWrite ( buf , 1 , " \" " ) ;
}
else {
xmlOutputBufferWrite ( buf , 1 , " ' " ) ;
xmlOutputBufferWriteString ( buf , ( const char * ) string ) ;
xmlOutputBufferWrite ( buf , 1 , " ' " ) ;
}
} else {
xmlOutputBufferWrite ( buf , 1 , " \" " ) ;
xmlOutputBufferWriteString ( buf , ( const char * ) string ) ;
xmlOutputBufferWrite ( buf , 1 , " \" " ) ;
}
}
2001-02-23 20:55:21 +03:00
/**
* 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 ) {
int nbchars = 0 , ret = 0 ;
2003-10-08 22:58:28 +04:00
if ( ( out = = NULL ) | | ( out - > error ) ) return ( - 1 ) ;
2001-02-23 20:55:21 +03:00
/*
* first handle encoding stuff .
*/
if ( ( out - > conv ! = NULL ) & & ( out - > encoder ! = NULL ) ) {
/*
2013-03-27 07:00:31 +04:00
* convert as much as possible to the parser output buffer .
2001-02-23 20:55:21 +03:00
*/
2013-03-27 07:00:31 +04:00
do {
nbchars = xmlCharEncOutput ( out , 0 ) ;
2023-12-10 19:50:22 +03:00
if ( nbchars < 0 )
2013-03-27 07:00:31 +04:00
return ( - 1 ) ;
} while ( nbchars ) ;
2001-02-23 20:55:21 +03:00
}
/*
* second flush the stuff to the I / O channel
*/
if ( ( out - > conv ! = NULL ) & & ( out - > encoder ! = NULL ) & &
( out - > writecallback ! = NULL ) ) {
ret = out - > writecallback ( out - > context ,
2012-07-16 10:22:54 +04:00
( const char * ) xmlBufContent ( out - > conv ) ,
xmlBufUse ( out - > conv ) ) ;
2001-02-23 20:55:21 +03:00
if ( ret > = 0 )
2012-07-16 10:22:54 +04:00
xmlBufShrink ( out - > conv , ret ) ;
2001-02-23 20:55:21 +03:00
} else if ( out - > writecallback ! = NULL ) {
ret = out - > writecallback ( out - > context ,
2012-07-16 10:22:54 +04:00
( const char * ) xmlBufContent ( out - > buffer ) ,
xmlBufUse ( out - > buffer ) ) ;
2001-02-23 20:55:21 +03:00
if ( ret > = 0 )
2012-07-16 10:22:54 +04:00
xmlBufShrink ( out - > buffer , ret ) ;
2001-02-23 20:55:21 +03:00
}
if ( ret < 0 ) {
2024-06-10 17:21:12 +03:00
out - > error = ( ret = = - 1 ) ? XML_IO_WRITE : - ret ;
2001-02-23 20:55:21 +03:00
return ( ret ) ;
}
2019-10-14 17:56:59 +03:00
if ( out - > written > INT_MAX - ret )
out - > written = INT_MAX ;
else
out - > written + = ret ;
2001-02-23 20:55:21 +03:00
return ( ret ) ;
}
2003-09-29 17:20:24 +04:00
# endif /* LIBXML_OUTPUT_ENABLED */
2001-02-23 20:55:21 +03:00
2001-07-18 23:30:27 +04:00
/**
2001-02-23 20:55:21 +03: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 ;
if ( filename = = NULL ) return ( NULL ) ;
2007-08-14 13:41:21 +04:00
2022-03-01 00:42:10 +03:00
# if defined(_WIN32)
2007-08-14 13:41:21 +04:00
# define IS_XMLPGD_SEP(ch) ((ch==' / ')||(ch=='\\'))
# else
# define IS_XMLPGD_SEP(ch) (ch==' / ')
2001-02-23 20:55:21 +03:00
# endif
strncpy ( dir , filename , 1023 ) ;
dir [ 1023 ] = 0 ;
cur = & dir [ strlen ( dir ) ] ;
while ( cur > dir ) {
2007-08-14 13:41:21 +04:00
if ( IS_XMLPGD_SEP ( * cur ) ) break ;
2001-02-23 20:55:21 +03:00
cur - - ;
}
2007-08-14 13:41:21 +04:00
if ( IS_XMLPGD_SEP ( * cur ) ) {
2001-02-23 20:55:21 +03:00
if ( cur = = dir ) dir [ 1 ] = 0 ;
else * cur = 0 ;
ret = xmlMemStrdup ( dir ) ;
} else {
if ( getcwd ( dir , 1024 ) ! = NULL ) {
dir [ 1023 ] = 0 ;
ret = xmlMemStrdup ( dir ) ;
}
}
return ( ret ) ;
2007-08-14 13:41:21 +04:00
# undef IS_XMLPGD_SEP
2001-02-23 20:55:21 +03:00
}
2003-10-19 17:35:37 +04:00
/**
2023-12-23 02:35:30 +03:00
* xmlNoNetExists :
* @ filename : the path to check
2003-10-19 17:35:37 +04:00
*
2023-12-21 20:09:42 +03:00
* DEPRECATED : Internal function , don ' t use .
*
2023-12-23 02:35:30 +03:00
* Like xmlCheckFilename but handles file URIs .
2024-05-20 14:58:22 +03:00
*
* Returns 0 , 1 , or 2.
2003-10-19 17:35:37 +04:00
*/
2023-12-23 02:35:30 +03:00
int
xmlNoNetExists ( const char * filename ) {
2023-12-23 02:00:15 +03:00
char * fromUri ;
int ret ;
2001-08-24 01:17:48 +04:00
2023-12-23 02:00:15 +03:00
if ( filename = = NULL )
2001-08-24 01:17:48 +04:00
return ( 0 ) ;
2023-12-23 02:00:15 +03:00
if ( xmlConvertUriToPath ( filename , & fromUri ) < 0 )
return ( 0 ) ;
if ( fromUri ! = NULL )
filename = fromUri ;
ret = xmlCheckFilename ( filename ) ;
2009-08-11 19:51:22 +04:00
2023-12-23 02:00:15 +03:00
xmlFree ( fromUri ) ;
return ( ret ) ;
2001-08-24 01:17:48 +04:00
}
2023-12-20 22:01:19 +03:00
/************************************************************************
* *
* Input / output callbacks *
* *
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
2023-12-20 22:11:09 +03:00
/**
* xmlInitIOCallbacks :
*
* Initialize callback tables .
*/
void
xmlInitIOCallbacks ( void )
{
xmlInputCallbackNr = 1 ;
xmlInputCallbackTable [ 0 ] . matchcallback = xmlIODefaultMatch ;
# ifdef LIBXML_OUTPUT_ENABLED
xmlOutputCallbackNr = 1 ;
xmlOutputCallbackTable [ 0 ] . matchcallback = xmlIODefaultMatch ;
# endif
}
2023-12-20 22:01:19 +03:00
/**
* xmlRegisterInputCallbacks :
* @ matchFunc : the xmlInputMatchCallback
* @ openFunc : the xmlInputOpenCallback
* @ readFunc : the xmlInputReadCallback
* @ closeFunc : the xmlInputCloseCallback
*
2024-06-11 04:51:43 +03:00
* DEPRECATED : Use xmlCtxtSetResourceLoader or similar functions .
*
2023-12-20 22:01:19 +03:00
* 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 matchFunc ,
xmlInputOpenCallback openFunc , xmlInputReadCallback readFunc ,
xmlInputCloseCallback closeFunc ) {
if ( xmlInputCallbackNr > = MAX_INPUT_CALLBACK ) {
return ( - 1 ) ;
}
xmlInputCallbackTable [ xmlInputCallbackNr ] . matchcallback = matchFunc ;
xmlInputCallbackTable [ xmlInputCallbackNr ] . opencallback = openFunc ;
xmlInputCallbackTable [ xmlInputCallbackNr ] . readcallback = readFunc ;
xmlInputCallbackTable [ xmlInputCallbackNr ] . closecallback = closeFunc ;
return ( xmlInputCallbackNr + + ) ;
}
/**
* xmlRegisterDefaultInputCallbacks :
*
* Registers the default compiled - in I / O handlers .
*/
void
xmlRegisterDefaultInputCallbacks ( void ) {
xmlRegisterInputCallbacks ( xmlIODefaultMatch , NULL , NULL , NULL ) ;
}
/**
* xmlPopInputCallbacks :
*
* Clear the top input callback from the input stack . this includes the
* compiled - in I / O .
*
* Returns the number of input callback registered or - 1 in case of error .
*/
int
xmlPopInputCallbacks ( void )
{
if ( xmlInputCallbackNr < = 0 )
return ( - 1 ) ;
xmlInputCallbackNr - - ;
return ( xmlInputCallbackNr ) ;
}
/**
* xmlCleanupInputCallbacks :
*
* clears the entire input callback table . this includes the
* compiled - in I / O .
*/
void
xmlCleanupInputCallbacks ( void )
{
xmlInputCallbackNr = 0 ;
}
# ifdef LIBXML_OUTPUT_ENABLED
/**
* xmlRegisterOutputCallbacks :
* @ matchFunc : the xmlOutputMatchCallback
* @ openFunc : the xmlOutputOpenCallback
* @ writeFunc : the xmlOutputWriteCallback
* @ closeFunc : 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 matchFunc ,
xmlOutputOpenCallback openFunc , xmlOutputWriteCallback writeFunc ,
xmlOutputCloseCallback closeFunc ) {
if ( xmlOutputCallbackNr > = MAX_OUTPUT_CALLBACK ) {
return ( - 1 ) ;
}
xmlOutputCallbackTable [ xmlOutputCallbackNr ] . matchcallback = matchFunc ;
xmlOutputCallbackTable [ xmlOutputCallbackNr ] . opencallback = openFunc ;
xmlOutputCallbackTable [ xmlOutputCallbackNr ] . writecallback = writeFunc ;
xmlOutputCallbackTable [ xmlOutputCallbackNr ] . closecallback = closeFunc ;
return ( xmlOutputCallbackNr + + ) ;
}
/**
* xmlRegisterDefaultOutputCallbacks :
*
* Registers the default compiled - in I / O handlers .
*/
void
xmlRegisterDefaultOutputCallbacks ( void ) {
xmlRegisterOutputCallbacks ( xmlIODefaultMatch , NULL , NULL , NULL ) ;
}
/**
* xmlPopOutputCallbacks :
*
* Remove the top output callbacks from the output stack . This includes the
* compiled - in I / O .
*
* Returns the number of output callback registered or - 1 in case of error .
*/
int
xmlPopOutputCallbacks ( void )
{
if ( xmlOutputCallbackNr < = 0 )
return ( - 1 ) ;
xmlOutputCallbackNr - - ;
return ( xmlOutputCallbackNr ) ;
}
/**
* xmlCleanupOutputCallbacks :
*
* clears the entire output callback table . this includes the
* compiled - in I / O callbacks .
*/
void
xmlCleanupOutputCallbacks ( void )
{
xmlOutputCallbackNr = 0 ;
}
# ifdef LIBXML_HTTP_ENABLED
/**
* xmlRegisterHTTPPostCallbacks :
*
2023-12-21 20:09:42 +03:00
* DEPRECATED : Support for HTTP POST has been removed .
2023-12-20 22:01:19 +03:00
*/
void
xmlRegisterHTTPPostCallbacks ( void ) {
xmlRegisterDefaultOutputCallbacks ( ) ;
}
# endif
# endif /* LIBXML_OUTPUT_ENABLED */