diff --git a/code/IFCLoader.cpp b/code/IFCLoader.cpp index 6b8789be0..add16565a 100644 --- a/code/IFCLoader.cpp +++ b/code/IFCLoader.cpp @@ -48,6 +48,7 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. #include #include +#include "../contrib/unzip/unzip.h" #include "IFCLoader.h" #include "STEPFileReader.h" @@ -103,7 +104,7 @@ static const aiImporterDesc desc = { 0, 0, 0, - "ifc" + "ifc ifczip" }; @@ -123,7 +124,7 @@ IFCImporter::~IFCImporter() bool IFCImporter::CanRead( const std::string& pFile, IOSystem* pIOHandler, bool checkSig) const { const std::string& extension = GetExtension(pFile); - if (extension == "ifc") { + if (extension == "ifc" || extension == "ifczip") { return true; } @@ -168,6 +169,53 @@ void IFCImporter::InternReadFile( const std::string& pFile, ThrowException("Could not open file for reading"); } + // if this is a ifczip file, decompress its contents first + if(GetExtension(pFile) == "ifczip") { + unzFile zip = unzOpen( pFile.c_str() ); + if(zip == NULL) { + ThrowException("Could not open ifczip file for reading, unzip failed"); + } + + // chop 'zip' postfix + std::string fileName = pFile.substr(0,pFile.length() - 3); + + std::string::size_type s = pFile.find_last_of('\\'); + if(s == std::string::npos) { + s = pFile.find_last_of('/'); + } + if(s != std::string::npos) { + fileName = fileName.substr(s+1); + } + + // search file (same name as the IFCZIP except for the file extension) and place file pointer there + if ( unzLocateFile( zip, fileName.c_str(), 0 ) == UNZ_OK ) + { + // get file size, etc. + unz_file_info fileInfo; + unzGetCurrentFileInfo( zip , &fileInfo, 0, 0, 0, 0, 0, 0 ); + + uint8_t* buff = new uint8_t[fileInfo.uncompressed_size]; + + LogInfo("Decompressing IFCZIP file"); + + unzOpenCurrentFile( zip ); + const int ret = unzReadCurrentFile( zip, buff, fileInfo.uncompressed_size); + size_t filesize = fileInfo.uncompressed_size; + if ( ret < 0 || size_t(ret) != filesize ) + { + delete[] buff; + ThrowException("Failed to decompress IFC ZIP file"); + } + unzCloseCurrentFile( zip ); + stream.reset(new MemoryIOStream(buff,fileInfo.uncompressed_size,true)); + } + else { + ThrowException("Found no IFC file member in IFCZIP file"); + } + + unzClose(zip); + } + boost::scoped_ptr db(STEP::ReadFileHeader(stream)); const STEP::HeaderInfo& head = static_cast(*db).GetHeader(); diff --git a/code/MemoryIOWrapper.h b/code/MemoryIOWrapper.h index 231ae8111..ccb255fed 100644 --- a/code/MemoryIOWrapper.h +++ b/code/MemoryIOWrapper.h @@ -53,12 +53,20 @@ class MemoryIOStream : public IOStream { //friend class MemoryIOSystem; public: - MemoryIOStream (const uint8_t* buff, size_t len) - : buffer (buff), length(len), pos((size_t)0) { + MemoryIOStream (const uint8_t* buff, size_t len, bool own = false) + : buffer (buff) + , length(len) + , pos((size_t)0) + , own(own) + { } public: + ~MemoryIOStream () { + if(own) { + delete[] buffer; + } } // ------------------------------------------------------------------- @@ -124,6 +132,7 @@ public: private: const uint8_t* buffer; size_t length,pos; + bool own; }; // ---------------------------------------------------------------------------