If someone tries seeking in a compressed file, don't flush and redecompress, just copy it to a temp file instead and work from there (this is primarily for roq files like the one from q3f).

git-svn-id: https://svn.code.sf.net/p/fteqw/code/trunk@2121 fc73d0e0-1445-4013-8a0c-d673dee63da5
This commit is contained in:
Spoike 2006-03-15 20:05:25 +00:00
parent 2d4680335a
commit ea14d7facc

View file

@ -901,6 +901,8 @@ int FSZIP_GeneratePureCRC(void *handle, int seed, int crctype)
typedef struct { typedef struct {
vfsfile_t funcs; vfsfile_t funcs;
vfsfile_t *defer;
//in case we're forced away. //in case we're forced away.
zipfile_t *parent; zipfile_t *parent;
qboolean iscompressed; qboolean iscompressed;
@ -941,6 +943,9 @@ int VFSZIP_ReadBytes (struct vfsfile_s *file, void *buffer, int bytestoread)
int read; int read;
vfszip_t *vfsz = (vfszip_t*)file; vfszip_t *vfsz = (vfszip_t*)file;
if (vfsz->defer)
return VFS_READ(vfsz->defer, buffer, bytestoread);
if (vfsz->iscompressed) if (vfsz->iscompressed)
{ {
VFSZIP_MakeActive(vfsz); VFSZIP_MakeActive(vfsz);
@ -969,11 +974,49 @@ qboolean VFSZIP_Seek (struct vfsfile_s *file, unsigned long pos)
{ {
vfszip_t *vfsz = (vfszip_t*)file; vfszip_t *vfsz = (vfszip_t*)file;
if (vfsz->defer)
return VFS_SEEK(vfsz->defer, pos);
//This is *really* inefficient //This is *really* inefficient
if (vfsz->parent->currentfile == file) if (vfsz->parent->currentfile == file)
{
if (vfsz->iscompressed)
{ //if they're going to seek on a file in a zip, let's just copy it out
char buffer[8192];
unsigned int chunk;
unsigned int i;
unsigned int length;
vfsz->defer = FS_OpenTemp();
if (vfsz->defer)
{ {
unzCloseCurrentFile(vfsz->parent->handle); unzCloseCurrentFile(vfsz->parent->handle);
vfsz->parent->currentfile = NULL; //make it not us vfsz->parent->currentfile = NULL; //make it not us
length = vfsz->length;
i = 0;
vfsz->pos = 0;
VFSZIP_MakeActive(vfsz);
while (1)
{
chunk = length - i;
if (chunk > sizeof(buffer))
chunk = sizeof(buffer);
if (chunk == 0)
break;
unzReadCurrentFile(vfsz->parent->handle, buffer, chunk);
VFS_WRITE(vfsz->defer, buffer, chunk);
i += chunk;
}
}
}
unzCloseCurrentFile(vfsz->parent->handle);
vfsz->parent->currentfile = NULL; //make it not us
if (vfsz->defer)
return VFS_SEEK(vfsz->defer, pos);
} }
@ -987,6 +1030,10 @@ qboolean VFSZIP_Seek (struct vfsfile_s *file, unsigned long pos)
unsigned long VFSZIP_Tell (struct vfsfile_s *file) unsigned long VFSZIP_Tell (struct vfsfile_s *file)
{ {
vfszip_t *vfsz = (vfszip_t*)file; vfszip_t *vfsz = (vfszip_t*)file;
if (vfsz->defer)
return VFS_TELL(vfsz->defer);
return vfsz->pos; return vfsz->pos;
} }
unsigned long VFSZIP_GetLen (struct vfsfile_s *file) unsigned long VFSZIP_GetLen (struct vfsfile_s *file)
@ -1001,6 +1048,9 @@ void VFSZIP_Close (struct vfsfile_s *file)
if (vfsz->parent->currentfile == file) if (vfsz->parent->currentfile == file)
vfsz->parent->currentfile = NULL; //make it not us vfsz->parent->currentfile = NULL; //make it not us
if (vfsz->defer)
VFS_CLOSE(vfsz->defer);
FSZIP_ClosePath(vfsz->parent); FSZIP_ClosePath(vfsz->parent);
Z_Free(vfsz); Z_Free(vfsz);
} }
@ -1040,6 +1090,7 @@ vfsfile_t *FSZIP_OpenVFS(void *handle, flocation_t *loc, char *mode)
} }
zip->references++; zip->references++;
return (vfsfile_t*)vfsz; return (vfsfile_t*)vfsz;
} }