Added: #1440 Extended parser for ClassDirectory3

--HG--
branch : build_pipeline_v3
hg/feature/build_pipeline_v3
kaetemi 12 years ago
parent 2042692ad1
commit 6fc37e7338

@ -95,7 +95,7 @@ protected:
* \brief CClassDataHeader
* \date 2012-08-18 18:01GMT
* \author Jan Boon (Kaetemi)
* CClassDirectoryHeader
* CClassDataHeader
*/
class CClassDataHeader : public IStorageObject
{

@ -29,6 +29,7 @@
#include "class_directory_3.h"
// STL includes
#include <iomanip>
// NeL includes
// #include <nel/misc/debug.h>
@ -50,9 +51,23 @@ CClassDirectory3::CClassDirectory3()
}
// Parallel to CDllDirectory
CClassDirectory3::~CClassDirectory3()
{
// Delete m_ChunkCache and m_Entries when !ChunksOwnsPointers
if (!ChunksOwnsPointers)
{
for (TStorageObjectContainer::iterator it = m_ChunkCache.begin(), end = m_ChunkCache.end(); it != end; ++it)
{
delete it->second;
}
for (std::vector<CClassEntry *>::iterator subit = m_Entries.begin(), subend = m_Entries.end(); subit != subend; ++subit)
{
delete (*subit);
}
}
m_ChunkCache.clear();
m_Entries.clear();
}
std::string CClassDirectory3::getClassName()
@ -60,29 +75,162 @@ std::string CClassDirectory3::getClassName()
return "ClassDirectory3";
}
// Parallel to CDllDirectory
void CClassDirectory3::toString(std::ostream &ostream, const std::string &pad)
{
CStorageContainer::toString(ostream, pad);
if (ChunksOwnsPointers)
{
CStorageContainer::toString(ostream, pad);
}
else
{
ostream << "(" << getClassName() << ") [" << Chunks.size() << "] PARSED { ";
std::string padpad = pad + "\t";
sint i = 0;
for (TStorageObjectContainer::const_iterator it = m_ChunkCache.begin(), end = m_ChunkCache.end(); it != end; ++it)
{
uint16 id = it->first;
switch (id)
{
case 0x2040: // ClassEntry
{
uint subi = 0;
for (std::vector<CClassEntry *>::iterator subit = m_Entries.begin(), subend = m_Entries.end(); subit != subend; ++subit)
{
ostream << "\n" << pad << "Entries[" << subi << "]: ";
(*subit)->toString(ostream, padpad);
++subi;
}
}
break;
default:
std::stringstream ss;
ss << std::hex << std::setfill('0');
ss << std::setw(4) << it->first;
ostream << "\n" << pad << "0x" << ss.str() << ": ";
it->second->toString(ostream, padpad);
++i;
break;
}
}
ostream << "} ";
}
}
// Parallel to CDllDirectory
void CClassDirectory3::parse(uint16 version, TParseLevel level)
{
CStorageContainer::parse(version, level);
if (level & PARSE_INTERNAL)
{
// Ensure not yet parsed
nlassert(m_ChunkCache.empty());
nlassert(m_Entries.empty());
// Parse entries first
CStorageContainer::parse(version, level);
// Initialize
uint16 lastCached = 0xFFFF;
bool parsedDllEntry = false;
// Parse chunks
for (TStorageObjectContainer::iterator it = Chunks.begin(), end = Chunks.end(); it != end; ++it)
{
uint16 id = it->first;
switch (id)
{
case 0x2040: // ClassEntry
if (parsedDllEntry && (lastCached != id))
throw EStorageParse(); // There were chunks inbetween
if (!parsedDllEntry)
{
m_ChunkCache.push_back(TStorageObjectWithId(id, NULL)); // Dummy entry to know the location
lastCached = id;
parsedDllEntry = true;
}
m_Entries.push_back(static_cast<CClassEntry *>(it->second));
break;
default:
m_ChunkCache.push_back(*it); // Dummy entry to know the location
lastCached = id;
break;
}
}
// Now ownership of the pointers lies in m_ChunkCache and m_Entries
ChunksOwnsPointers = false;
}
}
// Parallel to CDllDirectory
void CClassDirectory3::clean()
{
CStorageContainer::clean();
// Ensure parsed
nlassert(!ChunksOwnsPointers);
// Clear Chunks
Chunks.clear();
// Clean chunks
for (TStorageObjectContainer::iterator it = m_ChunkCache.begin(), end = m_ChunkCache.end(); it != end; ++it)
{
if (it->second != NULL && it->second->isContainer())
{
static_cast<CStorageContainer *>(it->second)->clean();
}
}
for (std::vector<CClassEntry *>::iterator subit = m_Entries.begin(), subend = m_Entries.end(); subit != subend; ++subit)
{
(*subit)->clean();
}
}
// Parallel to CDllDirectory
void CClassDirectory3::build(uint16 version)
{
// Ensure parsed
nlassert(!ChunksOwnsPointers);
// Initialize
nlassert(Chunks.empty());
// Set up the Chunks list, when (CClassEntry::ID, NULL) is found write out all of the entries.
for (TStorageObjectContainer::iterator it = m_ChunkCache.begin(), end = m_ChunkCache.end(); it != end; ++it)
{
uint16 id = it->first;
switch (id)
{
case 0x2040: // ClassEntry
for (std::vector<CClassEntry *>::iterator subit = m_Entries.begin(), subend = m_Entries.end(); subit != subend; ++subit)
Chunks.push_back(TStorageObjectWithId(id, (*subit)));
break;
default:
Chunks.push_back(*it);
break;
}
}
// Build the entries last (after Chunks is built)
CStorageContainer::build(version);
// NOTE: Ownership remains with m_ChunkCache and m_Entries
}
// Parallel to CDllDirectory
void CClassDirectory3::disown()
{
CStorageContainer::disown();
m_ChunkCache.clear();
m_Entries.clear();
// Ownership goes back to Chunks
ChunksOwnsPointers = true;
}
// Parallel to CDllDirectory
const CClassEntry *CClassDirectory3::get(std::vector<CClassEntry *>::size_type idx) const
{
return m_Entries[idx];
}
IStorageObject *CClassDirectory3::createChunkById(uint16 id, bool container)
@ -101,8 +249,14 @@ IStorageObject *CClassDirectory3::createChunkById(uint16 id, bool container)
////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////
CClassEntry::CClassEntry()
// Entries[13]: (ClassEntry) [2] {
// 0 0x2060: (ClassEntryHeader) {
// DllIndex: -2
// ClassID: (0x222b9eb9, 0x64c75fec)
// SuperClassID: 3072 }
// 1 0x2042: (CStorageValue) { NeL Material } }
CClassEntry::CClassEntry() : m_Header(NULL), m_Name(NULL)
{
}
@ -119,27 +273,53 @@ std::string CClassEntry::getClassName()
void CClassEntry::toString(std::ostream &ostream, const std::string &pad)
{
CStorageContainer::toString(ostream, pad);
if (m_Header && m_Name)
{
ostream << "(" << getClassName() << ") [" << Chunks.size() << "] PARSED { ";
std::string padpad = pad + "\t";
ostream << "\n" << pad << "Header: ";
m_Header->toString(ostream, padpad);
ostream << "\n" << pad << "Name: " << m_Name->Value.toUtf8();
ostream << "} ";
}
else
{
CStorageContainer::toString(ostream, pad);
}
}
void CClassEntry::parse(uint16 version, TParseLevel level)
{
CStorageContainer::parse(version, level);
// CStorageContainer::parse(version, level);
nlassert(ChunksOwnsPointers);
nlassert(Chunks.size() == 2);
TStorageObjectContainer::iterator it = Chunks.begin();
nlassert(it->first == 0x2060); // ClassEntryHeader
m_Header = static_cast<CClassEntryHeader *>(it->second);
++it;
nlassert(it->first == 0x2042); // ClassEntryName
m_Name = static_cast<CStorageValue<ucstring> *>(it->second);
// ++it;
}
void CClassEntry::clean()
{
CStorageContainer::clean();
// Nothing to do here! (Chunks retains ownership)
// CStorageContainer::clean();
}
void CClassEntry::build(uint16 version)
{
CStorageContainer::build(version);
// Nothing to do here!
// CStorageContainer::build(version);
}
void CClassEntry::disown()
{
CStorageContainer::disown();
// CStorageContainer::disown();
m_Header = NULL;
m_Name = NULL;
nlassert(ChunksOwnsPointers);
}
IStorageObject *CClassEntry::createChunkById(uint16 id, bool container)
@ -148,9 +328,9 @@ IStorageObject *CClassEntry::createChunkById(uint16 id, bool container)
{
switch (id)
{
case 0x2060: // ClassDirectoryHeader
return new CClassDirectoryHeader();
case 0x2042: // ClassName
case 0x2060: // ClassEntryHeader
return new CClassEntryHeader();
case 0x2042: // ClassEntryName
return new CStorageValue<ucstring>();
}
}
@ -161,29 +341,29 @@ IStorageObject *CClassEntry::createChunkById(uint16 id, bool container)
////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////
CClassDirectoryHeader::CClassDirectoryHeader()
CClassEntryHeader::CClassEntryHeader()
{
}
CClassDirectoryHeader::~CClassDirectoryHeader()
CClassEntryHeader::~CClassEntryHeader()
{
}
std::string CClassDirectoryHeader::getClassName()
std::string CClassEntryHeader::getClassName()
{
return "ClassDirectoryHeader";
return "ClassEntryHeader";
}
void CClassDirectoryHeader::serial(NLMISC::IStream &stream)
void CClassEntryHeader::serial(NLMISC::IStream &stream)
{
stream.serial(DllIndex);
stream.serial(ClassID);
stream.serial(SuperClassID);
}
void CClassDirectoryHeader::toString(std::ostream &ostream, const std::string &pad)
void CClassEntryHeader::toString(std::ostream &ostream, const std::string &pad)
{
ostream << "(" << getClassName() << ") { ";
ostream << "\n" << pad << "DllIndex: " << DllIndex;

@ -33,6 +33,7 @@
// NeL includes
#include <nel/misc/class_id.h>
#include <nel/misc/ucstring.h>
// Project includes
#include "storage_object.h"
@ -41,6 +42,8 @@
namespace PIPELINE {
namespace MAX {
class CClassEntry;
/**
* \brief CClassDirectory3
* \date 2012-08-18 18:01GMT
@ -61,11 +64,42 @@ public:
virtual void build(uint16 version);
virtual void disown();
// public
const CClassEntry *get(std::vector<CClassEntry *>::size_type idx) const;
protected:
virtual IStorageObject *createChunkById(uint16 id, bool container);
private:
TStorageObjectContainer m_ChunkCache;
std::vector<CClassEntry *> m_Entries;
}; /* class CClassDirectory3 */
/**
* \brief CClassEntryHeader
* \date 2012-08-18 18:01GMT
* \author Jan Boon (Kaetemi)
* CClassEntryHeader
*/
class CClassEntryHeader : public IStorageObject
{
public:
CClassEntryHeader();
virtual ~CClassEntryHeader();
// public data
sint32 DllIndex;
NLMISC::CClassId ClassID;
uint32 SuperClassID;
// inherited
virtual std::string getClassName();
virtual void serial(NLMISC::IStream &stream);
virtual void toString(std::ostream &ostream, const std::string &pad = "");
}; /* class CClassEntryHeader */
/**
* \brief CClassEntry
* \date 2012-08-18 18:01GMT
@ -86,35 +120,18 @@ public:
virtual void build(uint16 version);
virtual void disown();
const ucstring &displayName() const { return m_Name->Value; }
sint32 dllIndex() const { return m_Header->DllIndex; }
NLMISC::CClassId cslassId() const { return m_Header->ClassID; }
uint32 superClassId() const { return m_Header->SuperClassID; }
protected:
virtual IStorageObject *createChunkById(uint16 id, bool container);
CClassEntryHeader *m_Header;
CStorageValue<ucstring> *m_Name;
}; /* class CClassEntry */
/**
* \brief CClassDirectoryHeader
* \date 2012-08-18 18:01GMT
* \author Jan Boon (Kaetemi)
* CClassDirectoryHeader
*/
class CClassDirectoryHeader : public IStorageObject
{
public:
CClassDirectoryHeader();
virtual ~CClassDirectoryHeader();
// public data
sint32 DllIndex;
NLMISC::CClassId ClassID;
uint32 SuperClassID;
// inherited
virtual std::string getClassName();
virtual void serial(NLMISC::IStream &stream);
virtual void toString(std::ostream &ostream, const std::string &pad = "");
}; /* class CClassDirectoryHeader */
} /* namespace MAX */
} /* namespace PIPELINE */

@ -29,6 +29,7 @@
#include "dll_directory.h"
// STL includes
#include <iomanip>
// NeL includes
// #include <nel/misc/debug.h>
@ -46,6 +47,7 @@ CDllDirectory::CDllDirectory()
}
// Parallel to CClassDirectory3
CDllDirectory::~CDllDirectory()
{
// Delete m_ChunkCache and m_Entries when !ChunksOwnsPointers
@ -69,6 +71,7 @@ std::string CDllDirectory::getClassName()
return "DllDirectory";
}
// Parallel to CClassDirectory3
void CDllDirectory::toString(std::ostream &ostream, const std::string &pad)
{
if (ChunksOwnsPointers)
@ -110,6 +113,7 @@ void CDllDirectory::toString(std::ostream &ostream, const std::string &pad)
}
}
// Parallel to CClassDirectory3
void CDllDirectory::parse(uint16 version, TParseLevel level)
{
if (level & PARSE_INTERNAL)
@ -154,6 +158,7 @@ void CDllDirectory::parse(uint16 version, TParseLevel level)
}
}
// Parallel to CClassDirectory3
void CDllDirectory::clean()
{
// Ensure parsed
@ -176,6 +181,7 @@ void CDllDirectory::clean()
}
}
// Parallel to CClassDirectory3
void CDllDirectory::build(uint16 version)
{
// Ensure parsed
@ -206,6 +212,7 @@ void CDllDirectory::build(uint16 version)
// NOTE: Ownership remains with m_ChunkCache and m_Entries
}
// Parallel to CClassDirectory3
void CDllDirectory::disown()
{
CStorageContainer::disown();
@ -216,6 +223,7 @@ void CDllDirectory::disown()
ChunksOwnsPointers = true;
}
// Parallel to CClassDirectory3
const CDllEntry *CDllDirectory::get(std::vector<CDllEntry *>::size_type idx) const
{
return m_Entries[idx];
@ -276,6 +284,7 @@ void CDllEntry::toString(std::ostream &ostream, const std::string &pad)
void CDllEntry::parse(uint16 version, TParseLevel level)
{
// CStorageContainer::parse(version, level);
nlassert(ChunksOwnsPointers);
nlassert(Chunks.size() == 2);
TStorageObjectContainer::iterator it = Chunks.begin();
nlassert(it->first == 0x2039); // DllDescription

@ -32,7 +32,6 @@
// STL includes
// NeL includes
#include <iomanip>
// Project includes
#include "storage_object.h"
@ -95,8 +94,8 @@ public:
virtual void build(uint16 version);
virtual void disown();
const ucstring &dllDescription() { return m_DllDescription->Value; }
const ucstring &dllFilename() { return m_DllFilename->Value; }
const ucstring &dllDescription() const { return m_DllDescription->Value; }
const ucstring &dllFilename() const { return m_DllFilename->Value; }
protected:
virtual IStorageObject *createChunkById(uint16 id, bool container);

@ -72,10 +72,12 @@ int main(int argc, char **argv)
display_name = g_filename_display_name(filename);
g_print("%s\n", display_name);
g_free(display_name);
g_print("%s\n", streamname);
// g_print("%s\n", streamname);
std::cout << "\n";
GsfInput *input = NULL;
PIPELINE::MAX::CDllDirectory dllDirectory;
input = gsf_infile_child_by_name(infile, "DllDirectory");
{
@ -83,16 +85,39 @@ int main(int argc, char **argv)
dllDirectory.serial(instream);
}
g_object_unref(input);
//dllDirectory.toString(std::cout);
//std::cout << "\n";
dllDirectory.parse(PIPELINE::MAX::VersionUnknown, PIPELINE::MAX::PARSE_INTERNAL); // parse the structure to readable data
dllDirectory.clean(); // cleanup unused file structure
dllDirectory.toString(std::cout);
std::cout << "\n";
dllDirectory.parse(PIPELINE::MAX::VersionUnknown, PIPELINE::MAX::PARSE_INTERNAL);
dllDirectory.clean();
dllDirectory.toString(std::cout);
//dllDirectory.build(PIPELINE::MAX::VersionUnknown);
//dllDirectory.disown();
//dllDirectory.toString(std::cout);
//std::cout << "\n";
std::cout << "\n";
dllDirectory.build(PIPELINE::MAX::VersionUnknown);
dllDirectory.disown();
dllDirectory.toString(std::cout);
PIPELINE::MAX::CClassDirectory3 classDirectory3;
input = gsf_infile_child_by_name(infile, "ClassDirectory3");
{
PIPELINE::MAX::CStorageStream instream(input);
classDirectory3.serial(instream);
}
g_object_unref(input);
//classDirectory3.toString(std::cout);
//std::cout << "\n";
classDirectory3.parse(PIPELINE::MAX::VersionUnknown, PIPELINE::MAX::PARSE_INTERNAL); // parse the structure to readable data
classDirectory3.clean(); // cleanup unused file structure
classDirectory3.toString(std::cout);
std::cout << "\n";
//classDirectory3.build(PIPELINE::MAX::VersionUnknown);
//classDirectory3.disown();
//classDirectory3.toString(std::cout);
//std::cout << "\n";
/*
@ -114,6 +139,9 @@ int main(int argc, char **argv)
g_object_unref(infile);
g_object_unref(src);
gsf_shutdown();
return 0;
}

Loading…
Cancel
Save