Browse Source

Fixed unzip support to use IOSystem/IOStream abstraction

Léo Terziman 11 years ago
parent
commit
77263c631f
3 changed files with 118 additions and 5 deletions
  1. 2 2
      code/Q3BSPFileImporter.cpp
  2. 88 2
      code/Q3BSPZipArchive.cpp
  3. 28 1
      code/Q3BSPZipArchive.h

+ 2 - 2
code/Q3BSPFileImporter.cpp

@@ -188,9 +188,9 @@ const aiImporterDesc* Q3BSPFileImporter::GetInfo () const
 
 
 // ------------------------------------------------------------------------------------------------
 // ------------------------------------------------------------------------------------------------
 //	Import method.
 //	Import method.
-void Q3BSPFileImporter::InternReadFile(const std::string &rFile, aiScene* pScene, IOSystem* /*pIOHandler*/)
+void Q3BSPFileImporter::InternReadFile(const std::string &rFile, aiScene* pScene, IOSystem* pIOHandler)
 {
 {
-	Q3BSPZipArchive Archive( rFile );
+	Q3BSPZipArchive Archive( pIOHandler, rFile );
 	if ( !Archive.isOpen() )
 	if ( !Archive.isOpen() )
 	{
 	{
 		throw DeadlyImportError( "Failed to open file " + rFile + "." );
 		throw DeadlyImportError( "Failed to open file " + rFile + "." );

+ 88 - 2
code/Q3BSPZipArchive.cpp

@@ -49,6 +49,92 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 namespace Assimp {
 namespace Assimp {
 namespace Q3BSP {
 namespace Q3BSP {
 
 
+voidpf IOSystem2Unzip::open(voidpf opaque, const char* filename, int mode) {
+	IOSystem* io_system = (IOSystem*) opaque;
+
+	const char* mode_fopen = NULL;
+	if((mode & ZLIB_FILEFUNC_MODE_READWRITEFILTER)==ZLIB_FILEFUNC_MODE_READ) {
+		mode_fopen = "rb";
+	} else {
+		if(mode & ZLIB_FILEFUNC_MODE_EXISTING) {
+			mode_fopen = "r+b";
+		} else {
+			if(mode & ZLIB_FILEFUNC_MODE_CREATE) {
+				mode_fopen = "wb";
+			}
+		}
+	}
+
+	return (voidpf) io_system->Open(filename, mode_fopen);
+}
+
+uLong IOSystem2Unzip::read(voidpf opaque, voidpf stream, void* buf, uLong size) {
+	IOStream* io_stream = (IOStream*) stream;
+
+	return io_stream->Read(buf, 1, size);
+}
+
+uLong IOSystem2Unzip::write(voidpf opaque, voidpf stream, const void* buf, uLong size) {
+	IOStream* io_stream = (IOStream*) stream;
+
+	return io_stream->Write(buf, 1, size);
+}
+
+long IOSystem2Unzip::tell(voidpf opaque, voidpf stream) {
+	IOStream* io_stream = (IOStream*) stream;
+
+	return io_stream->Tell();
+}
+
+long IOSystem2Unzip::seek(voidpf opaque, voidpf stream, uLong offset, int origin) {
+	IOStream* io_stream = (IOStream*) stream;
+
+	aiOrigin assimp_origin;
+	switch (origin) {
+		default:
+		case ZLIB_FILEFUNC_SEEK_CUR:
+			assimp_origin = aiOrigin_CUR;
+			break;
+		case ZLIB_FILEFUNC_SEEK_END:
+			assimp_origin = aiOrigin_END;
+			break;
+		case ZLIB_FILEFUNC_SEEK_SET:
+			assimp_origin = aiOrigin_SET;
+			break;
+	}
+
+	return (io_stream->Seek(offset, assimp_origin) == aiReturn_SUCCESS ? 0 : -1);
+}
+
+int IOSystem2Unzip::close(voidpf opaque, voidpf stream) {
+	IOSystem* io_system = (IOSystem*) opaque;
+	IOStream* io_stream = (IOStream*) stream;
+
+	io_system->Close(io_stream);
+
+	return 0;
+}
+
+int IOSystem2Unzip::testerror(voidpf opaque, voidpf stream) {
+	return 0;
+}
+
+zlib_filefunc_def IOSystem2Unzip::get(IOSystem* pIOHandler) {
+	zlib_filefunc_def mapping;
+
+	mapping.zopen_file = open;
+	mapping.zread_file = read;
+	mapping.zwrite_file = write;
+	mapping.ztell_file = tell;
+	mapping.zseek_file = seek;
+	mapping.zclose_file = close;
+	mapping.zerror_file = testerror;
+	mapping.opaque = (voidpf) pIOHandler;
+
+	return mapping;
+}
+
+// ------------------------------------------------------------------------------------------------
 ZipFile::ZipFile(size_t size) : m_Size(size) {
 ZipFile::ZipFile(size_t size) : m_Size(size) {
 	ai_assert(m_Size != 0);
 	ai_assert(m_Size != 0);
 
 
@@ -91,9 +177,9 @@ void ZipFile::Flush() {
 
 
 // ------------------------------------------------------------------------------------------------
 // ------------------------------------------------------------------------------------------------
 //	Constructor.
 //	Constructor.
-Q3BSPZipArchive::Q3BSPZipArchive(const std::string& rFile) : m_ZipFileHandle(NULL), m_ArchiveMap() {
+Q3BSPZipArchive::Q3BSPZipArchive(IOSystem* pIOHandler, const std::string& rFile) : m_ZipFileHandle(NULL), m_ArchiveMap() {
 	if (! rFile.empty()) {
 	if (! rFile.empty()) {
-		m_ZipFileHandle = unzOpen(rFile.c_str());
+		m_ZipFileHandle = unzOpen2(rFile.c_str(), &IOSystem2Unzip::get(pIOHandler));
 		if(m_ZipFileHandle != NULL) {
 		if(m_ZipFileHandle != NULL) {
 			mapArchive();
 			mapArchive();
 		}
 		}

+ 28 - 1
code/Q3BSPZipArchive.h

@@ -51,6 +51,33 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 namespace Assimp {
 namespace Assimp {
 namespace Q3BSP {
 namespace Q3BSP {
 
 
+// ------------------------------------------------------------------------------------------------
+///	\class		IOSystem2Unzip
+///	\ingroup	Assimp::Q3BSP
+///
+///	\brief
+// ------------------------------------------------------------------------------------------------
+class IOSystem2Unzip {
+
+	public:
+
+		static voidpf open(voidpf opaque, const char* filename, int mode);
+
+		static uLong read(voidpf opaque, voidpf stream, void* buf, uLong size);
+
+		static uLong write(voidpf opaque, voidpf stream, const void* buf, uLong size);
+
+		static long tell(voidpf opaque, voidpf stream);
+
+		static long seek(voidpf opaque, voidpf stream, uLong offset, int origin);
+
+		static int close(voidpf opaque, voidpf stream);
+
+		static int testerror(voidpf opaque, voidpf stream);
+
+		static zlib_filefunc_def get(IOSystem* pIOHandler);
+};
+
 // ------------------------------------------------------------------------------------------------
 // ------------------------------------------------------------------------------------------------
 ///	\class		ZipFile
 ///	\class		ZipFile
 ///	\ingroup	Assimp::Q3BSP
 ///	\ingroup	Assimp::Q3BSP
@@ -101,7 +128,7 @@ class Q3BSPZipArchive : public Assimp::IOSystem {
 
 
 	public:
 	public:
 
 
-		Q3BSPZipArchive(const std::string & rFile);
+		Q3BSPZipArchive(IOSystem* pIOHandler, const std::string & rFile);
 
 
 		~Q3BSPZipArchive();
 		~Q3BSPZipArchive();