From 9397301a732e020fe5def609c6032852c69ed170 Mon Sep 17 00:00:00 2001 From: Alibek Omarov Date: Thu, 15 Dec 2022 04:01:30 +0300 Subject: [PATCH] filesystem: remove excessive filename field from archive structs, use common in searchpath_t. Small optimizations for PAK --- filesystem/pak.c | 78 ++++++++++++++---------------------------------- filesystem/wad.c | 31 +++++++++---------- filesystem/zip.c | 11 ++++--- 3 files changed, 41 insertions(+), 79 deletions(-) diff --git a/filesystem/pak.c b/filesystem/pak.c index f98cffae..bb1721c8 100644 --- a/filesystem/pak.c +++ b/filesystem/pak.c @@ -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; - - // 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 ); + const dpackfile_t *a = _a, *b = _b; - // 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; diff --git a/filesystem/wad.c b/filesystem/wad.c index 6408486b..6b94610d 100644 --- a/filesystem/wad.c +++ b/filesystem/wad.c @@ -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; } /* diff --git a/filesystem/zip.c b/filesystem/zip.c index 5d3cc2ad..c1edd88c 100644 --- a/filesystem/zip.c +++ b/filesystem/zip.c @@ -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;