filesystem: allow to pass custom allocation functions to LoadFile

This commit is contained in:
Alibek Omarov 2024-02-07 05:05:22 +03:00
parent 21c828ee40
commit bb03e2597c
4 changed files with 71 additions and 33 deletions

View File

@ -233,7 +233,7 @@ static file_t *FS_OpenFile_AndroidAssets( searchpath_t *search, const char *file
return file;
}
static byte *FS_LoadAndroidAssetsFile( searchpath_t *search, const char *path, int pack_ind, fs_offset_t *filesize )
static byte *FS_LoadAndroidAssetsFile( searchpath_t *search, const char *path, int pack_ind, fs_offset_t *filesize, void *( *pfnAlloc )( size_t ), void ( *pfnFree )( void * ))
{
byte *buf;
off_t size;
@ -247,18 +247,24 @@ static byte *FS_LoadAndroidAssetsFile( searchpath_t *search, const char *path, i
size = AAsset_getLength( asset );
buf = (byte *)Mem_Malloc( fs_mempool, size + 1 );
buf = (byte *)pfnAlloc( size + 1 );
if( unlikely( !buf ))
{
Con_Reportf( "%s: can't alloc %d bytes, no free memory\n", __func__, size + 1 );
AAsset_close( asset );
return NULL;
}
buf[size] = '\0';
if( AAsset_read( asset, buf, size ) < 0 )
{
Mem_Free( buf );
pfnFree( buf );
AAsset_close( asset );
return NULL;
}
AAsset_close( asset );
if( filesize ) *filesize = size;
return buf;

View File

@ -2419,6 +2419,16 @@ static void FS_Purge( file_t *file )
file->ungetc = EOF;
}
static void *FS_CustomAlloc( size_t size )
{
return Mem_Malloc( fs_mempool, size );
}
static void FS_CustomFree( void *data )
{
return Mem_Free( data );
}
/*
============
FS_LoadFile
@ -2427,12 +2437,16 @@ Filename are relative to the xash directory.
Always appends a 0 byte.
============
*/
byte *FS_LoadFile( const char *path, fs_offset_t *filesizeptr, qboolean gamedironly )
static byte *FS_LoadFile_( const char *path, fs_offset_t *filesizeptr, const qboolean gamedironly, const qboolean custom_alloc )
{
searchpath_t *search;
fs_offset_t filesize;
file_t *file;
byte *buf;
char netpath[MAX_SYSPATH];
int pack_ind;
void *( *pfnAlloc )( size_t ) = custom_alloc ? FS_CustomAlloc : malloc;
void ( *pfnFree )( void * ) = custom_alloc ? FS_CustomFree : free;
// some mappers used leading '/' or '\' in path to models or sounds
if( path[0] == '/' || path[0] == '\\' )
@ -2451,27 +2465,35 @@ byte *FS_LoadFile( const char *path, fs_offset_t *filesizeptr, qboolean gamediro
// custom load file function for compressed files
if( search->pfnLoadFile )
return search->pfnLoadFile( search, netpath, pack_ind, filesizeptr );
return search->pfnLoadFile( search, netpath, pack_ind, filesizeptr, pfnAlloc, pfnFree );
file = search->pfnOpenFile( search, netpath, "rb", pack_ind );
if( file )
if( !file ) // TODO: indicate errors
return NULL;
filesize = file->real_length;
buf = (byte *)pfnAlloc( filesize + 1 );
if( unlikely( !buf )) // TODO: indicate errors
{
fs_offset_t filesize = file->real_length;
byte *buf;
buf = (byte *)Mem_Malloc( fs_mempool, filesize + 1 );
buf[filesize] = '\0';
FS_Read( file, buf, filesize );
Con_Reportf( "%s: can't alloc %d bytes, no free memory\n", __func__, filesize + 1 );
FS_Close( file );
if( filesizeptr )
*filesizeptr = filesize;
return buf;
return NULL;
}
return NULL;
buf[filesize] = '\0';
FS_Read( file, buf, filesize );
FS_Close( file );
if( filesizeptr ) *filesizeptr = filesize;
return buf;
}
byte *FS_LoadFile( const char *path, fs_offset_t *filesizeptr, qboolean gamedironly )
{
return FS_LoadFile_( path, filesizeptr, gamedironly, g_engfuncs._Mem_Alloc != _Mem_Alloc );
}
qboolean CRC32_File( dword *crcvalue, const char *filename )

View File

@ -591,7 +591,7 @@ W_ReadLump
reading lump into temp buffer
===========
*/
static byte *W_ReadLump( searchpath_t *search, const char *path, int pack_ind, fs_offset_t *lumpsizeptr )
static byte *W_ReadLump( searchpath_t *search, const char *path, int pack_ind, fs_offset_t *lumpsizeptr, void *( *pfnAlloc )( size_t ), void ( *pfnFree )( void * ))
{
const wfile_t *wad = search->wad;
const dlumpinfo_t *lump = &wad->lumps[pack_ind];
@ -613,19 +613,25 @@ static byte *W_ReadLump( searchpath_t *search, const char *path, int pack_ind, f
return NULL;
}
buf = (byte *)Mem_Malloc( wad->mempool, lump->disksize );
buf = (byte *)pfnAlloc( lump->disksize );
if( unlikely( !buf ))
{
Con_Reportf( S_ERROR "%s: can't alloc %d bytes, no free memory\n", __func__, lump->disksize );
FS_Seek( wad->handle, oldpos, SEEK_SET );
return NULL;
}
size = FS_Read( wad->handle, buf, lump->disksize );
FS_Seek( wad->handle, oldpos, SEEK_SET );
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 );
pfnFree( buf );
return NULL;
}
if( lumpsizeptr ) *lumpsizeptr = lump->disksize;
FS_Seek( wad->handle, oldpos, SEEK_SET );
return buf;
}

