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; 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; byte *buf;
off_t size; off_t size;
@ -247,18 +247,24 @@ static byte *FS_LoadAndroidAssetsFile( searchpath_t *search, const char *path, i
size = AAsset_getLength( asset ); 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'; buf[size] = '\0';
if( AAsset_read( asset, buf, size ) < 0 ) if( AAsset_read( asset, buf, size ) < 0 )
{ {
Mem_Free( buf ); pfnFree( buf );
AAsset_close( asset ); AAsset_close( asset );
return NULL; return NULL;
} }
AAsset_close( asset ); AAsset_close( asset );
if( filesize ) *filesize = size; if( filesize ) *filesize = size;
return buf; return buf;

View File

@ -2419,6 +2419,16 @@ static void FS_Purge( file_t *file )
file->ungetc = EOF; 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 FS_LoadFile
@ -2427,12 +2437,16 @@ Filename are relative to the xash directory.
Always appends a 0 byte. 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; searchpath_t *search;
fs_offset_t filesize;
file_t *file; file_t *file;
byte *buf;
char netpath[MAX_SYSPATH]; char netpath[MAX_SYSPATH];
int pack_ind; 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 // some mappers used leading '/' or '\' in path to models or sounds
if( path[0] == '/' || path[0] == '\\' ) 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 // custom load file function for compressed files
if( search->pfnLoadFile ) 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 ); 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; Con_Reportf( "%s: can't alloc %d bytes, no free memory\n", __func__, filesize + 1 );
byte *buf;
buf = (byte *)Mem_Malloc( fs_mempool, filesize + 1 );
buf[filesize] = '\0';
FS_Read( file, buf, filesize );
FS_Close( file ); FS_Close( file );
return NULL;
if( filesizeptr )
*filesizeptr = filesize;
return buf;
} }
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 ) qboolean CRC32_File( dword *crcvalue, const char *filename )

View File

@ -591,7 +591,7 @@ W_ReadLump
reading lump into temp buffer 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 wfile_t *wad = search->wad;
const dlumpinfo_t *lump = &wad->lumps[pack_ind]; 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; 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 ); size = FS_Read( wad->handle, buf, lump->disksize );
FS_Seek( wad->handle, oldpos, SEEK_SET );
if( size < lump->disksize ) if( size < lump->disksize )
{ {
Con_Reportf( S_WARN "W_ReadLump: %s is probably corrupted\n", lump->name ); Con_Reportf( S_WARN "W_ReadLump: %s is probably corrupted\n", lump->name );
FS_Seek( wad->handle, oldpos, SEEK_SET ); pfnFree( buf );
Mem_Free( buf );
return NULL; return NULL;
} }
if( lumpsizeptr ) *lumpsizeptr = lump->disksize; if( lumpsizeptr ) *lumpsizeptr = lump->disksize;
FS_Seek( wad->handle, oldpos, SEEK_SET );
return buf; 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; zipfile_t *file;
byte *compressed_buffer = NULL, *decompressed_buffer = NULL; 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; 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 ) 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 ); c = read( search->zip->handle, decompressed_buffer, file->size );
if( c != 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 ) if( final_crc != file->crc32 )
{ {
Con_Reportf( S_ERROR "Zip_LoadFile: %s file crc32 mismatch\n", file->name ); Con_Reportf( S_ERROR "Zip_LoadFile: %s file crc32 mismatch\n", file->name );
Mem_Free( decompressed_buffer ); pfnFree( decompressed_buffer );
return NULL; return NULL;
} }
#endif // ENABLE_CRC_CHECK #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 ) else if( file->flags == ZIP_COMPRESSION_DEFLATED )
{ {
compressed_buffer = Mem_Malloc( fs_mempool, file->compressed_size + 1 ); 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 ); c = read( search->zip->handle, compressed_buffer, file->compressed_size );
if( c != 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 ) if( final_crc != file->crc32 )
{ {
Con_Reportf( S_ERROR "Zip_LoadFile: %s file crc32 mismatch\n", file->name ); Con_Reportf( S_ERROR "Zip_LoadFile: %s file crc32 mismatch\n", file->name );
Mem_Free( decompressed_buffer ); pfnFree( decompressed_buffer );
return NULL; return NULL;
} }
#endif #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 ); 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( compressed_buffer );
Mem_Free( decompressed_buffer ); pfnFree( decompressed_buffer );
return NULL; return NULL;
} }
@ -550,6 +553,7 @@ static byte *FS_LoadZIPFile( searchpath_t *search, const char *path, int pack_in
else else
{ {
Con_Reportf( S_ERROR "Zip_LoadFile: %s : file compressed with unknown algorithm.\n", file->name ); Con_Reportf( S_ERROR "Zip_LoadFile: %s : file compressed with unknown algorithm.\n", file->name );
pfnFree( decompressed_buffer );
return NULL; return NULL;
} }