diff --git a/src/render.cpp b/src/render.cpp index afdfa82..5c7d7f0 100644 --- a/src/render.cpp +++ b/src/render.cpp @@ -44,6 +44,8 @@ u32 mem_edit_bg_color_fn(const u8 *, u64 off, void *user_data) // TFile start if (off <= tdata.root_file_header_size) return COL(app->viewer.col_tfile_header); if (tdata.rng_root_file_obj.start <= off && off < tdata.rng_root_file_obj.end()) return COL(app->viewer.col_tfile_obj); + if (tdata.rng_root_file_info.start <= off && off < tdata.rng_root_file_info.end()) return COL(app->viewer.col_tfile_info); + if (tdata.rng_root_file_free.start <= off && off < tdata.rng_root_file_free.end()) return COL(app->viewer.col_tfile_free); // Handle pages // fast case: `off` is in the same page info as previous `off`. @@ -139,6 +141,8 @@ void make_viewer(App_State &app) COL(col_key, 0, 100, 50); COL(col_tfile_header, 90, 90, 90); COL(col_tfile_obj, 120, 120, 120); + COL(col_tfile_info, 95, 76, 76); + COL(col_tfile_free, 60, 60, 90); COL(col_page, 125, 0, 125); COL(col_page_start, 200, 0, 200); COL(col_checksum, 134, 65, 25); @@ -233,6 +237,14 @@ void update_and_render(Arena *arena, App_State &app, f32 delta_time_ms) ImGui::SameLine(); if (ImGui::Button("TFile Object")) viewer_jump_to(app.viewer, app.tfile_data.rng_root_file_obj.start); + ImGui::ColorEdit3("_TFile Info", app.viewer.col_tfile_info, flags); + ImGui::SameLine(); + if (ImGui::Button("TFile Info")) viewer_jump_to(app.viewer, app.tfile_data.rng_root_file_info.start); + + ImGui::ColorEdit3("_TFile FreeList", app.viewer.col_tfile_free, flags); + ImGui::SameLine(); + if (ImGui::Button("TFile FreeList")) viewer_jump_to(app.viewer, app.tfile_data.rng_root_file_free.start); + ImGui::ColorEdit3("_RNTuple Anchor", app.viewer.col_anchor, flags); ImGui::SameLine(); if (ImGui::Button("RNTuple Anchor")) viewer_jump_to(app.viewer, app.rndata.rng_anchor.start); @@ -290,6 +302,7 @@ void update_and_render(Arena *arena, App_State &app, f32 delta_time_ms) app.tfile_data.root_version_minor, app.tfile_data.root_version_patch); ImGui::Text("ROOT version: %s", root_version_str.c()); + ImGui::Text("TFile compression: %u", app.tfile_data.compression); ImGui::Text("Num pages: %lu", app.rndata.n_pages); ImGui::Text("Num elements: %lu", app.rndata.n_elems); diff --git a/src/render.h b/src/render.h index 7b0d7f2..3777019 100644 --- a/src/render.h +++ b/src/render.h @@ -7,6 +7,8 @@ struct Viewer { f32 col_key[3]; f32 col_tfile_header[3]; f32 col_tfile_obj[3]; + f32 col_tfile_info[3]; + f32 col_tfile_free[3]; f32 col_page[3]; f32 col_page_start[3]; f32 col_checksum[3]; diff --git a/src/rntuple.cpp b/src/rntuple.cpp index 594c4b8..3d290d6 100644 --- a/src/rntuple.cpp +++ b/src/rntuple.cpp @@ -240,10 +240,8 @@ TFile_Data get_tfile_data(const Inspected_File &file) tfile_data.rng_root_file_obj.len = root_file_info.tfile_obj_nbytes; // parse root version - const u64 len_root_magic = 4; - assert(file.size > len_root_magic + sizeof(u32)); u32 version_be; - memcpy(&version_be, file.mem + len_root_magic, sizeof(version_be)); + memcpy(&version_be, file.mem + root_file_info.version_seek, sizeof(version_be)); u32 version = bswap_32(version_be); u32 version_major = version / 10000; u32 version_minor = (version - version_major * 10000) / 100; @@ -251,6 +249,27 @@ TFile_Data get_tfile_data(const Inspected_File &file) tfile_data.root_version_major = (u16)version_major; tfile_data.root_version_minor = (u16)version_minor; tfile_data.root_version_patch = (u16)version_patch; + + // 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; + 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; + 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/rntuple.h b/src/rntuple.h index 21dbb8a..9037817 100644 --- a/src/rntuple.h +++ b/src/rntuple.h @@ -43,6 +43,9 @@ struct TFile_Data { u16 root_version_major; u16 root_version_minor; u16 root_version_patch; + u32 compression; + Byte_Range rng_root_file_info; + Byte_Range rng_root_file_free; }; struct RNTuple_Data { diff --git a/src/root/RMicroFileReader.cxx b/src/root/RMicroFileReader.cxx index 0e0ec11..57fa3e0 100644 --- a/src/root/RMicroFileReader.cxx +++ b/src/root/RMicroFileReader.cxx @@ -1075,6 +1075,14 @@ Root_File_Info get_root_file_info(const char *fname) fileInfo.tfile_header_nbytes = RTFHeader{}.GetSize(); 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); return fileInfo; } diff --git a/src/root/RMicroFileReader.hxx b/src/root/RMicroFileReader.hxx index 67a8331..734f607 100644 --- a/src/root/RMicroFileReader.hxx +++ b/src/root/RMicroFileReader.hxx @@ -44,6 +44,14 @@ struct Root_File_Info { std::uint64_t tfile_header_nbytes; std::uint64_t tfile_obj_seek; std::uint64_t tfile_obj_nbytes; + 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);