Added: #1440 Extended parser for DllDirectory

--HG--
branch : build_pipeline_v3
hg/feature/build_pipeline_v3
kaetemi 12 years ago
parent dc0e9a513e
commit 33f548341a

@ -48,7 +48,7 @@ CDllDirectory::CDllDirectory()
CDllDirectory::~CDllDirectory() CDllDirectory::~CDllDirectory()
{ {
// TODO: Delete m_ChunkCache and m_Entries when !ChunksOwnsPointers
} }
std::string CDllDirectory::getClassName() std::string CDllDirectory::getClassName()
@ -58,17 +58,102 @@ std::string CDllDirectory::getClassName()
void CDllDirectory::toString(std::ostream &ostream, const std::string &pad) void CDllDirectory::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 0x2038:
{
uint subi = 0;
for (std::vector<CDllEntry *>::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 << "} ";
}
} }
void CDllDirectory::parse(uint16 version, TParseLevel level) void CDllDirectory::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
m_ParseVersion = version;
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 0x2038: // DllEntry
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<CDllEntry *>(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;
}
} }
void CDllDirectory::build(uint16 version) void CDllDirectory::build(uint16 version)
{ {
// TODO: Set up the Chunks list, when (CDllEntry::ID, NULL) is found write out all of the entries.
// Build the entries last
CStorageContainer::build(version); CStorageContainer::build(version);
// NOTE: Ownership remains with m_ChunkCache and m_Entries
}
const CDllEntry *CDllDirectory::get(std::vector<CDllEntry *>::size_type idx) const
{
return m_Entries[idx];
} }
IStorageObject *CDllDirectory::createChunkById(uint16 id, bool container) IStorageObject *CDllDirectory::createChunkById(uint16 id, bool container)
@ -92,7 +177,7 @@ IStorageObject *CDllDirectory::createChunkById(uint16 id, bool container)
return CStorageContainer::createChunkById(id, container); return CStorageContainer::createChunkById(id, container);
} }
CDllEntry::CDllEntry() CDllEntry::CDllEntry() : m_DllDescription(NULL), m_DllFilename(NULL)
{ {
} }
@ -109,17 +194,37 @@ std::string CDllEntry::getClassName()
void CDllEntry::toString(std::ostream &ostream, const std::string &pad) void CDllEntry::toString(std::ostream &ostream, const std::string &pad)
{ {
CStorageContainer::toString(ostream, pad); if (m_DllDescription && m_DllFilename)
{
ostream << "(" << getClassName() << ") [" << Chunks.size() << "] PARSED { ";
std::string padpad = pad + "\t";
ostream << "\n" << pad << "DllDescription: " << m_DllDescription->Value.toUtf8();
ostream << "\n" << pad << "DllFilename: " << m_DllFilename->Value.toUtf8();
ostream << "} ";
}
else
{
CStorageContainer::toString(ostream, pad);
}
} }
void CDllEntry::parse(uint16 version, TParseLevel level) void CDllEntry::parse(uint16 version, TParseLevel level)
{ {
CStorageContainer::parse(version, level); // CStorageContainer::parse(version, level);
nlassert(Chunks.size() == 2);
TStorageObjectContainer::iterator it = Chunks.begin();
nlassert(it->first == 0x2039); // DllDescription
m_DllDescription = static_cast<CStorageValue<ucstring> *>(it->second);
++it;
nlassert(it->first == 0x2037); // DllFilename
m_DllFilename = static_cast<CStorageValue<ucstring> *>(it->second);
// ++it;
} }
void CDllEntry::build(uint16 version) void CDllEntry::build(uint16 version)
{ {
CStorageContainer::build(version); // Nothing to do here!
// CStorageContainer::build(version);
} }
IStorageObject *CDllEntry::createChunkById(uint16 id, bool container) IStorageObject *CDllEntry::createChunkById(uint16 id, bool container)

