r795 - in trunk: . archivers lzma
DONOTREPLY at icculus.org
DONOTREPLY at icculus.org
Sun Nov 5 05:06:02 EST 2006
Author: icculus
Date: 2006-11-05 05:06:02 -0500 (Sun, 05 Nov 2006)
New Revision: 795
Modified:
trunk/CHANGELOG
trunk/archivers/lzma.c
trunk/lzma/LZMA-LICENSE.txt
Log:
More 7zip work (thanks, Dennis!)
Modified: trunk/CHANGELOG
===================================================================
--- trunk/CHANGELOG 2006-09-27 09:21:56 UTC (rev 794)
+++ trunk/CHANGELOG 2006-11-05 10:06:02 UTC (rev 795)
@@ -2,6 +2,7 @@
* CHANGELOG.
*/
+11052006 - More 7zip archiver work (thanks, Dennis!).
09272006 - Reworked 7zip archiver (thanks, Dennis!).
09232006 - Fixed typo in doxygen comment.
04112006 - Added LZMA archiver...7zip support (thanks, Dennis!).
Modified: trunk/archivers/lzma.c
===================================================================
--- trunk/archivers/lzma.c 2006-09-27 09:21:56 UTC (rev 794)
+++ trunk/archivers/lzma.c 2006-11-05 10:06:02 UTC (rev 795)
@@ -51,16 +51,29 @@
void *File;
} CFileInStream;
-/* Set by LZMA_openArchive, except blockXXX which is handled by LZMA_read() */
+/*
+ * In LZMA the archive is splited in blocks, those are called folders
+ * Set by LZMA_read()
+*/
+typedef struct _LZMAfolder
+{
+ PHYSFS_uint8 *cache; /* Cached folder */
+ PHYSFS_uint32 size; /* Size of folder */
+ PHYSFS_uint32 index; /* Index of folder in archive */
+ PHYSFS_uint32 references; /* Number of files using this block */
+} LZMAfolder;
+
+/*
+ * Set by LZMA_openArchive(), except folder which gets it's values
+ * in LZMA_read()
+ */
typedef struct _LZMAarchive
{
struct _LZMAentry *firstEntry; /* Used for cleanup on shutdown */
struct _LZMAentry *lastEntry;
+ LZMAfolder *folder; /* Array of folders */
CArchiveDatabaseEx db; /* For 7z: Database */
CFileInStream stream; /* For 7z: Input file incl. read and seek callbacks */
- unsigned char *block; /* Currently cached block */
- size_t blockSize; /* Size of current block */
- PHYSFS_uint32 blockIndex; /* Index of current block */
} LZMAarchive;
/* Set by LZMA_openRead(), except offset which is set by LZMA_read() */
@@ -70,8 +83,9 @@
struct _LZMAentry *previous;
LZMAarchive *archive; /* Link to corresponding archive */
CFileItem *file; /* For 7z: File info, eg. name, size */
- PHYSFS_uint32 index; /* Index inside the archive */
- size_t offset; /* Offset inside archive block */
+ PHYSFS_uint32 fileIndex; /* Index of file in archive */
+ PHYSFS_uint32 folderIndex; /* Index of folder in archive */
+ size_t offset; /* Offset in folder */
PHYSFS_uint32 position; /* Current "virtual" position in file */
} LZMAentry;
@@ -273,23 +287,30 @@
allocTempImp.Alloc = SzAllocPhysicsFS;
allocTempImp.Free = SzFreePhysicsFS;
- if (lzma_err(SzExtract(
- &entry->archive->stream.InStream, /* compressed data */
- &entry->archive->db,
- entry->index,
- &entry->archive->blockIndex, /* Index of currently cached block, may be changed by SzExtract */
- &entry->archive->block, /* Cache of current decompressed block, may be allocated/freed by SzExtract */
- &entry->archive->blockSize, /* Size of current cache, may be changed by SzExtract */
- &entry->offset, /* Offset of this file inside the cache block, set by SzExtract */
- &fileSize, /* Size of this file */
- &allocImp,
- &allocTempImp
- )) != SZ_OK)
- return -1;
+ /* Only decompress the folder if it is not allready cached */
+ if (entry->archive->folder[entry->folderIndex].cache == NULL)
+ if (lzma_err(SzExtract(
+ &entry->archive->stream.InStream, /* compressed data */
+ &entry->archive->db,
+ entry->fileIndex,
+ /* Index of cached folder, will be changed by SzExtract */
+ &entry->archive->folder[entry->folderIndex].index,
+ /* Cache for decompressed folder, allocated/freed by SzExtract */
+ &entry->archive->folder[entry->folderIndex].cache,
+ /* Size of cache, will be changed by SzExtract */
+ &entry->archive->folder[entry->folderIndex].size,
+ /* Offset of this file inside the cache, set by SzExtract */
+ &entry->offset,
+ &fileSize, /* Size of this file */
+ &allocImp,
+ &allocTempImp
+ )) != SZ_OK)
+ return -1;
/* Copy wanted bytes over from cache to outBuffer */
strncpy(outBuffer,
- (void*)(entry->archive->block + entry->offset + entry->position),
+ (void*) (entry->archive->folder[entry->folderIndex].cache +
+ entry->offset + entry->position),
wantedSize);
entry->position += wantedSize;
return objCount;
@@ -352,6 +373,13 @@
if (entry->next != NULL)
entry->next->previous = entry->previous;
+ entry->archive->folder[entry->folderIndex].references--;
+ if (entry->archive->folder[entry->folderIndex].references == 0)
+ {
+ allocator.Free(entry->archive->folder[entry->folderIndex].cache);
+ entry->archive->folder[entry->folderIndex].cache = NULL;
+ }
+
allocator.Free(entry);
entry = NULL;
@@ -384,17 +412,17 @@
static void *LZMA_openArchive(const char *name, int forWriting)
{
+ PHYSFS_uint64 len;
LZMAarchive *archive = NULL;
ISzAlloc allocImp;
ISzAlloc allocTempImp;
BAIL_IF_MACRO(forWriting, ERR_ARC_IS_READ_ONLY, NULL);
- BAIL_IF_MACRO(!LZMA_isArchive(name, forWriting), ERR_UNSUPPORTED_ARCHIVE, 0);
+ BAIL_IF_MACRO(!LZMA_isArchive(name,forWriting), ERR_UNSUPPORTED_ARCHIVE, 0);
archive = (LZMAarchive *) allocator.Malloc(sizeof (LZMAarchive));
BAIL_IF_MACRO(archive == NULL, ERR_OUT_OF_MEMORY, NULL);
- archive->block = NULL;
archive->firstEntry = NULL;
archive->lastEntry = NULL;
@@ -424,6 +452,16 @@
return NULL;
} /* if */
+ len = archive->db.Database.NumFolders * sizeof (LZMAfolder);
+ archive->folder = (LZMAfolder *) allocator.Malloc(len);
+ BAIL_IF_MACRO(archive->folder == NULL, ERR_OUT_OF_MEMORY, NULL);
+
+ /*
+ * Init with 0 so we know when a folder is already cached
+ * Values will be set by LZMA_read()
+ */
+ memset(archive->folder, 0, len);
+
return(archive);
} /* LZMA_openArchive */
@@ -529,20 +567,27 @@
{
LZMAarchive *archive = (LZMAarchive *) opaque;
LZMAentry *entry = NULL;
- PHYSFS_uint32 index = 0;
+ PHYSFS_uint32 fileIndex = 0;
+ PHYSFS_uint32 folderIndex = 0;
- *fileExists = lzma_find_entry(archive, name, &index);
+ *fileExists = lzma_find_entry(archive, name, &fileIndex);
BAIL_IF_MACRO(!*fileExists, ERR_NO_SUCH_FILE, NULL);
+ folderIndex = archive->db.FileIndexToFolderIndexMap[fileIndex];
+ BAIL_IF_MACRO(folderIndex == (PHYSFS_uint32)-1, ERR_UNKNOWN_ERROR, NULL);
+
entry = (LZMAentry *) allocator.Malloc(sizeof (LZMAentry));
BAIL_IF_MACRO(entry == NULL, ERR_OUT_OF_MEMORY, NULL);
- entry->index = index;
+ entry->fileIndex = fileIndex;
+ entry->folderIndex = folderIndex;
entry->archive = archive;
- entry->file = archive->db.Database.Files + entry->index;
+ entry->file = archive->db.Database.Files + entry->fileIndex;
entry->offset = 0; /* Offset will be set by LZMA_read() */
entry->position = 0;
+ archive->folder[folderIndex].references++;
+
entry->next = NULL;
entry->previous = entry->archive->lastEntry;
if (entry->previous != NULL)
@@ -584,7 +629,7 @@
__PHYSFS_platformClose(archive->stream.File);
/* Free the cache which might have been allocated by LZMA_read() */
- allocator.Free(archive->block);
+ allocator.Free(archive->folder);
allocator.Free(archive);
} /* LZMA_dirClose */
Modified: trunk/lzma/LZMA-LICENSE.txt
===================================================================
--- trunk/lzma/LZMA-LICENSE.txt 2006-09-27 09:21:56 UTC (rev 794)
+++ trunk/lzma/LZMA-LICENSE.txt 2006-11-05 10:06:02 UTC (rev 795)
@@ -92,4 +92,3 @@
You should have received a copy of the Common Public License
along with this library.
-k
More information about the physfs-commits
mailing list