2004-06-03 15:00:19 +02:00
|
|
|
#include "XML.h"
|
|
|
|
#include "CStr.h"
|
2004-06-03 19:34:49 +02:00
|
|
|
#include "CLogger.h"
|
2004-06-03 15:00:19 +02:00
|
|
|
|
|
|
|
#include "res/vfs.h"
|
|
|
|
|
|
|
|
XERCES_CPP_NAMESPACE_USE
|
|
|
|
|
|
|
|
CStr XMLTranscode(const XMLCh* xmltext)
|
|
|
|
{
|
|
|
|
char* str=XMLString::transcode((const XMLCh *)xmltext);
|
|
|
|
CStr result(str);
|
|
|
|
XMLString::release(&str);
|
|
|
|
return result;
|
|
|
|
}
|
|
|
|
|
|
|
|
XMLCh *XMLTranscode(const CStr &str)
|
|
|
|
{
|
|
|
|
const char *cstr=(const char *)str;
|
|
|
|
return XMLString::transcode(cstr);
|
|
|
|
}
|
|
|
|
|
|
|
|
int CVFSInputSource::OpenFile(const char *path)
|
|
|
|
{
|
|
|
|
debug_out("CVFSInputSource::OpenFile(): opening file %s.\n", path);
|
|
|
|
|
|
|
|
m_hFile=vfs_open(path);
|
2004-06-03 19:34:49 +02:00
|
|
|
if (m_hFile <= 0)
|
|
|
|
{
|
|
|
|
LOG(ERROR, "CVFSInputSource: file %s couldn't be opened (vfs_open)\n", path);
|
|
|
|
return -1;
|
|
|
|
}
|
2004-06-03 15:00:19 +02:00
|
|
|
|
2004-06-03 19:34:49 +02:00
|
|
|
int err;
|
|
|
|
if ((err=vfs_map(m_hFile, 0, m_pBuffer, m_BufferSize)) != 0)
|
2004-06-03 15:00:19 +02:00
|
|
|
{
|
2004-06-03 19:34:49 +02:00
|
|
|
LOG(ERROR, "CVFSInputSource: file %s couldn't be opened (vfs_map: %d)\n", path, err);
|
2004-06-03 15:00:19 +02:00
|
|
|
vfs_close(m_hFile);
|
|
|
|
m_hFile=0;
|
|
|
|
return -1;
|
|
|
|
}
|
|
|
|
|
|
|
|
XMLCh *sysId=XMLString::transcode(path);
|
|
|
|
setSystemId(sysId);
|
|
|
|
XMLString::release(&sysId);
|
|
|
|
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
CVFSInputSource::~CVFSInputSource()
|
|
|
|
{
|
|
|
|
if (m_hFile > 0)
|
|
|
|
{
|
|
|
|
vfs_unmap(m_hFile);
|
|
|
|
vfs_close(m_hFile);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
BinInputStream *CVFSInputSource::makeStream() const
|
|
|
|
{
|
|
|
|
if (m_hFile > 0)
|
|
|
|
{
|
|
|
|
return new BinMemInputStream((XMLByte *)m_pBuffer, m_BufferSize,
|
|
|
|
BinMemInputStream::BufOpt_Reference);
|
|
|
|
}
|
|
|
|
else
|
|
|
|
return NULL;
|
|
|
|
}
|
|
|
|
|
|
|
|
InputSource *CVFSEntityResolver::resolveEntity(const XMLCh *const publicId,
|
|
|
|
const XMLCh *const systemId)
|
|
|
|
{
|
|
|
|
CVFSInputSource *ret=new CVFSInputSource();
|
|
|
|
char *path=XMLString::transcode(systemId);
|
|
|
|
char *orgpath=path;
|
|
|
|
|
2004-06-03 19:34:49 +02:00
|
|
|
CStr abspath=m_DocName;
|
|
|
|
const char *end=m_DocName+abspath.Length();
|
|
|
|
if (strncmp(path, "..", 2) == 0 && (path[2] == '/' || path[2] == '\\'))
|
2004-06-03 15:00:19 +02:00
|
|
|
{
|
|
|
|
do
|
|
|
|
--end;
|
2004-06-03 19:34:49 +02:00
|
|
|
while (end > m_DocName && (*end != '/' && *end != '\\'));
|
2004-06-03 15:00:19 +02:00
|
|
|
|
2004-06-03 19:34:49 +02:00
|
|
|
while (strncmp(path, "..", 2) == 0 && (path[2] == '/' || path[2] == '\\'))
|
2004-06-03 15:00:19 +02:00
|
|
|
{
|
|
|
|
path += 3;
|
|
|
|
|
|
|
|
do
|
|
|
|
--end;
|
2004-06-03 19:34:49 +02:00
|
|
|
while (end > m_DocName && (*end != '/' && *end != '\\'));
|
2004-06-03 15:00:19 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
--path;
|
2004-06-03 19:34:49 +02:00
|
|
|
|
|
|
|
abspath=abspath.Left(end-m_DocName)+path;
|
|
|
|
|
|
|
|
int pos=0;
|
|
|
|
if (abspath.Find('\\') != -1)
|
|
|
|
{
|
|
|
|
LOG(WARNING, "While resolving XML entities for %s: path %s [%s] contains non-portable path separator \\", m_DocName, orgpath, abspath.c_str());
|
|
|
|
abspath.Replace("\\", "/");
|
|
|
|
}
|
2004-06-03 15:00:19 +02:00
|
|
|
}
|
|
|
|
|
2004-06-03 19:34:49 +02:00
|
|
|
if ((orgpath != path && ret->OpenFile(abspath)!=0)
|
2004-06-03 15:00:19 +02:00
|
|
|
|| (orgpath == path && ret->OpenFile(path)!=0))
|
|
|
|
{
|
|
|
|
delete ret;
|
|
|
|
ret=NULL;
|
|
|
|
}
|
|
|
|
|
|
|
|
success:
|
|
|
|
XMLString::release(&orgpath);
|
|
|
|
return ret;
|
|
|
|
}
|