From 14e1392229621566724912e92240a7211e1c47c5 Mon Sep 17 00:00:00 2001 From: silverweed Date: Fri, 16 Aug 2024 10:01:17 +0200 Subject: [PATCH] allow not passing an ntuple name --- src/argparse.cpp | 14 ++++++++------ src/rntuple.cpp | 6 +++++- src/rntviewer.cpp | 6 +++--- src/root/RMicroFileReader.cxx | 9 +++++++-- src/root/RMicroFileReader.hxx | 3 +++ 5 files changed, 26 insertions(+), 12 deletions(-) diff --git a/src/argparse.cpp b/src/argparse.cpp index 404d084..d7444da 100644 --- a/src/argparse.cpp +++ b/src/argparse.cpp @@ -4,13 +4,15 @@ void print_help(const char *argv0) fprintf(stderr, "rntviewer v" V_MAJOR "." V_MINOR " by silverweed" "\n" - "\nUsage: %s [-t] [-s START] [-l LEN] [-w WIDTH] [-e] " + "\nUsage: %s [-t] [-s START] [-l LEN] [-w WIDTH] [-e] [ntuple_name]" "\n\t-t: no graphics, output to terminal" "\n\t-s: set first displayed byte to START" "\n\t-l: display LEN bytes (only in terminal mode)" "\n\t-w: display WIDTH bytes per column" "\n\t-e: display some extended info (may slow down the startup)" "\n" + "\nNOTE: if `ntuple_name' is not passed, rntviewer will look for the first RNTuple in the TFile." + "\n" , argv0); } @@ -89,7 +91,7 @@ internal Cmdline_Args parse_args(i32 argc, char **argv) { Cmdline_Args args {}; - if (argc < 3) { + if (argc < 2) { args.show_help_and_exit = true; return args; } @@ -117,13 +119,13 @@ Cmdline_Args parse_args(i32 argc, char **argv) } else { args.show_help_and_exit = true; } - } else if (args.ntpl_name.size) { - if (args.file_name.size) + } else if (args.file_name.size) { + if (args.ntpl_name.size) args.show_help_and_exit = true; else - args.file_name = arg; + args.ntpl_name = arg; } else { - args.ntpl_name = arg; + args.file_name = arg; } } return args; diff --git a/src/rntuple.cpp b/src/rntuple.cpp index 2f13904..21cf862 100644 --- a/src/rntuple.cpp +++ b/src/rntuple.cpp @@ -385,8 +385,9 @@ u64 calc_page_uncomp_size(const u8 *fmem, const Page_Info_Node *page_head) return tot_size; } +// NOTE: ntpl_name may be empty internal -RNTuple_Data get_rntuple_data(Arena *arena, const Inspected_File &file, String8 ntpl_name, b8 extended_info) +RNTuple_Data get_rntuple_data(Arena *arena, const Inspected_File &file, String8 &ntpl_name, b8 extended_info) { RNTuple_Data rndata {}; @@ -409,6 +410,9 @@ RNTuple_Data get_rntuple_data(Arena *arena, const Inspected_File &file, String8 rndata.rblob_header_size = file_info.rblob_key_header_nbytes; rndata.rng_tkeys_list.start = file_info.tkeys_list_seek; rndata.rng_tkeys_list.len = file_info.tkeys_list_nbytes; + if (!ntpl_name.size) { + ntpl_name = push_str8f(arena, "%s", file_info.ntuple_name.c_str()); + } gather_ntuple_metadata(arena, file_reader, file_info, rndata); if (extended_info) diff --git a/src/rntviewer.cpp b/src/rntviewer.cpp index e430c15..11c2a7a 100644 --- a/src/rntviewer.cpp +++ b/src/rntviewer.cpp @@ -104,7 +104,7 @@ int main(int argc, char **argv) // Parse cmdline Cmdline_Args args = parse_args(argc, argv); - if (args.show_help_and_exit || !args.ntpl_name.size || !args.file_name.size) { + if (args.show_help_and_exit || !args.file_name.size) { print_help(argv[0]); return 1; } @@ -131,10 +131,10 @@ int main(int argc, char **argv) os_start_file_watch(args.file_name, app); } - app.ntpl_name = args.ntpl_name; + app.ntpl_name = args.ntpl_name; // may be null app.base_display_addr = args.start_addr; - app.tfile_data = get_tfile_data(app.inspected_file, app.ntpl_name); app.rndata = get_rntuple_data(arena, app.inspected_file, app.ntpl_name, args.extended_info); + app.tfile_data = get_tfile_data(app.inspected_file, app.ntpl_name); if (args.print_to_terminal) { u64 nbytes_displayed = args.nbytes_displayed; diff --git a/src/root/RMicroFileReader.cxx b/src/root/RMicroFileReader.cxx index 966c390..e0cb9cd 100644 --- a/src/root/RMicroFileReader.cxx +++ b/src/root/RMicroFileReader.cxx @@ -1187,14 +1187,19 @@ RMicroFileReader::GetNTupleProper(const char *ntupleName) offset += name.GetSize(); ReadBuffer(&name, 1, offset); ReadBuffer(&name, name.GetSize(), offset); - if (std::string_view(name.fData, name.fLName) == std::string_view(ntupleName)) { + if (!ntupleName || ntupleName[0] == 0 || std::string_view(name.fData, name.fLName) == std::string_view(ntupleName)) { + fileInfo.ntuple_name = { name.fData, name.fLName }; found = true; break; } offset = offsetNextKey; } if (!found) { - FAIL("no RNTuple named '" + std::string(ntupleName) + "' in file '" + impl->fRawFile->GetUrl() + "'"); + if (!ntupleName || ntupleName[0] == 0) { + FAIL("no RNTuple found in file '" + impl->fRawFile->GetUrl() + "'"); + } else { + FAIL("no RNTuple named '" + std::string(ntupleName) + "' in file '" + impl->fRawFile->GetUrl() + "'"); + } } offset = key.GetSeekKey() + key.fKeyLen; diff --git a/src/root/RMicroFileReader.hxx b/src/root/RMicroFileReader.hxx index 20e93a1..afbad64 100644 --- a/src/root/RMicroFileReader.hxx +++ b/src/root/RMicroFileReader.hxx @@ -1,6 +1,7 @@ #pragma once #include +#include // We are forced to use our own RNTuple anchor struct because we cannot // write into the private members of the real RNTuple class from RMicroFileReader. @@ -42,6 +43,7 @@ struct RNTuple_File_Info { std::uint64_t rblob_key_header_nbytes; std::uint64_t tkeys_list_seek; std::uint64_t tkeys_list_nbytes; + std::string ntuple_name; // useful when not passing an explicit name to GetNTupleProper }; struct Root_File_Info { @@ -64,6 +66,7 @@ public: explicit RMicroFileReader(const char *fname); ~RMicroFileReader(); + // if ntupleName == "", look for the first RNTuple in the file. RNTuple_File_Info GetNTupleProper(const char *ntupleName); void ReadBuffer(void *buffer, std::size_t nbytes, std::uint64_t offset);