filesystem: switch file operations to an interface

This commit is contained in:
Velaron 2022-11-18 15:35:21 +02:00 committed by Alibek Omarov
parent 49d93c0e76
commit 24f7db19d8
6 changed files with 281 additions and 248 deletions

110
filesystem/dir.c Normal file
View File

@ -0,0 +1,110 @@
/*
dir.c - directory operations
Copyright (C) 2022 Alibek Omarov, Velaron
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
*/
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#if XASH_POSIX
#include <unistd.h>
#endif
#include <errno.h>
#include <stddef.h>
#include "port.h"
#include "filesystem_internal.h"
#include "crtlib.h"
#include "xash3d_mathlib.h"
#include "common/com_strings.h"
void FS_Close_DIR( searchpath_t *search ) {}
void FS_PrintInfo_DIR( searchpath_t *search, char *dst, size_t size )
{
Q_strncpy( dst, search->filename, size );
}
int FS_FindFile_DIR( searchpath_t *search, const char *path )
{
char netpath[MAX_SYSPATH];
Q_sprintf( netpath, "%s%s", search->filename, path );
if( FS_SysFileExists( netpath, !( search->flags & FS_CUSTOM_PATH ) ) )
return 0;
return -1;
}
void FS_Search_DIR( searchpath_t *search, stringlist_t *list, const char *pattern, int caseinsensitive )
{
string netpath, temp;
stringlist_t dirlist;
const char *slash, *backslash, *colon, *separator;
int basepathlength, dirlistindex, resultlistindex;
char *basepath;
slash = Q_strrchr( pattern, '/' );
backslash = Q_strrchr( pattern, '\\' );
colon = Q_strrchr( pattern, ':' );
separator = Q_max( slash, backslash );
separator = Q_max( separator, colon );
basepathlength = separator ? (separator + 1 - pattern) : 0;
basepath = Mem_Calloc( fs_mempool, basepathlength + 1 );
if( basepathlength ) memcpy( basepath, pattern, basepathlength );
basepath[basepathlength] = 0;
Q_sprintf( netpath, "%s%s", search->filename, basepath );
stringlistinit( &dirlist );
listdirectory( &dirlist, netpath, caseinsensitive );
for( dirlistindex = 0; dirlistindex < dirlist.numstrings; dirlistindex++ )
{
Q_sprintf( temp, "%s%s", basepath, dirlist.strings[dirlistindex] );
if( matchpattern( temp, (char *)pattern, true ) )
{
for( resultlistindex = 0; resultlistindex < list->numstrings; resultlistindex++ )
{
if( !Q_strcmp( list->strings[resultlistindex], temp ) )
break;
}
if( resultlistindex == list->numstrings )
stringlistappend( list, temp );
}
}
stringlistfreecontents( &dirlist );
Mem_Free( basepath );
}
int FS_FileTime_DIR( struct searchpath_s *search, const char *filename )
{
char path[MAX_SYSPATH];
// found in the filesystem?
Q_sprintf( path, "%s%s", search->filename, filename );
return FS_SysFileTime( path );
}
file_t *FS_OpenFile_DIR( struct searchpath_s *search, const char *filename, const char *mode, int pack_ind )
{
char path[MAX_SYSPATH];
// found in the filesystem?
Q_sprintf( path, "%s%s", search->filename, filename );
return FS_SysOpen( path, mode );
}

View File

