add hover info for tfile object
This commit is contained in:
parent
e9aae3f310
commit
b758f63ed3
2 changed files with 172 additions and 57 deletions
207
src/rntuple.cpp
207
src/rntuple.cpp
|
@ -457,6 +457,13 @@ String8_Node *hover_display_val(Arena *arena, String8_Node *prev, const char *fm
|
||||||
return push_str8_node(arena, prev, fmt, val);
|
return push_str8_node(arena, prev, fmt, val);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
template <>
|
||||||
|
String8_Node *hover_display_val(Arena *arena, String8_Node *prev, const char *fmt, String8 val)
|
||||||
|
{
|
||||||
|
hover_postproc_val(val);
|
||||||
|
return push_str8_node(arena, prev, fmt, val.c());
|
||||||
|
}
|
||||||
|
|
||||||
internal
|
internal
|
||||||
String8_Node *hover_display_datetime_str(Arena *arena, String8_Node *prev, const char *fmt_pre, u32 datetime)
|
String8_Node *hover_display_datetime_str(Arena *arena, String8_Node *prev, const char *fmt_pre, u32 datetime)
|
||||||
{
|
{
|
||||||
|
@ -464,7 +471,7 @@ String8_Node *hover_display_datetime_str(Arena *arena, String8_Node *prev, const
|
||||||
|
|
||||||
// datetime:
|
// datetime:
|
||||||
// year (6b) | month (4b) | day (5b) | hour (5b) | min (6b) | sec (6b)
|
// year (6b) | month (4b) | day (5b) | hour (5b) | min (6b) | sec (6b)
|
||||||
u32 year = (datetime >> 26) - 1900 + 1995;
|
u32 year = (datetime >> 26) + 1995;
|
||||||
u32 month = ((datetime & 0x3ff'ffff) >> 22) - 1;
|
u32 month = ((datetime & 0x3ff'ffff) >> 22) - 1;
|
||||||
u32 day = (datetime & 0x3f'ffff) >> 17;
|
u32 day = (datetime & 0x3f'ffff) >> 17;
|
||||||
u32 hour = (datetime & 0x1'ffff) >> 12;
|
u32 hour = (datetime & 0x1'ffff) >> 12;
|
||||||
|
@ -482,7 +489,7 @@ struct Try_Sec_Hover_Fn {
|
||||||
u64 &cur_field_off;
|
u64 &cur_field_off;
|
||||||
|
|
||||||
template <typename TField_Type>
|
template <typename TField_Type>
|
||||||
bool operator()(const char *desc_fmt,
|
bool field(const char *desc_fmt,
|
||||||
String8_Node *(*display_val)(Arena *, String8_Node *, const char *, TField_Type) = hover_display_val<TField_Type>
|
String8_Node *(*display_val)(Arena *, String8_Node *, const char *, TField_Type) = hover_display_val<TField_Type>
|
||||||
) const
|
) const
|
||||||
{
|
{
|
||||||
|
@ -497,8 +504,77 @@ struct Try_Sec_Hover_Fn {
|
||||||
cur_field_off += field_len;
|
cur_field_off += field_len;
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
template <>
|
||||||
|
bool field<String8>(const char *desc_fmt,
|
||||||
|
String8_Node *(*display_val)(Arena *, String8_Node *, const char *, String8)
|
||||||
|
) 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 };
|
||||||
|
u8 *buf = arena_push_array_nozero<u8>(arena, str_size + 1);
|
||||||
|
memcpy(buf, data + start + cur_field_off + 1, 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;
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool range(const char *desc, u64 range_len) const
|
||||||
|
{
|
||||||
|
if (roff < cur_field_off + range_len) {
|
||||||
|
info.rng = { start + cur_field_off, range_len };
|
||||||
|
push_str8_node(arena, info.desc, "%s", desc);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
cur_field_off += range_len;
|
||||||
|
return false;
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
internal
|
||||||
|
bool hover_try_key(const Try_Sec_Hover_Fn &try_sec_hover, const u8 *data, u64 start)
|
||||||
|
{
|
||||||
|
u16 version_be;
|
||||||
|
memcpy(&version_be, data + start + 4, sizeof(u16));
|
||||||
|
u32 version = bswap_16(version_be);
|
||||||
|
b8 is_big = version > 1000;
|
||||||
|
|
||||||
|
if (is_big) {
|
||||||
|
return try_sec_hover.field<u32>("NBytes: %u")
|
||||||
|
|| try_sec_hover.field<u16>("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.field<u32>("Obj Len: %u")
|
||||||
|
|| try_sec_hover.field<u32>("Datetime: ", hover_display_datetime_str)
|
||||||
|
|| try_sec_hover.field<u16>("Key Len: %u")
|
||||||
|
|| try_sec_hover.field<u16>("Cycle: %u")
|
||||||
|
|| try_sec_hover.field<u64>("Seek Key: 0x%lX")
|
||||||
|
|| try_sec_hover.field<u64>("Seek Pdir: 0x%lX")
|
||||||
|
;
|
||||||
|
} else {
|
||||||
|
return try_sec_hover.field<u32>("NBytes: %u")
|
||||||
|
|| try_sec_hover.field<u16>("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.field<u32>("Obj Len: %u")
|
||||||
|
|| try_sec_hover.field<u32>("Datetime: ", hover_display_datetime_str)
|
||||||
|
|| try_sec_hover.field<u16>("Key Len: %u")
|
||||||
|
|| try_sec_hover.field<u16>("Cycle: %u")
|
||||||
|
|| try_sec_hover.field<u32>("Seek Key: 0x%lX")
|
||||||
|
|| try_sec_hover.field<u32>("Seek Pdir: 0x%lX")
|
||||||
|
;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// `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)
|
||||||
|
@ -520,23 +596,23 @@ Sec_Hover_Info get_section_hover_info(Arena *arena, Section section, u64 off, co
|
||||||
|
|
||||||
switch (section.id) {
|
switch (section.id) {
|
||||||
case Sec_RNTuple_Anchor: {
|
case Sec_RNTuple_Anchor: {
|
||||||
try_sec_hover.operator()<u32>("Object len: %u", [] (Arena *arena, String8_Node *prev, const char *fmt, u32 x) {
|
try_sec_hover.field<u32>("Object len: %u", [] (Arena *arena, String8_Node *prev, const char *fmt, u32 x) {
|
||||||
x = bswap_32(x);
|
x = bswap_32(x);
|
||||||
x -= 0x4000'0000;
|
x -= 0x4000'0000;
|
||||||
return push_str8_node(arena, prev, fmt, x);
|
return push_str8_node(arena, prev, fmt, x);
|
||||||
})
|
})
|
||||||
|| try_sec_hover.operator()<u16>("Class version: %u")
|
|| try_sec_hover.field<u16>("Class version: %u")
|
||||||
|| try_sec_hover.operator()<u16>("Version Epoch: %u")
|
|| try_sec_hover.field<u16>("Version Epoch: %u")
|
||||||
|| try_sec_hover.operator()<u16>("Version Major: %u")
|
|| try_sec_hover.field<u16>("Version Major: %u")
|
||||||
|| try_sec_hover.operator()<u16>("Version Minor: %u")
|
|| try_sec_hover.field<u16>("Version Minor: %u")
|
||||||
|| try_sec_hover.operator()<u16>("Version Patch: %u")
|
|| try_sec_hover.field<u16>("Version Patch: %u")
|
||||||
|| try_sec_hover.operator()<u64>("Seek Header: %u")
|
|| try_sec_hover.field<u64>("Seek Header: %u")
|
||||||
|| try_sec_hover.operator()<u64>("NBytes Header: %u")
|
|| try_sec_hover.field<u64>("NBytes Header: %u")
|
||||||
|| try_sec_hover.operator()<u64>("Len Header: %u")
|
|| try_sec_hover.field<u64>("Len Header: %u")
|
||||||
|| try_sec_hover.operator()<u64>("Seek Footer: %u")
|
|| try_sec_hover.field<u64>("Seek Footer: %u")
|
||||||
|| try_sec_hover.operator()<u64>("NBytes Footer: %u")
|
|| try_sec_hover.field<u64>("NBytes Footer: %u")
|
||||||
|| try_sec_hover.operator()<u64>("Len Footer: %u")
|
|| try_sec_hover.field<u64>("Len Footer: %u")
|
||||||
|| try_sec_hover.operator()<u64>("Max Key Size: %u")
|
|| try_sec_hover.field<u64>("Max Key Size: %u")
|
||||||
;
|
;
|
||||||
} break;
|
} break;
|
||||||
|
|
||||||
|
@ -544,56 +620,91 @@ Sec_Hover_Info get_section_hover_info(Arena *arena, Section section, u64 off, co
|
||||||
u32 root_version_be;
|
u32 root_version_be;
|
||||||
memcpy(&root_version_be, data + start + 4, sizeof(u32));
|
memcpy(&root_version_be, data + start + 4, sizeof(u32));
|
||||||
u32 root_version = bswap_32(root_version_be);
|
u32 root_version = bswap_32(root_version_be);
|
||||||
b32x is_big = root_version > 1000000;
|
b8 is_big = root_version > 1000000;
|
||||||
|
|
||||||
if (is_big) {
|
if (is_big) {
|
||||||
try_sec_hover.operator()<u32>("ROOT magic number")
|
try_sec_hover.field<u32>("ROOT magic number")
|
||||||
|| try_sec_hover.operator()<u32>("ROOT version: %u", [] (Arena *arena, String8_Node *prev, const char *fmt, u32 x) {
|
|| try_sec_hover.field<u32>("ROOT version: %u", [] (Arena *arena, String8_Node *prev, const char *fmt, u32 x) {
|
||||||
x = bswap_32(x);
|
x = bswap_32(x);
|
||||||
x -= 1000000;
|
x -= 1000000;
|
||||||
return push_str8_node(arena, prev, fmt, x);
|
return push_str8_node(arena, prev, fmt, x);
|
||||||
})
|
})
|
||||||
|| try_sec_hover.operator()<u32>("fBEGIN: 0x%lX")
|
|| try_sec_hover.field<u32>("fBEGIN: 0x%lX")
|
||||||
|| try_sec_hover.operator()<u64>("fEND: 0x%lX")
|
|| try_sec_hover.field<u64>("fEND: 0x%lX")
|
||||||
|| try_sec_hover.operator()<u64>("Seek Free: 0x%lX")
|
|| try_sec_hover.field<u64>("Seek Free: 0x%lX")
|
||||||
|| try_sec_hover.operator()<u32>("NBytes Free: %u")
|
|| try_sec_hover.field<u32>("NBytes Free: %u")
|
||||||
|| try_sec_hover.operator()<u32>("N Free: %u")
|
|| try_sec_hover.field<u32>("N Free: %u")
|
||||||
|| try_sec_hover.operator()<u32>("NBytes Name: %u")
|
|| try_sec_hover.field<u32>("NBytes Name: %u")
|
||||||
|| try_sec_hover.operator()<u8>("Units: %u")
|
|| try_sec_hover.field<u8>("Units: %u")
|
||||||
|| try_sec_hover.operator()<u32>("Compression: %u")
|
|| try_sec_hover.field<u32>("Compression: %u")
|
||||||
|| try_sec_hover.operator()<u64>("Seek Info: 0x%lX")
|
|| try_sec_hover.field<u64>("Seek Info: 0x%lX")
|
||||||
|| try_sec_hover.operator()<u32>("NBytes Info: %u")
|
|| try_sec_hover.field<u32>("NBytes Info: %u")
|
||||||
;
|
;
|
||||||
} else {
|
} else {
|
||||||
try_sec_hover.operator()<u32>("ROOT magic number")
|
try_sec_hover.field<u32>("ROOT magic number")
|
||||||
|| try_sec_hover.operator()<u32>("ROOT version: %u")
|
|| try_sec_hover.field<u32>("ROOT version: %u")
|
||||||
|| try_sec_hover.operator()<u32>("fBEGIN: 0x%lX")
|
|| try_sec_hover.field<u32>("fBEGIN: 0x%lX")
|
||||||
|| try_sec_hover.operator()<u32>("fEND: 0x%lX")
|
|| try_sec_hover.field<u32>("fEND: 0x%lX")
|
||||||
|| try_sec_hover.operator()<u32>("Seek Free: 0x%lX")
|
|| try_sec_hover.field<u32>("Seek Free: 0x%lX")
|
||||||
|| try_sec_hover.operator()<u32>("NBytes Free: %u")
|
|| try_sec_hover.field<u32>("NBytes Free: %u")
|
||||||
|| try_sec_hover.operator()<u32>("N Free: %u")
|
|| try_sec_hover.field<u32>("N Free: %u")
|
||||||
|| try_sec_hover.operator()<u32>("NBytes Name: %u")
|
|| try_sec_hover.field<u32>("NBytes Name: %u")
|
||||||
|| try_sec_hover.operator()<u8>("Units: %u")
|
|| try_sec_hover.field<u8>("Units: %u")
|
||||||
|| try_sec_hover.operator()<u32>("Compression: %u")
|
|| try_sec_hover.field<u32>("Compression: %u")
|
||||||
|| try_sec_hover.operator()<u32>("Seek Info: 0x%lX")
|
|| try_sec_hover.field<u32>("Seek Info: 0x%lX")
|
||||||
|| try_sec_hover.operator()<u32>("NBytes Info: %u")
|
|| try_sec_hover.field<u32>("NBytes Info: %u")
|
||||||
;
|
;
|
||||||
}
|
}
|
||||||
} break;
|
} break;
|
||||||
|
|
||||||
case Sec_TFile_Object: {
|
case Sec_TFile_Object: {
|
||||||
// FIXME
|
if (!hover_try_key(try_sec_hover, data, start)) {
|
||||||
try_sec_hover.operator()<u32>("ROOT magic number")
|
b8 ok = try_sec_hover.field<String8>("Class Name: %s")
|
||||||
|| try_sec_hover.operator()<u16>("Class version: %u", [] (Arena *arena, String8_Node *prev, const char *fmt, u16 x) {
|
|| try_sec_hover.field<String8>("Obj Name: %s")
|
||||||
|
|| try_sec_hover.field<String8>("Obj Title: %s")
|
||||||
|
|| try_sec_hover.field<String8>("File Name: %s")
|
||||||
|
|| try_sec_hover.field<String8>("File Title: %s")
|
||||||
|
;
|
||||||
|
|
||||||
|
if (!ok) {
|
||||||
|
u16 version_be;
|
||||||
|
memcpy(&version_be, data + cur_field_off, sizeof(u16));
|
||||||
|
u16 version = bswap_16(version_be);
|
||||||
|
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) {
|
||||||
x = bswap_16(x);
|
x = bswap_16(x);
|
||||||
x -= (x > 1000) * 1000;
|
x -= 1000;
|
||||||
return push_str8_node(arena, prev, fmt, x);
|
return push_str8_node(arena, prev, fmt, x);
|
||||||
})
|
})
|
||||||
|| try_sec_hover.operator()<u32>("Created: ", hover_display_datetime_str)
|
|| try_sec_hover.field<u32>("Created: ", hover_display_datetime_str)
|
||||||
|| try_sec_hover.operator()<u32>("Modified: ", hover_display_datetime_str)
|
|| try_sec_hover.field<u32>("Modified: ", hover_display_datetime_str)
|
||||||
|| try_sec_hover.operator()<u32>("NBytes Keys %u")
|
|| try_sec_hover.field<u32>("NBytes Key: %u")
|
||||||
|| try_sec_hover.operator()<u32>("NBytes Name %u")
|
|| try_sec_hover.field<u32>("NBytes Name: %u")
|
||||||
|
|| try_sec_hover.field<u64>("Seek Dir: 0x%lX")
|
||||||
|
|| try_sec_hover.field<u64>("Seek Parent: 0x%lX")
|
||||||
|
|| try_sec_hover.field<u64>("Seek Keys: 0x%lX")
|
||||||
;
|
;
|
||||||
|
} 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%lX")
|
||||||
|
|| try_sec_hover.field<u32>("Seek Parent: 0x%lX")
|
||||||
|
|| try_sec_hover.field<u32>("Seek Keys: 0x%lX")
|
||||||
|
;
|
||||||
|
}
|
||||||
|
ok = ok || try_sec_hover.field<u16>("UUID Vers.Class: %u")
|
||||||
|
|| try_sec_hover.field<u16>("UUID: %u", [] (Arena *arena, String8_Node *prev, const char *fmt, u16 x) {
|
||||||
|
return push_str8_node(arena, prev, fmt, x);
|
||||||
|
})
|
||||||
|
|| try_sec_hover.range("Padding", 3 * sizeof(u32))
|
||||||
|
;
|
||||||
|
}
|
||||||
|
}
|
||||||
} break;
|
} break;
|
||||||
|
|
||||||
default:;
|
default:;
|
||||||
|
|
|
@ -1077,7 +1077,11 @@ Root_File_Info get_root_file_info(const char *fname, bool is_big_file)
|
||||||
header.SetBigFile();
|
header.SetBigFile();
|
||||||
fileInfo.tfile_header_nbytes = header.GetSize();
|
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();
|
RTFKey fileHeader {
|
||||||
|
100, 0, RTFString{ "TFile" }, fileName, RTFString{},
|
||||||
|
sizeof(RTFFile) + fileName.GetSize() + RTFString{}.GetSize() + RTFUUID{}.GetSize()
|
||||||
|
};
|
||||||
|
fileInfo.tfile_obj_nbytes = fileHeader.GetSize();
|
||||||
fileInfo.version_seek = offsetof(RTFHeader, fVersion);
|
fileInfo.version_seek = offsetof(RTFHeader, fVersion);
|
||||||
fileInfo.compression_seek = is_big_file ? offsetof(RTFHeader, fInfoLong.fCompress) : offsetof(RTFHeader, fInfoShort.fCompress);
|
fileInfo.compression_seek = is_big_file ? offsetof(RTFHeader, fInfoLong.fCompress) : offsetof(RTFHeader, fInfoShort.fCompress);
|
||||||
fileInfo.info_seek_seek = is_big_file ? offsetof(RTFHeader, fInfoLong.fSeekInfo) : offsetof(RTFHeader, fInfoShort.fSeekInfo);
|
fileInfo.info_seek_seek = is_big_file ? offsetof(RTFHeader, fInfoLong.fSeekInfo) : offsetof(RTFHeader, fInfoShort.fSeekInfo);
|
||||||
|
|
Loading…
Reference in a new issue