mirror of
https://github.com/1dot13/source.git
synced 2026-07-22 13:40:22 +02:00
* Merged Source Code from Development Trunk: Revision 4063 * ************************************************************ - Source Code is merged from: https://81.169.133.124/source/ja2/branches/Wanne/JA2%201.13%20MP - This will be the Source for the Beta 2011 Test git-svn-id: https://ja2svn.mooo.com/source/ja2/trunk/GameSource/ja2_v1.13/Build@4064 3b4a5df2-a311-0410-b5c6-a8a6f20db521
227 lines
5.9 KiB
C++
227 lines
5.9 KiB
C++
#include <vfs/Core/vfs_types.h>
|
|
#include <vfs/Core/vfs.h>
|
|
#include <vfs/Core/vfs_file_raii.h>
|
|
#include <vfs/Core/File/vfs_file.h>
|
|
|
|
#include <vfs/Tools/vfs_tools.h>
|
|
#include <vfs/Tools/vfs_property_container.h>
|
|
|
|
#include "XML_Parser.h"
|
|
#include "XMLWriter.h"
|
|
#include "Debug.h"
|
|
|
|
vfs::PropertyContainer::TagMap::TagMap()
|
|
{
|
|
// setup default map
|
|
_map[L"Container"] = L"Container";
|
|
_map[L"Section"] = L"Section";
|
|
_map[L"SectionID"] = L"name";
|
|
_map[L"Key"] = L"Key";
|
|
_map[L"KeyID"] = L"name";
|
|
}
|
|
vfs::String const& vfs::PropertyContainer::TagMap::container(vfs::String::char_t* container)
|
|
{
|
|
if(container)
|
|
{
|
|
_map[L"Container"] = container;
|
|
}
|
|
return _map[L"Container"];
|
|
}
|
|
vfs::String const& vfs::PropertyContainer::TagMap::section(vfs::String::char_t* section)
|
|
{
|
|
if(section)
|
|
{
|
|
_map[L"Section"] = section;
|
|
}
|
|
return _map[L"Section"];
|
|
}
|
|
vfs::String const& vfs::PropertyContainer::TagMap::sectionID(vfs::String::char_t* section_id)
|
|
{
|
|
if(section_id)
|
|
{
|
|
_map[L"SectionID"] = section_id;
|
|
}
|
|
return _map[L"SectionID"];
|
|
}
|
|
vfs::String const& vfs::PropertyContainer::TagMap::key(vfs::String::char_t* key)
|
|
{
|
|
if(key)
|
|
{
|
|
_map[L"Key"] = key;
|
|
}
|
|
return _map[L"Key"];
|
|
}
|
|
vfs::String const& vfs::PropertyContainer::TagMap::keyID(vfs::String::char_t* key_id)
|
|
{
|
|
if(key_id)
|
|
{
|
|
_map[L"KeyID"] = key_id;
|
|
}
|
|
return _map[L"KeyID"];
|
|
}
|
|
|
|
bool vfs::PropertyContainer::writeToXMLFile(vfs::Path const& sFileName, vfs::PropertyContainer::TagMap& tagmap)
|
|
{
|
|
XMLWriter xmlw;
|
|
|
|
xmlw.openNode(tagmap.container());
|
|
|
|
tSections::iterator sit = m_mapProps.begin();
|
|
for(; sit != m_mapProps.end(); ++sit)
|
|
{
|
|
xmlw.addAttributeToNextValue(tagmap.sectionID(),sit->first.utf8());
|
|
xmlw.openNode(tagmap.section());
|
|
|
|
vfs::PropertyContainer::Section& section = sit->second;
|
|
vfs::PropertyContainer::Section::tProps::iterator kit = section.mapProps.begin();
|
|
for(; kit != section.mapProps.end(); ++kit)
|
|
{
|
|
xmlw.addAttributeToNextValue(tagmap.keyID(), kit->first.utf8());
|
|
xmlw.addValue(tagmap.key(), kit->second.utf8());
|
|
}
|
|
|
|
xmlw.closeNode();
|
|
|
|
}
|
|
|
|
xmlw.closeNode();
|
|
|
|
return xmlw.writeToFile(sFileName);
|
|
}
|
|
|
|
/*********************************************************************************/
|
|
/*********************************************************************************/
|
|
|
|
class CPropertyXMLParser : public IXMLParser
|
|
{
|
|
enum DOM_OBJECT
|
|
{
|
|
DO_ELEMENT_Container,
|
|
DO_ELEMENT_Section,
|
|
DO_ELEMENT_Key,
|
|
DO_ELEMENT_NONE,
|
|
};
|
|
public:
|
|
CPropertyXMLParser(
|
|
vfs::PropertyContainer& container,
|
|
vfs::PropertyContainer::TagMap& tagmap,
|
|
XML_Parser &parser,
|
|
IXMLParser* caller = NULL)
|
|
: IXMLParser("",&parser,caller),
|
|
_container(container),
|
|
_tagmap(tagmap),
|
|
current_state(DO_ELEMENT_NONE) // doesn't matter where we come from, we start fresh
|
|
{};
|
|
virtual void onStartElement(const XML_Char* name, const XML_Char** atts);
|
|
virtual void onEndElement(const XML_Char* name);
|
|
virtual void onTextElement(const XML_Char *str, int len);
|
|
private:
|
|
vfs::PropertyContainer& _container;
|
|
vfs::PropertyContainer::TagMap& _tagmap;
|
|
DOM_OBJECT current_state;
|
|
vfs::String current_section;
|
|
vfs::String current_key;
|
|
};
|
|
|
|
|
|
void CPropertyXMLParser::onStartElement(const XML_Char *name, const XML_Char **atts)
|
|
{
|
|
vfs::String utf8_name(name);
|
|
if(current_state == DO_ELEMENT_NONE && vfs::StrCmp::Equal(utf8_name,_tagmap.container()))
|
|
{
|
|
current_state = DO_ELEMENT_Container;
|
|
}
|
|
else if(current_state == DO_ELEMENT_Container && vfs::StrCmp::Equal(utf8_name, _tagmap.section()))
|
|
{
|
|
current_state = DO_ELEMENT_Section;
|
|
current_section = this->getAttribute(_tagmap.sectionID().utf8().c_str(),atts);
|
|
}
|
|
else if(current_state == DO_ELEMENT_Section && vfs::StrCmp::Equal(utf8_name, _tagmap.key()))
|
|
{
|
|
current_state = DO_ELEMENT_Key;
|
|
current_key = this->getAttribute(_tagmap.keyID().utf8().c_str(),atts);
|
|
}
|
|
sCharData = "";
|
|
}
|
|
|
|
void CPropertyXMLParser::onEndElement(const XML_Char* name)
|
|
{
|
|
vfs::String utf8_name(name);
|
|
if(current_state == DO_ELEMENT_Key && vfs::StrCmp::Equal(utf8_name, _tagmap.key()))
|
|
{
|
|
_container.setStringProperty(current_section, current_key, vfs::trimString(sCharData,0,sCharData.length()));
|
|
current_state = DO_ELEMENT_Section;
|
|
}
|
|
else if(current_state == DO_ELEMENT_Section && vfs::StrCmp::Equal(utf8_name, _tagmap.section()))
|
|
{
|
|
current_state = DO_ELEMENT_Container;
|
|
}
|
|
else if(current_state == DO_ELEMENT_Container && vfs::StrCmp::Equal(utf8_name, _tagmap.container()))
|
|
{
|
|
current_state = DO_ELEMENT_NONE;
|
|
}
|
|
}
|
|
|
|
void CPropertyXMLParser::onTextElement(const XML_Char *str, int len)
|
|
{
|
|
if(current_state == DO_ELEMENT_Key)
|
|
{
|
|
sCharData.append(str,len);
|
|
}
|
|
}
|
|
|
|
bool vfs::PropertyContainer::initFromXMLFile(vfs::Path const& sFileName, vfs::PropertyContainer::TagMap& tagmap)
|
|
{
|
|
vfs::tReadableFile *file = NULL;
|
|
bool delete_file = false;
|
|
if(getVFS()->fileExists(sFileName))
|
|
{
|
|
vfs::COpenReadFile rfile(sFileName);
|
|
file = &rfile.file();
|
|
rfile.release();
|
|
}
|
|
else
|
|
{
|
|
vfs::CFile* rfile = new vfs::CFile(sFileName);
|
|
delete_file = true;
|
|
file = vfs::tReadableFile::cast(rfile);
|
|
if(!file->openRead())
|
|
{
|
|
delete file;
|
|
return false;
|
|
}
|
|
}
|
|
if(!file)
|
|
{
|
|
return false;
|
|
}
|
|
|
|
vfs::size_t size = file->getSize();
|
|
|
|
std::vector<vfs::Byte> buffer(size+1);
|
|
|
|
SGP_TRYCATCH_RETHROW( file->read(&buffer[0],size), L"" );
|
|
buffer[size] = 0;
|
|
|
|
file->close();
|
|
if(delete_file) delete file;
|
|
|
|
XML_Parser parser = XML_ParserCreate(NULL);
|
|
|
|
CPropertyXMLParser pp(*this,tagmap,parser,NULL);
|
|
pp.grabParser();
|
|
|
|
if(!XML_Parse(parser, &buffer[0], size, TRUE))
|
|
{
|
|
std::wstringstream wss;
|
|
wss << L"XML Parser Error in Groups.xml: "
|
|
<< vfs::String::as_utf16(XML_ErrorString(XML_GetErrorCode(parser)))
|
|
<< L" at line "
|
|
<< XML_GetCurrentLineNumber(parser);
|
|
SGP_THROW(wss.str().c_str());
|
|
//return false;
|
|
}
|
|
|
|
return true;
|
|
}
|