@ -117,12 +117,12 @@ FILEMATCH COMMON SYSTEM
=============================================================================
*/
static void stringlistinit( stringlist_t *list )
void stringlistinit( stringlist_t *list )
{
memset( list, 0, sizeof( *list ));
}
static void stringlistfreecontents( stringlist_t *list )
void stringlistfreecontents( stringlist_t *list )
{
int i;
@ -193,7 +193,7 @@ static void listlowercase( stringlist_t *list )
}
}
static void listdirectory( stringlist_t *list, const char *path, qboolean lowercase )
void listdirectory( stringlist_t *list, const char *path, qboolean lowercase )
{
int i;
signed char *c;
@ -463,6 +463,14 @@ void FS_AddGameDirectory( const char *dir, uint flags )
search->next = fs_searchpaths;
search->type = SEARCHPATH_PLAIN;
search->flags = flags;
search->printinfo = FS_PrintInfo_DIR;
search->close = FS_Close_DIR;
search->openfile = FS_OpenFile_DIR;
search->filetime = FS_FileTime_DIR;
search->findfile = FS_FindFile_DIR;
search->search = FS_Search_DIR;
fs_searchpaths = search;
}
@ -488,20 +496,7 @@ void FS_ClearSearchPath( void )
}
else fs_searchpaths = search->next;
switch( search->type )
{
case SEARCHPATH_PAK:
FS_ClosePAK( search->pack );
break;
case SEARCHPATH_WAD:
FS_CloseWAD( search->wad );
break;
case SEARCHPATH_ZIP:
FS_CloseZIP( search->zip );
break;
default:
break;
}
search->close( search );
Mem_Free( search );
}
@ -1323,7 +1318,7 @@ static qboolean FS_FindLibrary( const char *dllname, qboolean directpath, fs_dll
dllInfo->encrypted = FS_CheckForCrypt( dllInfo->shortPath );
if( index < 0 && !dllInfo->encrypted && search )
if( index >= 0 && !dllInfo->encrypted && search )
{
Q_snprintf( dllInfo->fullPath, sizeof( dllInfo->fullPath ),
"%s%s", search->filename, dllInfo->shortPath );
@ -1533,21 +1528,7 @@ void FS_Path_f( void )
{
string info;
switch( s->type )
{
case SEARCHPATH_PAK:
FS_PrintPAKInfo( info, sizeof( info ), s->pack );
break;
case SEARCHPATH_WAD:
FS_PrintWADInfo( info, sizeof( info ), s->wad );
break;
case SEARCHPATH_ZIP:
FS_PrintZIPInfo( info, sizeof( info ), s->zip );
break;
case SEARCHPATH_PLAIN:
Q_strncpy( info, s->filename, sizeof( info ));
break;
}
s->printinfo( s, info, sizeof(info) );
Con_Printf( "%s", info );
@ -1816,48 +1797,16 @@ searchpath_t *FS_FindFile( const char *name, int *index, qboolean gamedironly )
// search through the path, one element at a time
for( search = fs_searchpaths; search; search = search->next )
{
int pack_ind;
if( gamedironly & !FBitSet( search->flags, FS_GAMEDIRONLY_SEARCH_FLAGS ))
continue;
// is the element a pak file?
if( search->type == SEARCHPATH_PAK )
pack_ind = search->findfile( search, name );
if( pack_ind >= 0 )
{
int pack_ind = FS_FindFilePAK( search->pack, name );
if( pack_ind >= 0 )
{
if( index ) *index = pack_ind;
return search;
}
}
else if( search->type == SEARCHPATH_WAD )
{
int pack_ind = FS_FindFileWAD( search->wad, name );
if( pack_ind >= 0 )
{
if( index ) *index = pack_ind;
return search;
}
}
else if( search->type == SEARCHPATH_ZIP )
{
int pack_ind = FS_FindFileZIP( search->zip, name );
if( pack_ind >= 0 )
{
if( index ) *index = pack_ind;
return search;
}
}
else
{
char netpath[MAX_SYSPATH];
Q_sprintf( netpath, "%s%s", search->filename, name );
if( FS_SysFileExists( netpath, !( search->flags & FS_CUSTOM_PATH ) ))
{
if( index != NULL ) *index = -1;
return search;
}
if( index ) *index = pack_ind;
return search;
}
}
@ -1907,26 +1856,7 @@ file_t *FS_OpenReadFile( const char *filename, const char *mode, qboolean gamedi
if( search == NULL )
return NULL;
switch( search->type )
{
case SEARCHPATH_PAK:
return FS_OpenPackedFile( search->pack, pack_ind );
case SEARCHPATH_WAD:
return NULL; // let W_LoadFile get lump correctly
case SEARCHPATH_ZIP:
return FS_OpenZipFile( search->zip, pack_ind );
default:
if( pack_ind < 0 )
{
char path [MAX_SYSPATH];
// found in the filesystem?
Q_sprintf( path, "%s%s", search->filename, filename );
return FS_SysOpen( path, mode );
}
}
return NULL;
return search->openfile( search, filename, mode, pack_ind );
}
/*
@ -2611,26 +2541,7 @@ int FS_FileTime( const char *filename, qboolean gamedironly )
search = FS_FindFile( filename, &pack_ind, gamedironly );
if( !search ) return -1; // doesn't exist
switch( search->type )
{
case SEARCHPATH_PAK:
return FS_FileTimePAK( search->pack );
case SEARCHPATH_WAD:
return FS_FileTimeWAD( search->wad );
case SEARCHPATH_ZIP:
return FS_FileTimeZIP( search->zip );
default:
if( pack_ind < 0 )
{
char path [MAX_SYSPATH];
// found in the filesystem?
Q_sprintf( path, "%s%s", search->filename, filename );
return FS_SysFileTime( path );
}
}
return -1; // doesn't exist
return search->filetime( search, filename );
}
/*
@ -2724,80 +2635,23 @@ Allocate and fill a search structure with information on matching filenames.
*/
search_t *FS_Search( const char *pattern, int caseinsensitive, int gamedironly )
{
search_t *search = NULL;
searchpath_t *searchpath;
pack_t *pak;
wfile_t *wad;
zip_t *zip;
int i, basepathlength, numfiles, numchars;
int resultlistindex, dirlistindex;
const char *slash, *backslash, *colon, *separator;
string netpath, temp;
stringlist_t resultlist;
stringlist_t dirlist;
char *basepath;
search_t *search = NULL;
searchpath_t *searchpath;
int i, numfiles, numchars;
stringlist_t resultlist;
if( pattern[0] == '.' || pattern[0] == ':' || pattern[0] == '/' || pattern[0] == '\\' )
return NULL; // punctuation issues
stringlistinit( &resultlist );
stringlistinit( &dirlist );
slash = Q_strrchr( pattern, '/' );
backslash = Q_strrchr( pattern, '\\' );
colon = Q_strrchr( pattern, ':' );
separator = Q_max( slash, backslash );
separator = Q_max( separator, colon );
basepathlength = separator ? (separator + 1 - pattern) : 0;
basepath = Mem_Calloc( fs_mempool, basepathlength + 1 );
if( basepathlength ) memcpy( basepath, pattern, basepathlength );
basepath[basepathlength] = 0;
// search through the path, one element at a time
for( searchpath = fs_searchpaths; searchpath; searchpath = searchpath->next )
{
if( gamedironly && !FBitSet( searchpath->flags, FS_GAMEDIRONLY_SEARCH_FLAGS ))
continue;
// is the element a pak file?
if( searchpath->type == SEARCHPATH_PAK )
{
// look through all the pak file elements
FS_SearchPAK( &resultlist, searchpath->pack, pattern );
}
else if( searchpath->type == SEARCHPATH_ZIP )
{
FS_SearchZIP( &resultlist, searchpath->zip, pattern );
}
else if( searchpath->type == SEARCHPATH_WAD )
{
FS_SearchWAD( &resultlist, searchpath->wad, pattern );
}
else
{
// get a directory listing and look at each name
Q_sprintf( netpath, "%s%s", searchpath->filename, basepath );
stringlistinit( &dirlist );
listdirectory( &dirlist, netpath, caseinsensitive );
for( dirlistindex = 0; dirlistindex < dirlist.numstrings; dirlistindex++ )
{
Q_sprintf( temp, "%s%s", basepath, dirlist.strings[dirlistindex] );
if( matchpattern( temp, (char *)pattern, true ))
{
for( resultlistindex = 0; resultlistindex < resultlist.numstrings; resultlistindex++ )
{
if( !Q_strcmp( resultlist.strings[resultlistindex], temp ))
break;
}
if( resultlistindex == resultlist.numstrings )
stringlistappend( &resultlist, temp );
}
}
stringlistfreecontents( &dirlist );
}
searchpath->search( searchpath, &resultlist, pattern, caseinsensitive );
}
if( resultlist.numstrings )
@ -2806,21 +2660,21 @@ search_t *FS_Search( const char *pattern, int caseinsensitive, int gamedironly )
numfiles = resultlist.numstrings;
numchars = 0;
for( resultlistindex = 0; resultlistindex < resultlist.numstrings; resultlistindex++ )
numchars += (int)Q_strlen( resultlist.strings[resultlistindex]) + 1;
for( i = 0; i < resultlist.numstrings; i++ )
numchars += (int)Q_strlen( resultlist.strings[i]) + 1;
search = Mem_Calloc( fs_mempool, sizeof(search_t) + numchars + numfiles * sizeof( char* ));
search->filenames = (char **)((char *)search + sizeof( search_t ));
search->filenamesbuffer = (char *)((char *)search + sizeof( search_t ) + numfiles * sizeof( char* ));
search->numfilenames = (int)numfiles;
numfiles = numchars = 0;
for( resultlistindex = 0; resultlistindex < resultlist.numstrings; resultlistindex++ )
for( i = 0; i < resultlist.numstrings; i++ )
{
size_t textlen;
search->filenames[numfiles] = search->filenamesbuffer + numchars;
textlen = Q_strlen(resultlist.strings[resultlistindex]) + 1;
memcpy( search->filenames[numfiles], resultlist.strings[resultlistindex], textlen );
textlen = Q_strlen(resultlist.strings[i]) + 1;
memcpy( search->filenames[numfiles], resultlist.strings[i], textlen );
numfiles++;
numchars += (int)textlen;
}
@ -2828,8 +2682,6 @@ search_t *FS_Search( const char *pattern, int caseinsensitive, int gamedironly )
stringlistfreecontents( &resultlist );
Mem_Free( basepath );
return search;
}

View File

@ -69,13 +69,22 @@ typedef struct searchpath_s
string filename;
int type;
int flags;
union
{
pack_t *pack;
wfile_t *wad;
zip_t *zip;
};
struct searchpath_s *next;
void ( *printinfo )( struct searchpath_s *search, char *dst, size_t size );
void ( *close )( struct searchpath_s *search );
file_t *( *openfile )( struct searchpath_s *search, const char *filename, const char *mode, int pack_ind );
int ( *filetime )( struct searchpath_s *search, const char *filename );
int ( *findfile )( struct searchpath_s *search, const char *path );
void ( *search )( struct searchpath_s *search, stringlist_t *list, const char *pattern, int caseinsensitive );
} searchpath_t;
extern fs_globals_t FI;
@ -156,7 +165,10 @@ qboolean FS_Rename( const char *oldname, const char *newname );
qboolean FS_Delete( const char *path );
qboolean FS_SysFileExists( const char *path, qboolean casesensitive );
const char *FS_GetDiskPath( const char *name, qboolean gamedironly );
void stringlistinit( stringlist_t *list );
void stringlistfreecontents( stringlist_t *list );
void stringlistappend( stringlist_t *list, char *text );
void listdirectory( stringlist_t *list, const char *path, qboolean lowercase );
void FS_CreatePath( char *path );
qboolean FS_SysFolderExists( const char *path );
file_t *FS_OpenReadFile( const char *filename, const char *mode, qboolean gamedironly );
@ -170,22 +182,22 @@ searchpath_t *FS_FindFile( const char *name, int *index, qboolean gamedironly );
//
// pak.c
//
int FS_FileTimePAK( pack_t *pack );
int FS_FindFilePAK( pack_t *pack, const char *name );
void FS_PrintPAKInfo( char *dst, size_t size, pack_t *pack );
void FS_ClosePAK( pack_t *pack );
void FS_SearchPAK( stringlist_t *list, pack_t *pack, const char *pattern );
file_t *FS_OpenPackedFile( pack_t *pack, int pack_ind );
int FS_FileTime_PAK( searchpath_t *search, const char *filename );
int FS_FindFile_PAK( searchpath_t *search, const char *path );
void FS_PrintInfo_PAK( searchpath_t *search, char *dst, size_t size );
void FS_Close_PAK( searchpath_t *search );
void FS_Search_PAK( searchpath_t *search, stringlist_t *list, const char *pattern, int caseinsensitive );
file_t *FS_OpenFile_PAK( searchpath_t *search, const char *filename, const char *mode, int pack_ind );
qboolean FS_AddPak_Fullpath( const char *pakfile, qboolean *already_loaded, int flags );
//
// wad.c
//
int FS_FileTimeWAD( wfile_t *wad );
int FS_FindFileWAD( wfile_t *wad, const char *name );
void FS_PrintWADInfo( char *dst, size_t size, wfile_t *wad );
void FS_CloseWAD( wfile_t *wad );
void FS_SearchWAD( stringlist_t *list, wfile_t *wad, const char *pattern );
int FS_FileTime_WAD( searchpath_t *search, const char *filename );
int FS_FindFile_WAD( searchpath_t *search, const char *path );
void FS_PrintInfo_WAD( searchpath_t *search, char *dst, size_t size );
void FS_Close_WAD( searchpath_t *search );
void FS_Search_WAD( searchpath_t *search, stringlist_t *list, const char *pattern, int caseinsensitive );
byte *FS_LoadWADFile( const char *path, fs_offset_t *sizeptr, qboolean gamedironly );
qboolean FS_AddWad_Fullpath( const char *wadfile, qboolean *already_loaded, int flags );
@ -199,15 +211,25 @@ void FS_WatchFrame( void );
//
// zip.c
//
int FS_FileTimeZIP( zip_t *zip );
int FS_FindFileZIP( zip_t *zip, const char *name );
void FS_PrintZIPInfo( char *dst, size_t size, zip_t *zip );
void FS_CloseZIP( zip_t *zip );
void FS_SearchZIP( stringlist_t *list, zip_t *zip, const char *pattern );
int FS_FileTime_ZIP( searchpath_t *search, const char *filename );
int FS_FindFile_ZIP( searchpath_t *search, const char *path );
void FS_PrintInfo_ZIP( searchpath_t *search, char *dst, size_t size );
void FS_Close_ZIP( searchpath_t *search );
void FS_Search_ZIP( searchpath_t *search, stringlist_t *list, const char *pattern, int caseinsensitive );
byte *FS_LoadZIPFile( const char *path, fs_offset_t *sizeptr, qboolean gamedironly );
file_t *FS_OpenZipFile( zip_t *zip, int pack_ind );
file_t *FS_OpenFile_ZIP( searchpath_t *search, const char *filename, const char *mode, int pack_ind );
qboolean FS_AddZip_Fullpath( const char *zipfile, qboolean *already_loaded, int flags );
//
// dir.c
//
void FS_PrintInfo_DIR( searchpath_t *search, char *dst, size_t size );
void FS_Close_DIR( searchpath_t *search );
file_t *FS_OpenFile_DIR( searchpath_t *search, const char *filename, const char *mode, int pack_ind );
int FS_FileTime_DIR( searchpath_t *search, const char *filename );
int FS_FindFile_DIR( searchpath_t *search, const char *path );
void FS_Search_DIR( searchpath_t *search, stringlist_t *list, const char *pattern, int caseinsensitive );
#ifdef __cplusplus
}
#endif

View File

@ -230,13 +230,13 @@ FS_OpenPackedFile
Open a packed file using its package file descriptor
===========
*/
file_t *FS_OpenPackedFile( pack_t *pack, int pack_ind )
file_t *FS_OpenFile_PAK( searchpath_t *search, const char *filename, const char *mode, int pack_ind )
{
dpackfile_t *pfile;
pfile = &pack->files[pack_ind];
pfile = &search->pack->files[pack_ind];
return FS_OpenHandle( pack->filename, pack->handle, pfile->filepos, pfile->filelen );
return FS_OpenHandle( search->pack->filename, search->pack->handle, pfile->filepos, pfile->filelen );
}
/*
@ -284,6 +284,14 @@ qboolean FS_AddPak_Fullpath( const char *pakfile, qboolean *already_loaded, int
search->type = SEARCHPATH_PAK;
search->next = fs_searchpaths;
search->flags |= flags;
search->printinfo = FS_PrintInfo_PAK;
search->close = FS_Close_PAK;
search->openfile = FS_OpenFile_PAK;
search->filetime = FS_FileTime_PAK;
search->findfile = FS_FindFile_PAK;
search->search = FS_Search_PAK;
fs_searchpaths = search;
Con_Reportf( "Adding pakfile: %s (%i files)\n", pakfile, pak->numfiles );
@ -308,19 +316,19 @@ qboolean FS_AddPak_Fullpath( const char *pakfile, qboolean *already_loaded, int
}
}
int FS_FindFilePAK( pack_t *pack, const char *name )
int FS_FindFile_PAK( searchpath_t *search, const char *path )
{
int left, right, middle;
// look for the file (binary search)
left = 0;
right = pack->numfiles - 1;
right = search->pack->numfiles - 1;
while( left <= right )
{
int diff;
middle = (left + right) / 2;
diff = Q_stricmp( pack->files[middle].name, name );
diff = Q_stricmp( search->pack->files[middle].name, path );
// Found it
if( !diff )
@ -337,15 +345,15 @@ int FS_FindFilePAK( pack_t *pack, const char *name )
return -1;
}
void FS_SearchPAK( stringlist_t *list, pack_t *pack, const char *pattern )
void FS_Search_PAK( searchpath_t *search, stringlist_t *list, const char *pattern, int caseinsensitive )
{
string temp;
const char *slash, *backslash, *colon, *separator;
int j, i;
for( i = 0; i < pack->numfiles; i++ )
for( i = 0; i < search->pack->numfiles; i++ )
{
Q_strncpy( temp, pack->files[i].name, sizeof( temp ));
Q_strncpy( temp, search->pack->files[i].name, sizeof( temp ));
while( temp[0] )
{
if( matchpattern( temp, pattern, true ))
@ -377,21 +385,21 @@ void FS_SearchPAK( stringlist_t *list, pack_t *pack, const char *pattern )
}
}
int FS_FileTimePAK( pack_t *pack )
int FS_FileTime_PAK( searchpath_t *search, const char *filename )
{
return pack->filetime;
return search->pack->filetime;
}
void FS_PrintPAKInfo( char *dst, size_t size, pack_t *pack )
void FS_PrintInfo_PAK( searchpath_t *search, char *dst, size_t size )
{
Q_snprintf( dst, size, "%s (%i files)", pack->filename, pack->numfiles );
Q_snprintf( dst, size, "%s (%i files)", search->pack->filename, search->pack->numfiles );
}
void FS_ClosePAK( pack_t *pack )
void FS_Close_PAK( searchpath_t *search )
{
if( pack->files )
Mem_Free( pack->files );
if( pack->handle >= 0 )
close( pack->handle );
Mem_Free( pack );
}
if( search->pack->files )
Mem_Free( search->pack->files );
if( search->pack->handle >= 0 )
close( search->pack->handle );
Mem_Free( search->pack );
}

View File

@ -216,6 +216,26 @@ void FS_CloseWAD( wfile_t *wad )
Mem_Free( wad ); // free himself
}
/*
===========
FS_Close_WAD
===========
*/
void FS_Close_WAD( searchpath_t *search )
{
FS_CloseWAD( search->wad );
}
/*
===========
FS_OpenFile_WAD
===========
*/
file_t *FS_OpenFile_WAD( searchpath_t *search, const char *filename, const char *mode, int pack_ind )
{
return NULL;
}
/*
===========
W_Open
@ -376,6 +396,14 @@ qboolean FS_AddWad_Fullpath( const char *wadfile, qboolean *already_loaded, int
search->type = SEARCHPATH_WAD;
search->next = fs_searchpaths;
search->flags |= flags;
search->printinfo = FS_PrintInfo_WAD;
search->close = FS_Close_WAD;
search->openfile = FS_OpenFile_WAD;
search->filetime = FS_FileTime_WAD;
search->findfile = FS_FindFile_WAD;
search->search = FS_Search_WAD;
fs_searchpaths = search;
Con_Reportf( "Adding wadfile: %s (%i files)\n", wadfile, wad->numlumps );
@ -501,20 +529,20 @@ byte *FS_LoadWADFile( const char *path, fs_offset_t *lumpsizeptr, qboolean gamed
return NULL;
}
int FS_FileTimeWAD( wfile_t *wad )
int FS_FileTime_WAD( searchpath_t *search, const char *filename )
{
return wad->filetime;
return search->wad->filetime;
}
void FS_PrintWADInfo( char *dst, size_t size, wfile_t *wad )
void FS_PrintInfo_WAD( searchpath_t *search, char *dst, size_t size )
{
Q_snprintf( dst, size, "%s (%i files)", wad->filename, wad->numlumps );
Q_snprintf( dst, size, "%s (%i files)", search->wad->filename, search->wad->numlumps );
}
int FS_FindFileWAD( wfile_t *wad, const char *name )
int FS_FindFile_WAD( searchpath_t *search, const char *path )
{
dlumpinfo_t *lump;
signed char type = W_TypeFromExt( name );
signed char type = W_TypeFromExt( path );
qboolean anywadname = true;
string wadname, wadfolder;
string shortname;
@ -523,7 +551,7 @@ int FS_FindFileWAD( wfile_t *wad, const char *name )
if( type == TYP_NONE )
return -1;
COM_ExtractFilePath( name, wadname );
COM_ExtractFilePath( path, wadname );
wadfolder[0] = '\0';
if( COM_CheckStringEmpty( wadname ) )
@ -535,7 +563,7 @@ int FS_FindFileWAD( wfile_t *wad, const char *name )
}
// make wadname from wad fullpath
COM_FileBase( wad->filename, shortname );
COM_FileBase( search->wad->filename, shortname );
COM_DefaultExtension( shortname, ".wad" );
// quick reject by wadname
@ -544,20 +572,20 @@ int FS_FindFileWAD( wfile_t *wad, const char *name )
// NOTE: we can't using long names for wad,
// because we using original wad names[16];
COM_FileBase( name, shortname );
COM_FileBase( path, shortname );
lump = W_FindLump( wad, shortname, type );
lump = W_FindLump( search->wad, shortname, type );
if( lump )
{
return lump - wad->lumps;
return lump - search->wad->lumps;
}
return -1;
}
void FS_SearchWAD( stringlist_t *list, wfile_t *wad, const char *pattern )
void FS_Search_WAD( searchpath_t *search, stringlist_t *list, const char *pattern, int caseinsensitive )
{
string wadpattern, wadname, temp2;
signed char type = W_TypeFromExt( pattern );
@ -583,21 +611,21 @@ void FS_SearchWAD( stringlist_t *list, wfile_t *wad, const char *pattern )
}
// make wadname from wad fullpath
COM_FileBase( wad->filename, temp2 );
COM_FileBase( search->wad->filename, temp2 );
COM_DefaultExtension( temp2, ".wad" );
// quick reject by wadname
if( !anywadname && Q_stricmp( wadname, temp2 ))
return;
for( i = 0; i < wad->numlumps; i++ )
for( i = 0; i < search->wad->numlumps; i++ )
{
// if type not matching, we already have no chance ...
if( type != TYP_ANY && wad->lumps[i].type != type )
if( type != TYP_ANY && search->wad->lumps[i].type != type )
continue;
// build the lumpname with image suffix (if present)
Q_strncpy( temp, wad->lumps[i].name, sizeof( temp ));
Q_strncpy( temp, search->wad->lumps[i].name, sizeof( temp ));
while( temp[0] )
{
@ -613,7 +641,7 @@ void FS_SearchWAD( stringlist_t *list, wfile_t *wad, const char *pattern )
{
// build path: wadname/lumpname.ext
Q_snprintf( temp2, sizeof(temp2), "%s/%s", wadfolder, temp );
COM_DefaultExtension( temp2, va(".%s", W_ExtFromType( wad->lumps[i].type )));
COM_DefaultExtension( temp2, va(".%s", W_ExtFromType( search->wad->lumps[i].type )));
stringlistappend( list, temp2 );
}
}

View File

@ -159,6 +159,11 @@ void FS_CloseZIP( zip_t *zip )
Mem_Free( zip );
}
void FS_Close_ZIP( searchpath_t *search )
{
FS_CloseZIP( search->zip );
}
/*
============
FS_SortZip
@ -392,10 +397,10 @@ FS_OpenZipFile
Open a packed file using its package file descriptor
===========
*/
file_t *FS_OpenZipFile( zip_t *zip, int pack_ind )
file_t *FS_OpenFile_ZIP( searchpath_t *search, const char *filename, const char *mode, int pack_ind )
{
zipfile_t *pfile;
pfile = &zip->files[pack_ind];
pfile = &search->zip->files[pack_ind];
// compressed files handled in Zip_LoadFile
if( pfile->flags != ZIP_COMPRESSION_NO_COMPRESSION )
@ -404,7 +409,7 @@ file_t *FS_OpenZipFile( zip_t *zip, int pack_ind )
return NULL;
}
return FS_OpenHandle( zip->filename, zip->handle, pfile->offset, pfile->size );
return FS_OpenHandle( search->zip->filename, search->zip->handle, pfile->offset, pfile->size );
}
byte *FS_LoadZIPFile( const char *path, fs_offset_t *sizeptr, qboolean gamedironly )
@ -578,6 +583,14 @@ qboolean FS_AddZip_Fullpath( const char *zipfile, qboolean *already_loaded, int
search->type = SEARCHPATH_ZIP;
search->next = fs_searchpaths;
search->flags |= flags;
search->printinfo = FS_PrintInfo_ZIP;
search->close = FS_Close_ZIP;
search->openfile = FS_OpenFile_ZIP;
search->filetime = FS_FileTime_ZIP;
search->findfile = FS_FindFile_ZIP;
search->search = FS_Search_ZIP;
fs_searchpaths = search;
Con_Reportf( "Adding zipfile: %s (%i files)\n", zipfile, zip->numfiles );
@ -601,29 +614,29 @@ qboolean FS_AddZip_Fullpath( const char *zipfile, qboolean *already_loaded, int
}
}
int FS_FileTimeZIP( zip_t *zip )
int FS_FileTime_ZIP( searchpath_t *search, const char *filename )
{
return zip->filetime;
return search->zip->filetime;
}
void FS_PrintZIPInfo( char *dst, size_t size, zip_t *zip )
void FS_PrintInfo_ZIP( searchpath_t *search, char *dst, size_t size )
{
Q_snprintf( dst, size, "%s (%i files)", zip->filename, zip->numfiles );
Q_snprintf( dst, size, "%s (%i files)", search->zip->filename, search->zip->numfiles );
}
int FS_FindFileZIP( zip_t *zip, const char *name )
int FS_FindFile_ZIP( searchpath_t *search, const char *path )
{
int left, right, middle;
// look for the file (binary search)
left = 0;
right = zip->numfiles - 1;
right = search->zip->numfiles - 1;
while( left <= right )
{
int diff;
middle = (left + right) / 2;
diff = Q_stricmp( zip->files[middle].name, name );
diff = Q_stricmp( search->zip->files[middle].name, path );
// Found it
if( !diff )
@ -638,15 +651,15 @@ int FS_FindFileZIP( zip_t *zip, const char *name )
return -1;
}
void FS_SearchZIP( stringlist_t *list, zip_t *zip, const char *pattern )
void FS_Search_ZIP( searchpath_t *search, stringlist_t *list, const char *pattern, int caseinsensitive )
{
string temp;
const char *slash, *backslash, *colon, *separator;
int j, i;
for( i = 0; i < zip->numfiles; i++ )
for( i = 0; i < search->zip->numfiles; i++ )
{
Q_strncpy( temp, zip->files[i].name, sizeof( temp ));
Q_strncpy( temp, search->zip->files[i].name, sizeof( temp ));
while( temp[0] )
{
if( matchpattern( temp, pattern, true ))