From 51bf836db436b037b7b784a162548ce32a608fcd Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?L=C3=A9o=20Terziman?= Date: Fri, 8 Nov 2013 18:07:08 +0100 Subject: [PATCH] Fixed bugs in Q3BSPZipArchive & DefaultLogger --- code/DefaultLogger.cpp | 8 +- code/Q3BSPZipArchive.cpp | 254 +++++++++++++++++++++++++-------------- code/Q3BSPZipArchive.h | 151 ++++++++--------------- 3 files changed, 221 insertions(+), 192 deletions(-) diff --git a/code/DefaultLogger.cpp b/code/DefaultLogger.cpp index f15fd0284..1b9167c55 100644 --- a/code/DefaultLogger.cpp +++ b/code/DefaultLogger.cpp @@ -253,7 +253,7 @@ void DefaultLogger::OnDebug( const char* message ) if ( m_Severity == Logger::NORMAL ) return; - char msg[MAX_LOG_MESSAGE_LENGTH*2]; + char msg[MAX_LOG_MESSAGE_LENGTH + 16]; ::sprintf(msg,"Debug, T%i: %s", GetThreadID(), message ); WriteToStreams( msg, Logger::Debugging ); @@ -263,7 +263,7 @@ void DefaultLogger::OnDebug( const char* message ) // Logs an info void DefaultLogger::OnInfo( const char* message ) { - char msg[MAX_LOG_MESSAGE_LENGTH*2]; + char msg[MAX_LOG_MESSAGE_LENGTH + 16]; ::sprintf(msg,"Info, T%i: %s", GetThreadID(), message ); WriteToStreams( msg , Logger::Info ); @@ -273,7 +273,7 @@ void DefaultLogger::OnInfo( const char* message ) // Logs a warning void DefaultLogger::OnWarn( const char* message ) { - char msg[MAX_LOG_MESSAGE_LENGTH*2]; + char msg[MAX_LOG_MESSAGE_LENGTH + 16]; ::sprintf(msg,"Warn, T%i: %s", GetThreadID(), message ); WriteToStreams( msg, Logger::Warn ); @@ -283,7 +283,7 @@ void DefaultLogger::OnWarn( const char* message ) // Logs an error void DefaultLogger::OnError( const char* message ) { - char msg[MAX_LOG_MESSAGE_LENGTH*2]; + char msg[MAX_LOG_MESSAGE_LENGTH + 16]; ::sprintf(msg,"Error, T%i: %s", GetThreadID(), message ); WriteToStreams( msg, Logger::Err ); diff --git a/code/Q3BSPZipArchive.cpp b/code/Q3BSPZipArchive.cpp index c1cf5fce1..5d0414da7 100644 --- a/code/Q3BSPZipArchive.cpp +++ b/code/Q3BSPZipArchive.cpp @@ -46,23 +46,100 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. #include #include -namespace Assimp -{ -namespace Q3BSP -{ +namespace Assimp { +namespace Q3BSP { + +ZipFile::ZipFile(const std::string &rFileName, unzFile zipFile) : m_Name(rFileName), m_zipFile(zipFile) { + ai_assert(m_zipFile != NULL); +} + +ZipFile::~ZipFile() { + m_zipFile = NULL; +} + +size_t ZipFile::Read(void* pvBuffer, size_t pSize, size_t pCount ) { + size_t bytes_read = 0; + + DefaultLogger::get()->warn("file: \"" + m_Name + "\"."); + + if(m_zipFile != NULL) { + DefaultLogger::get()->warn("file: zip exist."); + + // search file and place file pointer there + if(unzLocateFile(m_zipFile, m_Name.c_str(), 0) == UNZ_OK) { + DefaultLogger::get()->warn("file: file located in the zip archive."); + + // get file size, etc. + unz_file_info fileInfo; + if(unzGetCurrentFileInfo(m_zipFile, &fileInfo, 0, 0, 0, 0, 0, 0) == UNZ_OK) { + const size_t size = pSize * pCount; + assert(size <= fileInfo.uncompressed_size); + + std::stringstream size_str; + size_str << fileInfo.uncompressed_size; + DefaultLogger::get()->warn("file: size = " + size_str.str() + "."); + + // The file has EXACTLY the size of uncompressed_size. In C + // you need to mark the last character with '\0', so add + // another character + if(unzOpenCurrentFile(m_zipFile) == UNZ_OK) { + DefaultLogger::get()->warn("file: file opened."); + + if(unzReadCurrentFile(m_zipFile, pvBuffer, fileInfo.uncompressed_size) == (long int) fileInfo.uncompressed_size) { + std::string file((char*) pvBuffer, ((char*) pvBuffer) + (fileInfo.uncompressed_size < 1000 ? fileInfo.uncompressed_size : 1000)); + DefaultLogger::get()->warn("file: data = \"" + file + "\"."); + + if(unzCloseCurrentFile(m_zipFile) == UNZ_OK) { + DefaultLogger::get()->warn("file: file closed."); + + bytes_read = fileInfo.uncompressed_size; + } + } + } + } + } + } + + return bytes_read; +} + +size_t ZipFile::Write(const void* /*pvBuffer*/, size_t /*pSize*/, size_t /*pCount*/) { + return 0; +} + +size_t ZipFile::FileSize() const { + size_t size = 0; + + if(m_zipFile != NULL) { + if(unzLocateFile(m_zipFile, m_Name.c_str(), 0) == UNZ_OK) { + unz_file_info fileInfo; + if(unzGetCurrentFileInfo(m_zipFile, &fileInfo, 0, 0, 0, 0, 0, 0) == UNZ_OK) { + size = fileInfo.uncompressed_size; + } + } + } + + return size; +} + +aiReturn ZipFile::Seek(size_t /*pOffset*/, aiOrigin /*pOrigin*/) { + return aiReturn_FAILURE; +} + +size_t ZipFile::Tell() const { + return 0; +} + +void ZipFile::Flush() { + // empty +} // ------------------------------------------------------------------------------------------------ // Constructor. -Q3BSPZipArchive::Q3BSPZipArchive( const std::string& rFile ) : - m_ZipFileHandle( NULL ), - m_FileList(), - m_bDirty( true ) -{ - if ( !rFile.empty() ) - { - m_ZipFileHandle = unzOpen( rFile.c_str() ); - if ( NULL != m_ZipFileHandle ) - { +Q3BSPZipArchive::Q3BSPZipArchive(const std::string& rFile) : m_ZipFileHandle(NULL), m_ArchiveMap(), m_FileList(), m_bDirty(true) { + if (! rFile.empty()) { + m_ZipFileHandle = unzOpen(rFile.c_str()); + if(m_ZipFileHandle != NULL) { mapArchive(); } } @@ -70,129 +147,126 @@ Q3BSPZipArchive::Q3BSPZipArchive( const std::string& rFile ) : // ------------------------------------------------------------------------------------------------ // Destructor. -Q3BSPZipArchive::~Q3BSPZipArchive() -{ - for( std::map::iterator it(m_ArchiveMap.begin()), end(m_ArchiveMap.end()); it != end; ++it ) - { - ZipFile *pZipFile = reinterpret_cast(it->second); +Q3BSPZipArchive::~Q3BSPZipArchive() { + for( std::map::iterator it(m_ArchiveMap.begin()), end(m_ArchiveMap.end()); it != end; ++it ) { + ZipFile *pZipFile = reinterpret_cast(it->first); delete pZipFile; } m_ArchiveMap.clear(); m_FileList.clear(); - if ( NULL != m_ZipFileHandle ) - { - unzClose( m_ZipFileHandle ); + if(m_ZipFileHandle != NULL) { + unzClose(m_ZipFileHandle); + m_ZipFileHandle = NULL; } - m_ZipFileHandle = NULL; } // ------------------------------------------------------------------------------------------------ // Returns true, if the archive is already open. -bool Q3BSPZipArchive::isOpen() const -{ - return ( NULL != m_ZipFileHandle ); +bool Q3BSPZipArchive::isOpen() const { + return (m_ZipFileHandle != NULL); } // ------------------------------------------------------------------------------------------------ // Returns true, if the filename is part of the archive. -bool Q3BSPZipArchive::Exists( const char* pFile ) const -{ - ai_assert( NULL != pFile ); - if ( NULL == pFile ) - { - return false; +bool Q3BSPZipArchive::Exists(const char* pFile) const { + ai_assert(pFile != NULL); + + bool exist = false; + + if (pFile != NULL) { + std::string rFile(pFile); + std::set::const_iterator it = m_FileList.find(rFile); + + if(it != m_FileList.end()) { + exist = true; + } } - std::string rFile( pFile ); - std::vector::const_iterator it = std::find( m_FileList.begin(), m_FileList.end(), rFile ); - if ( m_FileList.end() == it ) - { - return false; - } - - return true; + return exist; } // ------------------------------------------------------------------------------------------------ // Returns the separator delimiter. -char Q3BSPZipArchive::getOsSeparator() const -{ +char Q3BSPZipArchive::getOsSeparator() const { +#ifndef _WIN32 return '/'; +#else + return '\\'; +#endif } // ------------------------------------------------------------------------------------------------ // Opens a file, which is part of the archive. -IOStream *Q3BSPZipArchive::Open( const char* pFile, const char* /*pMode*/ ) -{ - ai_assert( NULL != pFile ); +IOStream *Q3BSPZipArchive::Open(const char* pFile, const char* /*pMode*/) { + ai_assert(pFile != NULL); - std::string rItem( pFile ); - std::vector::iterator it = std::find( m_FileList.begin(), m_FileList.end(), rItem ); - if ( m_FileList.end() == it ) - return NULL; + IOStream* result = NULL; - ZipFile *pZipFile = new ZipFile( *it, m_ZipFileHandle ); - m_ArchiveMap[ rItem ] = pZipFile; + std::string rItem(pFile); + std::set::iterator it = m_FileList.find(rItem); - return pZipFile; + if(it != m_FileList.end()) { + ZipFile *pZipFile = new ZipFile(*it, m_ZipFileHandle); + m_ArchiveMap[pZipFile] = rItem; + + result = pZipFile; + } + + return result; } // ------------------------------------------------------------------------------------------------ // Close a filestream. -void Q3BSPZipArchive::Close( IOStream *pFile ) -{ - ai_assert( NULL != pFile ); +void Q3BSPZipArchive::Close(IOStream *pFile) { + ai_assert(pFile != NULL); - std::map::iterator it; - for ( it = m_ArchiveMap.begin(); it != m_ArchiveMap.end(); ++it ) - { - if ( (*it).second == pFile ) - { - ZipFile *pZipFile = reinterpret_cast( (*it).second ); - delete pZipFile; - m_ArchiveMap.erase( it ); - break; - } + std::map::iterator it = m_ArchiveMap.find(pFile); + + if(it != m_ArchiveMap.end()) { + ZipFile *pZipFile = reinterpret_cast((*it).first); + delete pZipFile; + + m_ArchiveMap.erase(it); } } // ------------------------------------------------------------------------------------------------ // Returns the file-list of the archive. -void Q3BSPZipArchive::getFileList( std::vector &rFileList ) -{ - rFileList = m_FileList; +void Q3BSPZipArchive::getFileList(std::vector &rFileList) { + rFileList.clear(); + + std::copy(m_FileList.begin(), m_FileList.end(), rFileList.begin()); } // ------------------------------------------------------------------------------------------------ // Maps the archive content. -bool Q3BSPZipArchive::mapArchive() -{ - if ( NULL == m_ZipFileHandle ) - return false; +bool Q3BSPZipArchive::mapArchive() { + bool success = false; - if ( !m_bDirty ) - return true; + if(m_ZipFileHandle != NULL) { + if(m_bDirty) { + m_FileList.clear(); - if ( !m_FileList.empty() ) - m_FileList.resize( 0 ); + // At first ensure file is already open + if(unzGoToFirstFile(m_ZipFileHandle) == UNZ_OK) { + // Loop over all files + do { + char filename[FileNameSize]; - // At first ensure file is already open - if ( UNZ_OK == unzGoToFirstFile( m_ZipFileHandle ) ) - { - // Loop over all files - do { - char filename[ FileNameSize ]; - unzGetCurrentFileInfo( m_ZipFileHandle, NULL, filename, FileNameSize, NULL, 0, NULL, 0 ); - m_FileList.push_back( filename ); - unzCloseCurrentFile( m_ZipFileHandle ); - } while ( unzGoToNextFile( m_ZipFileHandle ) != UNZ_END_OF_LIST_OF_FILE ); - } + if(unzGetCurrentFileInfo(m_ZipFileHandle, NULL, filename, FileNameSize, NULL, 0, NULL, 0) == UNZ_OK) { + m_FileList.insert(filename); + } + } while(unzGoToNextFile(m_ZipFileHandle) != UNZ_END_OF_LIST_OF_FILE); + } - std::sort( m_FileList.begin(), m_FileList.end() ); - m_bDirty = false; + m_bDirty = false; + } - return true; + success = true; + } + + return success; } // ------------------------------------------------------------------------------------------------ diff --git a/code/Q3BSPZipArchive.h b/code/Q3BSPZipArchive.h index 06d8370e3..7e9647a14 100644 --- a/code/Q3BSPZipArchive.h +++ b/code/Q3BSPZipArchive.h @@ -48,10 +48,8 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. #include #include -namespace Assimp -{ -namespace Q3BSP -{ +namespace Assimp { +namespace Q3BSP { // ------------------------------------------------------------------------------------------------ /// \class ZipFile @@ -59,88 +57,31 @@ namespace Q3BSP /// /// \brief // ------------------------------------------------------------------------------------------------ -class ZipFile : public IOStream -{ -public: - ZipFile( const std::string &rFileName, unzFile zipFile ) : - m_Name( rFileName ), - m_zipFile( zipFile ) - { - ai_assert( NULL != m_zipFile ); - } +class ZipFile : public IOStream { + + public: + + ZipFile(const std::string &rFileName, unzFile zipFile); - ~ZipFile() - { - m_zipFile = NULL; - } + ~ZipFile(); - size_t Read(void* pvBuffer, size_t pSize, size_t pCount ) - { - size_t bytes_read = 0; - if ( NULL == m_zipFile ) - return bytes_read; - - // search file and place file pointer there - if ( unzLocateFile( m_zipFile, m_Name.c_str(), 0 ) == UNZ_OK ) - { - // get file size, etc. - unz_file_info fileInfo; - unzGetCurrentFileInfo( m_zipFile, &fileInfo, 0, 0, 0, 0, 0, 0 ); - const size_t size = pSize * pCount; - assert( size <= fileInfo.uncompressed_size ); - - // The file has EXACTLY the size of uncompressed_size. In C - // you need to mark the last character with '\0', so add - // another character - unzOpenCurrentFile( m_zipFile ); - const int ret = unzReadCurrentFile( m_zipFile, pvBuffer, fileInfo.uncompressed_size); - size_t filesize = fileInfo.uncompressed_size; - if ( ret < 0 || size_t(ret) != filesize ) - { - return 0; - } - bytes_read = ret; - unzCloseCurrentFile( m_zipFile ); - } - return bytes_read; - } + size_t Read(void* pvBuffer, size_t pSize, size_t pCount ); - size_t Write(const void* /*pvBuffer*/, size_t /*pSize*/, size_t /*pCount*/) - { - return 0; - } + size_t Write(const void* /*pvBuffer*/, size_t /*pSize*/, size_t /*pCount*/); - size_t FileSize() const - { - if ( NULL == m_zipFile ) - return 0; - if ( unzLocateFile( m_zipFile, m_Name.c_str(), 0 ) == UNZ_OK ) - { - unz_file_info fileInfo; - unzGetCurrentFileInfo( m_zipFile, &fileInfo, 0, 0, 0, 0, 0, 0 ); - return fileInfo.uncompressed_size; - } - return 0; - } + size_t FileSize() const; - aiReturn Seek(size_t /*pOffset*/, aiOrigin /*pOrigin*/) - { - return aiReturn_FAILURE; - } + aiReturn Seek(size_t /*pOffset*/, aiOrigin /*pOrigin*/); - size_t Tell() const - { - return 0; - } + size_t Tell() const; - void Flush() - { - // empty - } + void Flush(); -private: - std::string m_Name; - unzFile m_zipFile; + private: + + std::string m_Name; + + unzFile m_zipFile; }; // ------------------------------------------------------------------------------------------------ @@ -150,29 +91,43 @@ private: /// \brief IMplements a zip archive like the WinZip archives. Will be also used to import data /// from a P3K archive ( Quake level format ). // ------------------------------------------------------------------------------------------------ -class Q3BSPZipArchive : public Assimp::IOSystem -{ -public: - static const unsigned int FileNameSize = 256; +class Q3BSPZipArchive : public Assimp::IOSystem { -public: - Q3BSPZipArchive( const std::string & rFile ); - ~Q3BSPZipArchive(); - bool Exists( const char* pFile) const; - char getOsSeparator() const; - IOStream* Open(const char* pFile, const char* pMode = "rb"); - void Close( IOStream* pFile); - bool isOpen() const; - void getFileList( std::vector &rFileList ); + public: -private: - bool mapArchive(); + static const unsigned int FileNameSize = 256; -private: - unzFile m_ZipFileHandle; - std::map m_ArchiveMap; - std::vector m_FileList; - bool m_bDirty; + public: + + Q3BSPZipArchive(const std::string & rFile); + + ~Q3BSPZipArchive(); + + bool Exists(const char* pFile) const; + + char getOsSeparator() const; + + IOStream* Open(const char* pFile, const char* pMode = "rb"); + + void Close(IOStream* pFile); + + bool isOpen() const; + + void getFileList(std::vector &rFileList); + + private: + + bool mapArchive(); + + private: + + unzFile m_ZipFileHandle; + + std::map m_ArchiveMap; + + std::set m_FileList; + + bool m_bDirty; }; // ------------------------------------------------------------------------------------------------