📄 xmlio.c
字号:
#ifdef LIBXML_OUTPUT_ENABLED
/**
* xmlCleanupOutputCallbacks:
*
* clears the entire output callback table. this includes the
* compiled-in I/O callbacks.
*/
void
xmlCleanupOutputCallbacks(void)
{
int i;
if (!xmlOutputCallbackInitialized)
return;
for (i = xmlOutputCallbackNr - 1; i >= 0; i--) {
xmlOutputCallbackTable[i].matchcallback = NULL;
xmlOutputCallbackTable[i].opencallback = NULL;
xmlOutputCallbackTable[i].writecallback = NULL;
xmlOutputCallbackTable[i].closecallback = NULL;
}
xmlOutputCallbackNr = 0;
xmlOutputCallbackInitialized = 0;
}
#endif /* LIBXML_OUTPUT_ENABLED */
/************************************************************************
* *
* Standard I/O for file accesses *
* *
************************************************************************/
/**
* xmlCheckFilename:
* @path: the path to check
*
* function checks to see if @path is a valid source
* (file, socket...) for XML.
*
* 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,
* returns 2. otherwise returns 1.
*/
int
xmlCheckFilename (const char *path)
{
#ifdef HAVE_STAT
struct stat stat_buffer;
if (path == NULL)
return(0);
if (stat(path, &stat_buffer) == -1)
return 0;
#ifdef S_ISDIR
if (S_ISDIR(stat_buffer.st_mode)) {
return 2;
}
#endif
#endif
if (path == NULL)
return(0);
return 1;
}
static int
xmlNop(void) {
return(0);
}
/**
* 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.
*
* Returns the number of bytes written
*/
static int
xmlFdRead (void * context, char * buffer, int len) {
int ret;
ret = read((int) (long) context, &buffer[0], len);
if (ret < 0) xmlIOErr(0, "read()");
return(ret);
}
#ifdef LIBXML_OUTPUT_ENABLED
/**
* 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
*/
static int
xmlFdWrite (void * context, const char * buffer, int len) {
int ret;
ret = write((int) (long) context, &buffer[0], len);
if (ret < 0) xmlIOErr(0, "write()");
return(ret);
}
#endif /* LIBXML_OUTPUT_ENABLED */
/**
* xmlFdClose:
* @context: the I/O context
*
* Close an I/O channel
*
* Returns 0 in case of success and error code otherwise
*/
static int
xmlFdClose (void * context) {
int ret;
ret = close((int) (long) context);
if (ret < 0) xmlIOErr(0, "close()");
return(ret);
}
/**
* xmlFileMatch:
* @filename: the URI for matching
*
* input from FILE *
*
* Returns 1 if matches, 0 otherwise
*/
int
xmlFileMatch (const char *filename ATTRIBUTE_UNUSED) {
return(1);
}
/**
* xmlFileOpen_real:
* @filename: the URI for matching
*
* input from FILE *, supports compressed input
* if @filename is " " then the standard input is used
*
* Returns an I/O context or NULL in case of error
*/
static void *
xmlFileOpen_real (const char *filename) {
const char *path = NULL;
FILE *fd;
if (filename == NULL)
return(NULL);
if (!strcmp(filename, "-")) {
fd = stdin;
return((void *) fd);
}
if (!xmlStrncasecmp(BAD_CAST filename, BAD_CAST "file://localhost/", 17))
#if defined (_WIN32) || defined (__DJGPP__) && !defined(__CYGWIN__)
path = &filename[17];
#else
path = &filename[16];
#endif
else if (!xmlStrncasecmp(BAD_CAST filename, BAD_CAST "file:///", 8)) {
#if defined (_WIN32) || defined (__DJGPP__) && !defined(__CYGWIN__)
path = &filename[8];
#else
path = &filename[7];
#endif
} else
path = filename;
if (path == NULL)
return(NULL);
if (!xmlCheckFilename(path))
return(NULL);
#if defined(WIN32) || defined (__DJGPP__) && !defined (__CYGWIN__)
fd = fopen(path, "rb");
#else
fd = fopen(path, "r");
#endif /* WIN32 */
if (fd == NULL) xmlIOErr(0, path);
return((void *) fd);
}
/**
* xmlFileOpen:
* @filename: the URI for matching
*
* Wrapper around xmlFileOpen_real that try it with an unescaped
* version of @filename, if this fails fallback to @filename
*
* Returns a handler or NULL in case or failure
*/
void *
xmlFileOpen (const char *filename) {
char *unescaped;
void *retval;
unescaped = xmlURIUnescapeString(filename, 0, NULL);
if (unescaped != NULL) {
retval = xmlFileOpen_real(unescaped);
xmlFree(unescaped);
} else {
retval = xmlFileOpen_real(filename);
}
return retval;
}
#ifdef LIBXML_OUTPUT_ENABLED
/**
* xmlFileOpenW:
* @filename: the URI for matching
*
* output to from FILE *,
* if @filename is "-" then the standard output is used
*
* Returns an I/O context or NULL in case of error
*/
static void *
xmlFileOpenW (const char *filename) {
const char *path = NULL;
FILE *fd;
if (!strcmp(filename, "-")) {
fd = stdout;
return((void *) fd);
}
if (!xmlStrncasecmp(BAD_CAST filename, BAD_CAST "file://localhost/", 17))
#if defined (_WIN32) || defined (__DJGPP__) && !defined(__CYGWIN__)
path = &filename[17];
#else
path = &filename[16];
#endif
else if (!xmlStrncasecmp(BAD_CAST filename, BAD_CAST "file:///", 8)) {
#if defined (_WIN32) || defined (__DJGPP__) && !defined(__CYGWIN__)
path = &filename[8];
#else
path = &filename[7];
#endif
} else
path = filename;
if (path == NULL)
return(NULL);
fd = fopen(path, "wb");
if (fd == NULL) xmlIOErr(0, path);
return((void *) fd);
}
#endif /* LIBXML_OUTPUT_ENABLED */
/**
* xmlFileRead:
* @context: the I/O context
* @buffer: where to drop data
* @len: number of bytes to write
*
* Read @len bytes to @buffer from the I/O channel.
*
* Returns the number of bytes written or < 0 in case of failure
*/
int
xmlFileRead (void * context, char * buffer, int len) {
int ret;
if ((context == NULL) || (buffer == NULL))
return(-1);
ret = fread(&buffer[0], 1, len, (FILE *) context);
if (ret < 0) xmlIOErr(0, "fread()");
return(ret);
}
#ifdef LIBXML_OUTPUT_ENABLED
/**
* 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
*/
static int
xmlFileWrite (void * context, const char * buffer, int len) {
int items;
if ((context == NULL) || (buffer == NULL))
return(-1);
items = fwrite(&buffer[0], len, 1, (FILE *) context);
if ((items == 0) && (ferror((FILE *) context))) {
xmlIOErr(0, "fwrite()");
return(-1);
}
return(items * len);
}
#endif /* LIBXML_OUTPUT_ENABLED */
/**
* xmlFileClose:
* @context: the I/O context
*
* Close an I/O channel
*
* Returns 0 or -1 in case of error
*/
int
xmlFileClose (void * context) {
FILE *fil;
int ret;
if (context == NULL)
return(-1);
fil = (FILE *) context;
if ((fil == stdout) || (fil == stderr)) {
ret = fflush(fil);
if (ret < 0)
xmlIOErr(0, "fflush()");
return(0);
}
if (fil == stdin)
return(0);
ret = ( fclose((FILE *) context) == EOF ) ? -1 : 0;
if (ret < 0)
xmlIOErr(0, "fclose()");
return(ret);
}
/**
* xmlFileFlush:
* @context: the I/O context
*
* Flush an I/O channel
*/
static int
xmlFileFlush (void * context) {
int ret;
if (context == NULL)
return(-1);
ret = ( fflush((FILE *) context) == EOF ) ? -1 : 0;
if (ret < 0)
xmlIOErr(0, "fflush()");
return(ret);
}
#ifdef HAVE_ZLIB_H
/************************************************************************
* *
* I/O for compressed file accesses *
* *
************************************************************************/
/**
* xmlGzfileMatch:
* @filename: the URI for matching
*
* input from compressed file test
*
* Returns 1 if matches, 0 otherwise
*/
static int
xmlGzfileMatch (const char *filename ATTRIBUTE_UNUSED) {
return(1);
}
/**
* xmlGzfileOpen_real:
* @filename: the URI for matching
*
* input from compressed file open
* if @filename is " " then the standard input is used
*
* Returns an I/O context or NULL in case of error
*/
static void *
xmlGzfileOpen_real (const char *filename) {
const char *path = NULL;
gzFile fd;
if (!strcmp(filename, "-")) {
fd = gzdopen(dup(0), "rb");
return((void *) fd);
}
if (!xmlStrncasecmp(BAD_CAST filename, BAD_CAST "file://localhost/", 17))
#if defined (_WIN32) || defined (__DJGPP__) && !defined(__CYGWIN__)
path = &filename[17];
#else
path = &filename[16];
#endif
else if (!xmlStrncasecmp(BAD_CAST filename, BAD_CAST "file:///", 8)) {
#if defined (_WIN32) || defined (__DJGPP__) && !defined(__CYGWIN__)
path = &filename[8];
#else
path = &filename[7];
#endif
} else
path = filename;
if (path == NULL)
return(NULL);
if (!xmlCheckFilename(path))
return(NULL);
fd = gzopen(path, "rb");
return((void *) fd);
}
/**
* xmlGzfileOpen:
* @filename: the URI for matching
*
* Wrapper around xmlGzfileOpen if the open fais, it will
* try to unescape @filename
*/
static void *
xmlGzfileOpen (const char *filename) {
char *unescaped;
void *retval;
retval = xmlGzfileOpen_real(filename);
if (retval == NULL) {
unescaped = xmlURIUnescapeString(filename, 0, NULL);
if (unescaped != NULL) {
retval = xmlGzfileOpen_real(unescaped);
}
xmlFree(unescaped);
}
return retval;
}
#ifdef LIBXML_OUTPUT_ENABLED
/**
* xmlGzfileOpenW:
* @filename: the URI for matching
* @compression: the compression factor (0 - 9 included)
*
* input from compressed file open
* if @filename is " " then the standard input is used
*
* Returns an I/O context or NULL in case of error
*/
static void *
xmlGzfileOpenW (const char *filename, int compression) {
const char *path = NULL;
char mode[15];
gzFile fd;
snprintf(mode, sizeof(mode), "wb%d", compression);
if (!strcmp(filename, "-")) {
fd = gzdopen(dup(1), mode);
return((void *) fd);
}
if (!xmlStrncasecmp(BAD_CAST filename, BAD_CAST "file://localhost/", 17))
#if defined (_WIN32) || defined (__DJGPP__) && !defined(__CYGWIN__)
path = &filename[17];
#else
path = &filename[16];
#endif
else if (!xmlStrncasecmp(BAD_CAST filename, BAD_CAST "file:///", 8)) {
#if defined (_WIN32) || defined (__DJGPP__) && !defined(__CYGWIN__)
path = &filename[8];
#else
path = &filename[7];
#endif
} else
path = filename;
if (path == NULL)
return(NULL);
fd = gzopen(path, mode);
return((void *) fd);
}
#endif /* LIBXML_OUTPUT_ENABLED */
/**
* xmlGzfileRead:
* @context: the I/O context
* @buffer: where to drop data
* @len: number of bytes to write
*
* Read @len bytes to @buffer from the compressed I/O channel.
*
* Returns the number of bytes written
*/
static int
xmlGzfileRead (void * context, char * buffer, int len) {
int ret;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -