start reading header hover info
This commit is contained in:
parent
c210ef86cc
commit
705b4b353d
4 changed files with 254 additions and 152 deletions
|
@ -388,7 +388,7 @@ void update_and_render(Arena *arena, App_State &app, f32 delta_time_ms)
|
|||
{
|
||||
Section hovered_section = find_section(app, hovered_off - 1);
|
||||
Sec_Hover_Info hover_info = get_section_hover_info(scratch.arena, hovered_section, hovered_off - 1, app.inspected_file.mem);
|
||||
imgui_render_string_tree(scratch.arena, hover_info.desc);
|
||||
imgui_render_string_tree(scratch.arena, hover_info.desc->head);
|
||||
app.viewer.hovered_range = hover_info.rng;
|
||||
} else {
|
||||
app.viewer.hovered_range = {};
|
||||
|
|
389
src/rntuple.cpp
389
src/rntuple.cpp
|
@ -653,6 +653,12 @@ String8_Node *hover_display_val_le(Arena *arena, String8_Node *prev, const char
|
|||
return push_str8_node_child(arena, prev, fmt, val);
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
String8_Node *hover_display_val_le_abs(Arena *arena, String8_Node *prev, const char *fmt, T val)
|
||||
{
|
||||
return push_str8_node_child(arena, prev, fmt, std::abs(val));
|
||||
}
|
||||
|
||||
internal
|
||||
String8_Node *hover_display_datetime_str(Arena *arena, String8_Node *prev, const char *fmt_pre, u32 datetime)
|
||||
{
|
||||
|
@ -704,7 +710,7 @@ template <typename T>
|
|||
using Display_Fn = String8_Node *(*)(Arena *, String8_Node *, const char *, T);
|
||||
|
||||
// Functor used by get_section_hover_info to describe the structure of a section and print data about it.
|
||||
struct Try_Sec_Hover_Fn {
|
||||
struct Sec_Hover_Fn {
|
||||
u64 start;
|
||||
u64 roff;
|
||||
const u8 *data;
|
||||
|
@ -713,37 +719,49 @@ struct Try_Sec_Hover_Fn {
|
|||
u64 &cur_field_off;
|
||||
|
||||
template <typename T>
|
||||
b8 field(const char *desc_fmt, Display_Fn<T> display_val = hover_display_val_be<T>) const
|
||||
b8 field(const char *desc_fmt, Display_Fn<T> display_val) const
|
||||
{
|
||||
if constexpr (std::is_same_v<T, String8>) {
|
||||
return field_str8(desc_fmt, display_val);
|
||||
} else {
|
||||
u64 field_len = sizeof(T);
|
||||
if (roff < cur_field_off + field_len) {
|
||||
info.rng = { start + cur_field_off, field_len };
|
||||
T val;
|
||||
memcpy(&val, data + info.rng.start, info.rng.len);
|
||||
display_val(arena, info.desc, desc_fmt, val);
|
||||
return true;
|
||||
}
|
||||
cur_field_off += field_len;
|
||||
return false;
|
||||
static_assert(!std::is_same_v<T, String8>, "use field_str8 instead.");
|
||||
u64 field_len = sizeof(T);
|
||||
if (roff < cur_field_off + field_len) {
|
||||
info.rng = { start + cur_field_off, field_len };
|
||||
T val;
|
||||
memcpy(&val, data + info.rng.start, info.rng.len);
|
||||
display_val(arena, info.desc, desc_fmt, val);
|
||||
return true;
|
||||
}
|
||||
cur_field_off += field_len;
|
||||
return false;
|
||||
}
|
||||
|
||||
b8 field_str8(const char *desc_fmt, Display_Fn<String8> display_val) const
|
||||
template <typename T>
|
||||
b8 field_be(const char *desc_fmt) const
|
||||
{
|
||||
u8 str_size = data[start + cur_field_off];
|
||||
if (roff < cur_field_off + 1 + str_size) {
|
||||
info.rng = { start + cur_field_off, 1 + (u64)str_size };
|
||||
return field<T>(desc_fmt, hover_display_val_be<T>);
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
b8 field_le(const char *desc_fmt) const
|
||||
{
|
||||
return field<T>(desc_fmt, hover_display_val_le<T>);
|
||||
}
|
||||
|
||||
template <typename TStrSize>
|
||||
b8 field_str8(const char *desc_fmt, Display_Fn<String8> display_val = hover_display_val_be<String8>) const
|
||||
{
|
||||
// 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));
|
||||
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<u8>(arena, str_size + 1);
|
||||
memcpy(buf, data + start + cur_field_off + 1, str_size);
|
||||
memcpy(buf, data + start + cur_field_off + sizeof(TStrSize), str_size);
|
||||
buf[str_size] = 0;
|
||||
String8 s = { buf, str_size };
|
||||
display_val(arena, info.desc, desc_fmt, s);
|
||||
return true;
|
||||
}
|
||||
cur_field_off += 1 + str_size;
|
||||
cur_field_off += sizeof(TStrSize) + str_size;
|
||||
return false;
|
||||
}
|
||||
|
||||
|
@ -769,11 +787,12 @@ struct Try_Sec_Hover_Fn {
|
|||
return false;
|
||||
}
|
||||
|
||||
b8 maybe_rootzip(const u8 *data, u64 start) const
|
||||
b8 maybe_rootzip(b8 *was_zipped = nullptr) const
|
||||
{
|
||||
// TODO boundary checks
|
||||
const u64 range_len = 9;
|
||||
if (display_val_rootzip(arena, info.desc, "Zipped Block", data + start + cur_field_off)) {
|
||||
if (was_zipped) *was_zipped = true;
|
||||
if (roff < cur_field_off + range_len) {
|
||||
info.rng = { start + cur_field_off, range_len };
|
||||
hover_display_val_be(arena, info.desc, "", data + start + cur_field_off);
|
||||
|
@ -786,51 +805,100 @@ struct Try_Sec_Hover_Fn {
|
|||
info.desc->last_child = info.desc->last_child->prev;
|
||||
}
|
||||
cur_field_off += range_len;
|
||||
} else if (was_zipped) {
|
||||
*was_zipped = false;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
b8 tkey() const
|
||||
{
|
||||
u16 version_be;
|
||||
memcpy(&version_be, data + start + 4, sizeof(u16));
|
||||
u32 version = bswap(version_be);
|
||||
b8 is_big = version > 1000;
|
||||
return titled_section("TKey", [this] {
|
||||
u16 version_be;
|
||||
memcpy(&version_be, data + start + 4, sizeof(u16));
|
||||
u32 version = bswap(version_be);
|
||||
b8 is_big = version > 1000;
|
||||
|
||||
if (is_big) {
|
||||
return field<u32>("NBytes: %u")
|
||||
|| field<u16>("Version: %u", [] (Arena *arena, String8_Node *prev, const char *fmt, u16 x) {
|
||||
x = bswap(x);
|
||||
x -= 1000;
|
||||
return push_str8_node_child(arena, prev, fmt, x);
|
||||
})
|
||||
|| field<u32>("Obj Len: %u")
|
||||
|| field<u32>("Datetime: ", hover_display_datetime_str)
|
||||
|| field<u16>("Key Len: %u")
|
||||
|| field<u16>("Cycle: %u")
|
||||
|| field<u64>("Seek Key: 0x%" PRIX64)
|
||||
|| field<u64>("Seek Pdir: 0x%" PRIX64)
|
||||
|| field<String8>("Class Name: %s")
|
||||
|| field<String8>("Obj Name: %s")
|
||||
|| field<String8>("Obj Title: %s")
|
||||
;
|
||||
} else {
|
||||
return field<u32>("NBytes: %u")
|
||||
|| field<u16>("Version: %u", [] (Arena *arena, String8_Node *prev, const char *fmt, u16 x) {
|
||||
x = bswap(x);
|
||||
return push_str8_node_child(arena, prev, fmt, x);
|
||||
})
|
||||
|| field<u32>("Obj Len: %u")
|
||||
|| field<u32>("Datetime: ", hover_display_datetime_str)
|
||||
|| field<u16>("Key Len: %u")
|
||||
|| field<u16>("Cycle: %u")
|
||||
|| field<u32>("Seek Key: 0x%" PRIX64)
|
||||
|| field<u32>("Seek Pdir: 0x%" PRIX64)
|
||||
|| field<String8>("Class Name: %s")
|
||||
|| field<String8>("Obj Name: %s")
|
||||
|| field<String8>("Obj Title: %s")
|
||||
;
|
||||
if (is_big) {
|
||||
return field_be<u32>("NBytes: %u")
|
||||
|| field<u16>("Version: %u", [] (Arena *arena, String8_Node *prev, const char *fmt, u16 x) {
|
||||
x = bswap(x);
|
||||
x -= 1000;
|
||||
return push_str8_node_child(arena, prev, fmt, x);
|
||||
})
|
||||
|| field_be<u32>("Obj Len: %u")
|
||||
|| field<u32>("Datetime: ", hover_display_datetime_str)
|
||||
|| field_be<u16>("Key Len: %u")
|
||||
|| field_be<u16>("Cycle: %u")
|
||||
|| field_be<u64>("Seek Key: 0x%" PRIX64)
|
||||
|| field_be<u64>("Seek Pdir: 0x%" PRIX64)
|
||||
|| field_str8<u8>("Class Name: %s")
|
||||
|| field_str8<u8>("Obj Name: %s")
|
||||
|| field_str8<u8>("Obj Title: %s")
|
||||
;
|
||||
} else {
|
||||
return field_be<u32>("NBytes: %u")
|
||||
|| field<u16>("Version: %u", [] (Arena *arena, String8_Node *prev, const char *fmt, u16 x) {
|
||||
x = bswap(x);
|
||||
return push_str8_node_child(arena, prev, fmt, x);
|
||||
})
|
||||
|| field_be<u32>("Obj Len: %u")
|
||||
|| field<u32>("Datetime: ", hover_display_datetime_str)
|
||||
|| field_be<u16>("Key Len: %u")
|
||||
|| field_be<u16>("Cycle: %u")
|
||||
|| field_be<u32>("Seek Key: 0x%" PRIX64)
|
||||
|| field_be<u32>("Seek Pdir: 0x%" PRIX64)
|
||||
|| field_str8<u8>("Class Name: %s")
|
||||
|| field_str8<u8>("Obj Name: %s")
|
||||
|| field_str8<u8>("Obj Title: %s")
|
||||
;
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
b8 envelope_preamble() const
|
||||
{
|
||||
static const char *const envelope_names[] = { "INVALID", "Header", "Footer", "Page List" };
|
||||
return field<u16>("Envelope type: %s", [] (Arena *arena, String8_Node *prev, const char *fmt, u16 val) {
|
||||
const char *name = (val >= countof(envelope_names)) ? "Unknown" : envelope_names[val];
|
||||
return push_str8_node_child(arena, prev, fmt, name);
|
||||
})
|
||||
|| range_data("Envelope size: %s", 6, [] (Arena *arena, String8_Node *prev, const char *fmt, const u8 *payload) {
|
||||
u64 size;
|
||||
memcpy(&size, payload, 6);
|
||||
return push_str8_node_child(arena, prev, fmt, to_pretty_size(arena, size));
|
||||
});
|
||||
}
|
||||
|
||||
b8 list_frame_preamble() const
|
||||
{
|
||||
return titled_section("Frame Preamble", [this] {
|
||||
return field<i64>("Size: %" PRIi64, hover_display_val_le_abs<i64>)
|
||||
|| field_le<u32>("N Items: %u")
|
||||
;
|
||||
});
|
||||
}
|
||||
|
||||
b8 schema_description() const
|
||||
{
|
||||
return titled_section("Schema Description", [this] {
|
||||
return list_frame_preamble();
|
||||
});
|
||||
}
|
||||
|
||||
template <typename F>
|
||||
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;
|
||||
}
|
||||
};
|
||||
|
||||
|
@ -860,29 +928,29 @@ Sec_Hover_Info get_section_hover_info(Arena *arena, Section section, u64 off, co
|
|||
u64 start = section.range.start - section.pre_size;
|
||||
u64 roff = off - start; // offset relative to `section`
|
||||
u64 cur_field_off = 0;
|
||||
Try_Sec_Hover_Fn try_sec_hover { start, roff, data, arena, info, cur_field_off };
|
||||
Sec_Hover_Fn hover { start, roff, data, arena, info, cur_field_off };
|
||||
|
||||
switch (section.id) {
|
||||
case Sec_RNTuple_Anchor: {
|
||||
try_sec_hover.tkey()
|
||||
|| try_sec_hover.field<u32>("Object len: %u", [] (Arena *arena, String8_Node *prev, const char *fmt, u32 x) {
|
||||
hover.tkey()
|
||||
|| hover.field<u32>("Object len: %u", [] (Arena *arena, String8_Node *prev, const char *fmt, u32 x) {
|
||||
x = bswap(x);
|
||||
x -= 0x4000'0000;
|
||||
return push_str8_node_child(arena, prev, fmt, x);
|
||||
})
|
||||
|| try_sec_hover.field<u16>("Class version: %u")
|
||||
|| try_sec_hover.field<u16>("Version Epoch: %u")
|
||||
|| try_sec_hover.field<u16>("Version Major: %u")
|
||||
|| try_sec_hover.field<u16>("Version Minor: %u")
|
||||
|| try_sec_hover.field<u16>("Version Patch: %u")
|
||||
|| try_sec_hover.field<u64>("Seek Header: 0x%" PRIX64)
|
||||
|| try_sec_hover.field<u64>("NBytes Header: %u")
|
||||
|| try_sec_hover.field<u64>("Len Header: %u")
|
||||
|| try_sec_hover.field<u64>("Seek Footer: 0x%" PRIX64)
|
||||
|| try_sec_hover.field<u64>("NBytes Footer: %u")
|
||||
|| try_sec_hover.field<u64>("Len Footer: %u")
|
||||
|| try_sec_hover.field<u64>("Max Key Size: %u")
|
||||
|| try_sec_hover.field<u64>("Checksum: 0x%" PRIX64, hover_display_val_le)
|
||||
|| hover.field_be<u16>("Class version: %u")
|
||||
|| hover.field_be<u16>("Version Epoch: %u")
|
||||
|| hover.field_be<u16>("Version Major: %u")
|
||||
|| hover.field_be<u16>("Version Minor: %u")
|
||||
|| hover.field_be<u16>("Version Patch: %u")
|
||||
|| hover.field_be<u64>("Seek Header: 0x%" PRIX64)
|
||||
|| hover.field_be<u64>("NBytes Header: %u")
|
||||
|| hover.field_be<u64>("Len Header: %u")
|
||||
|| hover.field_be<u64>("Seek Footer: 0x%" PRIX64)
|
||||
|| hover.field_be<u64>("NBytes Footer: %u")
|
||||
|| hover.field_be<u64>("Len Footer: %u")
|
||||
|| hover.field_be<u64>("Max Key Size: %u")
|
||||
|| hover.field_le<u64>("Checksum: 0x%" PRIX64)
|
||||
;
|
||||
} break;
|
||||
|
||||
|
@ -893,46 +961,46 @@ Sec_Hover_Info get_section_hover_info(Arena *arena, Section section, u64 off, co
|
|||
b8 is_big = root_version > 1000000;
|
||||
|
||||
if (is_big) {
|
||||
try_sec_hover.field<u32>("ROOT magic number")
|
||||
|| try_sec_hover.field<u32>("ROOT version: %u", [] (Arena *arena, String8_Node *prev, const char *fmt, u32 x) {
|
||||
hover.field_be<u32>("ROOT magic number")
|
||||
|| hover.field<u32>("ROOT version: %u", [] (Arena *arena, String8_Node *prev, const char *fmt, u32 x) {
|
||||
x = bswap(x);
|
||||
x -= 1000000;
|
||||
return push_str8_node_child(arena, prev, fmt, x);
|
||||
})
|
||||
|| try_sec_hover.field<u32>("fBEGIN: 0x%" PRIX64)
|
||||
|| try_sec_hover.field<u64>("fEND: 0x%" PRIX64)
|
||||
|| try_sec_hover.field<u64>("Seek Free: 0x%" PRIX64)
|
||||
|| try_sec_hover.field<u32>("NBytes Free: %u")
|
||||
|| try_sec_hover.field<u32>("N Free: %u")
|
||||
|| try_sec_hover.field<u32>("NBytes Name: %u")
|
||||
|| try_sec_hover.field<u8>("Units: %u")
|
||||
|| try_sec_hover.field<u32>("Compression: %u")
|
||||
|| try_sec_hover.field<u64>("Seek Info: 0x%" PRIX64)
|
||||
|| try_sec_hover.field<u32>("NBytes Info: %u")
|
||||
|| try_sec_hover.range("Padding", section.post_size)
|
||||
|| hover.field_be<u32>("fBEGIN: 0x%" PRIX64)
|
||||
|| hover.field_be<u64>("fEND: 0x%" PRIX64)
|
||||
|| hover.field_be<u64>("Seek Free: 0x%" PRIX64)
|
||||
|| hover.field_be<u32>("NBytes Free: %u")
|
||||
|| hover.field_be<u32>("N Free: %u")
|
||||
|| hover.field_be<u32>("NBytes Name: %u")
|
||||
|| hover.field_be<u8>("Units: %u")
|
||||
|| hover.field_be<u32>("Compression: %u")
|
||||
|| hover.field_be<u64>("Seek Info: 0x%" PRIX64)
|
||||
|| hover.field_be<u32>("NBytes Info: %u")
|
||||
|| hover.range("Padding", section.post_size)
|
||||
;
|
||||
} else {
|
||||
try_sec_hover.field<u32>("ROOT magic number")
|
||||
|| try_sec_hover.field<u32>("ROOT version: %u")
|
||||
|| try_sec_hover.field<u32>("fBEGIN: 0x%" PRIX64)
|
||||
|| try_sec_hover.field<u32>("fEND: 0x%" PRIX64)
|
||||
|| try_sec_hover.field<u32>("Seek Free: 0x%" PRIX64)
|
||||
|| try_sec_hover.field<u32>("NBytes Free: %u")
|
||||
|| try_sec_hover.field<u32>("N Free: %u")
|
||||
|| try_sec_hover.field<u32>("NBytes Name: %u")
|
||||
|| try_sec_hover.field<u8>("Units: %u")
|
||||
|| try_sec_hover.field<u32>("Compression: %u")
|
||||
|| try_sec_hover.field<u32>("Seek Info: 0x%" PRIX64)
|
||||
|| try_sec_hover.field<u32>("NBytes Info: %u")
|
||||
|| try_sec_hover.range("Padding", section.post_size)
|
||||
hover.field_be<u32>("ROOT magic number")
|
||||
|| hover.field_be<u32>("ROOT version: %u")
|
||||
|| hover.field_be<u32>("fBEGIN: 0x%" PRIX64)
|
||||
|| hover.field_be<u32>("fEND: 0x%" PRIX64)
|
||||
|| hover.field_be<u32>("Seek Free: 0x%" PRIX64)
|
||||
|| hover.field_be<u32>("NBytes Free: %u")
|
||||
|| hover.field_be<u32>("N Free: %u")
|
||||
|| hover.field_be<u32>("NBytes Name: %u")
|
||||
|| hover.field_be<u8>("Units: %u")
|
||||
|| hover.field_be<u32>("Compression: %u")
|
||||
|| hover.field_be<u32>("Seek Info: 0x%" PRIX64)
|
||||
|| hover.field_be<u32>("NBytes Info: %u")
|
||||
|| hover.range("Padding", section.post_size)
|
||||
;
|
||||
}
|
||||
} break;
|
||||
|
||||
case Sec_TFile_Object: {
|
||||
if (!try_sec_hover.tkey()) {
|
||||
b8 ok = try_sec_hover.field<String8>("File Name: %s")
|
||||
|| try_sec_hover.field<String8>("File Title: %s")
|
||||
if (!hover.tkey()) {
|
||||
b8 ok = hover.field_str8<u8>("File Name: %s")
|
||||
|| hover.field_str8<u8>("File Title: %s")
|
||||
;
|
||||
if (!ok) {
|
||||
u16 version_be;
|
||||
|
@ -941,33 +1009,33 @@ Sec_Hover_Info get_section_hover_info(Arena *arena, Section section, u64 off, co
|
|||
b8 is_big = version > 1000;
|
||||
|
||||
if (is_big) {
|
||||
ok = ok || try_sec_hover.field<u16>("Version: %u", [] (Arena *arena, String8_Node *prev, const char *fmt, u16 x) {
|
||||
ok = ok || hover.field<u16>("Version: %u", [] (Arena *arena, String8_Node *prev, const char *fmt, u16 x) {
|
||||
x = bswap(x);
|
||||
x -= 1000;
|
||||
return push_str8_node_child(arena, prev, fmt, x);
|
||||
})
|
||||
|| try_sec_hover.field<u32>("Created: ", hover_display_datetime_str)
|
||||
|| try_sec_hover.field<u32>("Modified: ", hover_display_datetime_str)
|
||||
|| try_sec_hover.field<u32>("NBytes Key: %u")
|
||||
|| try_sec_hover.field<u32>("NBytes Name: %u")
|
||||
|| try_sec_hover.field<u64>("Seek Dir: 0x%" PRIX64)
|
||||
|| try_sec_hover.field<u64>("Seek Parent: 0x%" PRIX64)
|
||||
|| try_sec_hover.field<u64>("Seek Keys: 0x%" PRIX64)
|
||||
|| try_sec_hover.field<u16>("UUID Vers.Class: %u")
|
||||
|| try_sec_hover.field<u16>("UUID: %u", hover_display_val_le)
|
||||
|| hover.field<u32>("Created: ", hover_display_datetime_str)
|
||||
|| hover.field<u32>("Modified: ", hover_display_datetime_str)
|
||||
|| hover.field_be<u32>("NBytes Key: %u")
|
||||
|| hover.field_be<u32>("NBytes Name: %u")
|
||||
|| hover.field_be<u64>("Seek Dir: 0x%" PRIX64)
|
||||
|| hover.field_be<u64>("Seek Parent: 0x%" PRIX64)
|
||||
|| hover.field_be<u64>("Seek Keys: 0x%" PRIX64)
|
||||
|| hover.field_be<u16>("UUID Vers.Class: %u")
|
||||
|| hover.field_le<u16>("UUID: %u")
|
||||
;
|
||||
} else {
|
||||
ok = ok || try_sec_hover.field<u16>("Version: %u")
|
||||
|| try_sec_hover.field<u32>("Created: ", hover_display_datetime_str)
|
||||
|| try_sec_hover.field<u32>("Modified: ", hover_display_datetime_str)
|
||||
|| try_sec_hover.field<u32>("NBytes Key: %u")
|
||||
|| try_sec_hover.field<u32>("NBytes Name: %u")
|
||||
|| try_sec_hover.field<u32>("Seek Dir: 0x%" PRIX64)
|
||||
|| try_sec_hover.field<u32>("Seek Parent: 0x%" PRIX64)
|
||||
|| try_sec_hover.field<u32>("Seek Keys: 0x%" PRIX64)
|
||||
|| try_sec_hover.field<u16>("UUID Vers.Class: %u")
|
||||
|| try_sec_hover.field<u16>("UUID: %u", hover_display_val_le)
|
||||
|| try_sec_hover.range("Padding", 3 * sizeof(u32))
|
||||
ok = ok || hover.field_be<u16>("Version: %u")
|
||||
|| hover.field<u32>("Created: ", hover_display_datetime_str)
|
||||
|| hover.field<u32>("Modified: ", hover_display_datetime_str)
|
||||
|| hover.field_be<u32>("NBytes Key: %u")
|
||||
|| hover.field_be<u32>("NBytes Name: %u")
|
||||
|| hover.field_be<u32>("Seek Dir: 0x%" PRIX64)
|
||||
|| hover.field_be<u32>("Seek Parent: 0x%" PRIX64)
|
||||
|| hover.field_be<u32>("Seek Keys: 0x%" PRIX64)
|
||||
|| hover.field_be<u16>("UUID Vers.Class: %u")
|
||||
|| hover.field_le<u16>("UUID: %u")
|
||||
|| hover.range("Padding", 3 * sizeof(u32))
|
||||
;
|
||||
}
|
||||
}
|
||||
|
@ -975,63 +1043,85 @@ Sec_Hover_Info get_section_hover_info(Arena *arena, Section section, u64 off, co
|
|||
} break;
|
||||
|
||||
case Sec_RNTuple_Header:
|
||||
if (!hover.tkey()) {
|
||||
b8 zipped;
|
||||
if (!hover.maybe_rootzip(&zipped)) {
|
||||
if (zipped) {
|
||||
hover.range("Payload", section.range.len - section.post_size)
|
||||
|| hover.field_le<u64>("Checksum: 0x%" PRIX64)
|
||||
;
|
||||
} else {
|
||||
hover.envelope_preamble()
|
||||
// NOTE: flags in principle require a more complex handling, but for now they are unused,
|
||||
// so they're always occupying only 8 bytes.
|
||||
|| hover.field_le<u64>("Flags: 0x%" PRIX64)
|
||||
|| hover.field_str8<u32>("Name: %s")
|
||||
|| hover.field_str8<u32>("Description: %s")
|
||||
|| hover.field_str8<u32>("ROOT version: %s")
|
||||
|| hover.schema_description()
|
||||
|| hover.field_le<u64>("Checksum: 0x%" PRIX64)
|
||||
;
|
||||
}
|
||||
}
|
||||
}
|
||||
break;
|
||||
case Sec_RNTuple_Footer:
|
||||
case Sec_Page_List: {
|
||||
try_sec_hover.tkey()
|
||||
|| try_sec_hover.maybe_rootzip(data, start)
|
||||
|| try_sec_hover.range("Payload", section.range.len - section.post_size) // TODO: improve
|
||||
|| try_sec_hover.field<u64>("Checksum: 0x%" PRIX64, hover_display_val_le)
|
||||
hover.tkey()
|
||||
|| hover.maybe_rootzip()
|
||||
|| hover.range("Payload", section.range.len - section.post_size) // TODO: improve
|
||||
|| hover.field_le<u64>("Checksum: 0x%" PRIX64)
|
||||
;
|
||||
} break;
|
||||
|
||||
case Sec_Page: {
|
||||
// only try hovering a key if this is the first page of the cluster (<=> pre_size != 0)
|
||||
b8 ok = section.pre_size && try_sec_hover.tkey();
|
||||
ok = ok || try_sec_hover.maybe_rootzip(data, start)
|
||||
|| try_sec_hover.range("Payload", section.range.len - section.post_size) // TODO: improve
|
||||
|| try_sec_hover.field<u64>("Checksum: 0x%" PRIX64, hover_display_val_le)
|
||||
b8 ok = section.pre_size && hover.tkey();
|
||||
ok = ok || hover.maybe_rootzip()
|
||||
|| hover.range("Payload", section.range.len - section.post_size) // TODO: improve
|
||||
|| hover.field_le<u64>("Checksum: 0x%" PRIX64)
|
||||
;
|
||||
} break;
|
||||
|
||||
case Sec_TFile_Info: {
|
||||
try_sec_hover.tkey()
|
||||
|| try_sec_hover.maybe_rootzip(data, start)
|
||||
// || try_sec_hover.field<u32>("Byte Count: %u", [] (Arena *arena, String8_Node *prev, const char *fmt, u32 x) {
|
||||
hover.tkey()
|
||||
|| hover.maybe_rootzip()
|
||||
// || hover.field<u32>("Byte Count: %u", [] (Arena *arena, String8_Node *prev, const char *fmt, u32 x) {
|
||||
// x = bswap(x);
|
||||
// x -= 0x400000000;
|
||||
// return push_str8_node_child(arena, prev, fmt, x);
|
||||
// })
|
||||
// || try_sec_hover.field<u16>("Version: %u")
|
||||
// || hover_try_object(try_sec_hover)
|
||||
// || try_sec_hover.field<u8>("Name: %u")
|
||||
// || try_sec_hover.field<u32>("N Objects: %u")
|
||||
|| try_sec_hover.range("Payload", section.range.len) // TODO: improve
|
||||
// || hover.field_be<u16>("Version: %u")
|
||||
// || hover_try_object(hover)
|
||||
// || hover.field_be<u8>("Name: %u")
|
||||
// || hover.field_be<u32>("N Objects: %u")
|
||||
|| hover.range("Payload", section.range.len) // TODO: improve
|
||||
;
|
||||
} break;
|
||||
|
||||
case Sec_TFile_FreeList: {
|
||||
if (!try_sec_hover.tkey()) {
|
||||
if (!hover.tkey()) {
|
||||
u16 version_be;
|
||||
memcpy(&version_be, data + start + try_sec_hover.cur_field_off, sizeof(u16));
|
||||
memcpy(&version_be, data + start + hover.cur_field_off, sizeof(u16));
|
||||
u32 version = bswap(version_be);
|
||||
b8 is_big = version > 1000;
|
||||
|
||||
if (is_big) {
|
||||
try_sec_hover.field<u16>("Version: %u", [] (Arena *arena, String8_Node *prev, const char *fmt, u16 x) {
|
||||
hover.field<u16>("Version: %u", [] (Arena *arena, String8_Node *prev, const char *fmt, u16 x) {
|
||||
x = bswap(x);
|
||||
x -= 1000;
|
||||
return push_str8_node_child(arena, prev, fmt, x);
|
||||
})
|
||||
|| try_sec_hover.field<u64>("First: 0x%" PRIX64)
|
||||
|| try_sec_hover.field<u64>("Last: 0x%" PRIX64)
|
||||
|| hover.field_be<u64>("First: 0x%" PRIX64)
|
||||
|| hover.field_be<u64>("Last: 0x%" PRIX64)
|
||||
;
|
||||
} else {
|
||||
try_sec_hover.field<u16>("Version: %u", [] (Arena *arena, String8_Node *prev, const char *fmt, u16 x) {
|
||||
hover.field<u16>("Version: %u", [] (Arena *arena, String8_Node *prev, const char *fmt, u16 x) {
|
||||
x = bswap(x);
|
||||
return push_str8_node_child(arena, prev, fmt, x);
|
||||
})
|
||||
|| try_sec_hover.field<u32>("First: 0x%X")
|
||||
|| try_sec_hover.field<u32>("Last: 0x%X")
|
||||
|| hover.field_be<u32>("First: 0x%X")
|
||||
|| hover.field_be<u32>("Last: 0x%X")
|
||||
;
|
||||
}
|
||||
}
|
||||
|
@ -1040,6 +1130,5 @@ Sec_Hover_Info get_section_hover_info(Arena *arena, Section section, u64 off, co
|
|||
default:;
|
||||
}
|
||||
|
||||
|
||||
return info;
|
||||
}
|
||||
|
|
14
src/str.cpp
14
src/str.cpp
|
@ -78,6 +78,20 @@ String8_Node *push_str8_node_child(Arena *arena, String8_Node *parent, const cha
|
|||
} else {
|
||||
parent->last_child = parent->first_child = snode;
|
||||
}
|
||||
snode->head = parent->head;
|
||||
|
||||
return snode;
|
||||
}
|
||||
|
||||
internal
|
||||
void pop_str8_node_child(String8_Node *parent, String8_Node *node)
|
||||
{
|
||||
if (node->next)
|
||||
node->next->prev = node->prev;
|
||||
if (node->prev)
|
||||
node->prev->next = node->next;
|
||||
if (node == parent->first_child)
|
||||
parent->first_child = node->next;
|
||||
if (node == parent->last_child)
|
||||
parent->last_child = node->prev;
|
||||
}
|
||||
|
|
|
@ -26,7 +26,6 @@ using i64 = int64_t;
|
|||
#define LIKELY(x) __builtin_expect(!!(x), 1)
|
||||
#define UNLIKELY(x) __builtin_expect(!!(x), 0)
|
||||
|
||||
|
||||
#ifdef R__BYTESWAP
|
||||
|
||||
#if defined(R__MACOSX)
|
||||
|
|
Loading…
Reference in a new issue