forked from 0ad/0ad
Conventience functions and VFS Wrappers for Xerces
This was SVN commit r380.
This commit is contained in:
parent
d32be2011f
commit
d759a8ef82
85
source/ps/XML.h
Executable file
85
source/ps/XML.h
Executable 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
102
source/ps/XMLUtils.cpp
Executable 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;
|
||||
}
|
Loading…
Reference in New Issue
Block a user