Conventience functions and VFS Wrappers for Xerces

This was SVN commit r380.
This commit is contained in:
Simon Brenner 2004-06-03 13:00:19 +00:00
parent d32be2011f
commit d759a8ef82
2 changed files with 187 additions and 0 deletions

85
source/ps/XML.h Executable file
View File

@ -0,0 +1,85 @@
/*
XMLUtils.h - Xerces wrappers & convenience functions
AUTHOR : Simon Brenner <simon@wildfiregames.com>, <simon.brenner@home.se>
EXAMPLE :
Simple usage:
CVFSEntityResolver *entRes=new CVFSEntityResolver(filename);
parser->setEntityResolver(entRes);
CVFSInputSource src;
if (src.OpenFile("this/is/a/vfs/path.xml")==0)
parser->parse(src);
delete entRes;
The input source object should be kept alive as long as the parser is
using its input stream (i.e. until the parse is complete). The same
goes for the entity resolver.
*/
#ifndef _XercesVFS_H
#define _XercesVFS_H
#include <xercesc/dom/DOM.hpp>
#include <xercesc/parsers/XercesDOMParser.hpp>
#include <xercesc/util/XMLString.hpp>
#include <xercesc/util/PlatformUtils.hpp>
#include <xercesc/sax/InputSource.hpp>
#include <xercesc/sax/EntityResolver.hpp>
#include <xercesc/util/BinMemInputStream.hpp>
#include "res/h_mgr.h"
#include "lib.h"
#include "XercesErrorHandler.h"
#include "CStr.h"
XERCES_CPP_NAMESPACE_USE
CStr XMLTranscode(const XMLCh *);
XMLCh *XMLTranscode(const CStr &);
/*
CLASS : CVFSInputSource
DESCRIPTION :
Use instead of LocalFileInputSource to read XML files from VFS
*/
class CVFSInputSource: public InputSource
{
Handle m_hFile;
void *m_pBuffer;
size_t m_BufferSize;
public:
CVFSInputSource():
m_hFile(0),
m_pBuffer(NULL),
m_BufferSize(0)
{}
~CVFSInputSource();
// Open a VFS path for XML parsing
// returns 0 if successful, -1 on failure
int OpenFile(const char *path);
virtual BinInputStream *makeStream() const;
};
class CVFSEntityResolver: public EntityResolver
{
const char *m_DocName;
public:
virtual InputSource *resolveEntity(
const XMLCh *const publicId,
const XMLCh *const systemId);
inline CVFSEntityResolver(const char *docName):
m_DocName(docName)
{}
};
#endif // _XercesVFS_H

102
source/ps/XMLUtils.cpp Executable file
View File

@ -0,0 +1,102 @@
#include "XML.h"
#include "CStr.h"
#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);
if (m_hFile <= 0) return -1;
if (vfs_map(m_hFile, 0, m_pBuffer, m_BufferSize) != 0)
{
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;
CStr base=m_DocName;
const char *end=m_DocName+base.Length();
if (strncmp(path, "../", 3) == 0)
{
do
--end;
while (end > m_DocName && *end != '/');
while (strncmp(path, "../", 3) == 0)
{
path += 3;
do
--end;
while (end > m_DocName && *end != '/');
}
--path;
}
if (
(orgpath != path &&
ret->OpenFile((base.Left(end-m_DocName)+path).c_str())!=0)
|| (orgpath == path && ret->OpenFile(path)!=0))
{
delete ret;
ret=NULL;
}
success:
XMLString::release(&orgpath);
return ret;
}