@ -32,6 +32,7 @@
// STL includes // STL includes
// NeL includes // NeL includes
#include <iomanip>
// Project includes // Project includes
#include "storage_object.h" #include "storage_object.h"
@ -40,6 +41,8 @@
namespace PIPELINE { namespace PIPELINE {
namespace MAX { namespace MAX {
class CDllEntry;
/** /**
* \brief CDllDirectory * \brief CDllDirectory
* \date 2012-08-18 09:01GMT * \date 2012-08-18 09:01GMT
@ -58,9 +61,17 @@ public:
virtual void parse(uint16 version, TParseLevel level); virtual void parse(uint16 version, TParseLevel level);
virtual void build(uint16 version); virtual void build(uint16 version);
// public
const CDllEntry *get(std::vector<CDllEntry *>::size_type idx) const;
protected: protected:
virtual IStorageObject *createChunkById(uint16 id, bool container); virtual IStorageObject *createChunkById(uint16 id, bool container);
private:
uint16 m_ParseVersion;
TStorageObjectContainer m_ChunkCache;
std::vector<CDllEntry *> m_Entries;
}; /* class CDllDirectory */ }; /* class CDllDirectory */
/** /**
@ -81,8 +92,13 @@ public:
virtual void parse(uint16 version, TParseLevel level); virtual void parse(uint16 version, TParseLevel level);
virtual void build(uint16 version); virtual void build(uint16 version);
const ucstring &dllDescription() { return m_DllDescription->Value; }
const ucstring &dllFilename() { return m_DllFilename->Value; }
protected: protected:
virtual IStorageObject *createChunkById(uint16 id, bool container); virtual IStorageObject *createChunkById(uint16 id, bool container);
CStorageValue<ucstring> *m_DllDescription;
CStorageValue<ucstring> *m_DllFilename;
}; /* class CDllDirectory */ }; /* class CDllDirectory */

@ -50,6 +50,16 @@ namespace MAX {
//////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////
//////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////
IStorageObject::IStorageObject()
{
}
IStorageObject::~IStorageObject()
{
}
std::string IStorageObject::toString() std::string IStorageObject::toString()
{ {
std::stringstream ss; std::stringstream ss;
@ -76,6 +86,19 @@ bool IStorageObject::isContainer() const
//////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////
//////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////
CStorageContainer::CStorageContainer() : ChunksOwnsPointers(true)
{
}
CStorageContainer::~CStorageContainer()
{
if (ChunksOwnsPointers)
{
}
}
std::string CStorageContainer::getClassName() // why is this not const in IClassable? std::string CStorageContainer::getClassName() // why is this not const in IClassable?
{ {
return "StorageContainer"; return "StorageContainer";
@ -83,6 +106,11 @@ std::string CStorageContainer::getClassName() // why is this not const in IClass
void CStorageContainer::serial(NLMISC::IStream &stream) void CStorageContainer::serial(NLMISC::IStream &stream)
{ {
if (stream.isReading())
{
nlassert(ChunksOwnsPointers);
nlassert(Chunks.empty());
}
if (stream.getPos() == 0) if (stream.getPos() == 0)
{ {
CStorageStream *storageStream = dynamic_cast<CStorageStream *>(&stream); CStorageStream *storageStream = dynamic_cast<CStorageStream *>(&stream);
@ -125,6 +153,7 @@ void CStorageContainer::toString(std::ostream &ostream, const std::string &pad)
// Blahblah: (Container) { // Blahblah: (Container) {
// Moo: (Foo) "What" } // Moo: (Foo) "What" }
// only increase pad when multi-lining sub-items // only increase pad when multi-lining sub-items
nlassert(ChunksOwnsPointers);
ostream << "(" << getClassName() << ") [" << Chunks.size() << "] { "; ostream << "(" << getClassName() << ") [" << Chunks.size() << "] { ";
std::string padpad = pad + "\t"; std::string padpad = pad + "\t";
sint i = 0; sint i = 0;
@ -171,13 +200,8 @@ void CStorageContainer::serial(CStorageChunks &chunks)
{ {
if (chunks.stream().isReading()) if (chunks.stream().isReading())
{ {
#ifdef NL_DEBUG_STORAGE nlassert(ChunksOwnsPointers);
if (Chunks.size()) nlassert(Chunks.empty());
{
nldebug("Storage container not empty, clearing");
}
#endif
Chunks.clear();
while (chunks.enterChunk()) while (chunks.enterChunk())
{ {
uint16 id = chunks.getChunkId(); uint16 id = chunks.getChunkId();
@ -221,6 +245,16 @@ IStorageObject *CStorageContainer::createChunkById(uint16 id, bool container)
//////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////
//////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////
CStorageRaw::CStorageRaw()
{
}
CStorageRaw::~CStorageRaw()
{
}
std::string CStorageRaw::getClassName() std::string CStorageRaw::getClassName()
{ {
return "StorageRaw"; return "StorageRaw";

@ -44,9 +44,17 @@ namespace MAX {
struct EStorage : public NLMISC::Exception struct EStorage : public NLMISC::Exception
{ {
EStorage() : NLMISC::Exception("PIPELINE::MAX::EStorage") { } EStorage() : NLMISC::Exception("PIPELINE::MAX::EStorage") { }
EStorage(const char *msg) : NLMISC::Exception(msg) { }
virtual ~EStorage() throw() { } virtual ~EStorage() throw() { }
}; };
struct EStorageParse : public EStorage
{
EStorageParse() : EStorage("PIPELINE::MAX::EStorageParse") { }
EStorageParse(const char *msg) : EStorage(msg) { }
virtual ~EStorageParse() throw() { }
};
enum TParseLevel enum TParseLevel
{ {
PARSE_INTERNAL = 0x00000001, // Directly parse basic class formats PARSE_INTERNAL = 0x00000001, // Directly parse basic class formats
@ -70,6 +78,9 @@ const uint16 Version2010 = 0x2012;
class IStorageObject : public NLMISC::IStreamable class IStorageObject : public NLMISC::IStreamable
{ {
public: public:
IStorageObject();
virtual ~IStorageObject();
// virtual std::string getClassName() = 0; // inherited from NLMISC::IClassable through NLMISC::IStreamable // virtual std::string getClassName() = 0; // inherited from NLMISC::IClassable through NLMISC::IStreamable
// virtual void serial(NLMISC::IStream &stream); // inherited from NLMISC::IStreamable // virtual void serial(NLMISC::IStream &stream); // inherited from NLMISC::IStreamable
std::string toString(); std::string toString();
@ -93,6 +104,14 @@ public:
typedef std::list<TStorageObjectWithId> TStorageObjectContainer; typedef std::list<TStorageObjectWithId> TStorageObjectContainer;
TStorageObjectContainer Chunks; TStorageObjectContainer Chunks;
protected:
// protected data
bool ChunksOwnsPointers;
public:
CStorageContainer();
virtual ~CStorageContainer();
// inherited // inherited
virtual std::string getClassName(); virtual std::string getClassName();
virtual void serial(NLMISC::IStream &stream); // only used to wrap a container inside another stream virtual void serial(NLMISC::IStream &stream); // only used to wrap a container inside another stream
@ -123,6 +142,10 @@ public:
typedef std::vector<uint8> TType; typedef std::vector<uint8> TType;
TType Value; TType Value;
public:
CStorageRaw();
virtual ~CStorageRaw();
// inherited // inherited
virtual std::string getClassName(); virtual std::string getClassName();
virtual void serial(NLMISC::IStream &stream); virtual void serial(NLMISC::IStream &stream);

@ -74,6 +74,23 @@ int main(int argc, char **argv)
g_free(display_name); g_free(display_name);
g_print("%s\n", streamname); g_print("%s\n", streamname);
GsfInput *input = NULL;
PIPELINE::MAX::CDllDirectory dllDirectory;
input = gsf_infile_child_by_name(infile, "DllDirectory");
{
PIPELINE::MAX::CStorageStream instream(input);
dllDirectory.serial(instream);
}
g_object_unref(input);
dllDirectory.toString(std::cout);
std::cout << "\n";
dllDirectory.parse(PIPELINE::MAX::VersionUnknown, PIPELINE::MAX::PARSE_INTERNAL);
dllDirectory.toString(std::cout);
std::cout << "\n";
/*
GsfInput *input = gsf_infile_child_by_name(infile, streamname); GsfInput *input = gsf_infile_child_by_name(infile, streamname);
{ {
@ -88,6 +105,9 @@ int main(int argc, char **argv)
} }
g_object_unref(input); g_object_unref(input);
*/
g_object_unref(infile); g_object_unref(infile);
return 0; return 0;

Loading…
Cancel
Save