2 * \file dll_directory.cpp
4 * \date 2012-08-18 09:01GMT
5 * \author Jan Boon (Kaetemi)
10 * Copyright (C) 2012 by authors
12 * This file is part of RYZOM CORE PIPELINE.
13 * RYZOM CORE PIPELINE is free software: you can redistribute it
14 * and/or modify it under the terms of the GNU Affero General Public
15 * License as published by the Free Software Foundation, either
16 * version 3 of the License, or (at your option) any later version.
18 * RYZOM CORE PIPELINE is distributed in the hope that it will be
19 * useful, but WITHOUT ANY WARRANTY; without even the implied warranty
20 * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
21 * GNU Affero General Public License for more details.
23 * You should have received a copy of the GNU Affero General Public
24 * License along with RYZOM CORE PIPELINE. If not, see
25 * <http://www.gnu.org/licenses/>.
28 #include <nel/misc/types_nl.h>
29 #include "dll_directory.h"
35 // #include <nel/misc/debug.h>
40 // using namespace NLMISC;
45 ////////////////////////////////////////////////////////////////////////
46 ////////////////////////////////////////////////////////////////////////
47 ////////////////////////////////////////////////////////////////////////
49 CDllDirectory::CDllDirectory() : m_DllEntryBuiltin(&DllPluginDescBuiltin
), m_DllEntryScript(&DllPluginDescScript
)
54 // Parallel to CClassDirectory3
55 CDllDirectory::~CDllDirectory()
57 // Delete m_ChunkCache and m_Entries when !m_ChunksOwnsPointers
58 if (!m_ChunksOwnsPointers
)
60 for (TStorageObjectContainer::iterator it
= m_ChunkCache
.begin(), end
= m_ChunkCache
.end(); it
!= end
; ++it
)
64 for (std::vector
<CDllEntry
*>::iterator subit
= m_Entries
.begin(), subend
= m_Entries
.end(); subit
!= subend
; ++subit
)
73 std::string
CDllDirectory::className() const
75 return "DllDirectory";
78 // Parallel to CClassDirectory3
79 void CDllDirectory::toString(std::ostream
&ostream
, const std::string
&pad
) const
81 if (m_ChunksOwnsPointers
)
83 CStorageContainer::toString(ostream
, pad
);
87 ostream
<< "(" << className() << ") [" << m_Chunks
.size() << "] PARSED { ";
88 std::string padpad
= pad
+ "\t";
90 for (TStorageObjectContainer::const_iterator it
= m_ChunkCache
.begin(), end
= m_ChunkCache
.end(); it
!= end
; ++it
)
92 uint16 id
= it
->first
;
95 case 0x2038: // DllEntry
98 for (std::vector
<CDllEntry
*>::const_iterator subit
= m_Entries
.begin(), subend
= m_Entries
.end(); subit
!= subend
; ++subit
)
100 ostream
<< "\n" << pad
<< "Entries[" << subi
<< "]: ";
101 (*subit
)->toString(ostream
, padpad
);
107 std::stringstream ss
;
108 ss
<< std::hex
<< std::setfill('0');
109 ss
<< std::setw(4) << it
->first
;
110 ostream
<< "\n" << pad
<< "0x" << ss
.str() << ": ";
111 it
->second
->toString(ostream
, padpad
);
120 // Parallel to CClassDirectory3
121 void CDllDirectory::parse(uint16 version
, uint filter
)
123 // Ensure not yet parsed
124 nlassert(m_ChunkCache
.empty());
125 nlassert(m_Entries
.empty());
127 // Parse entries first
128 CStorageContainer::parse(version
);
131 addInternalIndices();
132 uint16 lastCached
= 0xFFFF;
133 bool parsedDllEntry
= false;
136 for (TStorageObjectContainer::iterator it
= m_Chunks
.begin(), end
= m_Chunks
.end(); it
!= end
; ++it
)
138 uint16 id
= it
->first
;
141 case 0x2038: // DllEntry
143 if (parsedDllEntry
&& (lastCached
!= id
))
144 throw EStorageParse(); // There were chunks inbetween
147 m_ChunkCache
.push_back(TStorageObjectWithId(id
, NULL
)); // Dummy entry to know the location
149 parsedDllEntry
= true;
151 CDllEntry
*dllEntry
= static_cast<CDllEntry
*>(it
->second
);
152 m_InternalNameToIndex
[NLMISC::toLower(dllEntry
->dllFilename())] = m_Entries
.size();
153 m_Entries
.push_back(dllEntry
);
157 m_ChunkCache
.push_back(*it
); // Dummy entry to know the location
163 // Now ownership of the pointers lies in m_ChunkCache and m_Entries
164 m_ChunksOwnsPointers
= false;
167 // Parallel to CClassDirectory3
168 void CDllDirectory::clean()
171 nlassert(!m_ChunksOwnsPointers
);
177 for (TStorageObjectContainer::iterator it
= m_ChunkCache
.begin(), end
= m_ChunkCache
.end(); it
!= end
; ++it
)
179 if (it
->second
!= NULL
&& it
->second
->isContainer())
181 static_cast<CStorageContainer
*>(it
->second
)->clean();
184 for (std::vector
<CDllEntry
*>::iterator subit
= m_Entries
.begin(), subend
= m_Entries
.end(); subit
!= subend
; ++subit
)
190 // Parallel to CClassDirectory3
191 void CDllDirectory::build(uint16 version
, uint filter
)
194 nlassert(!m_ChunksOwnsPointers
);
197 nlassert(m_Chunks
.empty());
199 // Set up the m_Chunks list, when (CDllEntry::ID, NULL) is found write out all of the entries.
200 for (TStorageObjectContainer::iterator it
= m_ChunkCache
.begin(), end
= m_ChunkCache
.end(); it
!= end
; ++it
)
202 uint16 id
= it
->first
;
205 case 0x2038: // DllEntry
206 for (std::vector
<CDllEntry
*>::iterator subit
= m_Entries
.begin(), subend
= m_Entries
.end(); subit
!= subend
; ++subit
)
207 m_Chunks
.push_back(TStorageObjectWithId(id
, (*subit
)));
210 m_Chunks
.push_back(*it
);
215 // Build the entries last (after m_Chunks is built)
216 CStorageContainer::build(version
);
218 // NOTE: Ownership remains with m_ChunkCache and m_Entries
221 // Parallel to CClassDirectory3
222 void CDllDirectory::disown()
224 m_ChunkCache
.clear();
226 m_InternalNameToIndex
.clear();
228 // Ownership goes back to m_Chunks
229 m_ChunksOwnsPointers
= true;
231 // Disown child chunks
232 CStorageContainer::disown();
235 // Parallel to CClassDirectory3
236 const CDllEntry
*CDllDirectory::get(sint32 index
) const
238 nlassert(!m_ChunksOwnsPointers
);
241 // Handle internal dummy values
245 return &m_DllEntryBuiltin
;
247 return &m_DllEntryScript
;
249 nlerror("Bad dll entry index");
254 nlassert(index
< (sint32
)m_Entries
.size());
255 return m_Entries
[index
];
261 // Parallel to CClassDirectory3
262 void CDllDirectory::reset()
264 nlassert(!m_ChunksOwnsPointers
);
265 for (std::vector
<CDllEntry
*>::iterator subit
= m_Entries
.begin(), subend
= m_Entries
.end(); subit
!= subend
; ++subit
)
270 m_InternalNameToIndex
.clear();
271 addInternalIndices();
274 // Parallel to CClassDirectory3
275 sint32
CDllDirectory::getOrCreateIndex(const IDllPluginDescInternal
*dllPluginDesc
)
277 nlassert(!m_ChunksOwnsPointers
);
278 std::map
<ucstring
, sint32
>::iterator it
= m_InternalNameToIndex
.find(NLMISC::toLower(ucstring(dllPluginDesc
->internalName())));
280 // Return existing index
281 if (it
!= m_InternalNameToIndex
.end())
285 CDllEntry
*dllEntry
= new CDllEntry(dllPluginDesc
);
286 sint32 index
= m_Entries
.size();
287 m_InternalNameToIndex
[NLMISC::toLower(dllEntry
->dllFilename())] = index
;
288 m_Entries
.push_back(dllEntry
);
292 void CDllDirectory::addInternalIndices()
294 m_InternalNameToIndex
[NLMISC::toLower(ucstring(DllPluginDescBuiltin
.internalName()))] = -1;
295 m_InternalNameToIndex
[NLMISC::toLower(ucstring(DllPluginDescScript
.internalName()))] = -2;
298 IStorageObject
*CDllDirectory::createChunkById(uint16 id
, bool container
)
304 case 0x2038: // DllEntry
305 return new CDllEntry();
312 case 0x21C0: // DllDirectoryHeader
313 return new CStorageValue
<uint32
>();
316 return CStorageContainer::createChunkById(id
, container
);
319 ////////////////////////////////////////////////////////////////////////
320 ////////////////////////////////////////////////////////////////////////
321 ////////////////////////////////////////////////////////////////////////
322 // Entries[5]: (DllEntry) [2] PARSED {
323 // DllDescription: ...
324 // DllFilename: ... }
326 CDllEntry::CDllEntry() : m_DllDescription(NULL
), m_DllFilename(NULL
)
331 CDllEntry::CDllEntry(const IDllPluginDescInternal
*dllPluginDesc
) : m_DllDescription(new CStorageValue
<ucstring
>()), m_DllFilename(new CStorageValue
<ucstring
>())
333 m_Chunks
.push_back(TStorageObjectWithId(0x2039, m_DllDescription
));
334 m_Chunks
.push_back(TStorageObjectWithId(0x2037, m_DllFilename
));
335 m_DllDescription
->Value
= dllPluginDesc
->displayName();
336 m_DllFilename
->Value
= dllPluginDesc
->internalName();
339 CDllEntry::~CDllEntry()
344 std::string
CDllEntry::className() const
349 void CDllEntry::toString(std::ostream
&ostream
, const std::string
&pad
) const
351 if (m_DllDescription
&& m_DllFilename
)
353 ostream
<< "(" << className() << ") [" << m_Chunks
.size() << "] PARSED { ";
354 std::string padpad
= pad
+ "\t";
355 ostream
<< "\n" << pad
<< "DllDescription: " << m_DllDescription
->Value
.toUtf8();
356 ostream
<< "\n" << pad
<< "DllFilename: " << m_DllFilename
->Value
.toUtf8();
361 CStorageContainer::toString(ostream
, pad
);
365 void CDllEntry::parse(uint16 version
, uint filter
)
367 // CStorageContainer::parse(version);
368 nlassert(m_ChunksOwnsPointers
);
369 nlassert(m_Chunks
.size() == 2);
370 TStorageObjectContainer::iterator it
= m_Chunks
.begin();
371 nlassert(it
->first
== 0x2039); // DllDescription
372 m_DllDescription
= static_cast<CStorageValue
<ucstring
> *>(it
->second
);
374 nlassert(it
->first
== 0x2037); // DllFilename
375 m_DllFilename
= static_cast<CStorageValue
<ucstring
> *>(it
->second
);
379 void CDllEntry::clean()
381 // Nothing to do here! (m_Chunks retains ownership)
382 // CStorageContainer::clean();
385 void CDllEntry::build(uint16 version
, uint filter
)
387 // Nothing to do here!
388 // CStorageContainer::build(version);
391 void CDllEntry::disown()
393 // CStorageContainer::disown();
394 m_DllDescription
= NULL
;
395 m_DllFilename
= NULL
;
396 nlassert(m_ChunksOwnsPointers
);
399 IStorageObject
*CDllEntry::createChunkById(uint16 id
, bool container
)
405 case 0x2039: // DllDescription
406 case 0x2037: // DllFilename
407 return new CStorageValue
<ucstring
>();
410 return CStorageContainer::createChunkById(id
, container
);
413 ////////////////////////////////////////////////////////////////////////
414 ////////////////////////////////////////////////////////////////////////
415 ////////////////////////////////////////////////////////////////////////
417 } /* namespace MAX */
418 } /* namespace PIPELINE */