filesystem: make all archive searchpath functions private

This commit is contained in:
Alibek Omarov 2022-12-15 00:59:52 +03:00
parent 48c17d08d9
commit 08f834cd82
4 changed files with 434 additions and 352 deletions

View File

@ -182,22 +182,11 @@ searchpath_t *FS_FindFile( const char *name, int *index, qboolean gamedironly );
//
// pak.c
//
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_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 );
@ -211,13 +200,7 @@ void FS_WatchFrame( void );
//
// zip.c
//
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_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 );
//

View File

@ -230,7 +230,7 @@ FS_OpenPackedFile
Open a packed file using its package file descriptor
===========
*/
file_t *FS_OpenFile_PAK( searchpath_t *search, const char *filename, const char *mode, int pack_ind )
static file_t *FS_OpenFile_PAK( searchpath_t *search, const char *filename, const char *mode, int pack_ind )
{
dpackfile_t *pfile;
@ -239,6 +239,125 @@ file_t *FS_OpenFile_PAK( searchpath_t *search, const char *filename, const char
return FS_OpenHandle( search->pack->filename, search->pack->handle, pfile->filepos, pfile->filelen );
}
/*
===========
FS_FindFile_PAK
===========
*/
static int FS_FindFile_PAK( searchpath_t *search, const char *path )
{
int left, right, middle;
// look for the file (binary search)
left = 0;
right = search->pack->numfiles - 1;
while( left <= right )
{
int diff;
middle = (left + right) / 2;
diff = Q_stricmp( search->pack->files[middle].name, path );
// Found it
if( !diff )
{
return middle;
}
// if we're too far in the list
if( diff > 0 )
right = middle - 1;
else left = middle + 1;
}
return -1;
}
/*
===========
FS_Search_PAK
===========
*/
static 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 < search->pack->numfiles; i++ )
{
Q_strncpy( temp, search->pack->files[i].name, sizeof( temp ));
while( temp[0] )
{
if( matchpattern( temp, pattern, true ))
{
for( j = 0; j < list->numstrings; j++ )
{
if( !Q_strcmp( list->strings[j], temp ))
break;
}
if( j == list->numstrings )
stringlistappend( list, temp );
}
// strip off one path element at a time until empty
// this way directories are added to the listing if they match the pattern
slash = Q_strrchr( temp, '/' );
backslash = Q_strrchr( temp, '\\' );
colon = Q_strrchr( temp, ':' );
separator = temp;
if( separator < slash )
separator = slash;
if( separator < backslash )
separator = backslash;
if( separator < colon )
separator = colon;
*((char *)separator) = 0;
}
}
}
/*
===========
FS_FileTime_PAK
===========
*/
static int FS_FileTime_PAK( searchpath_t *search, const char *filename )
{
return search->pack->filetime;
}
/*
===========
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 );
}
/*
===========
FS_Close_PAK
===========
*/
static void FS_Close_PAK( searchpath_t *search )
{
if( search->pack->files )
Mem_Free( search->pack->files );
if( search->pack->handle >= 0 )
close( search->pack->handle );
Mem_Free( search->pack );
}
/*
================
FS_AddPak_Fullpath
@ -315,91 +434,3 @@ qboolean FS_AddPak_Fullpath( const char *pakfile, qboolean *already_loaded, int
return false;
}
}
int FS_FindFile_PAK( searchpath_t *search, const char *path )
{
int left, right, middle;
// look for the file (binary search)
left = 0;
right = search->pack->numfiles - 1;
while( left <= right )
{
int diff;
middle = (left + right) / 2;
diff = Q_stricmp( search->pack->files[middle].name, path );
// Found it
if( !diff )
{
return middle;
}
// if we're too far in the list
if( diff > 0 )
right = middle - 1;
else left = middle + 1;
}
return -1;
}
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 < search->pack->numfiles; i++ )
{
Q_strncpy( temp, search->pack->files[i].name, sizeof( temp ));
while( temp[0] )
{
if( matchpattern( temp, pattern, true ))
{
for( j = 0; j < list->numstrings; j++ )
{
if( !Q_strcmp( list->strings[j], temp ))
break;
}
if( j == list->numstrings )
stringlistappend( list, temp );
}
// strip off one path element at a time until empty
// this way directories are added to the listing if they match the pattern
slash = Q_strrchr( temp, '/' );
backslash = Q_strrchr( temp, '\\' );
colon = Q_strrchr( temp, ':' );
separator = temp;
if( separator < slash )
separator = slash;
if( separator < backslash )
separator = backslash;
if( separator < colon )
separator = colon;
*((char *)separator) = 0;
}
}
}
int FS_FileTime_PAK( searchpath_t *search, const char *filename )
{
return search->pack->filetime;
}
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 );
}
void FS_Close_PAK( searchpath_t *search )
{
if( search->pack->files )
Mem_Free( search->pack->files );
if( search->pack->handle >= 0 )
close( search->pack->handle );
Mem_Free( search->pack );
}

View File

@ -154,6 +154,48 @@ static const char *W_ExtFromType( signed char lumptype )
return "";
}
/*
===========
W_FindLump
Serach for already existed lump
===========
*/
static dlumpinfo_t *W_FindLump( wfile_t *wad, const char *name, const signed char matchtype )
{
int left, right;
if( !wad || !wad->lumps || matchtype == TYP_NONE )
return NULL;
// look for the file (binary search)
left = 0;
right = wad->numlumps - 1;
while( left <= right )
{
int middle = (left + right) / 2;
int diff = Q_stricmp( wad->lumps[middle].name, name );
if( !diff )
{
if(( matchtype == TYP_ANY ) || ( matchtype == wad->lumps[middle].type ))
return &wad->lumps[middle]; // found
else if( wad->lumps[middle].type < matchtype )
diff = 1;
else if( wad->lumps[middle].type > matchtype )
diff = -1;
else break; // not found
}
// if we're too far in the list
if( diff > 0 ) right = middle - 1;
else left = middle + 1;
}
return NULL;
}
/*
====================
W_AddFileToWad
@ -362,184 +404,35 @@ static wfile_t *W_Open( const char *filename, int *error )
return wad;
}
/*
====================
FS_AddWad_Fullpath
====================
*/
qboolean FS_AddWad_Fullpath( const char *wadfile, qboolean *already_loaded, int flags )
{
searchpath_t *search;
wfile_t *wad = NULL;
const char *ext = COM_FileExtension( wadfile );
int errorcode = WAD_LOAD_COULDNT_OPEN;
for( search = fs_searchpaths; search; search = search->next )
{
if( search->type == SEARCHPATH_WAD && !Q_stricmp( search->wad->filename, wadfile ))
{
if( already_loaded ) *already_loaded = true;
return true; // already loaded
}
}
if( already_loaded )
*already_loaded = false;
if( !Q_stricmp( ext, "wad" ))
wad = W_Open( wadfile, &errorcode );
if( wad )
{
search = (searchpath_t *)Mem_Calloc( fs_mempool, sizeof( searchpath_t ));
search->wad = wad;
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 );
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;
}
}
/*
=============================================================================
WADSYSTEM PRIVATE ROUTINES
=============================================================================
*/
/*
===========
W_FindLump
FS_FileTime_WAD
Serach for already existed lump
===========
*/
static dlumpinfo_t *W_FindLump( wfile_t *wad, const char *name, const signed char matchtype )
{
int left, right;
if( !wad || !wad->lumps || matchtype == TYP_NONE )
return NULL;
// look for the file (binary search)
left = 0;
right = wad->numlumps - 1;
while( left <= right )
{
int middle = (left + right) / 2;
int diff = Q_stricmp( wad->lumps[middle].name, name );
if( !diff )
{
if(( matchtype == TYP_ANY ) || ( matchtype == wad->lumps[middle].type ))
return &wad->lumps[middle]; // found
else if( wad->lumps[middle].type < matchtype )
diff = 1;
else if( wad->lumps[middle].type > matchtype )
diff = -1;
else break; // not found
}
// if we're too far in the list
if( diff > 0 ) right = middle - 1;
else left = middle + 1;
}
return NULL;
}
/*
===========
W_ReadLump
reading lump into temp buffer
===========
*/
static byte *W_ReadLump( wfile_t *wad, dlumpinfo_t *lump, fs_offset_t *lumpsizeptr )
{
size_t oldpos, size = 0;
byte *buf;
// assume error
if( lumpsizeptr ) *lumpsizeptr = 0;
// no wads loaded
if( !wad || !lump ) return NULL;
oldpos = FS_Tell( wad->handle ); // don't forget restore original position
if( FS_Seek( wad->handle, lump->filepos, SEEK_SET ) == -1 )
{
Con_Reportf( S_ERROR "W_ReadLump: %s is corrupted\n", lump->name );
FS_Seek( wad->handle, oldpos, SEEK_SET );
return NULL;
}
buf = (byte *)Mem_Malloc( wad->mempool, lump->disksize );
size = FS_Read( wad->handle, buf, lump->disksize );
if( size < lump->disksize )
{
Con_Reportf( S_WARN "W_ReadLump: %s is probably corrupted\n", lump->name );
FS_Seek( wad->handle, oldpos, SEEK_SET );
Mem_Free( buf );
return NULL;
}
if( lumpsizeptr ) *lumpsizeptr = lump->disksize;
FS_Seek( wad->handle, oldpos, SEEK_SET );
return buf;
}
/*
===========
FS_LoadWADFile
loading lump into the tmp buffer
===========
*/
byte *FS_LoadWADFile( const char *path, fs_offset_t *lumpsizeptr, qboolean gamedironly )
{
searchpath_t *search;
int index;
search = FS_FindFile( path, &index, gamedironly );
if( search && search->type == SEARCHPATH_WAD )
return W_ReadLump( search->wad, &search->wad->lumps[index], lumpsizeptr );
return NULL;
}
int FS_FileTime_WAD( searchpath_t *search, const char *filename )
static int FS_FileTime_WAD( searchpath_t *search, const char *filename )
{
return search->wad->filetime;
}
void FS_PrintInfo_WAD( searchpath_t *search, char *dst, size_t size )
/*
===========
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 );
}
int FS_FindFile_WAD( searchpath_t *search, const char *path )
/*
===========
FS_FindFile_WAD
===========
*/
static int FS_FindFile_WAD( searchpath_t *search, const char *path )
{
dlumpinfo_t *lump;
signed char type = W_TypeFromExt( path );
@ -582,10 +475,15 @@ int FS_FindFile_WAD( searchpath_t *search, const char *path )
}
return -1;
}
void FS_Search_WAD( searchpath_t *search, stringlist_t *list, const char *pattern, int caseinsensitive )
/*
===========
FS_Search_WAD
===========
*/
static 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 );
@ -662,3 +560,128 @@ void FS_Search_WAD( searchpath_t *search, stringlist_t *list, const char *patter
}
}
}
/*
====================
FS_AddWad_Fullpath
====================
*/
qboolean FS_AddWad_Fullpath( const char *wadfile, qboolean *already_loaded, int flags )
{
searchpath_t *search;
wfile_t *wad = NULL;
const char *ext = COM_FileExtension( wadfile );
int errorcode = WAD_LOAD_COULDNT_OPEN;
for( search = fs_searchpaths; search; search = search->next )
{
if( search->type == SEARCHPATH_WAD && !Q_stricmp( search->wad->filename, wadfile ))
{
if( already_loaded ) *already_loaded = true;
return true; // already loaded
}
}
if( already_loaded )
*already_loaded = false;
if( !Q_stricmp( ext, "wad" ))
wad = W_Open( wadfile, &errorcode );
if( wad )
{
search = (searchpath_t *)Mem_Calloc( fs_mempool, sizeof( searchpath_t ));
search->wad = wad;
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 );
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;
}
}
/*
=============================================================================
WADSYSTEM PRIVATE ROUTINES
=============================================================================
*/
/*
===========
W_ReadLump
reading lump into temp buffer
===========
*/
static byte *W_ReadLump( wfile_t *wad, dlumpinfo_t *lump, fs_offset_t *lumpsizeptr )
{
size_t oldpos, size = 0;
byte *buf;
// assume error
if( lumpsizeptr ) *lumpsizeptr = 0;
// no wads loaded
if( !wad || !lump ) return NULL;
oldpos = FS_Tell( wad->handle ); // don't forget restore original position
if( FS_Seek( wad->handle, lump->filepos, SEEK_SET ) == -1 )
{
Con_Reportf( S_ERROR "W_ReadLump: %s is corrupted\n", lump->name );
FS_Seek( wad->handle, oldpos, SEEK_SET );
return NULL;
}
buf = (byte *)Mem_Malloc( wad->mempool, lump->disksize );
size = FS_Read( wad->handle, buf, lump->disksize );
if( size < lump->disksize )
{
Con_Reportf( S_WARN "W_ReadLump: %s is probably corrupted\n", lump->name );
FS_Seek( wad->handle, oldpos, SEEK_SET );
Mem_Free( buf );
return NULL;
}
if( lumpsizeptr ) *lumpsizeptr = lump->disksize;
FS_Seek( wad->handle, oldpos, SEEK_SET );
return buf;
}
/*
===========
FS_LoadWADFile
loading lump into the tmp buffer
===========
*/
byte *FS_LoadWADFile( const char *path, fs_offset_t *lumpsizeptr, qboolean gamedironly )
{
searchpath_t *search;
int index;
search = FS_FindFile( path, &index, gamedironly );
if( search && search->type == SEARCHPATH_WAD )
return W_ReadLump( search->wad, &search->wad->lumps[index], lumpsizeptr );
return NULL;
}