View File

@ -422,7 +422,7 @@ FS_LoadZIPFile
===========
*/
static byte *FS_LoadZIPFile( searchpath_t *search, const char *path, int pack_ind, fs_offset_t *sizeptr )
static byte *FS_LoadZIPFile( searchpath_t *search, const char *path, int pack_ind, fs_offset_t *sizeptr, void *( *pfnAlloc )( size_t ), void ( *pfnFree )( void * ))
{
zipfile_t *file;
byte *compressed_buffer = NULL, *decompressed_buffer = NULL;
@ -451,11 +451,16 @@ static byte *FS_LoadZIPFile( searchpath_t *search, const char *path, int pack_in
return NULL;
}*/
decompressed_buffer = pfnAlloc( file->size + 1 );
if( unlikely( !decompressed_buffer ))
{
Con_Reportf( S_ERROR "%s: can't alloc %d bytes, no free memory\n", __func__, file->size + 1 );
return NULL;
}
decompressed_buffer[file->size] = '\0';
if( file->flags == ZIP_COMPRESSION_NO_COMPRESSION )
{
decompressed_buffer = Mem_Malloc( fs_mempool, file->size + 1 );
decompressed_buffer[file->size] = '\0';
c = read( search->zip->handle, decompressed_buffer, file->size );
if( c != file->size )
{
@ -472,7 +477,7 @@ static byte *FS_LoadZIPFile( searchpath_t *search, const char *path, int pack_in
if( final_crc != file->crc32 )
{
Con_Reportf( S_ERROR "Zip_LoadFile: %s file crc32 mismatch\n", file->name );
Mem_Free( decompressed_buffer );
pfnFree( decompressed_buffer );
return NULL;
}
#endif // ENABLE_CRC_CHECK
@ -485,8 +490,6 @@ static byte *FS_LoadZIPFile( searchpath_t *search, const char *path, int pack_in
else if( file->flags == ZIP_COMPRESSION_DEFLATED )
{
compressed_buffer = Mem_Malloc( fs_mempool, file->compressed_size + 1 );
decompressed_buffer = Mem_Malloc( fs_mempool, file->size + 1 );
decompressed_buffer[file->size] = '\0';
c = read( search->zip->handle, compressed_buffer, file->compressed_size );
if( c != file->compressed_size )
@ -529,7 +532,7 @@ static byte *FS_LoadZIPFile( searchpath_t *search, const char *path, int pack_in
if( final_crc != file->crc32 )
{
Con_Reportf( S_ERROR "Zip_LoadFile: %s file crc32 mismatch\n", file->name );
Mem_Free( decompressed_buffer );
pfnFree( decompressed_buffer );
return NULL;
}
#endif
@ -542,7 +545,7 @@ static byte *FS_LoadZIPFile( searchpath_t *search, const char *path, int pack_in
{
Con_Reportf( S_ERROR "Zip_LoadFile: %s : error while file decompressing. Zlib return code %d.\n", file->name, zlib_result );
Mem_Free( compressed_buffer );
Mem_Free( decompressed_buffer );
pfnFree( decompressed_buffer );
return NULL;
}
@ -550,6 +553,7 @@ static byte *FS_LoadZIPFile( searchpath_t *search, const char *path, int pack_in
else
{
Con_Reportf( S_ERROR "Zip_LoadFile: %s : file compressed with unknown algorithm.\n", file->name );
pfnFree( decompressed_buffer );
return NULL;
}