-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathhdf5_superblock.h
More file actions
64 lines (56 loc) · 2.4 KB
/
Copy pathhdf5_superblock.h
File metadata and controls
64 lines (56 loc) · 2.4 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
#pragma once
#include "hdf5_types.h"
#include "hdf5_io.h"
namespace hdf5_reader {
namespace detail {
// ============================================================================
// Superblock (version 0)
// ============================================================================
inline Superblock parse_superblock(std::ifstream& f) {
static const uint64_t CANDIDATES[] = { 0, 512, 1024, 2048, 4096 };
uint8_t sig[8];
uint64_t sb_abs = UNDEF64;
for (uint64_t c : CANDIDATES) {
f.seekg((std::streamoff)c);
if (!f.good()) continue;
f.read((char*)sig, 8);
if (f.gcount() == 8 && memcmp(sig, SIG_HDF5, 8) == 0) { sb_abs = c; break; }
}
if (sb_abs == UNDEF64) throw std::runtime_error(
"hdf5_reader: HDF5 superblock not found");
fseek(f, sb_abs);
fskip(f, 8); // signature
uint8_t ver = frd8(f);
if (ver != 0) throw std::runtime_error(
"hdf5_reader: only Superblock v0 supported, got v" + std::to_string(ver));
// v0 after signature:
// ver(1) freesp_ver(1) root_g_ver(1) res(1) shdr_ver(1) sz_off(1) sz_len(1) res(1)
// leaf_k(2) intern_k(2) flags(4)
// base(8) freesp(8) eof(8) drv(8)
// root STE: link_name(8) ohdr(8) cache_type(4) res(4) scratch(16)
fskip(f, 4); // [9..12]: freesp_ver, rootg_ver, res, shdr_ver
uint8_t sz_off = frd8(f); // [13]
uint8_t sz_len = frd8(f); // [14]
fskip(f, 1); // [15]: reserved
if (sz_off != 8 || sz_len != 8) throw std::runtime_error(
"hdf5_reader: only 8-byte offsets/lengths supported (got sz_off="
+ std::to_string(sz_off) + " sz_len=" + std::to_string(sz_len) + ")");
fskip(f, 2 + 2 + 4); // [16..23]: leaf_k(2), intern_k(2), flags(4)
Superblock sb;
sb.base = frd64(f); // base_address (absolute)
fskip(f, 8 + 8 + 8); // freesp, eof, drv_info
// Root group STE
fskip(f, 8); // link_name_offset (always 0)
uint64_t root_ohdr_rel = frd64(f);
sb.root_ohdr = sb.base + root_ohdr_rel;
uint32_t cache_type = frd32(f);
fskip(f, 4); // reserved
uint64_t btree_rel = frd64(f);
uint64_t heap_rel = frd64(f);
sb.root_btree = (btree_rel != UNDEF64) ? sb.base + btree_rel : UNDEF64;
sb.root_heap = (heap_rel != UNDEF64) ? sb.base + heap_rel : UNDEF64;
(void)cache_type;
return sb;
}
} // namespace detail
} // namespace hdf5_reader