diff --git a/code/nel/tools/pipeline/max/class_data.h b/code/nel/tools/pipeline/max/class_data.h index afad16c75..2fb96396e 100644 --- a/code/nel/tools/pipeline/max/class_data.h +++ b/code/nel/tools/pipeline/max/class_data.h @@ -95,7 +95,7 @@ protected: * \brief CClassDataHeader * \date 2012-08-18 18:01GMT * \author Jan Boon (Kaetemi) - * CClassDirectoryHeader + * CClassDataHeader */ class CClassDataHeader : public IStorageObject { diff --git a/code/nel/tools/pipeline/max/class_directory_3.cpp b/code/nel/tools/pipeline/max/class_directory_3.cpp index b5639c570..e62676d76 100644 --- a/code/nel/tools/pipeline/max/class_directory_3.cpp +++ b/code/nel/tools/pipeline/max/class_directory_3.cpp @@ -29,6 +29,7 @@ #include "class_directory_3.h" // STL includes +#include // NeL includes // #include @@ -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::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::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(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(it->second)->clean(); + } + } + for (std::vector::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::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::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(it->second); + ++it; + nlassert(it->first == 0x2042); // ClassEntryName + m_Name = static_cast *>(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(); } } @@ -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; diff --git a/code/nel/tools/pipeline/max/class_directory_3.h b/code/nel/tools/pipeline/max/class_directory_3.h index 404d90df1..a1bb5e9ac 100644 --- a/code/nel/tools/pipeline/max/class_directory_3.h +++ b/code/nel/tools/pipeline/max/class_directory_3.h @@ -33,6 +33,7 @@ // NeL includes #include +#include // 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::size_type idx) const; + protected: virtual IStorageObject *createChunkById(uint16 id, bool container); +private: + TStorageObjectContainer m_ChunkCache; + std::vector 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 *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 */ diff --git a/code/nel/tools/pipeline/max/dll_directory.cpp b/code/nel/tools/pipeline/max/dll_directory.cpp index 6a2861089..3c14d072a 100644 --- a/code/nel/tools/pipeline/max/dll_directory.cpp +++ b/code/nel/tools/pipeline/max/dll_directory.cpp @@ -29,6 +29,7 @@ #include "dll_directory.h" // STL includes +#include // NeL includes // #include @@ -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::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 diff --git a/code/nel/tools/pipeline/max/dll_directory.h b/code/nel/tools/pipeline/max/dll_directory.h index c4f43f00f..8db2ab9a5 100644 --- a/code/nel/tools/pipeline/max/dll_directory.h +++ b/code/nel/tools/pipeline/max/dll_directory.h @@ -32,7 +32,6 @@ // STL includes // NeL includes -#include // 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); diff --git a/code/nel/tools/pipeline/max_dump/main.cpp b/code/nel/tools/pipeline/max_dump/main.cpp index 26190f9f6..b9684b1d4 100644 --- a/code/nel/tools/pipeline/max_dump/main.cpp +++ b/code/nel/tools/pipeline/max_dump/main.cpp @@ -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; }