diff --git a/src/rntuple.cpp b/src/rntuple.cpp index 0e3bcb6..c60d4cc 100644 --- a/src/rntuple.cpp +++ b/src/rntuple.cpp @@ -718,6 +718,21 @@ struct Sec_Hover_Fn { Sec_Hover_Info &info; u64 &cur_field_off; + template + b8 titled_section(const char *title, F &&fn) const + { + String8_Node *prev_desc = info.desc; + info.desc = push_str8_node_child(arena, prev_desc, title); + + b8 ok = fn(); + + if (!ok) { + pop_str8_node_child(prev_desc, info.desc); + info.desc = prev_desc; + } + return ok; + } + template b8 field(const char *desc_fmt, Display_Fn display_val) const { @@ -752,6 +767,9 @@ struct Sec_Hover_Fn { // String size can be stored as different types, like u8 (by ROOT I/O) or u32 (by RNTuple). TStrSize str_size; memcpy(&str_size, data + start + cur_field_off, sizeof(TStrSize)); + // TEMP DEBUG + if (str_size > 1000) + return false; if (roff < cur_field_off + sizeof(TStrSize) + str_size) { info.rng = { start + cur_field_off, sizeof(TStrSize) + (u64)str_size }; u8 *buf = arena_push_array_nozero(arena, str_size + 1); @@ -879,26 +897,61 @@ struct Sec_Hover_Fn { }); } - b8 schema_description() const + b8 field_desc() const { - return titled_section("Schema Description", [this] { - return list_frame_preamble(); + static const char *const field_struct_names[] = { + "Leaf", "Collection", "Record", "Variant", "Unsplit" + }; + return titled_section("Field", [this] { + u64 flags_off = start + cur_field_off + 22; + u16 flags; + memcpy(&flags, data + flags_off, sizeof(flags)); + b8 ok = field_le("Size: %" PRIi64) + || field_le("Field version: %u") + || field_le("Type version: %u") + || field_le("On-disk parent id: %u") + || field("Field structure: %s", [] (Arena *arena, String8_Node *prev, const char *fmt, u16 type) { + const char *name = (type >= countof(field_struct_names)) ? "Unknown" : field_struct_names[type]; + return push_str8_node_child(arena, prev, fmt, name); + }) + || field_le("Flags: %u") + ; + if (ok) + return ok; + + using ROOT::Experimental::Internal::RNTupleSerializer; + + if ((flags & RNTupleSerializer::kFlagRepetitiveField) && field_le("N Repetitions: %" PRIu64)) + return true; + if ((flags & RNTupleSerializer::kFlagProjectedField) && field_le("On disk proj.src id: %u")) + return true; + if ((flags & RNTupleSerializer::kFlagHasTypeChecksum) && field_le("Checksum: %u")) + return true; + + return field_str8("Name: %s") + || field_str8("Type Name: %s") + || field_str8("Type Alias: %s") + || field_str8("Description: %s") + ; }); } - template - b8 titled_section(const char *title, F &&fn) const + b8 schema_description() const { - String8_Node *prev_desc = info.desc; - info.desc = push_str8_node_child(arena, prev_desc, title); - - b8 ok = fn(); - - if (!ok) { - pop_str8_node_child(prev_desc, info.desc); - info.desc = prev_desc; - } - return ok; + return titled_section("Schema Description", [this] { + if (list_frame_preamble()) + return true; + // we need to read back the number of fields to know how long is the next section. + u64 n_fields_off = cur_field_off - sizeof(u32); + u32 n_fields; + memcpy(&n_fields, data + start + n_fields_off, sizeof(n_fields)); + for (u32 i = 0; i < n_fields; ++i) + if (field_desc()) + return true; + if (field("Size: %" PRIi64, hover_display_val_le_abs)) + return true; + return false; // TODO + }); } }; @@ -1059,6 +1112,7 @@ Sec_Hover_Info get_section_hover_info(Arena *arena, Section section, u64 off, co || hover.field_str8("Description: %s") || hover.field_str8("ROOT version: %s") || hover.schema_description() + || hover.range("Payload", section.range.len - hover.cur_field_off) // TODO || hover.field_le("Checksum: 0x%" PRIX64) ; }