diff --git a/src/rntuple.cpp b/src/rntuple.cpp index 3d290d6..83a9261 100644 --- a/src/rntuple.cpp +++ b/src/rntuple.cpp @@ -233,22 +233,25 @@ internal 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); tfile_data.root_version_major = (u16)version_major; 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; @@ -256,19 +259,31 @@ TFile_Data get_tfile_data(const Inspected_File &file) tfile_data.compression = bswap_32(compression_be); // parse info - u32 info_seek_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)); + tfile_data.rng_root_file_info.start = bswap_32(info_seek_be); + } u32 info_nbytes_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); tfile_data.rng_root_file_info.len = bswap_32(info_nbytes_be); // parse free - u32 free_seek_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)); + tfile_data.rng_root_file_free.start = bswap_32(free_seek_be); + } u32 free_nbytes_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); tfile_data.rng_root_file_free.len = bswap_32(free_nbytes_be); return tfile_data; diff --git a/src/root/RMicroFileReader.cxx b/src/root/RMicroFileReader.cxx index 57fa3e0..4873e44 100644 --- a/src/root/RMicroFileReader.cxx +++ b/src/root/RMicroFileReader.cxx @@ -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; } diff --git a/src/root/RMicroFileReader.hxx b/src/root/RMicroFileReader.hxx index 734f607..9ab3a9f 100644 --- a/src/root/RMicroFileReader.hxx +++ b/src/root/RMicroFileReader.hxx @@ -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: