From d05a77523fe08211f7745b8d8dcfeddf5965af5b Mon Sep 17 00:00:00 2001 From: danij Date: Sun, 7 Oct 2012 09:42:19 +0100 Subject: [PATCH] LumpInfo|Cleanup: Implemented C++ constructors and copy-assignment --- .../engine/portable/include/abstractfile.h | 6 ++ doomsday/engine/portable/include/lumpindex.h | 4 +- doomsday/engine/portable/include/lumpinfo.h | 41 ++++++++++- doomsday/engine/portable/src/abstractfile.cpp | 3 +- doomsday/engine/portable/src/fs_main.cpp | 48 ++++--------- doomsday/engine/portable/src/lumpindex.cpp | 6 +- doomsday/engine/portable/src/wadfile.cpp | 68 ++++++++++--------- doomsday/engine/portable/src/zipfile.cpp | 52 ++++++-------- 8 files changed, 119 insertions(+), 109 deletions(-) diff --git a/doomsday/engine/portable/include/abstractfile.h b/doomsday/engine/portable/include/abstractfile.h index 8f67ebca32..f18c7adb1a 100644 --- a/doomsday/engine/portable/include/abstractfile.h +++ b/doomsday/engine/portable/include/abstractfile.h @@ -116,6 +116,12 @@ class AbstractFile return info().size; } + // Convenient lookup method for when only the is-compressed property is needed from info(). + /// @return Size of the uncompressed resource. + inline bool isCompressed() const { + return info().isCompressed(); + } + /// @return @c true if the resource is marked "startup". bool hasStartup() const; diff --git a/doomsday/engine/portable/include/lumpindex.h b/doomsday/engine/portable/include/lumpindex.h index 2d98b46f29..6ece83aed3 100644 --- a/doomsday/engine/portable/include/lumpindex.h +++ b/doomsday/engine/portable/include/lumpindex.h @@ -52,7 +52,7 @@ namespace de { class LumpIndex { public: - typedef QList LumpInfos; + typedef QList Lumps; public: /** @@ -80,7 +80,7 @@ class LumpIndex /** * Provides access to the list of lumps for efficient traversals. */ - LumpInfos const& lumps(); + Lumps const& lumps(); /** * Clear the index back to its default (i.e., empty state). diff --git a/doomsday/engine/portable/include/lumpinfo.h b/doomsday/engine/portable/include/lumpinfo.h index fa68d98a98..f4529f4908 100644 --- a/doomsday/engine/portable/include/lumpinfo.h +++ b/doomsday/engine/portable/include/lumpinfo.h @@ -28,6 +28,8 @@ #include #ifdef __cplusplus +#include + extern "C" { #endif @@ -37,18 +39,53 @@ struct abstractfile_s; * LumpInfo record. POD. * @ingroup fs */ -typedef struct { +typedef struct lumpinfo_s { uint lastModified; /// Unix timestamp. int lumpIdx; /// Relative index of this lump in the owning package else zero. size_t baseOffset; /// Offset from the start of the owning package. size_t size; /// Size of the uncompressed file. size_t compressedSize; /// Size of the original file compressed. + + /// @todo Move this property up to file level. struct abstractfile_s* container; /// Owning package else @c NULL. + +#ifdef __cplusplus + lumpinfo_s(uint _lastModified = 0, int _lumpIdx = 0, size_t _baseOffset = 0, + size_t _size = 0, size_t _compressedSize = 0, struct abstractfile_s* _container = 0) + : lastModified(_lastModified), lumpIdx(_lumpIdx), baseOffset(_baseOffset), + size(_size), compressedSize(_compressedSize), container(_container) + {} + + lumpinfo_s(lumpinfo_s const& other) + : lastModified(other.lastModified), lumpIdx(other.lumpIdx), baseOffset(other.baseOffset), + size(other.size), compressedSize(other.compressedSize), container(other.container) + {} + + ~lumpinfo_s() {} + + lumpinfo_s& operator = (lumpinfo_s other) + { + swap(*this, other); + return *this; + } + + friend void swap(lumpinfo_s& first, lumpinfo_s& second) // nothrow + { + using std::swap; + swap(first.lastModified, second.lastModified); + swap(first.lumpIdx, second.lumpIdx); + swap(first.baseOffset, second.baseOffset); + swap(first.size, second.size); + swap(first.compressedSize, second.compressedSize); + swap(first.container, second.container); + } + + inline bool isCompressed() const { return size != compressedSize; } +#endif } LumpInfo; void F_InitLumpInfo(LumpInfo* info); void F_CopyLumpInfo(LumpInfo* dst, const LumpInfo* src); -void F_DestroyLumpInfo(LumpInfo* info); #ifdef __cplusplus } // extern "C" diff --git a/doomsday/engine/portable/src/abstractfile.cpp b/doomsday/engine/portable/src/abstractfile.cpp index 7a1a388a5a..39af530ec4 100644 --- a/doomsday/engine/portable/src/abstractfile.cpp +++ b/doomsday/engine/portable/src/abstractfile.cpp @@ -45,14 +45,13 @@ AbstractFile::AbstractFile(filetype_t _type, char const* _path, DFile& file, Lum flags.startup = false; flags.custom = true; Str_Init(&path_); Str_Set(&path_, _path); - F_CopyLumpInfo(&info_, &_info); + info_ = _info; } AbstractFile::~AbstractFile() { FS::releaseFile(this); Str_Free(&path_); - F_DestroyLumpInfo(&info_); if(file) delete file; } diff --git a/doomsday/engine/portable/src/fs_main.cpp b/doomsday/engine/portable/src/fs_main.cpp index b64866debf..b10a59772d 100644 --- a/doomsday/engine/portable/src/fs_main.cpp +++ b/doomsday/engine/portable/src/fs_main.cpp @@ -441,17 +441,7 @@ void F_InitLumpInfo(LumpInfo* info) void F_CopyLumpInfo(LumpInfo* dst, LumpInfo const* src) { DENG_ASSERT(dst && src); - dst->lumpIdx = src->lumpIdx; - dst->baseOffset = src->baseOffset; - dst->size = src->size; - dst->compressedSize = src->compressedSize; - dst->lastModified = src->lastModified; - dst->container = src->container; -} - -void F_DestroyLumpInfo(LumpInfo* /*info*/) -{ - // Nothing to do. + *dst = *src; } void F_Init(void) @@ -830,8 +820,7 @@ lumpnum_t FS::openAuxiliary(char const* path, size_t baseOffset) auxiliaryWadLumpIndexInUse = true; // Prepare the temporary info descriptor. - LumpInfo info; F_InitLumpInfo(&info); - info.lastModified = lastModified(Str_Text(foundPath)); + LumpInfo info = LumpInfo(lastModified(Str_Text(foundPath))); WadFile* wad = new WadFile(*hndl, Str_Text(foundPath), info); hndl = DFileBuilder::fromFile(*wad); @@ -843,8 +832,6 @@ lumpnum_t FS::openAuxiliary(char const* path, size_t baseOffset) Str_Delete(foundPath); - // We're done with the descriptor. - F_DestroyLumpInfo(&info); return AUXILIARY_BASE; } @@ -1257,7 +1244,7 @@ int FS::allResourcePaths(char const* rawSearchPattern, int flags, // Check the Zip directory. { int result = 0; - DENG2_FOR_EACH(i, zipLumpIndex->lumps(), LumpIndex::LumpInfos::const_iterator) + DENG2_FOR_EACH(i, zipLumpIndex->lumps(), LumpIndex::Lumps::const_iterator) { LumpInfo const* lumpInfo = *i; AbstractFile* container = reinterpret_cast(lumpInfo->container); @@ -1475,9 +1462,8 @@ static DFile* openAsLumpFile(AbstractFile* container, int lumpIdx, /// but should instead be deferred until the content of the lump is read. DFile* hndl = DFileBuilder::fromFileLump(*container, lumpIdx, false/*dontBuffer*/); - // Prepare the temporary info descriptor. - LumpInfo info; F_InitLumpInfo(&info); - F_CopyLumpInfo(&info, &container->lumpInfo(lumpIdx)); + // Prepare a the temporary info descriptor. + LumpInfo info = container->lumpInfo(lumpIdx); // Try to open the referenced file as a specialised file type. DFile* file = tryOpenFile3(hndl, Str_Text(&absPath), &info); @@ -1490,11 +1476,7 @@ static DFile* openAsLumpFile(AbstractFile* container, int lumpIdx, } DENG_ASSERT(file); - // We're done with the descriptor. - F_DestroyLumpInfo(&info); - Str_Free(&absPath); - return file; } @@ -1623,8 +1605,7 @@ static DFile* tryOpenFile2(char const* path, char const* mode, size_t baseOffset DFile* hndl = DFileBuilder::fromNativeFile(*nativeFile, baseOffset); // Prepare the temporary info descriptor. - LumpInfo info; F_InitLumpInfo(&info); - info.lastModified = FS::lastModified(Str_Text(foundPath)); + LumpInfo info = LumpInfo(FS::lastModified(Str_Text(foundPath))); // Search path is used here rather than found path as the latter may have // been mapped to another location. We want the file to be attributed with @@ -1639,12 +1620,8 @@ static DFile* tryOpenFile2(char const* path, char const* mode, size_t baseOffset } DENG_ASSERT(dfile); - // We're done with the descriptor. - F_DestroyLumpInfo(&info); - Str_Delete(foundPath); Str_Free(&searchPath); - return dfile; } @@ -2208,24 +2185,23 @@ D_CMD(DumpLump) /** * Print a content listing of lumps in this directory to stdout (for debug). */ -static void printLumpIndex(LumpIndex& ld) +static void printLumpIndex(LumpIndex& index) { - const int numRecords = ld.size(); + const int numRecords = index.size(); const int numIndexDigits = MAX_OF(3, M_NumDigits(numRecords)); - Con_Printf("LumpIndex %p (%i records):\n", &ld, numRecords); + Con_Printf("LumpIndex %p (%i records):\n", &index, numRecords); int idx = 0; - DENG2_FOR_EACH(i, ld.lumps(), LumpIndex::LumpInfos::const_iterator) + DENG2_FOR_EACH(i, index.lumps(), LumpIndex::Lumps::const_iterator) { LumpInfo const* lumpInfo = *i; AbstractFile* container = reinterpret_cast(lumpInfo->container); - AutoStr* lumpPath = container->composeLumpPath(lumpInfo->lumpIdx); Con_Printf("%0*i - \"%s:%s\" (size: %lu bytes%s)\n", numIndexDigits, idx++, F_PrettyPath(Str_Text(container->path())), - F_PrettyPath(Str_Text(lumpPath)), + F_PrettyPath(Str_Text(container->composeLumpPath(lumpInfo->lumpIdx))), (unsigned long) lumpInfo->size, - (lumpInfo->compressedSize != lumpInfo->size? " compressed" : "")); + (lumpInfo->isCompressed()? " compressed" : "")); } Con_Printf("---End of lumps---\n"); } diff --git a/doomsday/engine/portable/src/lumpindex.cpp b/doomsday/engine/portable/src/lumpindex.cpp index 9bef5b4a8b..e7ace5908c 100644 --- a/doomsday/engine/portable/src/lumpindex.cpp +++ b/doomsday/engine/portable/src/lumpindex.cpp @@ -62,7 +62,7 @@ struct LumpIndex::Instance LumpIndex* self; int flags; /// @see lumpIndexFlags - LumpIndex::LumpInfos lumpInfos; + LumpIndex::Lumps lumpInfos; HashMap* hashMap; Instance(LumpIndex* d, int _flags) @@ -277,7 +277,7 @@ LumpInfo const& LumpIndex::lumpInfo(lumpnum_t lumpNum) return *d->lumpInfos[lumpNum]; } -LumpIndex::LumpInfos const& LumpIndex::lumps() +LumpIndex::Lumps const& LumpIndex::lumps() { // We may need to prune path-duplicate lumps. d->pruneDuplicates(); @@ -364,7 +364,7 @@ bool LumpIndex::catalogues(AbstractFile& file) // We may need to prune path-duplicate lumps. d->pruneDuplicates(); - DENG2_FOR_EACH(i, d->lumpInfos, LumpInfos::iterator) + DENG2_FOR_EACH(i, d->lumpInfos, Lumps::iterator) { LumpInfo const* lumpInfo = *i; if(reinterpret_cast(lumpInfo->container) == &file) return true; diff --git a/doomsday/engine/portable/src/wadfile.cpp b/doomsday/engine/portable/src/wadfile.cpp index df63719925..8cebc4b6c0 100644 --- a/doomsday/engine/portable/src/wadfile.cpp +++ b/doomsday/engine/portable/src/wadfile.cpp @@ -38,6 +38,7 @@ #include using namespace de; +using de::AbstractFile; using de::DFile; using de::PathDirectoryNode; @@ -58,23 +59,36 @@ typedef struct { struct WadLumpRecord { - uint crc; - LumpInfo info_; +public: + explicit WadLumpRecord(LumpInfo const& _info) : crc_(0), info_(_info) + {} - explicit WadLumpRecord(LumpInfo const& _info) : crc(0) - { - F_CopyLumpInfo(&info_, &_info); + LumpInfo const& info() const { + return info_; } - ~WadLumpRecord() - { - F_DestroyLumpInfo(&info_); - } + uint crc() const { return crc_; } - LumpInfo const& info() const + /// @attention Calls back into the owning container instance in order to obtain the name. + WadLumpRecord& updateCRC() { - return info_; + crc_ = uint(info_.size); + + AbstractFile* container = reinterpret_cast(info_.container); + DENG_ASSERT(container); + PathDirectoryNode const& node = container->lumpDirectoryNode(info_.lumpIdx); + ddstring_t const* name = node.pathFragment(); + int const nameLen = Str_Length(name); + for(int k = 0; k < nameLen; ++k) + { + crc_ += Str_At(name, k); + } + return *this; } + +private: + uint crc_; + LumpInfo info_; }; struct WadFile::Instance @@ -231,34 +245,24 @@ struct WadFile::Instance wadlumprecord_t const* arcRecord = arcRecords; for(int i = 0; i < arcRecordsCount; ++i, arcRecord++) { - LumpInfo info; F_InitLumpInfo(&info); - info.baseOffset = littleEndianByteOrder.toNative(arcRecord->filePos); - info.size = littleEndianByteOrder.toNative(arcRecord->size); - info.compressedSize = info.size; - info.container = reinterpret_cast(self); - // The modification date is inherited from the file (note recursion). - info.lastModified = self->lastModified(); - info.lumpIdx = i; - // Determine the name for this lump in the VFS. normalizeName(*arcRecord, &absPath); F_PrependBasePath(&absPath, &absPath); // Make it absolute. - WadLumpRecord* record = new WadLumpRecord(info); + WadLumpRecord* record = + new WadLumpRecord(LumpInfo(self->lastModified(), // Inherited from the file (note recursion). + i, + littleEndianByteOrder.toNative(arcRecord->filePos), + littleEndianByteOrder.toNative(arcRecord->size), + littleEndianByteOrder.toNative(arcRecord->size), + reinterpret_cast(self))); PathDirectoryNode* node = lumpDirectory->insert(Str_Text(&absPath)); node->setUserData(record); - F_DestroyLumpInfo(&info); - // Calcuate a simple CRC checksum for the lump. /// @note If we intend to use the CRC for anything meaningful this algorithm /// should be replaced and execution deferred until the CRC is needed. - record->crc = uint(record->info().size); - int nameLen = nameLength(*arcRecord); - for(int k = 0; k < nameLen; ++k) - { - record->crc += arcRecord->name[k]; - } + record->updateCRC(); } Str_Free(&absPath); @@ -415,7 +419,7 @@ uint8_t const* WadFile::cacheLump(int lumpIdx) << F_PrettyPath(Str_Text(path())) << F_PrettyPath(Str_Text(composeLumpPath(lumpIdx, '/'))) << (unsigned long) info.size - << (info.compressedSize != info.size? ", compressed" : ""); + << (info.isCompressed()? ", compressed" : ""); // Time to create the cache? if(!d->lumpCache) @@ -478,7 +482,7 @@ size_t WadFile::readLump(int lumpIdx, uint8_t* buffer, size_t startOffset, << F_PrettyPath(Str_Text(path())) << F_PrettyPath(Str_Text(composeLumpPath(lumpIdx, '/'))) << (unsigned long) lrec->info().size - << (lrec->info().compressedSize != lrec->info().size? ", compressed" : "") + << (lrec->info().isCompressed()? ", compressed" : "") << (unsigned long) startOffset << (unsigned long)length; @@ -512,7 +516,7 @@ uint WadFile::calculateCRC() for(int i = 0; i < numLumps; ++i) { WadLumpRecord const* lrec = d->lumpRecord(i); - crc += lrec->crc; + crc += lrec->crc(); } return crc; } diff --git a/doomsday/engine/portable/src/zipfile.cpp b/doomsday/engine/portable/src/zipfile.cpp index b10fcbcb69..940d242169 100644 --- a/doomsday/engine/portable/src/zipfile.cpp +++ b/doomsday/engine/portable/src/zipfile.cpp @@ -140,22 +140,16 @@ static void ApplyPathMappings(ddstring_t* dest, const ddstring_t* src); struct ZipLumpRecord { - LumpInfo info_; - - explicit ZipLumpRecord(LumpInfo const& _info) - { - F_CopyLumpInfo(&info_, &_info); - } - - ~ZipLumpRecord() - { - F_DestroyLumpInfo(&info_); - } +public: + explicit ZipLumpRecord(LumpInfo const& _info) : info_(_info) + {} - LumpInfo const& info() const - { + LumpInfo const& info() const { return info_; } + +private: + LumpInfo info_; }; struct ZipFile::Instance @@ -376,27 +370,20 @@ struct ZipFile::Instance self->file->seek(ULONG(header->relOffset), SeekSet); self->file->read((uint8_t*)&localHeader, sizeof(localHeader)); - LumpInfo info; - F_InitLumpInfo(&info); - info.lumpIdx = lumpIdx++; - info.size = ULONG(header->size); + size_t baseOffset = ULONG(header->relOffset) + sizeof(localfileheader_t) + + USHORT(header->fileNameSize) + USHORT(localHeader.extraFieldSize); + + size_t compressedSize; if(USHORT(header->compression) == ZFC_DEFLATED) { // Compressed using the deflate algorithm. - info.compressedSize = ULONG(header->compressedSize); + compressedSize = ULONG(header->compressedSize); } else // No compression. { - info.compressedSize = info.size; + compressedSize = ULONG(header->size); } - // The modification date is inherited from the real file (note recursion). - info.lastModified = self->lastModified(); - info.container = reinterpret_cast(self); - - info.baseOffset = ULONG(header->relOffset) + sizeof(localfileheader_t) - + USHORT(header->fileNameSize) + USHORT(localHeader.extraFieldSize); - // Convert all slashes to our internal separator. F_FixSlashes(&entryPath, &entryPath); @@ -406,11 +393,12 @@ struct ZipFile::Instance // Make it absolute. F_PrependBasePath(&entryPath, &entryPath); - ZipLumpRecord* record = new ZipLumpRecord(info); + ZipLumpRecord* record = + new ZipLumpRecord(LumpInfo(self->lastModified(), // Inherited from the file (note recursion). + lumpIdx++, baseOffset, ULONG(header->size), + compressedSize, reinterpret_cast(self))); PathDirectoryNode* node = lumpDirectory->insert(Str_Text(&entryPath)); node->setUserData(record); - - F_DestroyLumpInfo(&info); } } @@ -450,7 +438,7 @@ struct ZipFile::Instance self->file->seek(lumpRecord->info().baseOffset, SeekSet); - if(lumpRecord->info().compressedSize != lumpRecord->info().size) + if(lumpRecord->info().isCompressed()) { bool result; uint8_t* compressedData = (uint8_t*) M_Malloc(lumpRecord->info().compressedSize); @@ -600,7 +588,7 @@ uint8_t const* ZipFile::cacheLump(int lumpIdx) << F_PrettyPath(Str_Text(path())) << F_PrettyPath(Str_Text(composeLumpPath(lumpIdx, '/'))) << (unsigned long) info.size - << (info.compressedSize != info.size? ", compressed" : ""); + << (info.isCompressed()? ", compressed" : ""); // Time to create the cache? if(!d->lumpCache) @@ -663,7 +651,7 @@ size_t ZipFile::readLump(int lumpIdx, uint8_t* buffer, size_t startOffset, << F_PrettyPath(Str_Text(path())) << F_PrettyPath(Str_Text(composeLumpPath(lumpIdx, '/'))) << (unsigned long) lrec->info().size - << (lrec->info().compressedSize != lrec->info().size? ", compressed" : "") + << (lrec->info().isCompressed()? ", compressed" : "") << (unsigned long) startOffset << (unsigned long) length;