View File

@ -146,7 +146,12 @@ static void FS_EnsureOpenZip( zip_t *zip )
static void FS_EnsureOpenZip( zip_t *zip ) {}
#endif
void FS_CloseZIP( zip_t *zip )
/*
============
FS_CloseZIP
============
*/
static void FS_CloseZIP( zip_t *zip )
{
if( zip->files )
Mem_Free( zip->files );
@ -159,7 +164,12 @@ void FS_CloseZIP( zip_t *zip )
Mem_Free( zip );
}
void FS_Close_ZIP( searchpath_t *search )
/*
============
FS_Close_ZIP
============
*/
static void FS_Close_ZIP( searchpath_t *search )
{
FS_CloseZIP( search->zip );
}
@ -412,6 +422,12 @@ file_t *FS_OpenFile_ZIP( searchpath_t *search, const char *filename, const char
return FS_OpenHandle( search->zip->filename, search->zip->handle, pfile->offset, pfile->size );
}
/*
===========
FS_LoadZIPFile
===========
*/
byte *FS_LoadZIPFile( const char *path, fs_offset_t *sizeptr, qboolean gamedironly )
{
searchpath_t *search;
@ -551,7 +567,113 @@ byte *FS_LoadZIPFile( const char *path, fs_offset_t *sizeptr, qboolean gamediron
return NULL;
}
/*
===========
FS_FileTime_ZIP
===========
*/
int FS_FileTime_ZIP( searchpath_t *search, const char *filename )
{
return search->zip->filetime;
}
/*
===========
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 );
}
/*
===========
FS_FindFile_ZIP
===========
*/
int FS_FindFile_ZIP( searchpath_t *search, const char *path )
{
int left, right, middle;
// look for the file (binary search)
left = 0;
right = search->zip->numfiles - 1;
while( left <= right )
{
int diff;
middle = (left + right) / 2;
diff = Q_stricmp( search->zip->files[middle].name, path );
// Found it
if( !diff )
return middle;
// if we're too far in the list
if( diff > 0 )
right = middle - 1;
else left = middle + 1;
}
return -1;
}
/*
===========
FS_Search_ZIP
===========
*/
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 < search->zip->numfiles; i++ )
{
Q_strncpy( temp, search->zip->files[i].name, sizeof( temp ));
while( temp[0] )
{
if( matchpattern( temp, pattern, true ))
{
for( j = 0; j < list->numstrings; j++ )
{
if( !Q_strcmp( list->strings[j], temp ))
break;
}
if( j == list->numstrings )
stringlistappend( list, temp );
}
// strip off one path element at a time until empty
// this way directories are added to the listing if they match the pattern
slash = Q_strrchr( temp, '/' );
backslash = Q_strrchr( temp, '\\' );
colon = Q_strrchr( temp, ':' );
separator = temp;
if( separator < slash )
separator = slash;
if( separator < backslash )
separator = backslash;
if( separator < colon )
separator = colon;
*((char *)separator) = 0;
}
}
}
/*
===========
FS_AddZip_Fullpath
===========
*/
qboolean FS_AddZip_Fullpath( const char *zipfile, qboolean *already_loaded, int flags )
{
searchpath_t *search;
@ -614,80 +736,3 @@ qboolean FS_AddZip_Fullpath( const char *zipfile, qboolean *already_loaded, int
}
}
int FS_FileTime_ZIP( searchpath_t *search, const char *filename )
{
return search->zip->filetime;
}
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 );
}
int FS_FindFile_ZIP( searchpath_t *search, const char *path )
{
int left, right, middle;
// look for the file (binary search)
left = 0;
right = search->zip->numfiles - 1;
while( left <= right )
{
int diff;
middle = (left + right) / 2;
diff = Q_stricmp( search->zip->files[middle].name, path );
// Found it
if( !diff )
return middle;
// if we're too far in the list
if( diff > 0 )
right = middle - 1;
else left = middle + 1;
}
return -1;
}
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 < search->zip->numfiles; i++ )
{
Q_strncpy( temp, search->zip->files[i].name, sizeof( temp ));
while( temp[0] )
{
if( matchpattern( temp, pattern, true ))
{
for( j = 0; j < list->numstrings; j++ )
{
if( !Q_strcmp( list->strings[j], temp ))
break;
}
if( j == list->numstrings )
stringlistappend( list, temp );
}
// strip off one path element at a time until empty
// this way directories are added to the listing if they match the pattern
slash = Q_strrchr( temp, '/' );
backslash = Q_strrchr( temp, '\\' );
colon = Q_strrchr( temp, ':' );
separator = temp;
if( separator < slash )
separator = slash;
if( separator < backslash )
separator = backslash;
if( separator < colon )
separator = colon;
*((char *)separator) = 0;
}
}
}