add more hover info
This commit is contained in:
parent
8af9fddf73
commit
e9aae3f310
2 changed files with 144 additions and 32 deletions
169
src/rntuple.cpp
169
src/rntuple.cpp
|
@ -369,7 +369,7 @@ Section find_section(App_State &app, u64 off, i64 hilite_cluster = -1)
|
||||||
b8 hilite = false;
|
b8 hilite = false;
|
||||||
|
|
||||||
// TFile start
|
// TFile start
|
||||||
if (off <= tdata.root_file_header_size) return { Sec_TFile_Header, { 0, tdata.root_file_header_size }, 0, hilite };
|
if (off < tdata.root_file_header_size) return { Sec_TFile_Header, { 0, tdata.root_file_header_size }, 0, hilite };
|
||||||
if (tdata.rng_root_file_obj.start <= off && off < tdata.rng_root_file_obj.end()) return { Sec_TFile_Object, tdata.rng_root_file_obj, 0, hilite };
|
if (tdata.rng_root_file_obj.start <= off && off < tdata.rng_root_file_obj.end()) return { Sec_TFile_Object, tdata.rng_root_file_obj, 0, hilite };
|
||||||
if (tdata.rng_root_file_info.start <= off && off < tdata.rng_root_file_info.end()) return { Sec_TFile_Info, tdata.rng_root_file_info, 0, hilite };
|
if (tdata.rng_root_file_info.start <= off && off < tdata.rng_root_file_info.end()) return { Sec_TFile_Info, tdata.rng_root_file_info, 0, hilite };
|
||||||
if (tdata.rng_root_file_free.start <= off && off < tdata.rng_root_file_free.end()) return { Sec_TFile_FreeList, tdata.rng_root_file_free, 0, hilite };
|
if (tdata.rng_root_file_free.start <= off && off < tdata.rng_root_file_free.end()) return { Sec_TFile_FreeList, tdata.rng_root_file_free, 0, hilite };
|
||||||
|
@ -445,51 +445,160 @@ struct Sec_Hover_Info {
|
||||||
String8_Node *desc;
|
String8_Node *desc;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
template <typename T> void hover_postproc_val(T &) {}
|
||||||
|
template <> void hover_postproc_val(u16 &x) { x = bswap_16(x); }
|
||||||
|
template <> void hover_postproc_val(u32 &x) { x = bswap_32(x); }
|
||||||
|
template <> void hover_postproc_val(u64 &x) { x = bswap_64(x); }
|
||||||
|
|
||||||
|
template <typename T>
|
||||||
|
String8_Node *hover_display_val(Arena *arena, String8_Node *prev, const char *fmt, T val)
|
||||||
|
{
|
||||||
|
hover_postproc_val(val);
|
||||||
|
return push_str8_node(arena, prev, fmt, val);
|
||||||
|
}
|
||||||
|
|
||||||
|
internal
|
||||||
|
String8_Node *hover_display_datetime_str(Arena *arena, String8_Node *prev, const char *fmt_pre, u32 datetime)
|
||||||
|
{
|
||||||
|
hover_postproc_val(datetime);
|
||||||
|
|
||||||
|
// datetime:
|
||||||
|
// year (6b) | month (4b) | day (5b) | hour (5b) | min (6b) | sec (6b)
|
||||||
|
u32 year = (datetime >> 26) - 1900 + 1995;
|
||||||
|
u32 month = ((datetime & 0x3ff'ffff) >> 22) - 1;
|
||||||
|
u32 day = (datetime & 0x3f'ffff) >> 17;
|
||||||
|
u32 hour = (datetime & 0x1'ffff) >> 12;
|
||||||
|
u32 min = (datetime & 0xfff) >> 6;
|
||||||
|
u32 sec = datetime & 0x3f;
|
||||||
|
return push_str8_node(arena, prev, "%s%u/%02u/%02u %02u:%02u:%02u", fmt_pre, year, month, day, hour, min, sec);
|
||||||
|
}
|
||||||
|
|
||||||
|
struct Try_Sec_Hover_Fn {
|
||||||
|
u64 start;
|
||||||
|
u64 roff;
|
||||||
|
const u8 *data;
|
||||||
|
Arena *arena;
|
||||||
|
Sec_Hover_Info &info;
|
||||||
|
u64 &cur_field_off;
|
||||||
|
|
||||||
|
template <typename TField_Type>
|
||||||
|
bool operator()(const char *desc_fmt,
|
||||||
|
String8_Node *(*display_val)(Arena *, String8_Node *, const char *, TField_Type) = hover_display_val<TField_Type>
|
||||||
|
) const
|
||||||
|
{
|
||||||
|
u64 field_len = sizeof(TField_Type);
|
||||||
|
if (roff < cur_field_off + field_len) {
|
||||||
|
info.rng = { start + cur_field_off, field_len };
|
||||||
|
TField_Type 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;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
// `off` is the absolute offset into `data`.
|
// `off` is the absolute offset into `data`.
|
||||||
internal
|
internal
|
||||||
Sec_Hover_Info get_section_hover_info(Arena *arena, Section section, u64 off, const u8 *data)
|
Sec_Hover_Info get_section_hover_info(Arena *arena, Section section, u64 off, const u8 *data)
|
||||||
{
|
{
|
||||||
Sec_Hover_Info info {};
|
Sec_Hover_Info info {};
|
||||||
|
|
||||||
printf("off: 0x%lX, sec start: 0x%lX\n", off, section.range.start);
|
// printf("off: 0x%lX, sec start: 0x%lX\n", off, section.range.start);
|
||||||
// assert(off >= section.range.start);
|
// assert(off >= section.range.start);
|
||||||
if (off < section.range.start) {
|
if (off < section.range.start) {
|
||||||
printf("WRONG\n"); // TODO: fix TKey Header case
|
printf("WRONG\n"); // TODO: fix TKey Header case
|
||||||
}
|
}
|
||||||
|
|
||||||
|
info.desc = push_str8_node(arena, nullptr, section_names[section.id].c());
|
||||||
|
|
||||||
u64 start = section.range.start;
|
u64 start = section.range.start;
|
||||||
u64 roff = off - start; // offset relative to `section`
|
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 };
|
||||||
|
|
||||||
if (section.id == Sec_RNTuple_Anchor) {
|
switch (section.id) {
|
||||||
info.desc = push_str8_node(arena, nullptr, "RNTuple Anchor");
|
case Sec_RNTuple_Anchor: {
|
||||||
// TODO: dry
|
try_sec_hover.operator()<u32>("Object len: %u", [] (Arena *arena, String8_Node *prev, const char *fmt, u32 x) {
|
||||||
if (roff < sizeof(u32)) {
|
x = bswap_32(x);
|
||||||
info.rng = { start, sizeof(u32) };
|
x -= 0x4000'0000;
|
||||||
u32 val;
|
return push_str8_node(arena, prev, fmt, x);
|
||||||
memcpy(&val, data + info.rng.start, info.rng.len);
|
})
|
||||||
val = bswap_32(val);
|
|| try_sec_hover.operator()<u16>("Class version: %u")
|
||||||
val -= 0x40000000;
|
|| try_sec_hover.operator()<u16>("Version Epoch: %u")
|
||||||
push_str8_node(arena, info.desc, "Object len: %u", val);
|
|| try_sec_hover.operator()<u16>("Version Major: %u")
|
||||||
} else if (roff < sizeof(u32) + sizeof(u16)) {
|
|| try_sec_hover.operator()<u16>("Version Minor: %u")
|
||||||
info.rng = { start + sizeof(u32), sizeof(u16) };
|
|| try_sec_hover.operator()<u16>("Version Patch: %u")
|
||||||
u32 val;
|
|| try_sec_hover.operator()<u64>("Seek Header: %u")
|
||||||
memcpy(&val, data + info.rng.start, info.rng.len);
|
|| try_sec_hover.operator()<u64>("NBytes Header: %u")
|
||||||
val = bswap_16(val);
|
|| try_sec_hover.operator()<u64>("Len Header: %u")
|
||||||
push_str8_node(arena, info.desc, "Class version: %u", val);
|
|| try_sec_hover.operator()<u64>("Seek Footer: %u")
|
||||||
} else if (roff < sizeof(u32) + sizeof(u16) + sizeof(u16)) {
|
|| try_sec_hover.operator()<u64>("NBytes Footer: %u")
|
||||||
info.rng = { start + sizeof(u32) + sizeof(u16), sizeof(u16) };
|
|| try_sec_hover.operator()<u64>("Len Footer: %u")
|
||||||
u16 val;
|
|| try_sec_hover.operator()<u64>("Max Key Size: %u")
|
||||||
memcpy(&val, data + info.rng.start, info.rng.len);
|
;
|
||||||
val = bswap_16(val);
|
} break;
|
||||||
push_str8_node(arena, info.desc, "Version Epoch: %u", val);
|
|
||||||
} else if (roff < sizeof(u32) + sizeof(u16) + sizeof(u16) + sizeof(u16)) {
|
case Sec_TFile_Header: {
|
||||||
info.rng = { start + sizeof(u32) + sizeof(u16) + sizeof(u16), sizeof(u16) };
|
u32 root_version_be;
|
||||||
u16 val;
|
memcpy(&root_version_be, data + start + 4, sizeof(u32));
|
||||||
memcpy(&val, data + info.rng.start, info.rng.len);
|
u32 root_version = bswap_32(root_version_be);
|
||||||
val = bswap_16(val);
|
b32x is_big = root_version > 1000000;
|
||||||
push_str8_node(arena, info.desc, "Version Major: %u", val);
|
|
||||||
|
if (is_big) {
|
||||||
|
try_sec_hover.operator()<u32>("ROOT magic number")
|
||||||
|
|| try_sec_hover.operator()<u32>("ROOT version: %u", [] (Arena *arena, String8_Node *prev, const char *fmt, u32 x) {
|
||||||
|
x = bswap_32(x);
|
||||||
|
x -= 1000000;
|
||||||
|
return push_str8_node(arena, prev, fmt, x);
|
||||||
|
})
|
||||||
|
|| try_sec_hover.operator()<u32>("fBEGIN: 0x%lX")
|
||||||
|
|| try_sec_hover.operator()<u64>("fEND: 0x%lX")
|
||||||
|
|| try_sec_hover.operator()<u64>("Seek Free: 0x%lX")
|
||||||
|
|| try_sec_hover.operator()<u32>("NBytes Free: %u")
|
||||||
|
|| try_sec_hover.operator()<u32>("N Free: %u")
|
||||||
|
|| try_sec_hover.operator()<u32>("NBytes Name: %u")
|
||||||
|
|| try_sec_hover.operator()<u8>("Units: %u")
|
||||||
|
|| try_sec_hover.operator()<u32>("Compression: %u")
|
||||||
|
|| try_sec_hover.operator()<u64>("Seek Info: 0x%lX")
|
||||||
|
|| try_sec_hover.operator()<u32>("NBytes Info: %u")
|
||||||
|
;
|
||||||
|
} else {
|
||||||
|
try_sec_hover.operator()<u32>("ROOT magic number")
|
||||||
|
|| try_sec_hover.operator()<u32>("ROOT version: %u")
|
||||||
|
|| try_sec_hover.operator()<u32>("fBEGIN: 0x%lX")
|
||||||
|
|| try_sec_hover.operator()<u32>("fEND: 0x%lX")
|
||||||
|
|| try_sec_hover.operator()<u32>("Seek Free: 0x%lX")
|
||||||
|
|| try_sec_hover.operator()<u32>("NBytes Free: %u")
|
||||||
|
|| try_sec_hover.operator()<u32>("N Free: %u")
|
||||||
|
|| try_sec_hover.operator()<u32>("NBytes Name: %u")
|
||||||
|
|| try_sec_hover.operator()<u8>("Units: %u")
|
||||||
|
|| try_sec_hover.operator()<u32>("Compression: %u")
|
||||||
|
|| try_sec_hover.operator()<u32>("Seek Info: 0x%lX")
|
||||||
|
|| try_sec_hover.operator()<u32>("NBytes Info: %u")
|
||||||
|
;
|
||||||
}
|
}
|
||||||
|
} break;
|
||||||
|
|
||||||
|
case Sec_TFile_Object: {
|
||||||
|
// FIXME
|
||||||
|
try_sec_hover.operator()<u32>("ROOT magic number")
|
||||||
|
|| try_sec_hover.operator()<u16>("Class version: %u", [] (Arena *arena, String8_Node *prev, const char *fmt, u16 x) {
|
||||||
|
x = bswap_16(x);
|
||||||
|
x -= (x > 1000) * 1000;
|
||||||
|
return push_str8_node(arena, prev, fmt, x);
|
||||||
|
})
|
||||||
|
|| try_sec_hover.operator()<u32>("Created: ", hover_display_datetime_str)
|
||||||
|
|| try_sec_hover.operator()<u32>("Modified: ", hover_display_datetime_str)
|
||||||
|
|| try_sec_hover.operator()<u32>("NBytes Keys %u")
|
||||||
|
|| try_sec_hover.operator()<u32>("NBytes Name %u")
|
||||||
|
;
|
||||||
|
} break;
|
||||||
|
|
||||||
|
default:;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
return info;
|
return info;
|
||||||
}
|
}
|
||||||
|
|
|
@ -1072,7 +1072,10 @@ Root_File_Info get_root_file_info(const char *fname, bool is_big_file)
|
||||||
{
|
{
|
||||||
RTFString fileName { fname };
|
RTFString fileName { fname };
|
||||||
Root_File_Info fileInfo {};
|
Root_File_Info fileInfo {};
|
||||||
fileInfo.tfile_header_nbytes = RTFHeader{}.GetSize();
|
RTFHeader header;
|
||||||
|
if (is_big_file)
|
||||||
|
header.SetBigFile();
|
||||||
|
fileInfo.tfile_header_nbytes = header.GetSize();
|
||||||
fileInfo.tfile_obj_seek = 100; // kBEGIN
|
fileInfo.tfile_obj_seek = 100; // kBEGIN
|
||||||
fileInfo.tfile_obj_nbytes = sizeof(RTFFile) + fileName.GetSize() + RTFString{}.GetSize() + RTFUUID{}.GetSize();
|
fileInfo.tfile_obj_nbytes = sizeof(RTFFile) + fileName.GetSize() + RTFString{}.GetSize() + RTFUUID{}.GetSize();
|
||||||
fileInfo.version_seek = offsetof(RTFHeader, fVersion);
|
fileInfo.version_seek = offsetof(RTFHeader, fVersion);
|
||||||
|
|
Loading…
Reference in a new issue