summaryrefslogtreecommitdiff
path: root/library/VersionInfoFactory.cpp
diff options
context:
space:
mode:
authorPetr Mrázek2010-08-23 01:29:55 +0200
committerPetr Mrázek2010-08-23 01:29:55 +0200
commit368de864a1723df3ece4c58968036e76c8035e97 (patch)
tree0899557e0b4c1fedd9cbdbd291705751be9f0960 /library/VersionInfoFactory.cpp
parent1bceac23433fa097e4b5d43aa3eb1999a370872f (diff)
downloaddfhack-368de864a1723df3ece4c58968036e76c8035e97.tar.gz
dfhack-368de864a1723df3ece4c58968036e76c8035e97.tar.bz2
dfhack-368de864a1723df3ece4c58968036e76c8035e97.tar.xz
Sync
Diffstat (limited to 'library/VersionInfoFactory.cpp')
-rw-r--r--library/VersionInfoFactory.cpp363
1 files changed, 276 insertions, 87 deletions
diff --git a/library/VersionInfoFactory.cpp b/library/VersionInfoFactory.cpp
index 6f2e6a32..002b9ae4 100644
--- a/library/VersionInfoFactory.cpp
+++ b/library/VersionInfoFactory.cpp
@@ -32,18 +32,19 @@ using namespace DFHack;
VersionInfoFactory::~VersionInfoFactory()
{
- // for each in std::vector<memory_info*> meminfo;, delete
- for(uint32_t i = 0; i < meminfo.size();i++)
+ // for each stored version, delete
+ for(uint32_t i = 0; i < versions.size();i++)
{
- delete meminfo[i];
+ delete versions[i];
}
- meminfo.clear();
+ versions.clear();
}
void VersionInfoFactory::ParseVTable(TiXmlElement* vtable, VersionInfo* mem)
{
TiXmlElement* pClassEntry;
TiXmlElement* pClassSubEntry;
+ /*
// check for rebase, do rebase if check positive
const char * rebase = vtable->Attribute("rebase");
if(rebase)
@@ -51,6 +52,7 @@ void VersionInfoFactory::ParseVTable(TiXmlElement* vtable, VersionInfo* mem)
int32_t rebase_offset = strtol(rebase, NULL, 16);
mem->RebaseVTable(rebase_offset);
}
+ */
// parse vtable entries
pClassEntry = vtable->FirstChildElement();
for(;pClassEntry;pClassEntry=pClassEntry->NextSiblingElement())
@@ -92,26 +94,214 @@ void VersionInfoFactory::ParseVTable(TiXmlElement* vtable, VersionInfo* mem)
}
}
-void VersionInfoFactory::ParseEntry (TiXmlElement* entry, VersionInfo* mem, map <string ,TiXmlElement *>& knownEntries)
+void VersionInfoFactory::ParseBase (TiXmlElement* entry, VersionInfo* mem)
+{
+ TiXmlElement* pElement;
+ TiXmlElement* pElement2nd;
+ const char *cstr_version = entry->Attribute("name");
+
+ if (!cstr_version)
+ throw Error::MemoryXmlBadAttribute("name");
+
+ mem->setVersion(cstr_version);
+ mem->setOS(VersionInfo::OS_BAD);
+
+ // process additional entries
+ pElement = entry->FirstChildElement()->ToElement();
+ for(;pElement;pElement=pElement->NextSiblingElement())
+ {
+ // only elements get processed
+ const char *cstr_type = pElement->Value();
+ std::string type = cstr_type;
+ if(type == "VTable")
+ {
+ ParseVTable(pElement, mem);
+ continue;
+ }
+ else if(type == "Offsets")
+ {
+ // we don't care about the descriptions here, do nothing
+ //ParseBaseOffsets(pMemEntry, mem);
+ continue;
+ }
+ else if (type == "Professions")
+ {
+ pElement2nd = entry->FirstChildElement("Profession")->ToElement();
+ for(;pElement2nd;pElement2nd=pElement2nd->NextSiblingElement("Profession"))
+ {
+ const char * id = pElement2nd->Attribute("id");
+ const char * name = pElement2nd->Attribute("name");
+ // FIXME: missing some attributes here
+ if(id && name)
+ {
+ mem->setProfession(id,name);
+ }
+ else
+ {
+ // FIXME: this is crap, doesn't tell anything about the error
+ throw Error::MemoryXmlUnderspecifiedEntry(name);
+ }
+ }
+ }
+ else if (type == "Jobs")
+ {
+ pElement2nd = entry->FirstChildElement("Job")->ToElement();
+ for(;pElement2nd;pElement2nd=pElement2nd->NextSiblingElement("Job"))
+ {
+ const char * id = pElement2nd->Attribute("id");
+ const char * name = pElement2nd->Attribute("name");
+ if(id && name)
+ {
+ mem->setJob(id,name);
+ }
+ else
+ {
+ // FIXME: this is crap, doesn't tell anything about the error
+ throw Error::MemoryXmlUnderspecifiedEntry(name);
+ }
+ }
+ }
+ else if (type == "Skills")
+ {
+ pElement2nd = entry->FirstChildElement("Skill")->ToElement();
+ for(;pElement2nd;pElement2nd=pElement2nd->NextSiblingElement("Skill"))
+ {
+ const char * id = pElement2nd->Attribute("id");
+ const char * name = pElement2nd->Attribute("name");
+ if(id && name)
+ {
+ mem->setSkill(id,name);
+ }
+ else
+ {
+ // FIXME: this is crap, doesn't tell anything about the error
+ throw Error::MemoryXmlUnderspecifiedEntry(name);
+ }
+ }
+ }
+ else if (type == "Traits")
+ {
+ pElement2nd = entry->FirstChildElement("Trait")->ToElement();
+ for(;pElement2nd;pElement2nd=pElement2nd->NextSiblingElement("Trait"))
+ {
+ const char * id = pElement2nd->Attribute("id");
+ const char * name = pElement2nd->Attribute("name");
+ const char * lvl0 = pElement->Attribute("level_0");
+ const char * lvl1 = pElement->Attribute("level_1");
+ const char * lvl2 = pElement->Attribute("level_2");
+ const char * lvl3 = pElement->Attribute("level_3");
+ const char * lvl4 = pElement->Attribute("level_4");
+ const char * lvl5 = pElement->Attribute("level_5");
+ if(id && name && lvl0 && lvl1 && lvl2 && lvl3 && lvl4 && lvl5)
+ {
+ mem->setTrait(id, name, lvl0, lvl1, lvl2, lvl3, lvl4, lvl5);
+ }
+ else
+ {
+ // FIXME: this is crap, doesn't tell anything about the error
+ throw Error::MemoryXmlUnderspecifiedEntry(name);
+ }
+ }
+ }
+ else if (type == "Labors")
+ {
+ pElement2nd = entry->FirstChildElement("Labor")->ToElement();
+ for(;pElement2nd;pElement2nd=pElement2nd->NextSiblingElement("Labor"))
+ {
+ const char * id = pElement2nd->Attribute("id");
+ const char * name = pElement2nd->Attribute("name");
+ if(id && name)
+ {
+ mem->setLabor(id,name);
+ }
+ else
+ {
+ // FIXME: this is crap, doesn't tell anything about the error
+ throw Error::MemoryXmlUnderspecifiedEntry(name);
+ }
+ }
+ }
+ else if (type == "Levels")
+ {
+ pElement2nd = entry->FirstChildElement("Level")->ToElement();
+ for(;pElement2nd;pElement2nd=pElement2nd->NextSiblingElement("Level"))
+ {
+ const char * id = pElement2nd->Attribute("id");
+ const char * name = pElement2nd->Attribute("name");
+ const char * nextlvl = pElement2nd->Attribute("xpNxtLvl");
+ if(id && name && nextlvl)
+ {
+ mem->setLevel(id, name, nextlvl);
+ }
+ else
+ {
+ // FIXME: this is crap, doesn't tell anything about the error
+ throw Error::MemoryXmlUnderspecifiedEntry(name);
+ }
+ }
+ }
+ else if (type == "Moods")
+ {
+ pElement2nd = entry->FirstChildElement("Mood")->ToElement();
+ for(;pElement2nd;pElement2nd=pElement2nd->NextSiblingElement("Mood"))
+ {
+ const char * id = pElement2nd->Attribute("id");
+ const char * name = pElement2nd->Attribute("name");
+ if(id && name)
+ {
+ mem->setMood(id, name);
+ }
+ else
+ {
+ // FIXME: this is crap, doesn't tell anything about the error
+ throw Error::MemoryXmlUnderspecifiedEntry(name);
+ }
+ }
+ }
+ else
+ {
+ //FIXME: only log, not hard error
+ //throw Error::MemoryXmlUnknownType(type.c_str());
+ }
+ } // for
+} // method
+
+void VersionInfoFactory::EvalVersion(string base, VersionInfo * mem)
+{
+ if(knownVersions.find(base) != knownVersions.end())
+ {
+ v_descr & desc = knownVersions[base];
+ if (!desc.second)
+ {
+ VersionInfo * newmem = new VersionInfo();
+ ParseVersion(desc.first, newmem);
+ desc.second = newmem;
+ versions.push_back(newmem);
+ }
+ mem->copy(desc.second);
+ }
+}
+
+void VersionInfoFactory::ParseVersion (TiXmlElement* entry, VersionInfo* mem)
{
TiXmlElement* pMemEntry;
- const char *cstr_version = entry->Attribute("version");
+ const char *cstr_name = entry->Attribute("name");
const char *cstr_os = entry->Attribute("os");
const char *cstr_base = entry->Attribute("base");
const char *cstr_rebase = entry->Attribute("rebase");
if(cstr_base)
{
string base = cstr_base;
- ParseEntry(knownEntries[base], mem, knownEntries);
+ EvalVersion(base, mem);
}
- if (!cstr_version)
- throw Error::MemoryXmlBadAttribute("version");
+ if (!cstr_name)
+ throw Error::MemoryXmlBadAttribute("name");
if (!cstr_os)
throw Error::MemoryXmlBadAttribute("os");
string os = cstr_os;
- mem->setVersion(cstr_version);
+ mem->setVersion(cstr_name);
mem->setOS(cstr_os);
// offset inherited addresses by 'rebase'.
@@ -134,10 +324,6 @@ void VersionInfoFactory::ParseEntry (TiXmlElement* entry, VersionInfo* mem, map
// users are free to use a sane kernel that doesn't do this kind of **** by default
mem->setBase(0x0);
}
- else if ( os == "all")
- {
- // yay
- }
else
{
throw Error::MemoryXmlBadAttribute("os");
@@ -148,75 +334,55 @@ void VersionInfoFactory::ParseEntry (TiXmlElement* entry, VersionInfo* mem, map
pMemEntry = entry->FirstChildElement()->ToElement();
for(;pMemEntry;pMemEntry=pMemEntry->NextSiblingElement())
{
- // only elements get processed
- const char *cstr_type = pMemEntry->Value();
- const char *cstr_name = pMemEntry->Attribute("name");
- const char *cstr_value = pMemEntry->GetText();
-
- if(!cstr_value)
- cstr_value = pMemEntry->Attribute("id");
-
- // check for missing parts
string type, name, value;
+ const char *cstr_type = pMemEntry->Value();
type = cstr_type;
+ // check for missing parts
if(type == "VTable")
{
ParseVTable(pMemEntry, mem);
continue;
}
- if(!(cstr_name && cstr_value))
- {
- throw Error::MemoryXmlUnderspecifiedEntry(cstr_version);
- }
- name = cstr_name;
- value = cstr_value;
- if (type == "HexValue")
- {
- mem->setHexValue(name, value);
- }
- else if (type == "Address")
- {
- mem->setAddress(name, value);
- }
- else if (type == "Offset")
- {
- mem->setOffset(name, value);
- }
- else if (type == "String")
- {
- mem->setString(name, value);
- }
- else if (type == "Profession")
- {
- mem->setProfession(value,name);
- }
- else if (type == "Job")
- {
- mem->setJob(value,name);
- }
- else if (type == "Skill")
- {
- mem->setSkill(value,name);
- }
- else if (type == "Trait")
+ else if(type == "Offsets")
{
- mem->setTrait(value, name,pMemEntry->Attribute("level_0"),pMemEntry->Attribute("level_1"),pMemEntry->Attribute("level_2"),pMemEntry->Attribute("level_3"),pMemEntry->Attribute("level_4"),pMemEntry->Attribute("level_5"));
- }
- else if (type == "Labor")
- {
- mem->setLabor(value,name);
- }
- else if (type == "Level")
- {
- mem->setLevel(value, name, pMemEntry->Attribute("xpNxtLvl"));
+ /*
+ if (type == "HexValue")
+ {
+ mem->setHexValue(name, value);
+ }
+ else if (type == "Address")
+ {
+ mem->setAddress(name, value);
+ }
+ else if (type == "Offset")
+ {
+ mem->setOffset(name, value);
+ }
+ else if (type == "String")
+ {
+ mem->setString(name, value);
+ }
+ else
+ {
+ throw Error::MemoryXmlUnknownType(type.c_str());
+ }
+ */
+ //ParseOffsets(pMemEntry, mem);
+ continue;
}
- else if (type == "Mood")
+ else if (type == "MD5")
{
- mem->setMood(value, name);
+ const char *cstr_value = pMemEntry->Attribute("value");
+ if(!cstr_value)
+ throw Error::MemoryXmlUnderspecifiedEntry(cstr_name);
+ mem->setMD5(cstr_value);
}
- else
+ else if (type == "PETimeStamp")
{
- throw Error::MemoryXmlUnknownType(type.c_str());
+ const char *cstr_value = pMemEntry->Attribute("value");
+ if(!cstr_value)
+ throw Error::MemoryXmlUnderspecifiedEntry(cstr_name);
+ mem->setPE(atol(cstr_value));
}
} // for
} // method
@@ -240,7 +406,7 @@ bool VersionInfoFactory::loadFile(string path_to_xml)
TiXmlHandle hDoc(&doc);
TiXmlElement* pElem;
TiXmlHandle hRoot(0);
- VersionInfo mem;
+ VersionInfo *mem;
// block: name
{
@@ -263,31 +429,54 @@ bool VersionInfoFactory::loadFile(string path_to_xml)
// transform elements
{
// trash existing list
- for(uint32_t i = 0; i < meminfo.size(); i++)
+ for(uint32_t i = 0; i < versions.size(); i++)
{
- delete meminfo[i];
+ delete versions[i];
}
- meminfo.clear();
- TiXmlElement* pMemInfo=hRoot.FirstChild( "MemoryDescriptors" ).FirstChild( "Entry" ).Element();
+ versions.clear();
+
+ // For each base version
+ TiXmlElement* pMemInfo=hRoot.FirstChild( "Base" ).Element();
map <string ,TiXmlElement *> map_pNamedEntries;
- vector <TiXmlElement *> v_pEntries;
- for( ; pMemInfo; pMemInfo=pMemInfo->NextSiblingElement("Entry"))
+ vector <string> v_sEntries;
+ for( ; pMemInfo; pMemInfo=pMemInfo->NextSiblingElement("Base"))
{
- v_pEntries.push_back(pMemInfo);
- const char *id = pMemInfo->Attribute("id");
- if(id)
+ const char *name = pMemInfo->Attribute("name");
+ if(name)
{
- string str_id = id;
- map_pNamedEntries[str_id] = pMemInfo;
+ string str_name = name;
+ VersionInfo *base = new VersionInfo();
+ ParseBase( pMemInfo , mem );
+ knownVersions[str_name] = v_descr (pMemInfo, mem);
}
}
- for(uint32_t i = 0; i< v_pEntries.size();i++)
+
+ // For each derivative version
+ pMemInfo=hRoot.FirstChild( "Version" ).Element();
+ for( ; pMemInfo; pMemInfo=pMemInfo->NextSiblingElement("Version"))
+ {
+ const char *name = pMemInfo->Attribute("name");
+ if(name)
+ {
+ string str_name = name;
+ knownVersions[str_name] = v_descr (pMemInfo, NULL);
+ v_sEntries.push_back(str_name);
+ }
+ }
+ // Parse the versions
+ for(uint32_t i = 0; i< v_sEntries.size();i++)
{
- VersionInfo *mem = new VersionInfo();
//FIXME: add a set of entries processed in a step of this cycle, use it to check for infinite loops
- /* recursive */ParseEntry( v_pEntries[i] , mem , map_pNamedEntries);
- meminfo.push_back(mem);
+ string & name = v_sEntries[i];
+ v_descr & desc = knownVersions[name];
+ if(!desc.second)
+ {
+ VersionInfo *version = new VersionInfo();
+ ParseVersion( desc.first , version );
+ versions.push_back(version);
+ }
}
+
// process found things here
}
error = false;