[Scummvm-cvs-logs] SF.net SVN: scummvm:[52204] scummvm/trunk/common/unzip.cpp

sev at users.sourceforge.net sev at users.sourceforge.net
Thu Aug 19 12:15:12 CEST 2010


Revision: 52204
          http://scummvm.svn.sourceforge.net/scummvm/?rev=52204&view=rev
Author:   sev
Date:     2010-08-19 10:15:12 +0000 (Thu, 19 Aug 2010)

Log Message:
-----------
COMMON: Add caching to ZipArchive. Patch #3048388

Based on patch #3048388: "Hash map for ZipArchive class", though
I made the hashing by default and removed the old code.

It is a really good thing and will speed up any archive operations.

Modified Paths:
--------------
    scummvm/trunk/common/unzip.cpp

Modified: scummvm/trunk/common/unzip.cpp
===================================================================
--- scummvm/trunk/common/unzip.cpp	2010-08-19 10:11:52 UTC (rev 52203)
+++ scummvm/trunk/common/unzip.cpp	2010-08-19 10:15:12 UTC (rev 52204)
@@ -107,6 +107,9 @@
 #include "common/unzip.h"
 #include "common/file.h"
 
+#include "common/hashmap.h"
+#include "common/hash-str.h"
+
 #if defined(STRICTUNZIP) || defined(STRICTZIPUNZIP)
 /* like the STRICT of WIN32, we define a pointer that cannot be converted
     from (void*) without cast */
@@ -362,7 +365,17 @@
 	uLong byte_before_the_zipfile;/* byte before the zipfile, (>0 for sfx)*/
 } file_in_zip_read_info_s;
 
+typedef struct {
+	uLong num_file;					/* number of the current file in the zipfile*/
+	uLong pos_in_central_dir;		/* pos of the current file in the central dir*/
+	uLong current_file_ok;			/* flag about the usability of the current file*/
+	unz_file_info cur_file_info;					/* public info about the current file in zip*/
+	unz_file_info_internal cur_file_info_internal;	/* private info about it*/
+} cached_file_in_zip;
 
+typedef Common::HashMap<Common::String, cached_file_in_zip, Common::IgnoreCase_Hash, 
+	Common::IgnoreCase_EqualTo> ZipHash;
+
 /* unz_s contain internal information about the zipfile
 */
 typedef struct {
@@ -382,6 +395,7 @@
 	unz_file_info_internal cur_file_info_internal;	/* private info about it*/
 	file_in_zip_read_info_s* pfile_in_zip_read;		/* structure about the current
 													file if we are decompressing it */
+	ZipHash _hash;
 } unz_s;
 
 /* ===========================================================================
@@ -589,7 +603,27 @@
 	us->central_pos = central_pos;
 	us->pfile_in_zip_read = NULL;
 
-	unzGoToFirstFile((unzFile)us);
+	err = unzGoToFirstFile((unzFile)us);
+
+	while (err == UNZ_OK) {
+		// Get the file details
+		char szCurrentFileName[UNZ_MAXFILENAMEINZIP+1];
+		unzGetCurrentFileInfo(us, NULL, szCurrentFileName, sizeof(szCurrentFileName) - 1,
+							NULL, 0, NULL, 0);
+
+		// Save details into the hash
+		cached_file_in_zip fe;
+		fe.num_file = us->num_file;
+		fe.pos_in_central_dir = us->pos_in_central_dir;
+		fe.current_file_ok = us->current_file_ok;
+		fe.cur_file_info = us->cur_file_info;
+		fe.cur_file_info_internal = us->cur_file_info_internal;
+
+		us->_hash[Common::String(szCurrentFileName)] = fe;
+
+		// Move to the next file
+		err = unzGoToNextFile((unzFile)us);
+	}
 	return (unzFile)us;
 }
 
@@ -870,7 +904,6 @@
 	return err;
 }
 
-
 /*
   Try locate the file szFileName in the zipfile.
   For the iCaseSensitivity signification, see unzipStringFileNameCompare
@@ -881,13 +914,7 @@
 */
 int unzLocateFile(unzFile file, const char *szFileName, int iCaseSensitivity) {
 	unz_s* s;
-	int err;
 
-
-	uLong num_fileSaved;
-	uLong pos_in_central_dirSaved;
-
-
 	if (file==NULL)
 		return UNZ_PARAMERROR;
 
@@ -898,25 +925,20 @@
 	if (!s->current_file_ok)
 		return UNZ_END_OF_LIST_OF_FILE;
 
-	num_fileSaved = s->num_file;
-	pos_in_central_dirSaved = s->pos_in_central_dir;
+	// Check to see if the entry exists
+	ZipHash::iterator i = s->_hash.find(Common::String(szFileName));
+	if (i == s->_hash.end())
+		return UNZ_END_OF_LIST_OF_FILE;
 
-	err = unzGoToFirstFile(file);
+	// Found it, so reset the details in the main structure
+	cached_file_in_zip &fe = i->_value;
+	s->num_file = fe.num_file;
+	s->pos_in_central_dir = fe.pos_in_central_dir;
+	s->current_file_ok = fe.current_file_ok;
+	s->cur_file_info = fe.cur_file_info;
+	s->cur_file_info_internal = fe.cur_file_info_internal;
 
-	while (err == UNZ_OK) {
-		char szCurrentFileName[UNZ_MAXFILENAMEINZIP+1];
-		unzGetCurrentFileInfo(file,NULL,
-								szCurrentFileName,sizeof(szCurrentFileName)-1,
-								NULL,0,NULL,0);
-		if (unzStringFileNameCompare(szCurrentFileName,
-										szFileName,iCaseSensitivity)==0)
-			return UNZ_OK;
-		err = unzGoToNextFile(file);
-	}
-
-	s->num_file = num_fileSaved ;
-	s->pos_in_central_dir = pos_in_central_dirSaved ;
-	return err;
+	return UNZ_OK;
 }
 
 


This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site.




More information about the Scummvm-git-logs mailing list