Browse Source

filesystem: switch file operations to an interface

pull/2/head
Velaron 2 years ago committed by Alibek Omarov
parent
commit
24f7db19d8
  1. 110
      filesystem/dir.c
  2. 200
      filesystem/filesystem.c
  3. 56
      filesystem/filesystem_internal.h
  4. 46
      filesystem/pak.c
  5. 62
      filesystem/wad.c
  6. 39
      filesystem/zip.c

110
filesystem/dir.c

@ -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 );
}

200
filesystem/filesystem.c

@ -117,12 +117,12 @@ FILEMATCH COMMON SYSTEM
============================================================================= =============================================================================
*/ */
static void stringlistinit( stringlist_t *list ) void stringlistinit( stringlist_t *list )
{ {
memset( list, 0, sizeof( *list )); memset( list, 0, sizeof( *list ));
} }
static void stringlistfreecontents( stringlist_t *list ) void stringlistfreecontents( stringlist_t *list )
{ {
int i; 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; int i;
signed char *c; signed char *c;
@ -463,6 +463,14 @@ void FS_AddGameDirectory( const char *dir, uint flags )
search->next = fs_searchpaths; search->next = fs_searchpaths;
search->type = SEARCHPATH_PLAIN; search->type = SEARCHPATH_PLAIN;
search->flags = flags; 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; fs_searchpaths = search;
} }
@ -488,20 +496,7 @@ void FS_ClearSearchPath( void )
} }
else fs_searchpaths = search->next; else fs_searchpaths = search->next;
switch( search->type ) search->close( search );
{
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;
}
Mem_Free( 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 ); 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 ), Q_snprintf( dllInfo->fullPath, sizeof( dllInfo->fullPath ),
"%s%s", search->filename, dllInfo->shortPath ); "%s%s", search->filename, dllInfo->shortPath );
@ -1533,21 +1528,7 @@ void FS_Path_f( void )
{ {
string info; string info;
switch( s->type ) s->printinfo( s, info, sizeof(info) );
{
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;
}
Con_Printf( "%s", info ); Con_Printf( "%s", info );
@ -1816,50 +1797,18 @@ searchpath_t *FS_FindFile( const char *name, int *index, qboolean gamedironly )
// search through the path, one element at a time // search through the path, one element at a time
for( search = fs_searchpaths; search; search = search->next ) for( search = fs_searchpaths; search; search = search->next )
{ {
int pack_ind;
if( gamedironly & !FBitSet( search->flags, FS_GAMEDIRONLY_SEARCH_FLAGS )) if( gamedironly & !FBitSet( search->flags, FS_GAMEDIRONLY_SEARCH_FLAGS ))
continue; continue;
// is the element a pak file? pack_ind = search->findfile( search, name );
if( search->type == SEARCHPATH_PAK )
{
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( pack_ind >= 0 )
{ {
if( index ) *index = pack_ind; if( index ) *index = pack_ind;
return search; 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( fs_ext_path ) if( fs_ext_path )
{ {
@ -1907,26 +1856,7 @@ file_t *FS_OpenReadFile( const char *filename, const char *mode, qboolean gamedi
if( search == NULL ) if( search == NULL )
return NULL; return NULL;
switch( search->type ) return search->openfile( search, filename, mode, pack_ind );
{
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;
} }
/* /*
@ -2611,26 +2541,7 @@ int FS_FileTime( const char *filename, qboolean gamedironly )
search = FS_FindFile( filename, &pack_ind, gamedironly ); search = FS_FindFile( filename, &pack_ind, gamedironly );
if( !search ) return -1; // doesn't exist if( !search ) return -1; // doesn't exist
switch( search->type ) return search->filetime( search, filename );
{
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
} }
/* /*
@ -2726,31 +2637,13 @@ search_t *FS_Search( const char *pattern, int caseinsensitive, int gamedironly )
{ {
search_t *search = NULL; search_t *search = NULL;
searchpath_t *searchpath; searchpath_t *searchpath;
pack_t *pak; int i, numfiles, numchars;
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 resultlist;
stringlist_t dirlist;
char *basepath;
if( pattern[0] == '.' || pattern[0] == ':' || pattern[0] == '/' || pattern[0] == '\\' ) if( pattern[0] == '.' || pattern[0] == ':' || pattern[0] == '/' || pattern[0] == '\\' )
return NULL; // punctuation issues return NULL; // punctuation issues
stringlistinit( &resultlist ); 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 // search through the path, one element at a time
for( searchpath = fs_searchpaths; searchpath; searchpath = searchpath->next ) for( searchpath = fs_searchpaths; searchpath; searchpath = searchpath->next )
@ -2758,46 +2651,7 @@ search_t *FS_Search( const char *pattern, int caseinsensitive, int gamedironly )
if( gamedironly && !FBitSet( searchpath->flags, FS_GAMEDIRONLY_SEARCH_FLAGS )) if( gamedironly && !FBitSet( searchpath->flags, FS_GAMEDIRONLY_SEARCH_FLAGS ))
continue; continue;
// is the element a pak file? searchpath->search( searchpath, &resultlist, pattern, caseinsensitive );
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 );
}
} }
if( resultlist.numstrings ) if( resultlist.numstrings )
@ -2806,21 +2660,21 @@ search_t *FS_Search( const char *pattern, int caseinsensitive, int gamedironly )
numfiles = resultlist.numstrings; numfiles = resultlist.numstrings;
numchars = 0; numchars = 0;
for( resultlistindex = 0; resultlistindex < resultlist.numstrings; resultlistindex++ ) for( i = 0; i < resultlist.numstrings; i++ )
numchars += (int)Q_strlen( resultlist.strings[resultlistindex]) + 1; numchars += (int)Q_strlen( resultlist.strings[i]) + 1;
search = Mem_Calloc( fs_mempool, sizeof(search_t) + numchars + numfiles * sizeof( char* )); search = Mem_Calloc( fs_mempool, sizeof(search_t) + numchars + numfiles * sizeof( char* ));
search->filenames = (char **)((char *)search + sizeof( search_t )); search->filenames = (char **)((char *)search + sizeof( search_t ));
search->filenamesbuffer = (char *)((char *)search + sizeof( search_t ) + numfiles * sizeof( char* )); search->filenamesbuffer = (char *)((char *)search + sizeof( search_t ) + numfiles * sizeof( char* ));
search->numfilenames = (int)numfiles; search->numfilenames = (int)numfiles;
numfiles = numchars = 0; numfiles = numchars = 0;
for( resultlistindex = 0; resultlistindex < resultlist.numstrings; resultlistindex++ ) for( i = 0; i < resultlist.numstrings; i++ )
{ {
size_t textlen; size_t textlen;
search->filenames[numfiles] = search->filenamesbuffer + numchars; search->filenames[numfiles] = search->filenamesbuffer + numchars;
textlen = Q_strlen(resultlist.strings[resultlistindex]) + 1; textlen = Q_strlen(resultlist.strings[i]) + 1;
memcpy( search->filenames[numfiles], resultlist.strings[resultlistindex], textlen ); memcpy( search->filenames[numfiles], resultlist.strings[i], textlen );
numfiles++; numfiles++;
numchars += (int)textlen; numchars += (int)textlen;
} }
@ -2828,8 +2682,6 @@ search_t *FS_Search( const char *pattern, int caseinsensitive, int gamedironly )
stringlistfreecontents( &resultlist ); stringlistfreecontents( &resultlist );
Mem_Free( basepath );
return search; return search;
} }

56
filesystem/filesystem_internal.h

@ -69,13 +69,22 @@ typedef struct searchpath_s
string filename; string filename;
int type; int type;
int flags; int flags;
union union
{ {
pack_t *pack; pack_t *pack;
wfile_t *wad; wfile_t *wad;
zip_t *zip; zip_t *zip;
}; };
struct searchpath_s *next; 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; } searchpath_t;
extern fs_globals_t FI; 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_Delete( const char *path );
qboolean FS_SysFileExists( const char *path, qboolean casesensitive ); qboolean FS_SysFileExists( const char *path, qboolean casesensitive );
const char *FS_GetDiskPath( const char *name, qboolean gamedironly ); 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 stringlistappend( stringlist_t *list, char *text );
void listdirectory( stringlist_t *list, const char *path, qboolean lowercase );
void FS_CreatePath( char *path ); void FS_CreatePath( char *path );
qboolean FS_SysFolderExists( const char *path ); qboolean FS_SysFolderExists( const char *path );
file_t *FS_OpenReadFile( const char *filename, const char *mode, qboolean gamedironly ); 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 // pak.c
// //
int FS_FileTimePAK( pack_t *pack ); int FS_FileTime_PAK( searchpath_t *search, const char *filename );
int FS_FindFilePAK( pack_t *pack, const char *name ); int FS_FindFile_PAK( searchpath_t *search, const char *path );
void FS_PrintPAKInfo( char *dst, size_t size, pack_t *pack ); void FS_PrintInfo_PAK( searchpath_t *search, char *dst, size_t size );
void FS_ClosePAK( pack_t *pack ); void FS_Close_PAK( searchpath_t *search );
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 );
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 );
qboolean FS_AddPak_Fullpath( const char *pakfile, qboolean *already_loaded, int flags ); qboolean FS_AddPak_Fullpath( const char *pakfile, qboolean *already_loaded, int flags );
// //
// wad.c // wad.c
// //
int FS_FileTimeWAD( wfile_t *wad ); int FS_FileTime_WAD( searchpath_t *search, const char *filename );
int FS_FindFileWAD( wfile_t *wad, const char *name ); int FS_FindFile_WAD( searchpath_t *search, const char *path );
void FS_PrintWADInfo( char *dst, size_t size, wfile_t *wad ); void FS_PrintInfo_WAD( searchpath_t *search, char *dst, size_t size );
void FS_CloseWAD( wfile_t *wad ); void FS_Close_WAD( searchpath_t *search );
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 );
byte *FS_LoadWADFile( const char *path, fs_offset_t *sizeptr, qboolean gamedironly ); byte *FS_LoadWADFile( const char *path, fs_offset_t *sizeptr, qboolean gamedironly );
qboolean FS_AddWad_Fullpath( const char *wadfile, qboolean *already_loaded, int flags ); qboolean FS_AddWad_Fullpath( const char *wadfile, qboolean *already_loaded, int flags );
@ -199,15 +211,25 @@ void FS_WatchFrame( void );
// //
// zip.c // zip.c
// //
int FS_FileTimeZIP( zip_t *zip ); int FS_FileTime_ZIP( searchpath_t *search, const char *filename );
int FS_FindFileZIP( zip_t *zip, const char *name ); int FS_FindFile_ZIP( searchpath_t *search, const char *path );
void FS_PrintZIPInfo( char *dst, size_t size, zip_t *zip ); void FS_PrintInfo_ZIP( searchpath_t *search, char *dst, size_t size );
void FS_CloseZIP( zip_t *zip ); void FS_Close_ZIP( searchpath_t *search );
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 );
byte *FS_LoadZIPFile( const char *path, fs_offset_t *sizeptr, qboolean gamedironly ); 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 ); 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 #ifdef __cplusplus
} }
#endif #endif

46
filesystem/pak.c

@ -230,13 +230,13 @@ FS_OpenPackedFile
Open a packed file using its package file descriptor 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; 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->type = SEARCHPATH_PAK;
search->next = fs_searchpaths; search->next = fs_searchpaths;
search->flags |= flags; 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; fs_searchpaths = search;
Con_Reportf( "Adding pakfile: %s (%i files)\n", pakfile, pak->numfiles ); 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; int left, right, middle;
// look for the file (binary search) // look for the file (binary search)
left = 0; left = 0;
right = pack->numfiles - 1; right = search->pack->numfiles - 1;
while( left <= right ) while( left <= right )
{ {
int diff; int diff;
middle = (left + right) / 2; middle = (left + right) / 2;
diff = Q_stricmp( pack->files[middle].name, name ); diff = Q_stricmp( search->pack->files[middle].name, path );
// Found it // Found it
if( !diff ) if( !diff )
@ -337,15 +345,15 @@ int FS_FindFilePAK( pack_t *pack, const char *name )
return -1; 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; string temp;
const char *slash, *backslash, *colon, *separator; const char *slash, *backslash, *colon, *separator;
int j, i; 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] ) while( temp[0] )
{ {
if( matchpattern( temp, pattern, true )) 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 ) if( search->pack->files )
Mem_Free( pack->files ); Mem_Free( search->pack->files );
if( pack->handle >= 0 ) if( search->pack->handle >= 0 )
close( pack->handle ); close( search->pack->handle );
Mem_Free( pack ); Mem_Free( search->pack );
} }

62
filesystem/wad.c

@ -216,6 +216,26 @@ void FS_CloseWAD( wfile_t *wad )
Mem_Free( wad ); // free himself 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 W_Open
@ -376,6 +396,14 @@ qboolean FS_AddWad_Fullpath( const char *wadfile, qboolean *already_loaded, int
search->type = SEARCHPATH_WAD; search->type = SEARCHPATH_WAD;
search->next = fs_searchpaths; search->next = fs_searchpaths;
search->flags |= flags; 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; fs_searchpaths = search;
Con_Reportf( "Adding wadfile: %s (%i files)\n", wadfile, wad->numlumps ); 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; 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; dlumpinfo_t *lump;
signed char type = W_TypeFromExt( name ); signed char type = W_TypeFromExt( path );
qboolean anywadname = true; qboolean anywadname = true;
string wadname, wadfolder; string wadname, wadfolder;
string shortname; string shortname;
@ -523,7 +551,7 @@ int FS_FindFileWAD( wfile_t *wad, const char *name )
if( type == TYP_NONE ) if( type == TYP_NONE )
return -1; return -1;
COM_ExtractFilePath( name, wadname ); COM_ExtractFilePath( path, wadname );
wadfolder[0] = '\0'; wadfolder[0] = '\0';
if( COM_CheckStringEmpty( wadname ) ) if( COM_CheckStringEmpty( wadname ) )
@ -535,7 +563,7 @@ int FS_FindFileWAD( wfile_t *wad, const char *name )
} }
// make wadname from wad fullpath // make wadname from wad fullpath
COM_FileBase( wad->filename, shortname ); COM_FileBase( search->wad->filename, shortname );
COM_DefaultExtension( shortname, ".wad" ); COM_DefaultExtension( shortname, ".wad" );
// quick reject by wadname // 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, // NOTE: we can't using long names for wad,
// because we using original wad names[16]; // 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 ) if( lump )
{ {
return lump - wad->lumps; return lump - search->wad->lumps;
} }
return -1; 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; string wadpattern, wadname, temp2;
signed char type = W_TypeFromExt( pattern ); 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 // make wadname from wad fullpath
COM_FileBase( wad->filename, temp2 ); COM_FileBase( search->wad->filename, temp2 );
COM_DefaultExtension( temp2, ".wad" ); COM_DefaultExtension( temp2, ".wad" );
// quick reject by wadname // quick reject by wadname
if( !anywadname && Q_stricmp( wadname, temp2 )) if( !anywadname && Q_stricmp( wadname, temp2 ))
return; 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 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; continue;
// build the lumpname with image suffix (if present) // 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] ) while( temp[0] )
{ {
@ -613,7 +641,7 @@ void FS_SearchWAD( stringlist_t *list, wfile_t *wad, const char *pattern )
{ {
// build path: wadname/lumpname.ext // build path: wadname/lumpname.ext
Q_snprintf( temp2, sizeof(temp2), "%s/%s", wadfolder, temp ); 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 ); stringlistappend( list, temp2 );
} }
} }

39
filesystem/zip.c

@ -159,6 +159,11 @@ void FS_CloseZIP( zip_t *zip )
Mem_Free( zip ); Mem_Free( zip );
} }
void FS_Close_ZIP( searchpath_t *search )
{
FS_CloseZIP( search->zip );
}
/* /*
============ ============
FS_SortZip FS_SortZip
@ -392,10 +397,10 @@ FS_OpenZipFile
Open a packed file using its package file descriptor 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; zipfile_t *pfile;
pfile = &zip->files[pack_ind]; pfile = &search->zip->files[pack_ind];
// compressed files handled in Zip_LoadFile // compressed files handled in Zip_LoadFile
if( pfile->flags != ZIP_COMPRESSION_NO_COMPRESSION ) if( pfile->flags != ZIP_COMPRESSION_NO_COMPRESSION )
@ -404,7 +409,7 @@ file_t *FS_OpenZipFile( zip_t *zip, int pack_ind )
return NULL; 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 ) 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->type = SEARCHPATH_ZIP;
search->next = fs_searchpaths; search->next = fs_searchpaths;
search->flags |= flags; 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; fs_searchpaths = search;
Con_Reportf( "Adding zipfile: %s (%i files)\n", zipfile, zip->numfiles ); 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; int left, right, middle;
// look for the file (binary search) // look for the file (binary search)
left = 0; left = 0;
right = zip->numfiles - 1; right = search->zip->numfiles - 1;
while( left <= right ) while( left <= right )
{ {
int diff; int diff;
middle = (left + right) / 2; middle = (left + right) / 2;
diff = Q_stricmp( zip->files[middle].name, name ); diff = Q_stricmp( search->zip->files[middle].name, path );
// Found it // Found it
if( !diff ) if( !diff )
@ -638,15 +651,15 @@ int FS_FindFileZIP( zip_t *zip, const char *name )
return -1; 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; string temp;
const char *slash, *backslash, *colon, *separator; const char *slash, *backslash, *colon, *separator;
int j, i; 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] ) while( temp[0] )
{ {
if( matchpattern( temp, pattern, true )) if( matchpattern( temp, pattern, true ))

Loading…
Cancel
Save