From bb03e2597cb7275ac61d282d4979369bd5a91064 Mon Sep 17 00:00:00 2001 From: Alibek Omarov Date: Wed, 7 Feb 2024 05:05:22 +0300 Subject: [PATCH] filesystem: allow to pass custom allocation functions to LoadFile --- filesystem/android.c | 14 +++++++---- filesystem/filesystem.c | 52 +++++++++++++++++++++++++++++------------ filesystem/wad.c | 16 +++++++++---- filesystem/zip.c | 22 ++++++++++------- 4 files changed, 71 insertions(+), 33 deletions(-) diff --git a/filesystem/android.c b/filesystem/android.c index 88c2f303..62c4eca3 100644 --- a/filesystem/android.c +++ b/filesystem/android.c @@ -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; diff --git a/filesystem/filesystem.c b/filesystem/filesystem.c index be50ca09..39114992 100644 --- a/filesystem/filesystem.c +++ b/filesystem/filesystem.c @@ -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 ) diff --git a/filesystem/wad.c b/filesystem/wad.c index b11d3f49..ddc461bf 100644 --- a/filesystem/wad.c +++ b/filesystem/wad.c @@ -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; } diff --git a/filesystem/zip.c b/filesystem/zip.c index 81840dc8..97334ff8 100644 --- a/filesystem/zip.c +++ b/filesystem/zip.c @@ -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; }