📄 xmlio.c
字号:
/* * xmlIO.c : implementation of the I/O interfaces used by the parser * * See Copyright for the status of this software. * * daniel@veillard.com * * 14 Nov 2000 ht - for VMS, truncated name of long functions to under 32 char */#define IN_LIBXML#include "libxml.h"#include <string.h>#ifdef HAVE_ERRNO_H#include <errno.h>#endif#ifdef HAVE_SYS_TYPES_H#include <sys/types.h>#endif#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#ifdef HAVE_STDLIB_H#include <stdlib.h>#endif#ifdef HAVE_ZLIB_H#include <zlib.h>#endif/* Figure a portable way to know if a file is a directory. */#ifndef HAVE_STAT# ifdef HAVE__STAT /* MS C library seems to define stat and _stat. The definition is identical. Still, mapping them to each other causes a warning. */# ifndef _MSC_VER# define stat(x,y) _stat(x,y)# endif# define HAVE_STAT# endif#endif#ifdef HAVE_STAT# ifndef S_ISDIR# ifdef _S_ISDIR# define S_ISDIR(x) _S_ISDIR(x)# else# ifdef S_IFDIR# ifndef S_IFMT# ifdef _S_IFMT# define S_IFMT _S_IFMT# endif# endif# ifdef S_IFMT# define S_ISDIR(m) (((m) & S_IFMT) == S_IFDIR)# endif# endif# endif# endif#endif#include <libxml/xmlmemory.h>#include <libxml/parser.h>#include <libxml/parserInternals.h>#include <libxml/xmlIO.h>#include <libxml/uri.h>#include <libxml/nanohttp.h>#include <libxml/nanoftp.h>#include <libxml/xmlerror.h>#ifdef LIBXML_CATALOG_ENABLED#include <libxml/catalog.h>#endif#include <libxml/globals.h>/* #define VERBOSE_FAILURE *//* #define DEBUG_EXTERNAL_ENTITIES *//* #define DEBUG_INPUT */#ifdef DEBUG_INPUT#define MINLEN 40#else#define MINLEN 4000#endif/* * Input I/O callback sets */typedef struct _xmlInputCallback { xmlInputMatchCallback matchcallback; xmlInputOpenCallback opencallback; xmlInputReadCallback readcallback; xmlInputCloseCallback closecallback;} xmlInputCallback;#define MAX_INPUT_CALLBACK 15static xmlInputCallback xmlInputCallbackTable[MAX_INPUT_CALLBACK];static int xmlInputCallbackNr = 0;static int xmlInputCallbackInitialized = 0;#ifdef LIBXML_OUTPUT_ENABLED/* * Output I/O callback sets */typedef struct _xmlOutputCallback { xmlOutputMatchCallback matchcallback; xmlOutputOpenCallback opencallback; xmlOutputWriteCallback writecallback; xmlOutputCloseCallback closecallback;} xmlOutputCallback;#define MAX_OUTPUT_CALLBACK 15static xmlOutputCallback xmlOutputCallbackTable[MAX_OUTPUT_CALLBACK];static int xmlOutputCallbackNr = 0;static int xmlOutputCallbackInitialized = 0;#endif /* LIBXML_OUTPUT_ENABLED *//************************************************************************ * * * Tree memory error handler * * * ************************************************************************/static const char *IOerr[] = { "Unknown IO error", /* UNKNOWN */ "Permission denied", /* EACCES */ "Resource temporarily unavailable",/* EAGAIN */ "Bad file descriptor", /* EBADF */ "Bad message", /* EBADMSG */ "Resource busy", /* EBUSY */ "Operation canceled", /* ECANCELED */ "No child processes", /* ECHILD */ "Resource deadlock avoided",/* EDEADLK */ "Domain error", /* EDOM */ "File exists", /* EEXIST */ "Bad address", /* EFAULT */ "File too large", /* EFBIG */ "Operation in progress", /* EINPROGRESS */ "Interrupted function call",/* EINTR */ "Invalid argument", /* EINVAL */ "Input/output error", /* EIO */ "Is a directory", /* EISDIR */ "Too many open files", /* EMFILE */ "Too many links", /* EMLINK */ "Inappropriate message buffer length",/* EMSGSIZE */ "Filename too long", /* ENAMETOOLONG */ "Too many open files in system",/* ENFILE */ "No such device", /* ENODEV */ "No such file or directory",/* ENOENT */ "Exec format error", /* ENOEXEC */ "No locks available", /* ENOLCK */ "Not enough space", /* ENOMEM */ "No space left on device", /* ENOSPC */ "Function not implemented", /* ENOSYS */ "Not a directory", /* ENOTDIR */ "Directory not empty", /* ENOTEMPTY */ "Not supported", /* ENOTSUP */ "Inappropriate I/O control operation",/* ENOTTY */ "No such device or address",/* ENXIO */ "Operation not permitted", /* EPERM */ "Broken pipe", /* EPIPE */ "Result too large", /* ERANGE */ "Read-only file system", /* EROFS */ "Invalid seek", /* ESPIPE */ "No such process", /* ESRCH */ "Operation timed out", /* ETIMEDOUT */ "Improper link", /* EXDEV */ "Attempt to load network entity %s", /* XML_IO_NETWORK_ATTEMPT */ "encoder error", /* XML_IO_ENCODER */ "flush error", "write error", "no input", "buffer full", "loading error", "not a socket", /* ENOTSOCK */ "already connected", /* EISCONN */ "connection refused", /* ECONNREFUSED */ "unreachable network", /* ENETUNREACH */ "adddress in use", /* EADDRINUSE */ "already in use", /* EALREADY */ "unknown address familly", /* EAFNOSUPPORT */};/** * xmlIOErrMemory: * @extra: extra informations * * Handle an out of memory condition */static voidxmlIOErrMemory(const char *extra){ __xmlSimpleError(XML_FROM_IO, XML_ERR_NO_MEMORY, NULL, NULL, extra);}/** * __xmlIOErr: * @code: the error number * @ * @extra: extra informations * * Handle an I/O error */void__xmlIOErr(int domain, int code, const char *extra){ unsigned int idx; if (code == 0) {#ifdef HAVE_ERRNO_H if (errno == 0) code = 0;#ifdef EACCES else if (errno == EACCES) code = XML_IO_EACCES;#endif#ifdef EAGAIN else if (errno == EAGAIN) code = XML_IO_EAGAIN;#endif#ifdef EBADF else if (errno == EBADF) code = XML_IO_EBADF;#endif#ifdef EBADMSG else if (errno == EBADMSG) code = XML_IO_EBADMSG;#endif#ifdef EBUSY else if (errno == EBUSY) code = XML_IO_EBUSY;#endif#ifdef ECANCELED else if (errno == ECANCELED) code = XML_IO_ECANCELED;#endif#ifdef ECHILD else if (errno == ECHILD) code = XML_IO_ECHILD;#endif#ifdef EDEADLK else if (errno == EDEADLK) code = XML_IO_EDEADLK;#endif#ifdef EDOM else if (errno == EDOM) code = XML_IO_EDOM;#endif#ifdef EEXIST else if (errno == EEXIST) code = XML_IO_EEXIST;#endif#ifdef EFAULT else if (errno == EFAULT) code = XML_IO_EFAULT;#endif#ifdef EFBIG else if (errno == EFBIG) code = XML_IO_EFBIG;#endif#ifdef EINPROGRESS else if (errno == EINPROGRESS) code = XML_IO_EINPROGRESS;#endif#ifdef EINTR else if (errno == EINTR) code = XML_IO_EINTR;#endif#ifdef EINVAL else if (errno == EINVAL) code = XML_IO_EINVAL;#endif#ifdef EIO else if (errno == EIO) code = XML_IO_EIO;#endif#ifdef EISDIR else if (errno == EISDIR) code = XML_IO_EISDIR;#endif#ifdef EMFILE else if (errno == EMFILE) code = XML_IO_EMFILE;#endif#ifdef EMLINK else if (errno == EMLINK) code = XML_IO_EMLINK;#endif#ifdef EMSGSIZE else if (errno == EMSGSIZE) code = XML_IO_EMSGSIZE;#endif#ifdef ENAMETOOLONG else if (errno == ENAMETOOLONG) code = XML_IO_ENAMETOOLONG;#endif#ifdef ENFILE else if (errno == ENFILE) code = XML_IO_ENFILE;#endif#ifdef ENODEV else if (errno == ENODEV) code = XML_IO_ENODEV;#endif#ifdef ENOENT else if (errno == ENOENT) code = XML_IO_ENOENT;#endif#ifdef ENOEXEC else if (errno == ENOEXEC) code = XML_IO_ENOEXEC;#endif#ifdef ENOLCK else if (errno == ENOLCK) code = XML_IO_ENOLCK;#endif#ifdef ENOMEM else if (errno == ENOMEM) code = XML_IO_ENOMEM;#endif#ifdef ENOSPC else if (errno == ENOSPC) code = XML_IO_ENOSPC;#endif#ifdef ENOSYS else if (errno == ENOSYS) code = XML_IO_ENOSYS;#endif#ifdef ENOTDIR else if (errno == ENOTDIR) code = XML_IO_ENOTDIR;#endif#ifdef ENOTEMPTY else if (errno == ENOTEMPTY) code = XML_IO_ENOTEMPTY;#endif#ifdef ENOTSUP else if (errno == ENOTSUP) code = XML_IO_ENOTSUP;#endif#ifdef ENOTTY else if (errno == ENOTTY) code = XML_IO_ENOTTY;#endif#ifdef ENXIO else if (errno == ENXIO) code = XML_IO_ENXIO;#endif#ifdef EPERM else if (errno == EPERM) code = XML_IO_EPERM;#endif#ifdef EPIPE else if (errno == EPIPE) code = XML_IO_EPIPE;#endif#ifdef ERANGE else if (errno == ERANGE) code = XML_IO_ERANGE;#endif#ifdef EROFS else if (errno == EROFS) code = XML_IO_EROFS;#endif#ifdef ESPIPE else if (errno == ESPIPE) code = XML_IO_ESPIPE;#endif#ifdef ESRCH else if (errno == ESRCH) code = XML_IO_ESRCH;#endif#ifdef ETIMEDOUT else if (errno == ETIMEDOUT) code = XML_IO_ETIMEDOUT;#endif#ifdef EXDEV else if (errno == EXDEV) code = XML_IO_EXDEV;#endif#ifdef ENOTSOCK else if (errno == ENOTSOCK) code = XML_IO_ENOTSOCK;#endif#ifdef EISCONN else if (errno == EISCONN) code = XML_IO_EISCONN;#endif#ifdef ECONNREFUSED else if (errno == ECONNREFUSED) code = XML_IO_ECONNREFUSED;#endif#ifdef ETIMEDOUT else if (errno == ETIMEDOUT) code = XML_IO_ETIMEDOUT;#endif#ifdef ENETUNREACH else if (errno == ENETUNREACH) code = XML_IO_ENETUNREACH;#endif#ifdef EADDRINUSE else if (errno == EADDRINUSE) code = XML_IO_EADDRINUSE;#endif#ifdef EINPROGRESS else if (errno == EINPROGRESS) code = XML_IO_EINPROGRESS;#endif#ifdef EALREADY else if (errno == EALREADY) code = XML_IO_EALREADY;#endif#ifdef EAFNOSUPPORT else if (errno == EAFNOSUPPORT) code = XML_IO_EAFNOSUPPORT;#endif else code = XML_IO_UNKNOWN;#endif /* HAVE_ERRNO_H */ } idx = 0; if (code >= XML_IO_UNKNOWN) idx = code - XML_IO_UNKNOWN; if (idx >= (sizeof(IOerr) / sizeof(IOerr[0]))) idx = 0; __xmlSimpleError(domain, code, NULL, IOerr[idx], extra);}/** * xmlIOErr: * @code: the error number * @extra: extra informations * * Handle an I/O error */static voidxmlIOErr(int code, const char *extra){ __xmlIOErr(XML_FROM_IO, code, extra);}/** * __xmlLoaderErr: * @ctx: the parser context * @extra: extra informations * * Handle a resource access error */void__xmlLoaderErr(void *ctx, const char *msg, const char *filename){ xmlParserCtxtPtr ctxt = (xmlParserCtxtPtr) ctx; xmlStructuredErrorFunc schannel = NULL; xmlGenericErrorFunc channel = NULL; void *data = NULL; xmlErrorLevel level = XML_ERR_ERROR; if ((ctxt != NULL) && (ctxt->disableSAX != 0) && (ctxt->instate == XML_PARSER_EOF)) return; if ((ctxt != NULL) && (ctxt->sax != NULL)) { if (ctxt->validate) { channel = ctxt->sax->error; level = XML_ERR_ERROR; } else { channel = ctxt->sax->warning; level = XML_ERR_WARNING; } if (ctxt->sax->initialized == XML_SAX2_MAGIC) schannel = ctxt->sax->serror; data = ctxt->userData; } __xmlRaiseError(schannel, channel, data, ctxt, NULL, XML_FROM_IO, XML_IO_LOAD_ERROR, level, NULL, 0, filename, NULL, NULL, 0, 0, msg, filename); }/************************************************************************ * * * Tree memory error handler * * * ************************************************************************//** * xmlNormalizeWindowsPath: * @path: the input file path * * This function is obsolete. Please see xmlURIFromPath in uri.c for * a better solution. * * Returns a canonicalized version of the path */xmlChar *xmlNormalizeWindowsPath(const xmlChar *path){ return xmlCanonicPath(path);}/** * xmlCleanupInputCallbacks: * * clears the entire input callback table. this includes the * compiled-in I/O. */voidxmlCleanupInputCallbacks(void){ int i; if (!xmlInputCallbackInitialized) return; for (i = xmlInputCallbackNr - 1; i >= 0; i--) { xmlInputCallbackTable[i].matchcallback = NULL; xmlInputCallbackTable[i].opencallback = NULL; xmlInputCallbackTable[i].readcallback = NULL; xmlInputCallbackTable[i].closecallback = NULL; } xmlInputCallbackNr = 0; xmlInputCallbackInitialized = 0;}/** * 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. */intxmlPopInputCallbacks(void){ if (!xmlInputCallbackInitialized) return(-1); if (xmlInputCallbackNr <= 0) return(-1); xmlInputCallbackNr--; xmlInputCallbackTable[xmlInputCallbackNr].matchcallback = NULL; xmlInputCallbackTable[xmlInputCallbackNr].opencallback = NULL; xmlInputCallbackTable[xmlInputCallbackNr].readcallback = NULL; xmlInputCallbackTable[xmlInputCallbackNr].closecallback = NULL; return(xmlInputCallbackNr);}#ifdef LIBXML_OUTPUT_ENABLED/** * xmlCleanupOutputCallbacks: * * clears the entire output callback table. this includes the * compiled-in I/O callbacks. */voidxmlCleanupOutputCallbacks(void){ int i; if (!xmlOutputCallbackInitialized) return; for (i = xmlOutputCallbackNr - 1; i >= 0; i--) { xmlOutputCallbackTable[i].matchcallback = NULL; xmlOutputCallbackTable[i].opencallback = NULL;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -