properly handle big tfiles

This commit is contained in:
silverweed 2024-07-18 17:13:04 +02:00
parent 94c5d432ab
commit a3743238e8
3 changed files with 34 additions and 23 deletions

View file

@ -234,15 +234,13 @@ TFile_Data get_tfile_data(const Inspected_File &file)
{
TFile_Data tfile_data{};
Root_File_Info root_file_info = get_root_file_info(file.name.c());
tfile_data.root_file_header_size = root_file_info.tfile_header_nbytes;
tfile_data.rng_root_file_obj.start = root_file_info.tfile_obj_seek;
tfile_data.rng_root_file_obj.len = root_file_info.tfile_obj_nbytes;
// parse root version
const u64 version_seek = 4;
u32 version_be;
memcpy(&version_be, file.mem + root_file_info.version_seek, sizeof(version_be));
memcpy(&version_be, file.mem + version_seek, sizeof(version_be));
u32 version = bswap_32(version_be);
b32 is_big_file = version > 1000000;
version -= is_big_file * 1000000;
u32 version_major = version / 10000;
u32 version_minor = (version - version_major * 10000) / 100;
u32 version_patch = (version - version_major * 10000 - version_minor * 100);
@ -250,25 +248,42 @@ TFile_Data get_tfile_data(const Inspected_File &file)
tfile_data.root_version_minor = (u16)version_minor;
tfile_data.root_version_patch = (u16)version_patch;
Root_File_Info root_file_info = get_root_file_info(file.name.c(), is_big_file);
tfile_data.root_file_header_size = root_file_info.tfile_header_nbytes;
tfile_data.rng_root_file_obj.start = root_file_info.tfile_obj_seek;
tfile_data.rng_root_file_obj.len = root_file_info.tfile_obj_nbytes;
// parse compression
u32 compression_be;
memcpy(&compression_be, file.mem + root_file_info.compression_seek, sizeof(compression_be));
tfile_data.compression = bswap_32(compression_be);
// parse info
u32 info_seek_be;
u32 info_nbytes_be;
if (is_big_file) {
u64 info_seek_be;
memcpy(&info_seek_be, file.mem + root_file_info.info_seek_seek, sizeof(info_seek_be));
tfile_data.rng_root_file_info.start = bswap_64(info_seek_be);
} else {
u32 info_seek_be;
memcpy(&info_seek_be, file.mem + root_file_info.info_seek_seek, sizeof(info_seek_be));
memcpy(&info_nbytes_be, file.mem + root_file_info.info_nbytes_seek, sizeof(info_nbytes_be));
tfile_data.rng_root_file_info.start = bswap_32(info_seek_be);
}
u32 info_nbytes_be;
memcpy(&info_nbytes_be, file.mem + root_file_info.info_nbytes_seek, sizeof(info_nbytes_be));
tfile_data.rng_root_file_info.len = bswap_32(info_nbytes_be);
// parse free
u32 free_seek_be;
u32 free_nbytes_be;
if (is_big_file) {
u64 free_seek_be;
memcpy(&free_seek_be, file.mem + root_file_info.free_seek_seek, sizeof(free_seek_be));
tfile_data.rng_root_file_free.start = bswap_64(free_seek_be);
} else {
u32 free_seek_be;
memcpy(&free_seek_be, file.mem + root_file_info.free_seek_seek, sizeof(free_seek_be));
memcpy(&free_nbytes_be, file.mem + root_file_info.free_nbytes_seek, sizeof(free_nbytes_be));
tfile_data.rng_root_file_free.start = bswap_32(free_seek_be);
}
u32 free_nbytes_be;
memcpy(&free_nbytes_be, file.mem + root_file_info.free_nbytes_seek, sizeof(free_nbytes_be));
tfile_data.rng_root_file_free.len = bswap_32(free_nbytes_be);
return tfile_data;

View file

@ -1068,7 +1068,7 @@ static size_t ComputeNumChunks(size_t nbytes, size_t maxChunkSize)
// PUBLIC INTERFACE
// =========================================================================================
Root_File_Info get_root_file_info(const char *fname)
Root_File_Info get_root_file_info(const char *fname, bool is_big_file)
{
RTFString fileName { fname };
Root_File_Info fileInfo {};
@ -1076,13 +1076,11 @@ Root_File_Info get_root_file_info(const char *fname)
fileInfo.tfile_obj_seek = 100; // kBEGIN
fileInfo.tfile_obj_nbytes = sizeof(RTFFile) + fileName.GetSize() + RTFString{}.GetSize() + RTFUUID{}.GetSize();
fileInfo.version_seek = offsetof(RTFHeader, fVersion);
fileInfo.compression_seek = offsetof(RTFHeader, fInfoShort.fCompress);
fileInfo.info_seek_seek = offsetof(RTFHeader, fInfoShort.fSeekInfo);
fileInfo.info_seek_sizeof = 4; // TODO: check if big file
fileInfo.info_nbytes_seek = offsetof(RTFHeader, fInfoShort.fNbytesInfo);
fileInfo.free_seek_seek = offsetof(RTFHeader, fInfoShort.fSeekFree);
fileInfo.free_seek_sizeof = 4; // TODO: check if big file
fileInfo.free_nbytes_seek = offsetof(RTFHeader, fInfoShort.fNbytesFree);
fileInfo.compression_seek = is_big_file ? offsetof(RTFHeader, fInfoLong.fCompress) : offsetof(RTFHeader, fInfoShort.fCompress);
fileInfo.info_seek_seek = is_big_file ? offsetof(RTFHeader, fInfoLong.fSeekInfo) : offsetof(RTFHeader, fInfoShort.fSeekInfo);
fileInfo.info_nbytes_seek = is_big_file ? offsetof(RTFHeader, fInfoLong.fNbytesInfo) : offsetof(RTFHeader, fInfoShort.fNbytesInfo);
fileInfo.free_seek_seek = is_big_file ? offsetof(RTFHeader, fInfoLong.fSeekFree) : offsetof(RTFHeader, fInfoShort.fSeekFree);
fileInfo.free_nbytes_seek = is_big_file ? offsetof(RTFHeader, fInfoLong.fNbytesFree) : offsetof(RTFHeader, fInfoShort.fNbytesFree);
return fileInfo;
}

View file

@ -47,14 +47,12 @@ struct Root_File_Info {
std::uint64_t version_seek;
std::uint64_t compression_seek;
std::uint64_t info_seek_seek;
std::uint64_t info_seek_sizeof;
std::uint64_t info_nbytes_seek;
std::uint64_t free_seek_seek;
std::uint64_t free_seek_sizeof;
std::uint64_t free_nbytes_seek;
};
Root_File_Info get_root_file_info(const char *fname);
Root_File_Info get_root_file_info(const char *fname, bool is_big_file);
class RMicroFileReader final {
public: