diff --git a/src/hover.cpp b/src/hover.cpp index f1fcd4e..fc6bc71 100644 --- a/src/hover.cpp +++ b/src/hover.cpp @@ -135,6 +135,7 @@ struct Sec_Hover_Fn { u64 &cur_field_off; // current field offset relative to the start of `data` // settings b8 display_grouped; + b8 old_version; // if true, treat the RNTuple as 0.x rather than 1.x // internals u8 cur_section_nesting = 0; u8 innermost_section_highlighted = 0; @@ -440,17 +441,28 @@ struct Sec_Hover_Fn { if (!field<u16>("Flags: 0b%b", hover_display_val_le, &flags)) return; - if (flags & RNTupleSerializer::kFlagRepetitiveField) - field_le<u64>("N Repetitions: %" PRIu64); - if (flags & RNTupleSerializer::kFlagProjectedField) - field_le<u32>("On disk proj.src id: %u"); - if (flags & RNTupleSerializer::kFlagHasTypeChecksum) - field_le<u32>("Checksum: %u"); + if (old_version) { + if (flags & RNTupleSerializer::kFlagRepetitiveField) + field_le<u64>("N Repetitions: %" PRIu64); + if (flags & RNTupleSerializer::kFlagProjectedField) + field_le<u32>("On disk proj.src id: %u"); + if (flags & RNTupleSerializer::kFlagHasTypeChecksum) + field_le<u32>("Checksum: %u"); + } field_str8<u32>("Name: %s"); field_str8<u32>("Type Name: %s"); field_str8<u32>("Type Alias: %s"); field_str8<u32>("Description: %s"); + + if (!old_version) { + if (flags & RNTupleSerializer::kFlagRepetitiveField) + field_le<u64>("N Repetitions: %" PRIu64); + if (flags & RNTupleSerializer::kFlagProjectedField) + field_le<u32>("On disk proj.src id: %u"); + if (flags & RNTupleSerializer::kFlagHasTypeChecksum) + field_le<u32>("Checksum: %u"); + } }); } @@ -495,8 +507,12 @@ struct Sec_Hover_Fn { frame<Frame_List>("Extra Type Infos", [this] (u32 idx) { frame<Frame_Record>(push_str8f(arena, "Extra Type Info %u", idx).c(), [this] { field_le<u32>("Content identifier: %lu"); - field_le<u32>("Type version from: %lu"); - field_le<u32>("Type version to: %lu"); + if (old_version) { + field_le<u32>("Type version from: %lu"); + field_le<u32>("Type version to: %lu"); + } else { + field_le<u32>("Type version: %lu"); + } }); }); }); @@ -889,9 +905,11 @@ struct Sec_Hover_Fn { frame<Frame_Record>("Schema Extension", [this] { schema_description("Schema Extension"); }); - frame<Frame_List>("Column Groups", [this] (u32) { - field_le<u32>("Column Id: %u"); - }); + if (old_version) { + frame<Frame_List>("Column Groups", [this] (u32) { + field_le<u32>("Column Id: %u"); + }); + } frame<Frame_List>("Cluster Groups", [this] (u32) { cluster_group(); }); @@ -941,7 +959,7 @@ struct Sec_Hover_Fn { // `off` is the absolute offset into `data`. internal -Sec_Hover_Info get_section_hover_info(Arena *arena, Section section, u64 off, const u8 *data, b8 display_grouped) +Sec_Hover_Info get_section_hover_info(Arena *arena, Section section, u64 off, const u8 *data, b8 display_grouped, b8 old_version) { Sec_Hover_Info info {}; @@ -961,7 +979,7 @@ Sec_Hover_Info get_section_hover_info(Arena *arena, Section section, u64 off, co } u64 cur_field_off = section.range.start - section.pre_size; - Sec_Hover_Fn hover { off, data, section, arena, info, cur_field_off, display_grouped }; + Sec_Hover_Fn hover { off, data, section, arena, info, cur_field_off, display_grouped, old_version }; switch (section.id) { case Sec_RNTuple_Anchor: diff --git a/src/render.cpp b/src/render.cpp index f3fe825..57de613 100644 --- a/src/render.cpp +++ b/src/render.cpp @@ -251,7 +251,11 @@ void update_and_render(Arena *arena, App_State &app, f32 delta_time_ms) if (ImGui::Begin("main", nullptr, main_win_flags)) { String8 ntpl_desc = rntuple_description(scratch.arena, app.tfile_data.rntuple_anchor); - ImGui::Text("RNTuple '%s' (%s) from file \"%s\"", app.ntpl_name.c(), ntpl_desc.c(), app.inspected_file.name.c()); + if (rntuple_is_old_version(app.tfile_data.rntuple_anchor)) + ImGui::TextColored(ImColor(1.f, 0.f, 0.f), "RNTuple '%s' (%s) from file \"%s\" ** old version, some data missing! **", + app.ntpl_name.c(), ntpl_desc.c(), app.inspected_file.name.c()); + else + ImGui::Text("RNTuple '%s' (%s) from file \"%s\"", app.ntpl_name.c(), ntpl_desc.c(), app.inspected_file.name.c()); // Draw stats { @@ -398,12 +402,13 @@ void update_and_render(Arena *arena, App_State &app, f32 delta_time_ms) if (hovered_off) { + const ROOT::RNTuple &anchor = app.tfile_data.rntuple_anchor; ImGui::TextColored(ImColor(0.f, 0.65f, 0.f), "Offset: 0x%" PRIX64, hovered_off - 1); Section hovered_section = find_section(app, hovered_off - 1); b8 hover_display_grouped = !(app.user_input.key_state[KEY_ALT] & KEY_STATE_IS_DOWN); + b8 old_version = rntuple_is_old_version(anchor); Sec_Hover_Info hover_info = get_section_hover_info(scratch.arena, hovered_section, hovered_off - 1, - app.inspected_file.mem, hover_display_grouped); - const ROOT::RNTuple &anchor = app.tfile_data.rntuple_anchor; + app.inspected_file.mem, hover_display_grouped, old_version); b8 header_is_compressed = anchor.GetNBytesHeader() != anchor.GetLenHeader(); if (!header_is_compressed) ImGui::TextColored(ImColor(0.5f, 0.5f, 0.5f), "(Hint: press Alt for single-field hover information)"); diff --git a/src/rntuple.cpp b/src/rntuple.cpp index dae56cf..0d3de8d 100644 --- a/src/rntuple.cpp +++ b/src/rntuple.cpp @@ -1,3 +1,9 @@ +internal +b8 rntuple_is_old_version(const ROOT::RNTuple &ntuple) +{ + return ntuple.GetVersionEpoch() == 0 && ntuple.GetVersionMajor() < 3; +} + internal String8 rntuple_description(Arena *arena, const ROOT::RNTuple &ntuple) { @@ -23,6 +29,8 @@ ROOT::Experimental::RNTupleDescriptor create_descriptor(Arena *arena, const TFil defer { scratch_end(scratch); }; const ROOT::RNTuple &anchor = tfile_data.rntuple_anchor; + if (rntuple_is_old_version(anchor)) + fprintf(stderr, "Warning: the RNTuple being read is an old version. We'll probably fail to read some metadata.\n"); // Read compressed header+footer u8 *header_zip = arena_push_array_nozero<u8>(scratch.arena, anchor.GetNBytesHeader()); @@ -39,8 +47,8 @@ ROOT::Experimental::RNTupleDescriptor create_descriptor(Arena *arena, const TFil // Deserialize header+footer RNTupleDescriptorBuilder desc_builder; try { - RNTupleSerializer::DeserializeHeader(header, anchor.GetLenHeader(), desc_builder); - RNTupleSerializer::DeserializeFooter(footer, anchor.GetLenFooter(), desc_builder); + RNTupleSerializer::DeserializeHeader(header, anchor.GetLenHeader(), desc_builder).ThrowOnError(); + RNTupleSerializer::DeserializeFooter(footer, anchor.GetLenFooter(), desc_builder).ThrowOnError(); } catch (...) { fprintf(stderr, "Failed to deserialize header/footer!\n"); } diff --git a/test_old.root b/test_old.root deleted file mode 100644 index bbdcc88..0000000 Binary files a/test_old.root and /dev/null differ diff --git a/test_uncomp_old.root b/test_uncomp_old.root deleted file mode 100644 index 735d3d4..0000000 Binary files a/test_uncomp_old.root and /dev/null differ