filesystem: remove excessive filename field from archive structs, use common in searchpath_t. Small optimizations for PAK

This commit is contained in:
Alibek Omarov 2022-12-15 04:01:30 +03:00
parent f1ec612819
commit 9397301a73
3 changed files with 41 additions and 79 deletions

View File

@ -65,54 +65,23 @@ typedef struct
struct pack_s
{
string filename;
int handle;
int numfiles;
time_t filetime; // common for all packed files
dpackfile_t *files;
dpackfile_t files[1]; // flexible
};
/*
====================
FS_AddFileToPack
FS_SortPak
Add a file to the list of files contained into a package
====================
*/
static dpackfile_t *FS_AddFileToPack( const char *name, pack_t *pack, fs_offset_t offset, fs_offset_t size )
static int FS_SortPak( const void *_a, const void *_b )
{
int left, right, middle;
dpackfile_t *pfile;
const dpackfile_t *a = _a, *b = _b;
// look for the slot we should put that file into (binary search)
left = 0;
right = pack->numfiles - 1;
while( left <= right )
{
int diff;
middle = (left + right) / 2;
diff = Q_stricmp( pack->files[middle].name, name );
// If we found the file, there's a problem
if( !diff ) Con_Reportf( S_WARN "package %s contains the file %s several times\n", pack->filename, name );
// If we're too far in the list
if( diff > 0 ) right = middle - 1;
else left = middle + 1;
}
// We have to move the right of the list by one slot to free the one we need
pfile = &pack->files[left];
memmove( pfile + 1, pfile, (pack->numfiles - left) * sizeof( *pfile ));
pack->numfiles++;
Q_strncpy( pfile->name, name, sizeof( pfile->name ));
pfile->filepos = offset;
pfile->filelen = size;
return pfile;
return Q_stricmp( a->name, b->name );
}
/*
@ -129,9 +98,8 @@ static pack_t *FS_LoadPackPAK( const char *packfile, int *error )
{
dpackheader_t header;
int packhandle;
int i, numpackfiles;
int numpackfiles;
pack_t *pack;
dpackfile_t *info;
fs_size_t c;
packhandle = open( packfile, O_RDONLY|O_BINARY );
@ -188,28 +156,25 @@ static pack_t *FS_LoadPackPAK( const char *packfile, int *error )
return NULL;
}
info = (dpackfile_t *)Mem_Malloc( fs_mempool, sizeof( *info ) * numpackfiles );
pack = (pack_t *)Mem_Calloc( fs_mempool, sizeof( pack_t ) + sizeof( dpackfile_t ) * ( numpackfiles - 1 ));
lseek( packhandle, header.dirofs, SEEK_SET );
if( header.dirlen != read( packhandle, (void *)info, header.dirlen ))
if( header.dirlen != read( packhandle, (void *)pack->files, header.dirlen ))
{
Con_Reportf( "%s is an incomplete PAK, not loading\n", packfile );
if( error ) *error = PAK_LOAD_CORRUPTED;
if( error )
*error = PAK_LOAD_CORRUPTED;
close( packhandle );
Mem_Free( info );
Mem_Free( pack );
return NULL;
}
pack = (pack_t *)Mem_Calloc( fs_mempool, sizeof( pack_t ));
Q_strncpy( pack->filename, packfile, sizeof( pack->filename ));
pack->files = (dpackfile_t *)Mem_Calloc( fs_mempool, numpackfiles * sizeof( dpackfile_t ));
// TODO: validate directory?
pack->filetime = FS_SysFileTime( packfile );
pack->handle = packhandle;
pack->numfiles = 0;
// parse the directory
for( i = 0; i < numpackfiles; i++ )
FS_AddFileToPack( info[i].name, pack, info[i].filepos, info[i].filelen );
pack->numfiles = numpackfiles;
qsort( pack->files, pack->numfiles, sizeof( pack->files[0] ), FS_SortPak );
#ifdef XASH_REDUCE_FD
// will reopen when needed
@ -217,8 +182,8 @@ static pack_t *FS_LoadPackPAK( const char *packfile, int *error )
pack->handle = -1;
#endif
if( error ) *error = PAK_LOAD_OK;
Mem_Free( info );
if( error )
*error = PAK_LOAD_OK;
return pack;
}
@ -236,7 +201,7 @@ static file_t *FS_OpenFile_PAK( searchpath_t *search, const char *filename, cons
pfile = &search->pack->files[pack_ind];
return FS_OpenHandle( search->pack->filename, search->pack->handle, pfile->filepos, pfile->filelen );
return FS_OpenHandle( search->filename, search->pack->handle, pfile->filepos, pfile->filelen );
}
/*
@ -339,7 +304,7 @@ FS_PrintInfo_PAK
*/
static void FS_PrintInfo_PAK( searchpath_t *search, char *dst, size_t size )
{
Q_snprintf( dst, size, "%s (%i files)", search->pack->filename, search->pack->numfiles );
Q_snprintf( dst, size, "%s (%i files)", search->filename, search->pack->numfiles );
}
/*
@ -381,7 +346,7 @@ qboolean FS_AddPak_Fullpath( const char *pakfile, qboolean *already_loaded, int
for( search = fs_searchpaths; search; search = search->next )
{
if( search->type == SEARCHPATH_PAK && !Q_stricmp( search->pack->filename, pakfile ))
if( search->type == SEARCHPATH_PAK && !Q_stricmp( search->filename, pakfile ))
{
if( already_loaded ) *already_loaded = true;
return true; // already loaded
@ -399,10 +364,11 @@ qboolean FS_AddPak_Fullpath( const char *pakfile, qboolean *already_loaded, int
string fullpath;
search = (searchpath_t *)Mem_Calloc( fs_mempool, sizeof( searchpath_t ));
Q_strncpy( search->filename, pakfile, sizeof( search->filename ));
search->pack = pak;
search->type = SEARCHPATH_PAK;
search->next = fs_searchpaths;
search->flags |= flags;
search->flags = flags;
search->pfnPrintInfo = FS_PrintInfo_PAK;
search->pfnClose = FS_Close_PAK;

View File

@ -71,7 +71,6 @@ typedef struct
struct wfile_s
{
string filename;
int infotableofs;
int numlumps;
poolhandle_t mempool; // W_ReadLump temp buffers
@ -204,7 +203,7 @@ Add a file to the list of files contained into a package
and sort LAT in alpha-bethical order
====================
*/
static dlumpinfo_t *W_AddFileToWad( const char *name, wfile_t *wad, dlumpinfo_t *newlump )
static dlumpinfo_t *W_AddFileToWad( const char *wadfile, const char *name, wfile_t *wad, dlumpinfo_t *newlump )
{
int left, right;
dlumpinfo_t *plump;
@ -224,7 +223,7 @@ static dlumpinfo_t *W_AddFileToWad( const char *name, wfile_t *wad, dlumpinfo_t
diff = 1;
else if( wad->lumps[middle].type > newlump->type )
diff = -1;
else Con_Reportf( S_WARN "Wad %s contains the file %s several times\n", wad->filename, name );
else Con_Reportf( S_WARN "Wad %s contains the file %s several times\n", wadfile, name );
}
// If we're too far in the list
@ -313,7 +312,6 @@ static wfile_t *W_Open( const char *filename, int *error )
}
// copy wad name
Q_strncpy( wad->filename, filename, sizeof( wad->filename ));
wad->filetime = FS_SysFileTime( filename );
wad->mempool = Mem_AllocPool( filename );
@ -366,7 +364,7 @@ static wfile_t *W_Open( const char *filename, int *error )
if( FS_Read( wad->handle, srclumps, lat_size ) != lat_size )
{
Con_Reportf( S_ERROR "W_ReadLumpTable: %s has corrupted lump allocation table\n", wad->filename );
Con_Reportf( S_ERROR "W_ReadLumpTable: %s has corrupted lump allocation table\n", filename );
if( error ) *error = WAD_LOAD_CORRUPTED;
Mem_Free( srclumps );
FS_CloseWAD( wad );
@ -394,7 +392,7 @@ static wfile_t *W_Open( const char *filename, int *error )
if( srclumps[i].type == 68 && !Q_stricmp( srclumps[i].name, "conchars" ))
srclumps[i].type = TYP_GFXPIC;
W_AddFileToWad( name, wad, &srclumps[i] );
W_AddFileToWad( filename, name, wad, &srclumps[i] );
}
// release source lumps
@ -423,7 +421,7 @@ FS_PrintInfo_WAD
*/
static void FS_PrintInfo_WAD( searchpath_t *search, char *dst, size_t size )
{
Q_snprintf( dst, size, "%s (%i files)", search->wad->filename, search->wad->numlumps );
Q_snprintf( dst, size, "%s (%i files)", search->filename, search->wad->numlumps );
}
/*
@ -456,7 +454,7 @@ static int FS_FindFile_WAD( searchpath_t *search, const char *path )
}
// make wadname from wad fullpath
COM_FileBase( search->wad->filename, shortname );
COM_FileBase( search->filename, shortname );
COM_DefaultExtension( shortname, ".wad" );
// quick reject by wadname
@ -509,7 +507,7 @@ static void FS_Search_WAD( searchpath_t *search, stringlist_t *list, const char
}
// make wadname from wad fullpath
COM_FileBase( search->wad->filename, temp2 );
COM_FileBase( search->filename, temp2 );
COM_DefaultExtension( temp2, ".wad" );
// quick reject by wadname
@ -575,7 +573,7 @@ qboolean FS_AddWad_Fullpath( const char *wadfile, qboolean *already_loaded, int
for( search = fs_searchpaths; search; search = search->next )
{
if( search->type == SEARCHPATH_WAD && !Q_stricmp( search->wad->filename, wadfile ))
if( search->type == SEARCHPATH_WAD && !Q_stricmp( search->filename, wadfile ))
{
if( already_loaded ) *already_loaded = true;
return true; // already loaded
@ -591,10 +589,11 @@ qboolean FS_AddWad_Fullpath( const char *wadfile, qboolean *already_loaded, int
if( wad )
{
search = (searchpath_t *)Mem_Calloc( fs_mempool, sizeof( searchpath_t ));
Q_strncpy( search->filename, wadfile, sizeof( search->filename ));
search->wad = wad;
search->type = SEARCHPATH_WAD;
search->next = fs_searchpaths;
search->flags |= flags;
search->flags = flags;
search->pfnPrintInfo = FS_PrintInfo_WAD;
search->pfnClose = FS_Close_WAD;
@ -608,12 +607,10 @@ qboolean FS_AddWad_Fullpath( const char *wadfile, qboolean *already_loaded, int
Con_Reportf( "Adding wadfile: %s (%i files)\n", wadfile, wad->numlumps );
return true;
}
else
{
if( errorcode != WAD_LOAD_NO_FILES )
Con_Reportf( S_ERROR "FS_AddWad_Fullpath: unable to load wad \"%s\"\n", wadfile );
return false;
}
if( errorcode != WAD_LOAD_NO_FILES )
Con_Reportf( S_ERROR "FS_AddWad_Fullpath: unable to load wad \"%s\"\n", wadfile );
return false;
}
/*

View File

@ -120,7 +120,6 @@ typedef struct zipfile_s
struct zip_s
{
string filename;
int handle;
int numfiles;
time_t filetime;
@ -381,7 +380,6 @@ static zip_t *FS_LoadZip( const char *zipfile, int *error )
info[i].offset = info[i].offset + header.filename_len + header.extrafield_len + sizeof( header );
}
Q_strncpy( zip->filename, zipfile, sizeof( zip->filename ) );
zip->filetime = FS_SysFileTime( zipfile );
zip->numfiles = numpackfiles;
zip->files = info;
@ -419,7 +417,7 @@ file_t *FS_OpenFile_ZIP( searchpath_t *search, const char *filename, const char
return NULL;
}
return FS_OpenHandle( search->zip->filename, search->zip->handle, pfile->offset, pfile->size );
return FS_OpenHandle( search->filename, search->zip->handle, pfile->offset, pfile->size );
}
/*
@ -586,7 +584,7 @@ FS_PrintInfo_ZIP
*/
void FS_PrintInfo_ZIP( searchpath_t *search, char *dst, size_t size )
{
Q_snprintf( dst, size, "%s (%i files)", search->zip->filename, search->zip->numfiles );
Q_snprintf( dst, size, "%s (%i files)", search->filename, search->zip->numfiles );
}
/*
@ -683,7 +681,7 @@ qboolean FS_AddZip_Fullpath( const char *zipfile, qboolean *already_loaded, int
for( search = fs_searchpaths; search; search = search->next )
{
if( search->type == SEARCHPATH_ZIP && !Q_stricmp( search->zip->filename, zipfile ))
if( search->type == SEARCHPATH_ZIP && !Q_stricmp( search->filename, zipfile ))
{
if( already_loaded ) *already_loaded = true;
return true; // already loaded
@ -701,10 +699,11 @@ qboolean FS_AddZip_Fullpath( const char *zipfile, qboolean *already_loaded, int
int i;
search = (searchpath_t *)Mem_Calloc( fs_mempool, sizeof( searchpath_t ) );
Q_strncpy( search->filename, zipfile, sizeof( search->filename ));
search->zip = zip;
search->type = SEARCHPATH_ZIP;
search->next = fs_searchpaths;
search->flags |= flags;
search->flags = flags;
search->pfnPrintInfo = FS_PrintInfo_ZIP;
search->pfnClose = FS_Close_ZIP;