diff options
Diffstat (limited to 'xmlIO.c')
-rw-r--r-- | xmlIO.c | 494 |
1 files changed, 259 insertions, 235 deletions
@@ -50,6 +50,12 @@ # endif # define HAVE_STAT # endif +#else +# ifdef HAVE__STAT +# if defined(_WIN32) || defined (__DJGPP__) && !defined (__CYGWIN__) +# define stat _stat +# endif +# endif #endif #ifdef HAVE_STAT # ifndef S_ISDIR @@ -193,7 +199,7 @@ static const char *IOerr[] = { "unknown address familly", /* EAFNOSUPPORT */ }; -#if defined(WIN32) || defined (__DJGPP__) && !defined (__CYGWIN__) +#if defined(_WIN32) || defined (__DJGPP__) && !defined (__CYGWIN__) /** * __xmlIOWin32UTF8ToWChar: * @u8String: uft-8 string @@ -203,26 +209,25 @@ static const char *IOerr[] = { static wchar_t * __xmlIOWin32UTF8ToWChar(const char *u8String) { - wchar_t *wString = NULL; + wchar_t *wString = NULL; + + 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; + } + } + } + } - if (u8String) - { - int wLen = MultiByteToWideChar(CP_UTF8,0,u8String,-1,NULL,0); - if (wLen) - { - wString = malloc((wLen+1) * sizeof(wchar_t)); - if (wString) - { - if (MultiByteToWideChar(CP_UTF8,0,u8String,-1,wString,wLen+1) == 0) - { - free(wString); - wString = NULL; - } - } - } - } - - return wString; + return wString; } #endif @@ -572,6 +577,132 @@ xmlCleanupOutputCallbacks(void) * * ************************************************************************/ +#if defined(_WIN32) || defined (__DJGPP__) && !defined (__CYGWIN__) + +/** + * xmlWrapOpenUtf8: + * @path: the path in utf-8 encoding + * @mode: type of access (0 - read, 1 - write) + * + * function opens the file specified by @path + * + */ +static FILE* +xmlWrapOpenUtf8(const char *path,int mode) +{ + FILE *fd = NULL; + wchar_t *wPath; + + wPath = __xmlIOWin32UTF8ToWChar(path); + if(wPath) + { + fd = _wfopen(wPath, mode ? L"wb" : L"rb"); + xmlFree(wPath); + } + /* maybe path in native encoding */ + if(fd == NULL) + fd = fopen(path, mode ? "wb" : "rb"); + + return fd; +} + +/** + * xmlWrapStatUtf8: + * @path: the path in utf-8 encoding + * @info: structure that stores results + * + * function obtains information about the file or directory + * + */ +static int +xmlWrapStatUtf8(const char *path,struct stat *info) +{ +#ifdef HAVE_STAT + int retval = -1; + wchar_t *wPath; + + wPath = __xmlIOWin32UTF8ToWChar(path); + if (wPath) + { + retval = _wstat(wPath,info); + xmlFree(wPath); + } + /* maybe path in native encoding */ + if(retval < 0) + retval = stat(path,info); + return retval; +#else + return -1; +#endif +} + +/** + * xmlWrapOpenNative: + * @path: the path + * @mode: type of access (0 - read, 1 - write) + * + * function opens the file specified by @path + * + */ +static FILE* +xmlWrapOpenNative(const char *path,int mode) +{ + return fopen(path,mode ? "wb" : "rb"); +} + +/** + * xmlWrapStatNative: + * @path: the path + * @info: structure that stores results + * + * function obtains information about the file or directory + * + */ +static int +xmlWrapStatNative(const char *path,struct stat *info) +{ +#ifdef HAVE_STAT + return stat(path,info); +#else + return -1; +#endif +} + +typedef int (* xmlWrapStatFunc) (const char *f, struct stat *s); +static xmlWrapStatFunc xmlWrapStat = xmlWrapStatNative; +typedef FILE* (* xmlWrapOpenFunc)(const char *f,int mode); +static xmlWrapOpenFunc xmlWrapOpen = xmlWrapOpenNative; + +/** + * xmlInitPlatformSpecificIo: + * + * Initialize platform specific features. + */ +static void +xmlInitPlatformSpecificIo(void) +{ + static int xmlPlatformIoInitialized = 0; + OSVERSIONINFO osvi; + + if(xmlPlatformIoInitialized) + return; + + osvi.dwOSVersionInfoSize = sizeof(osvi); + + if(GetVersionEx(&osvi) && (osvi.dwPlatformId == VER_PLATFORM_WIN32_NT)) { + xmlWrapStat = xmlWrapStatUtf8; + xmlWrapOpen = xmlWrapOpenUtf8; + } else { + xmlWrapStat = xmlWrapStatNative; + xmlWrapOpen = xmlWrapOpenNative; + } + + xmlPlatformIoInitialized = 1; + return; +} + +#endif + /** * xmlCheckFilename: * @path: the path to check @@ -594,41 +725,20 @@ xmlCheckFilename (const char *path) #endif if (path == NULL) return(0); - -#if defined(WIN32) || defined (__DJGPP__) && !defined (__CYGWIN__) - { - int retval = 0; - - wchar_t *wPath = __xmlIOWin32UTF8ToWChar(path); - if (wPath) - { - struct _stat stat_buffer; - - if (_wstat(wPath,&stat_buffer) == 0) - { - retval = 1; - - if (((stat_buffer.st_mode & S_IFDIR) == S_IFDIR)) - retval = 2; - } - - free(wPath); - } - return retval; - } -#else #ifdef HAVE_STAT +#if defined(_WIN32) || defined (__DJGPP__) && !defined (__CYGWIN__) + if (xmlWrapStat(path, &stat_buffer) == -1) + return 0; +#else if (stat(path, &stat_buffer) == -1) return 0; - +#endif #ifdef S_ISDIR if (S_ISDIR(stat_buffer.st_mode)) return 2; -#endif /* S_ISDIR */ +#endif #endif /* HAVE_STAT */ -#endif /* WIN32 */ - return 1; } @@ -750,19 +860,8 @@ xmlFileOpen_real (const char *filename) { if (!xmlCheckFilename(path)) return(NULL); -#if defined(WIN32) || defined (__DJGPP__) && !defined (__CYGWIN__) - { - wchar_t *wPath = __xmlIOWin32UTF8ToWChar(path); - if (wPath) - { - fd = _wfopen(wPath, L"rb"); - free(wPath); - } - else - { - fd = fopen(path, "rb"); - } - } +#if defined(_WIN32) || defined (__DJGPP__) && !defined (__CYGWIN__) + fd = xmlWrapOpen(path, 0); #else fd = fopen(path, "r"); #endif /* WIN32 */ @@ -832,19 +931,8 @@ xmlFileOpenW (const char *filename) { if (path == NULL) return(NULL); -#if defined(WIN32) || defined (__DJGPP__) && !defined (__CYGWIN__) - { - wchar_t *wPath = __xmlIOWin32UTF8ToWChar(path); - if (wPath) - { - fd = _wfopen(wPath, L"wb"); - free(wPath); - } - else - { - fd = fopen(path, "wb"); - } - } +#if defined(_WIN32) || defined (__DJGPP__) && !defined (__CYGWIN__) + fd = xmlWrapOpen(path, 1); #else fd = fopen(path, "wb"); #endif /* WIN32 */ @@ -2018,11 +2106,14 @@ xmlRegisterOutputCallbacks(xmlOutputMatchCallback matchFunc, * Registers the default compiled-in I/O handlers. */ void -xmlRegisterDefaultInputCallbacks -(void) { +xmlRegisterDefaultInputCallbacks(void) { if (xmlInputCallbackInitialized) return; +#if defined(_WIN32) || defined (__DJGPP__) && !defined (__CYGWIN__) + xmlInitPlatformSpecificIo(); +#endif + xmlRegisterInputCallbacks(xmlFileMatch, xmlFileOpen, xmlFileRead, xmlFileClose); #ifdef HAVE_ZLIB_H @@ -2049,11 +2140,14 @@ xmlRegisterDefaultInputCallbacks * Registers the default compiled-in I/O handlers. */ void -xmlRegisterDefaultOutputCallbacks -(void) { +xmlRegisterDefaultOutputCallbacks (void) { if (xmlOutputCallbackInitialized) return; +#if defined(_WIN32) || defined (__DJGPP__) && !defined (__CYGWIN__) + xmlInitPlatformSpecificIo(); +#endif + xmlRegisterOutputCallbacks(xmlFileMatch, xmlFileOpenW, xmlFileWrite, xmlFileClose); @@ -2368,7 +2462,8 @@ __xmlOutputBufferCreateFilename(const char *URI, /* * try to limit the damages of the URI unescaping code. */ - if (puri->scheme != NULL) + if ((puri->scheme == NULL) || + (xmlStrEqual(BAD_CAST puri->scheme, BAD_CAST "file"))) unescaped = xmlURIUnescapeString(URI, 0, NULL); xmlFreeURI(puri); } @@ -3499,10 +3594,7 @@ xmlCheckHTTPInput(xmlParserCtxtPtr ctxt, xmlParserInputPtr ret) { return(ret); } -static int xmlSysIDExists(const char *URL) { -#ifdef HAVE_STAT - int ret; - struct stat info; +static int xmlNoNetExists(const char *URL) { const char *path; if (URL == NULL) @@ -3522,13 +3614,88 @@ static int xmlSysIDExists(const char *URL) { #endif } else path = URL; - ret = stat(path, &info); - if (ret == 0) - return(1); -#endif - return(0); + + return xmlCheckFilename(path); } +#ifdef LIBXML_CATALOG_ENABLED + +/** + * xmlResolveResourceFromCatalog: + * @URL: the URL for the entity to load + * @ID: the System ID for the entity to load + * @ctxt: the context in which the entity is called or NULL + * + * Resolves the URL and ID against the appropriate catalog. + * This function is used by xmlDefaultExternalEntityLoader and + * xmlNoNetExternalEntityLoader. + * + * Returns a new allocated URL, or NULL. + */ +xmlChar * +xmlResolveResourceFromCatalog(const char *URL, const char *ID, + xmlParserCtxtPtr ctxt) { + xmlChar *resource = NULL; + xmlCatalogAllow pref; + + /* + * If the resource doesn't exists as a file, + * try to load it from the resource pointed in the catalogs + */ + pref = xmlCatalogGetDefaults(); + + if ((pref != XML_CATA_ALLOW_NONE) && (!xmlNoNetExists(URL))) { + /* + * Do a local lookup + */ + if ((ctxt != NULL) && (ctxt->catalogs != NULL) && + ((pref == XML_CATA_ALLOW_ALL) || + (pref == XML_CATA_ALLOW_DOCUMENT))) { + resource = xmlCatalogLocalResolve(ctxt->catalogs, + (const xmlChar *)ID, + (const xmlChar *)URL); + } + /* + * Try a global lookup + */ + if ((resource == NULL) && + ((pref == XML_CATA_ALLOW_ALL) || + (pref == XML_CATA_ALLOW_GLOBAL))) { + resource = xmlCatalogResolve((const xmlChar *)ID, + (const xmlChar *)URL); + } + if ((resource == NULL) && (URL != NULL)) + resource = xmlStrdup((const xmlChar *) URL); + + /* + * TODO: do an URI lookup on the reference + */ + if ((resource != NULL) && (!xmlNoNetExists((const char *)resource))) { + xmlChar *tmp = NULL; + + if ((ctxt != NULL) && (ctxt->catalogs != NULL) && + ((pref == XML_CATA_ALLOW_ALL) || + (pref == XML_CATA_ALLOW_DOCUMENT))) { + tmp = xmlCatalogLocalResolveURI(ctxt->catalogs, resource); + } + if ((tmp == NULL) && + ((pref == XML_CATA_ALLOW_ALL) || + (pref == XML_CATA_ALLOW_GLOBAL))) { + tmp = xmlCatalogResolveURI(resource); + } + + if (tmp != NULL) { + xmlFree(resource); + resource = tmp; + } + } + } + + return resource; +} + +#endif + /** * xmlDefaultExternalEntityLoader: * @URL: the URL for the entity to load @@ -3546,15 +3713,10 @@ xmlDefaultExternalEntityLoader(const char *URL, const char *ID, xmlParserInputPtr ret = NULL; xmlChar *resource = NULL; -#ifdef LIBXML_CATALOG_ENABLED - xmlCatalogAllow pref; -#endif - #ifdef DEBUG_EXTERNAL_ENTITIES xmlGenericError(xmlGenericErrorContext, "xmlDefaultExternalEntityLoader(%s, xxx)\n", URL); #endif -#ifdef LIBXML_CATALOG_ENABLED if ((ctxt != NULL) && (ctxt->options & XML_PARSE_NONET)) { int options = ctxt->options; @@ -3563,60 +3725,8 @@ xmlDefaultExternalEntityLoader(const char *URL, const char *ID, ctxt->options = options; return(ret); } - - /* - * If the resource doesn't exists as a file, - * try to load it from the resource pointed in the catalogs - */ - pref = xmlCatalogGetDefaults(); - - if ((pref != XML_CATA_ALLOW_NONE) && (!xmlSysIDExists(URL))) { - /* - * Do a local lookup - */ - if ((ctxt != NULL) && (ctxt->catalogs != NULL) && - ((pref == XML_CATA_ALLOW_ALL) || - (pref == XML_CATA_ALLOW_DOCUMENT))) { - resource = xmlCatalogLocalResolve(ctxt->catalogs, - (const xmlChar *) ID, - (const xmlChar *) URL); - } - /* - * Try a global lookup - */ - if ((resource == NULL) && - ((pref == XML_CATA_ALLOW_ALL) || - (pref == XML_CATA_ALLOW_GLOBAL))) { - resource = xmlCatalogResolve((const xmlChar *) ID, - (const xmlChar *) URL); - } - if ((resource == NULL) && (URL != NULL)) - resource = xmlStrdup((const xmlChar *) URL); - - /* - * TODO: do an URI lookup on the reference - */ - if ((resource != NULL) - && (!xmlSysIDExists((const char *) resource))) { - xmlChar *tmp = NULL; - - if ((ctxt != NULL) && (ctxt->catalogs != NULL) && - ((pref == XML_CATA_ALLOW_ALL) || - (pref == XML_CATA_ALLOW_DOCUMENT))) { - tmp = xmlCatalogLocalResolveURI(ctxt->catalogs, resource); - } - if ((tmp == NULL) && - ((pref == XML_CATA_ALLOW_ALL) || - (pref == XML_CATA_ALLOW_GLOBAL))) { - tmp = xmlCatalogResolveURI(resource); - } - - if (tmp != NULL) { - xmlFree(resource); - resource = tmp; - } - } - } +#ifdef LIBXML_CATALOG_ENABLED + resource = xmlResolveResourceFromCatalog(URL, ID, ctxt); #endif if (resource == NULL) @@ -3674,7 +3784,7 @@ xmlGetExternalEntityLoader(void) { xmlParserInputPtr xmlLoadExternalEntity(const char *URL, const char *ID, xmlParserCtxtPtr ctxt) { - if ((URL != NULL) && (xmlSysIDExists(URL) == 0)) { + if ((URL != NULL) && (xmlNoNetExists(URL) == 0)) { char *canonicFilename; xmlParserInputPtr ret; @@ -3697,40 +3807,6 @@ xmlLoadExternalEntity(const char *URL, const char *ID, * * ************************************************************************/ -#ifdef LIBXML_CATALOG_ENABLED -static int -xmlNoNetExists(const char *URL) -{ -#ifdef HAVE_STAT - int ret; - struct stat info; - const char *path; - - if (URL == NULL) - return (0); - - if (!xmlStrncasecmp(BAD_CAST URL, BAD_CAST "file://localhost/", 17)) -#if defined (_WIN32) || defined (__DJGPP__) && !defined(__CYGWIN__) - path = &URL[17]; -#else - path = &URL[16]; -#endif - else if (!xmlStrncasecmp(BAD_CAST URL, BAD_CAST "file:///", 8)) { -#if defined (_WIN32) || defined (__DJGPP__) && !defined(__CYGWIN__) - path = &URL[8]; -#else - path = &URL[7]; -#endif - } else - path = URL; - ret = stat(path, &info); - if (ret == 0) - return (1); -#endif - return (0); -} -#endif - /** * xmlNoNetExternalEntityLoader: * @URL: the URL for the entity to load @@ -3749,61 +3825,9 @@ xmlNoNetExternalEntityLoader(const char *URL, const char *ID, xmlChar *resource = NULL; #ifdef LIBXML_CATALOG_ENABLED - xmlCatalogAllow pref; - - /* - * If the resource doesn't exists as a file, - * try to load it from the resource pointed in the catalogs - */ - pref = xmlCatalogGetDefaults(); - - if ((pref != XML_CATA_ALLOW_NONE) && (!xmlNoNetExists(URL))) { - /* - * Do a local lookup - */ - if ((ctxt != NULL) && (ctxt->catalogs != NULL) && - ((pref == XML_CATA_ALLOW_ALL) || - (pref == XML_CATA_ALLOW_DOCUMENT))) { - resource = xmlCatalogLocalResolve(ctxt->catalogs, - (const xmlChar *)ID, - (const xmlChar *)URL); - } - /* - * Try a global lookup - */ - if ((resource == NULL) && - ((pref == XML_CATA_ALLOW_ALL) || - (pref == XML_CATA_ALLOW_GLOBAL))) { - resource = xmlCatalogResolve((const xmlChar *)ID, - (const xmlChar *)URL); - } - if ((resource == NULL) && (URL != NULL)) - resource = xmlStrdup((const xmlChar *) URL); - - /* - * TODO: do an URI lookup on the reference - */ - if ((resource != NULL) && (!xmlNoNetExists((const char *)resource))) { - xmlChar *tmp = NULL; - - if ((ctxt != NULL) && (ctxt->catalogs != NULL) && - ((pref == XML_CATA_ALLOW_ALL) || - (pref == XML_CATA_ALLOW_DOCUMENT))) { - tmp = xmlCatalogLocalResolveURI(ctxt->catalogs, resource); - } - if ((tmp == NULL) && - ((pref == XML_CATA_ALLOW_ALL) || - (pref == XML_CATA_ALLOW_GLOBAL))) { - tmp = xmlCatalogResolveURI(resource); - } - - if (tmp != NULL) { - xmlFree(resource); - resource = tmp; - } - } - } + resource = xmlResolveResourceFromCatalog(URL, ID, ctxt); #endif + if (resource == NULL) resource = (xmlChar *) URL; |