39#define G_LOAD "GHdf5::load(GFilename&)"
40#define G_XML_HDF5_ENTRY "GHdf5::xml_hdf5_entry(std::string&)"
41#define G_READ_SUPERBLOCK "GHdf5::read_superblock(FILE*)"
42#define G_READ_SYMBOL_TABLE_NODE "GHdf5::read_symbol_table_node(FILE*, "\
43 "uint64_t&, uint64_t&, std::string&, GXmlElement*, int&)"
44#define G_READ_SYMBOL_TABLE_ENTRY "GHdf5::read_symbol_table_entry(FILE*, "\
45 "uint64_t&, GXmlElement*, int&)"
46#define G_READ_GROUP "GHdf5::read_group(FILE*, uint64_t&, uint64_t&, "\
48#define G_READ_BTREE_CHUNKED "GHdf5::read_btree(FILE*, "\
49 "uint64_t&, GXmlElement*, int& indent)"
50#define G_READ_OBJECT_HEADER "GHdf5::read_object_header(FILE*, "\
51 "uint64_t&, GXmlElement*, int&)"
52#define G_READ_OBJECT_HEADER_V1 "GHdf5::read_object_header_v1(FILE*, int&)"
53#define G_READ_OBJECT_HEADER_V2 "GHdf5::read_object_header_v2(FILE*, int&)"
54#define G_READ_OBJECT_HEADER_MESSAGE "GHdf5::read_object_header_message("\
56#define G_READ_MESSAGE_DATASPACE "GHdf5::read_message_dataspace(FILE*, "\
57 "GXmlElement*, std::string&)"
58#define G_READ_MESSAGE_DATATYPE "GHdf5::read_message_datatype(FILE*, "\
59 "GXmlElement*, std::string&)"
60#define G_READ_MESSAGE_LAYOUT "GHdf5::read_message_layout(FILE*, "\
61 "GXmlElement*, std::string&)"
62#define G_READ_MESSAGE_FILTER "GHdf5::read_message_filter(FILE*, "\
63 "GXmlElement*, std::string&)"
64#define G_READ_MESSAGE_ATTRIBUTE "GHdf5::read_message_attribute(FILE*, "\
65 "GXmlElement*, std::string&)"
66#define G_GLOBAL_HEAP_STRING "GHdf5::global_heap_string(FILE*, uint64_t&, "\
68#define G_FREAD_DATA1 "GHdf5::fread_data(FILE*, int&)"
69#define G_FREAD_DATA2 "gammalib::hdf5::fread_data(FILE*, GXmlElement*, "\
70 "GXmlElement*, GXmlElement*, GXmlElement*)"
71#define G_FREAD_DATA_CHUNK "gammalib::hdf5::fread_data_chunk(FILE*, "\
72 "GXmlElement*, GXmlElement*, GXmlElement*, GXmlElement*, GXmlElement*)"
73#define G_FREAD_INT "gammalib::hdf5::fread_int(FILE*, int&)"
74#define G_FREAD_UINT32 "gammalib::hdf5::fread_uint32(FILE*, int&)"
75#define G_FREAD_UINT64 "gammalib::hdf5::fread_uint64(FILE*, int&)"
76#define G_FREAD_STRING "gammalib::hdf5::fread_string(FILE*, int&)"
77#define G_FREAD_DATA_AS_STRING "gammalib::hdf5::fread_data_as_string(FILE*, "\
79#define G_FREAD_ZERO "gammalib::hdf5::fread_zero(FILE*, int&)"
80#define G_DATA_TO_INT "gammalib::hdf5::data_to_int(char*, GXmlElement*)"
81#define G_DATA_TO_DOUBLE "gammalib::hdf5::data_to_double(char*, "\
83#define G_DATA_TO_STRING "gammalib::hdf5::data_to_string(char*, "\
85#define G_DATA_FILTER "gammalib::hdf5::data_filter(std::string&, "\
87#define G_DATA_FILTER_BITSHUFFLE \
88 "gammalib::hdf5::data_filter_bitshuffle(std::string&, GXmlElement*)"
89#define G_XML_MSG_TYPE "gammalib::hdf5::xml_msg_type(GXmlElement*, "\
90 "std::string& type, int&)"
91#define G_XML_MSG_ATTRIBUTE \
92 "gammalib::hdf5::xml_msg_attribute(GXmlElement*, std::string&)"
93#define G_DECOMPRESS_LZ4 "decompress_lz4(char*, char*, size_t&, size_t&)"
94#define G_READ_VARIABLE_LENGTH "read_variable_length(uint8_t**, uint8_t*, "\
96#define G_MEMCPY_USING_OFFSET "memcpy_using_offset(uint8_t*, uint8_t*, "\
113 const size_t& elements,
114 const size_t& element_size,
120 const size_t& elements,
121 const size_t& element_size);
124 const size_t& srcSize,
125 const size_t& outputSize);
127 const uint8_t* ilimit,
128 const bool& initial_check);
133 const size_t& offset);
287 return new GHdf5(*
this);
313 FILE* fptr = std::fopen(fname.c_str(),
"rb");
315 std::string msg =
"Unable to open file \""+fname+
"\" for read access. "
316 "Please specify a readable file.";
344 std::fseek(fptr, 0, SEEK_SET);
375 std::string msg =
"No HDF5 metadata were loaded. Please first "
376 "load metadata from a HDF5 file.";
390 if (element == NULL) {
391 std::string msg =
"No entry with attribute "+name+
"=\""+name+
392 "\" found in HDF5 metadata.";
416 result.append(
"=== GHdf5 ===");
519 const char hdf5_signature[] = {
static_cast<char>(0x89), 0x48, 0x44, 0x46, 0x0d, 0x0a, 0x1a, 0x0a};
525 if (std::strncmp(signature.c_str(), &hdf5_signature[0], 8) != 0) {
526 std::string msg =
"File does not contain a valid HDF5 signature. "
527 "Please specify a valid HDF5 file.";
536 std::string msg =
"Superblock version "+
gammalib::str(version)+
" is "
537 "not comprised between 0 and 3. Please specify a "
558 "than 1 Byte. Please specify a valid HDF5 file.";
563 "than 8 Bytes. Please specify a valid HDF5 file.";
568 "than 1 Byte. Please specify a valid HDF5 file.";
573 "than 8 Bytes. Please specify a valid HDF5 file.";
579 int group_leaf_node =
fread_int(fptr, 2);
580 int group_internal_node =
fread_int(fptr, 2);
582 int indexed_storage = 0;
597 #if defined(G_HDF5_DEBUG)
598 std::string msg =
"Superblock(version="+
gammalib::str(version)+
606 uint64_t pos = std::ftell(fptr);
644 "than 1 Byte. Please specify a valid HDF5 file.";
649 "than 8 Bytes. Please specify a valid HDF5 file.";
654 "than 1 Byte. Please specify a valid HDF5 file.";
659 "than 8 Bytes. Please specify a valid HDF5 file.";
721 const uint64_t& address,
722 const uint64_t& offset,
723 const std::string& heap,
728 const char table_signature[] = {
'S',
'N',
'O',
'D'};
731 std::fseek(fptr, address, SEEK_SET);
737 if (std::strncmp(signature.c_str(), &table_signature[0], 4) != 0) {
738 std::string msg =
"No \"SNOD\" signature found at address "+
740 "Please specify a valid HDF5 file.";
749 std::string msg =
"Symbol table node version "+
gammalib::str(version)+
750 " is not 1. Please specify a valid HDF5 file.";
759 #if defined(G_HDF5_DEBUG)
760 std::string msg =
"Symbol_table_node(address=" +
hexaddress(address) +
767 uint64_t pos = std::ftell(fptr);
770 for (
int i = 0; i < symbols; ++i) {
810 const uint64_t& address,
811 const uint64_t& offset,
812 const std::string& heap,
817 uint64_t address_btree = 0;
818 uint64_t address_heap = 0;
819 uint32_t offset_link_value = 0;
822 std::fseek(fptr, address, SEEK_SET);
831 std::string link_name =
extract(heap, offset+link_name_offset);
837 switch (cache_type) {
859 std::string msg =
"Invalid cache type "+
gammalib::str(cache_type)+
860 " encountered in symbol table entry located at "
861 "address "+
hexaddress(address)+
" in HDF5 file. "
862 "Please specify a valid HDF5 file.";
868 #if defined(G_HDF5_DEBUG)
869 std::string msg =
"Symbol_table_entry(address="+
hexaddress(address)+
872 ", header_address="+
hexaddress(object_header_address);
873 if (cache_type == 1) {
874 msg +=
", btree_address="+
hexaddress(address_btree)+
877 else if (cache_type == 2) {
878 msg +=
"offset_link_value="+
hexaddress(offset_link_value);
891 if (cache_type == 1) {
897 read_group(fptr, address_btree, address_heap, group, indent+1);
924 const uint64_t& address_btree,
925 const uint64_t& address_heap,
930 const char tree_signature[] = {
'T',
'R',
'E',
'E'};
931 const char heap_signature[] = {
'H',
'E',
'A',
'P'};
934 #if defined(G_HDF5_DEBUG)
935 std::string msg =
"Group(btree_address="+
hexaddress(address_btree)+
936 ", heap_address="+
hexaddress(address_heap)+
")";
941 std::fseek(fptr, address_heap, SEEK_SET);
947 if (std::strncmp(signature.c_str(), &heap_signature[0], 4) != 0) {
948 std::string msg =
"No \"HEAP\" signature found at address "+
950 "Please specify a valid HDF5 file.";
959 std::string msg =
"Heap version "+
gammalib::str(version)+
" is not 0."
960 " Please specify a valid HDF5 file.";
971 std::fseek(fptr, heap_address, SEEK_SET);
974 std::string heap =
fread_data(fptr, heap_size);
977 #if defined(G_HDF5_DEBUG)
978 msg =
"Heap(address="+
hexaddress(address_heap)+
985 std::fseek(fptr, address_btree, SEEK_SET);
991 if (std::strncmp(signature.c_str(), &tree_signature[0], 4) != 0) {
992 std::string msg =
"No \"TREE\" signature found at address "+
994 "Please specify a valid HDF5 file.";
1002 if (node_type < 0 || node_type > 1) {
1003 std::string msg =
"B-tree node type "+
gammalib::str(node_type)+
" is not 0 "
1004 "or 1. Please specify a valid HDF5 file.";
1015 #if defined(G_HDF5_DEBUG)
1016 msg =
"B-tree(address="+
hexaddress(address_btree)+
1018 if (node_type == 0) {
1019 msg +=
"\"group nodes\"";
1022 msg +=
"\"raw data chunk\"";
1029 for (
int i = 0; i < entries; ++i) {
1032 if (node_type == 0) {
1074 const uint64_t& address,
1075 const int& dimensions,
1079 const char tree_signature[] = {
'T',
'R',
'E',
'E'};
1082 std::fseek(fptr, address, SEEK_SET);
1088 if (std::strncmp(signature.c_str(), &tree_signature[0], 4) != 0) {
1089 std::string msg =
"No \"TREE\" signature found at address "+
1091 "Please specify a valid HDF5 file.";
1099 if (node_type != 1) {
1100 std::string msg =
"B-tree node type "+
gammalib::str(node_type)+
1101 " for chunked data is not 1."
1102 "Please specify a valid HDF5 file.";
1119 for (
int i = 0; i < entries; ++i) {
1133 for (
int k = 0; k < dimensions; ++k) {
1139 if (k < dimensions-1) {
1156 if (node_level != 0) {
1159 uint64_t address = std::ftell(fptr);
1168 std::fseek(fptr, address, SEEK_SET);
1208 const uint64_t& address,
1213 std::fseek(fptr, address, SEEK_SET);
1227 std::string msg =
"Object header version "+
gammalib::str(version)+
" is "
1228 "not comprised between 1 and 2. Please specify a "
1261 uint64_t address = std::ftell(fptr);
1264 #if defined(G_HDF5_DEBUG)
1265 std::string msg =
"Object_header(address="+
hexaddress(address)+
1274 for (
int i = 0; i < messages; ++i) {
1277 std::fseek(fptr, address, SEEK_SET);
1286 if (msg_type < 0 || msg_type > 23) {
1287 std::string msg =
"Invalid message type "+
hexaddress(msg_type)+
1288 " encountered at address "+
hexaddress(address)+
1289 " in HDF5 file. Please specify a valid HDF5 file.";
1295 if (msg_size % 8 != 0) {
1296 #if defined(G_HDF5_DEBUG)
1297 std::string msg =
"*** invalid message size "+
gammalib::str(msg_size)+
1305 address += msg_size + 8;
1310 address += msg_size + 8;
1313 if (msg_type == 16) {
1320 #if defined(G_HDF5_DEBUG)
1321 std::string msg =
"- message(address=" +
hexaddress(address) +
1361 std::string msg =
"Decoding of header version 2 not yet implemented.";
1386 #if defined(G_HDF5_DEBUG)
1387 std::string msg =
"- message(address=" +
hexaddress(std::ftell(fptr)) +
", ";
1398 #if defined(G_HDF5_DEBUG)
1410 #if defined(G_HDF5_DEBUG)
1415 message->
attribute(
"type",
"Dataspace");
1425 #if defined(G_HDF5_DEBUG)
1426 msg +=
"Link Info - NOT DECODED!";
1437 #if defined(G_HDF5_DEBUG)
1452 #if defined(G_HDF5_DEBUG)
1453 msg +=
"Fill Value (old) - NOT FULLY DECODED!";
1457 message->
attribute(
"type",
"FillValueOld");
1469 #if defined(G_HDF5_DEBUG)
1478 #if defined(G_HDF5_DEBUG)
1479 msg +=
"Fill Value - NOT DECODED!";
1483 message->
attribute(
"type",
"FillValue");
1490 #if defined(G_HDF5_DEBUG)
1491 msg +=
"Link - NOT DECODED!";
1502 #if defined(G_HDF5_DEBUG)
1503 msg +=
"External Data Files - NOT DECODED!";
1507 message->
attribute(
"type",
"ExternalDataFile");
1514 #if defined(G_HDF5_DEBUG)
1515 msg +=
"Data Storage - Layout";
1519 message->
attribute(
"type",
"DataStorageLayout");
1529 #if defined(G_HDF5_DEBUG)
1530 msg +=
"Bogus - NOT DECODED!";
1541 #if defined(G_HDF5_DEBUG)
1542 msg +=
"Group Info - NOT DECODED!";
1546 message->
attribute(
"type",
"GroupInfo");
1553 #if defined(G_HDF5_DEBUG)
1554 msg +=
"Data Storage - Filter Pipeline";
1558 message->
attribute(
"type",
"DataStorageFilterPipeline");
1568 #if defined(G_HDF5_DEBUG)
1573 message->
attribute(
"type",
"Attribute");
1583 #if defined(G_HDF5_DEBUG)
1584 msg +=
"Object Comment - NOT DECODED!";
1588 message->
attribute(
"type",
"ObjectComment");
1595 #if defined(G_HDF5_DEBUG)
1596 msg +=
"Object Modification Time (Old) - NOT DECODED!";
1600 message->
attribute(
"type",
"ObjectModificationTimeOld");
1607 #if defined(G_HDF5_DEBUG)
1608 msg +=
"Shared Message Table - NOT DECODED!";
1612 message->
attribute(
"type",
"SharedMessageTable");
1619 #if defined(G_HDF5_DEBUG)
1620 msg +=
"Continuation";
1624 message->
attribute(
"type",
"Continuation");
1631 #if defined(G_HDF5_DEBUG)
1632 msg +=
"Symbol Table Message";
1636 message->
attribute(
"type",
"SymbolTableMessage");
1647 #if defined(G_HDF5_DEBUG)
1648 msg +=
", address_tree=" +
hexaddress(address_tree) +
1649 ", address_heap=" +
hexaddress(address_heap);
1657 #if defined(G_HDF5_DEBUG)
1658 msg +=
"Object Modification Time - NOT DECODED!";
1662 message->
attribute(
"type",
"ObjectModificationTime");
1669 #if defined(G_HDF5_DEBUG)
1670 msg +=
"B-tree K Values - NOT DECODED!";
1674 message->
attribute(
"type",
"BtreeKValue");
1681 #if defined(G_HDF5_DEBUG)
1682 msg +=
"Driver Info - NOT DECODED!";
1686 message->
attribute(
"type",
"DriverInfo");
1693 #if defined(G_HDF5_DEBUG)
1694 msg +=
"Attribute Info - NOT DECODED!";
1698 message->
attribute(
"type",
"AttributeInfo");
1705 #if defined(G_HDF5_DEBUG)
1706 msg +=
"Object Reference Count - NOT DECODED!";
1710 message->
attribute(
"type",
"ObjectReferenceCount");
1717 #if defined(G_HDF5_DEBUG)
1718 msg +=
"File Space Info - NOT DECODED!";
1722 message->
attribute(
"type",
"FileSpaceInfo");
1733 #if defined(G_HDF5_DEBUG)
1765 uint64_t elements = 0;
1774 if (version < 1 || version > 2) {
1777 #if defined(G_HDF5_DEBUG)
1778 if (msg.length() > 0) {
1803 #if defined(G_HDF5_DEBUG)
1804 if (msg.length() > 0) {
1816 if (dimensions == 0) {
1825 for (
int i = 0; i < dimensions; ++i) {
1832 elements = int(size);
1835 elements *= int(size);
1842 #if defined(G_HDF5_DEBUG)
1843 if (msg.length() > 0) {
1853 if ((flags & 1) == 1) {
1856 for (
int i = 0; i < dimensions; ++i) {
1865 #if defined(G_HDF5_DEBUG)
1866 if (msg.length() > 0) {
1876 if ((version == 1) && ((flags & 2) == 2)) {
1879 for (
int i = 0; i < dimensions; ++i) {
1888 #if defined(G_HDF5_DEBUG)
1889 if (msg.length() > 0) {
1902 #if defined(G_HDF5_DEBUG)
1903 if (msg.length() > 0) {
1950 int version = class_version / 16;
1951 int cls = class_version & 15;
1954 if (version < 1 || version > 5) {
1955 std::string msg =
"Datatype version "+
gammalib::str(version)+
1956 " is not between 1 and 5."
1957 " Please specify a valid HDF5 file.";
1962 if (cls < 0 || cls > 11) {
1964 " is not between 0 and 11."
1965 " Please specify a valid HDF5 file.";
1975 message->
attribute(
"classname", clsname);
1979 #if defined(G_HDF5_DEBUG)
1980 if (msg.length() > 0) {
1983 ", classname=\"" + clsname +
"\"" +
1994 int order = bits1 & 1;
1995 int lopad = (bits1 & 2) / 2;
1996 int hipad = (bits1 & 4) / 4;
1997 int sign = (bits1 & 8) / 8;
2006 message->
attribute(
"ordername",
"little-endian");
2009 message->
attribute(
"ordername",
"big-endian");
2057 int number = bits1 + bits2 * 256;
2063 #if defined(G_HDF5_DEBUG)
2064 if (msg.length() > 0) {
2070 if ((version == 1) || (version == 2)) {
2078 std::vector<std::string> names;
2079 std::vector<std::string> values;
2082 for (
int i = 0; i < number; ++i) {
2087 bool looping =
true;
2094 for (
int k = 0; k < 8; ++k) {
2095 if (segment[k] ==
'\0') {
2097 name += segment.substr(0,k);
2113 names.push_back(name);
2118 for (
int i = 0; i < number; ++i) {
2124 values.push_back(value);
2129 for (
int i = 0; i < number; ++i) {
2135 enumeration->
attribute(
"name", names[i]);
2136 enumeration->
attribute(
"value", values[i]);
2147 int type = bits1 & 15;
2148 int padding = bits1 / 16;
2149 int charset = bits2 & 15;
2162 #if defined(G_HDF5_DEBUG)
2163 if (msg.length() > 0) {
2227 #if defined(G_HDF5_DEBUG)
2237 message->
attribute(
"classname",
"compact");
2240 #if defined(G_HDF5_DEBUG)
2249 message->
attribute(
"classname",
"contiguous");
2252 #if defined(G_HDF5_DEBUG)
2253 msg +=
", contiguous";
2265 #if defined(G_HDF5_DEBUG)
2275 message->
attribute(
"classname",
"chunked");
2278 #if defined(G_HDF5_DEBUG)
2291 #if defined(G_HDF5_DEBUG)
2300 for (
int i = 0; i < dimensions; ++i) {
2317 #if defined(G_HDF5_DEBUG)
2328 #if defined(G_HDF5_DEBUG)
2343 std::string msg =
"Data storage layout class "+
gammalib::str(cls)+
2344 " is not between 0 and 2."
2345 " Please specify a valid HDF5 file.";
2355 std::string msg =
"Data storage layout version "+
gammalib::str(version)+
2356 " is not between 1 and 3."
2357 " Please specify a valid HDF5 file.";
2399 #if defined(G_HDF5_DEBUG)
2404 for (
int i = 0; i < filters; ++i) {
2413 int number_of_values =
fread_int(fptr, 2);
2417 if (name_length > 0) {
2427 for (
int k = 0; k < number_of_values; ++k) {
2454 std::string msg =
"Data storage filter pipeline version " +
2456 " Please specify a valid HDF5 file.";
2516 #if defined(G_HDF5_DEBUG)
2517 msg +=
", name=" + name;
2521 uint64_t address = std::ftell(fptr);
2524 std::fseek(fptr, address+datatype_size, SEEK_SET);
2527 address = std::ftell(fptr);
2530 std::fseek(fptr, address+dataspace_size, SEEK_SET);
2558 #if defined(G_HDF5_DEBUG)
2559 msg +=
", sequence_length="+
gammalib::str(sequence_length) +
2560 ", collection_address="+
hexaddress(collection_address) +
2577 #if defined(G_HDF5_DEBUG)
2578 msg +=
", value=\""+value+
"\"";
2590 int data_size = size * elements;
2593 if (data_size > 0) {
2596 if (elements == 1) {
2610 for (
int i = 0; i < elements; ++i) {
2648 std::string msg =
"Attribute version "+
gammalib::str(version)+
2649 " is not between 1 and 3."
2650 " Please specify a valid HDF5 file.";
2685 const uint64_t& address,
2687 const uint32_t& length)
2690 const char global_heap_signature[] = {
'G',
'C',
'O',
'L'};
2705 int elements = root->
elements(
"global_heap");
2706 for (
int i = 0; i < elements; ++i) {
2707 if (root->
element(
"global_heap", i)->
attribute(
"address") == str_address) {
2708 global_heap = root->
element(
"global_heap", i);
2714 if (global_heap == NULL) {
2717 global_heap = root->
append(
"global_heap");
2720 global_heap->
attribute(
"address", str_address);
2723 uint64_t current_pos = std::ftell(fptr);
2726 std::fseek(fptr, address, SEEK_SET);
2732 if (std::strncmp(signature.c_str(), &global_heap_signature[0], 4) != 0) {
2733 std::string msg =
"No \"GCOL\" signature found at address "+
2735 "Please specify a valid HDF5 file.";
2744 std::string msg =
"Global heap version "+
gammalib::str(version)+
2745 " is not 1. Please specify a valid HDF5 file.";
2758 int object_header_size = 8 +
m_length;
2766 int remaining = size -
read;
2770 if (remaining < object_header_size) {
2779 read += object_header_size;
2789 read += object_size;
2792 int padded =
pad2eight(object_size) - object_size;
2804 object->attribute(
"object_size",
gammalib::str(object_size));
2805 object->attribute(
"value", value);
2810 std::fseek(fptr, current_pos, SEEK_SET);
2815 int objects = global_heap->
elements(
"object");
2821 for (
int i = 0; i < objects; ++i) {
2831 if (object_length != length) {
2832 std::string msg =
"Length "+
object->attribute(
"object_size")+
2834 " in global heap at address "+
2836 "not correspond to the expected length "+
2838 "Please specify a valid HDF5 file.";
2843 string =
object->attribute(
"value");
2856 std::string msg =
"No object with index "+
gammalib::str(
id)+
2857 " found in global heap at address "+
2859 "Please specify a valid HDF5 file.";
2877 for (
int i = 0; i < indent; ++i) {
2882 std::cout << msg << std::endl;
2919 std::string result =
"";
2922 int n =
string.length();
2925 for (
int i = pos; i < n; ++i) {
2926 if (
string[i] !=
'\0') {
2927 result +=
string[i];
2951 int result = nbytes;
2954 if (result % 8 != 0) {
2955 result = ((result / 8) + 1) * 8;
2988 std::string msg =
"Non positive number "+
gammalib::str(nbytes)+
2989 " of Bytes specified. Please specify a number "
2998 string.resize(nbytes);
3001 const std::size_t n = std::fread(&
string[0], 1, nbytes, fptr);
3005 std::string msg =
"Attempt to read beyond the end of file. Read "
3007 " Bytes from file.";
3055 std::string msg =
"\"Dataspace\" message is missing \"elements\""
3060 std::string msg =
"\"Datatype\" message is missing \"size\""
3065 std::string msg =
"\"DataStorageLayout\" message is missing \"address\""
3070 std::string msg =
"\"DataStorageLayout\" message is missing \"class\""
3076 if (datalayout->
attribute(
"class") ==
"2") {
3101 int nbytes = elements * size;
3104 string.resize(nbytes);
3107 uint64_t current_address = std::ftell(fptr);
3110 std::fseek(fptr, address, SEEK_SET);
3113 const std::size_t n = std::fread(&
string[0], 1, nbytes, fptr);
3117 std::string msg =
"Attempt to read beyond the end of file. Read "
3119 " Bytes from file.";
3124 std::fseek(fptr, current_address, SEEK_SET);
3131 if (datafilter != NULL) {
3184 std::string msg =
"Chunk key message is missing \"address\""
3189 std::string msg =
"Chunk key message is missing \"size\""
3194 std::string msg =
"\"DataStorageLayout\" message is missing \"class\""
3200 if (datalayout->
attribute(
"class") !=
"2") {
3201 std::string msg =
"\"DataStorageLayout\" is " +
3202 datalayout->
attribute(
"class") +
" which is not "
3203 "chunked. Please specify a chunked layout.";
3212 string.resize(size);
3215 uint64_t current_address = std::ftell(fptr);
3218 std::fseek(fptr, address, SEEK_SET);
3221 const std::size_t n = std::fread(&
string[0], 1, size, fptr);
3225 std::string msg =
"Attempt to read beyond the end of file. Read "
3227 " Bytes from file.";
3232 std::fseek(fptr, current_address, SEEK_SET);
3235 if (datafilter != NULL) {
3262 if (nbytes < 1 || nbytes > 4) {
3267 const std::size_t n = std::fread(&buffer[0], 1, nbytes, fptr);
3271 std::string msg =
"Attempt to read beyond the end of file; read "
3273 " Bytes from file.";
3281 for (
int i = 0, shift = 0; i < nbytes; ++i, shift += 8) {
3282 integer += (
unsigned char)buffer[i] << shift;
3308 if (nbytes < 1 || nbytes > 4) {
3313 const std::size_t n = std::fread(&buffer[0], 1, nbytes, fptr);
3317 std::string msg =
"Attempt to read beyond the end of file; read "
3319 " Bytes from file.";
3324 uint32_t integer = 0;
3327 for (
int i = 0, shift = 0; i < nbytes; ++i, shift += 8) {
3328 integer += (
unsigned char)buffer[i] << shift;
3354 if (nbytes < 1 || nbytes > 8) {
3359 const std::size_t n = std::fread(&buffer[0], 1, nbytes, fptr);
3363 std::string msg =
"Attempt to read beyond the end of file; read "
3365 " Bytes from file.";
3370 uint64_t integer = 0;
3373 for (
int i = 0, shift = 0; i < nbytes; ++i, shift += 8) {
3374 integer += (
unsigned char)buffer[i] << shift;
3403 std::string msg =
"Non positive number "+
gammalib::str(nbytes)+
3404 " of Bytes specified. Please specify a number "
3413 string.resize(nbytes);
3416 const std::size_t n = std::fread(&
string[0], 1, nbytes, fptr);
3420 std::string msg =
"Attempt to read beyond the end of file; read "
3422 " Bytes from file.";
3427 for (
int i = 0; i <
string.length(); ++i) {
3428 if (
string[i] ==
'\0') {
3430 string =
string.substr(0,i);
3466 string.resize(size);
3469 const std::size_t n = std::fread(&
string[0], 1, size, fptr);
3473 std::string msg =
"Attempt to read beyond the end of file; read "
3475 " Bytes from file.";
3502 std::string msg =
"Non positive number "+
gammalib::str(nbytes)+
3503 " of Bytes specified. Please specify a number "
3509 char* buffer =
new char(nbytes);
3512 uint64_t pos = std::ftell(fptr);
3515 const std::size_t n = std::fread(&buffer[0], 1, nbytes, fptr);
3519 std::string msg =
"Attempt to read beyond the end of file; read "
3521 " Bytes from file.";
3526 for (
int i = 0; i < nbytes; ++i) {
3527 if ((
unsigned char)buffer[i] != 0) {
3528 std::string msg =
"Non-zero Byte "+
gammalib::str((
int)buffer[i])+
" encountered "
3578 for (
int i = 0, shift = 0; i < size; ++i, shift += 8) {
3579 value += (int)((
unsigned char)data[i] << shift);
3585 for (
int i = 0, shift = 0; i < size; ++i, shift += 8) {
3586 value += (int)((
unsigned char)data[size-i-1] << shift);
3595 value = (int)(*((
const float*)data));
3597 else if (size == 8) {
3598 value = (int)(*((
const double*)data));
3601 std::string msg =
"Conversion of floating point value of "
3603 "value is not supported.";
3611 std::string msg =
"Conversion of \""+
classname(cls)+
"\" to integer "
3612 "value is not yet implemented.";
3659 for (
int i = 0, shift = 0; i < size; ++i, shift += 8) {
3660 value += (double)((
unsigned char)data[i] << shift);
3666 for (
int i = 0, shift = 0; i < size; ++i, shift += 8) {
3667 value += (double)((
unsigned char)data[size-i-1] << shift);
3676 value = (double)(*((
const float*)data));
3678 else if (size == 8) {
3679 value = *((
const double*)data);
3682 std::string msg =
"Conversion of floating point value of "
3684 "precision value is not supported.";
3692 std::string msg =
"Conversion of \""+
classname(cls)+
"\" to double "
3693 "precision value is not yet implemented.";
3743 for (
int i = 0, shift = 0; i < size; ++i, shift += 8) {
3744 value += (
unsigned char)data[i] << shift;
3759 for (
int i = 0, shift = 0; i < size; ++i, shift += 8) {
3760 value += (
unsigned char)data[i] << shift;
3793 std::string msg =
"Conversion of \""+
classname(cls)+
"\" to string "
3794 "not yet implemented.";
3830 std::string msg =
"\"DataStorageFilterPipeline\" message is missing "
3831 "\"filters\" attribute";
3839 if (datafilter->
elements(
"filter") != filters) {
3841 "filters found in \"DataStorageFilterPipeline\" "
3843 ". Please specify a valid HDF5 file.";
3848 for (
int i = 0; i < filters; ++i) {
3856 "missing \"id\" attribute";
3871 std::string msg =
"Requested data filter with id="+
3910 #if defined(G_BITSHUFFLE_DEBUG)
3911 std::cout <<
"data_filter_bitshuffle" << std::endl;
3912 std::cout <<
"======================" << std::endl;
3916 int client_values = filter->
elements(
"data");
3919 if (client_values < 3) {
3921 " client data values found in filter, but at least "
3922 "3 values are required for the bitshuffle filter. "
3923 "Please specify a valid HDF5 file.";
3931 size_t block_size = (client_values > 3) ? filter->
element(
"data", 3)->
integer() : 0;
3934 if (block_size == 0) {
3935 block_size = 8192 / element_size;
3936 block_size = (block_size / 8) * 8;
3937 block_size = (block_size > 128) ? block_size : 128;
3941 int compression = (client_values > 4) ? filter->
element(
"data", 4)->
integer() : 0;
3944 if (compression != 2) {
3945 std::string msg =
"Unsupported bitshuffle compression algorithm "+
3947 "Only algorithm=2 (LZ4 compression) is so far supported.";
3952 char* input = (
char*)data.c_str();
3955 switch(compression) {
3960 size_t nbytes_uncompressed = data.length();
3961 size_t buf_size_out = data.length();
3962 size_t size = nbytes_uncompressed / element_size;
3965 string.resize(buf_size_out);
3968 char* output = (
char*)
string.c_str();
3983 size_t elements = nbytes_uncompressed / element_size;
3986 string.resize(nbytes_uncompressed);
3989 char* output = (
char*)
string.c_str();
3992 #if defined(G_BITSHUFFLE_DEBUG)
3993 std::cout <<
"LZ4 compression:";
3994 std::cout <<
" nbytes_uncompressed=" << nbytes_uncompressed;
3995 std::cout <<
", block_size=" << block_size;
3996 std::cout <<
", elements=" << elements;
3997 std::cout <<
", element_size=" << element_size << std::endl;
4027 const std::string& type,
4034 int messages = header->
elements(
"message");
4040 for (
int i = 0; i < messages; ++i) {
4047 if (message->
attribute(
"type") == type) {
4048 if (occurences ==
number) {
4061 if (element == NULL) {
4063 std::string msg =
"No \""+type+
"\" message found in HDF5 object header.";
4068 type+
"\" message not found in HDF5 object header.";
4090 const std::string& type,
4097 int messages = header->
elements(
"message");
4103 for (
int i = 0; i < messages; ++i) {
4110 if (message->
attribute(
"type") == type) {
4111 if (occurences ==
number) {
4124 return (element != NULL);
4139 const std::string& name)
4145 int messages = header->
elements(
"message");
4148 bool check_name = (name.length() > 0);
4151 for (
int i = 0; i < messages; ++i) {
4158 if (message->
attribute(
"type") ==
"Attribute") {
4161 if (message->
attribute(
"name") == name) {
4194 const std::string& name,
4201 int messages = header->
elements(
"message");
4207 for (
int i = 0; i < messages; ++i) {
4214 if (message->
attribute(
"type") ==
"Attribute") {
4216 if (message->
attribute(
"name") == name) {
4217 if (occurences ==
number) {
4232 if (element == NULL) {
4234 std::string msg =
"No \"Attribute\" message with attribute name=\""+
4235 name+
"\" found in HDF5 metadata.";
4240 "\"Attribute\" message with attribute name=\""+
4241 name+
"\" not found in HDF5 metadata.";
4262 const std::string& name,
4269 int messages = header->
elements(
"message");
4275 for (
int i = 0; i < messages; ++i) {
4282 if (message->
attribute(
"type") ==
"Attribute") {
4284 if (message->
attribute(
"name") == name) {
4285 if (occurences ==
number) {
4300 return (element != NULL);
4320 const std::string& name,
4321 const std::string& key)
4327 int messages = header->
elements(
"message");
4330 for (
int i = 0; i < messages; ++i) {
4338 if (message->
attribute(
"type") ==
"Attribute") {
4340 if (message->
attribute(
"name") == name) {
4440 const size_t& elements,
4441 const size_t& element_size,
4445 uint64_t cum_count = 0;
4448 int nblocks = elements / block_size;
4451 #if defined(G_BITSHUFFLE_DEBUG)
4452 std::cout <<
"bitshuffle_decompress" << std::endl;
4453 std::cout <<
"=====================" << std::endl;
4454 std::cout <<
"nblocks=" << nblocks << std::endl;
4458 for (
int i = 0; i < nblocks+1; ++i) {
4462 size_t this_block_size = block_size;
4464 this_block_size = elements % block_size;
4465 this_block_size = this_block_size - this_block_size % 8;
4469 if (this_block_size != 0) {
4475 int buffer_size = this_block_size * element_size;
4478 char* buffer =
new char[buffer_size];
4487 #if defined(G_BITSHUFFLE_DEBUG)
4488 std::cout <<
"block=" << i;
4489 std::cout <<
", nbytes_from_header=" << nbytes_from_header;
4490 std::cout <<
", block_size=" << this_block_size;
4491 std::cout <<
", buffer_size=" << buffer_size;
4492 std::cout <<
", nbytes=" << nbytes;
4493 std::cout << std::endl;
4497 if (nbytes != buffer_size) {
4498 std::string msg =
"Invalid number of "+
gammalib::str(nbytes)+
4499 " decompressed Bytes, expected "+
4508 input += nbytes_from_header + 4;
4509 output += this_block_size * element_size;
4512 cum_count += nbytes_from_header + 4;
4522 size_t leftover_bytes = elements % 8 * element_size;
4525 #if defined(G_BITSHUFFLE_DEBUG)
4526 std::cout <<
"leftover_bytes=" << leftover_bytes;
4527 std::cout << std::endl;
4532 for (
int i = 0; i < leftover_bytes; ++i) {
4533 *output++ = *input++;
4537 cum_count += leftover_bytes;
4540 #if defined(G_BITSHUFFLE_DEBUG)
4541 std::cout <<
"cum_count=" << cum_count;
4542 std::cout << std::endl;
4566 const uint64_t pow28 = 256;
4569 uint8_t* b = (uint8_t*)buffer;
4576 for (
int i = 7; i >= 0; i--) {
4601 const uint32_t pow28 = 256;
4604 uint8_t* b = (uint8_t*)buffer;
4611 for (
int i = 3; i >= 0; i--) {
4635 const size_t& elements,
4636 const size_t& element_size)
4639 int nbytes = elements * element_size;
4642 char* buffer =
new char[nbytes];
4645 int nbyte_row = elements / 8;
4649 for (
int i = 0; i < element_size; ++i) {
4651 for (
int j = 0; j < nbyte_row; ++j) {
4652 int joffset = j * 8 * element_size + i8;
4653 for (
int k = 0; k < 8; ++k) {
4654 buffer[joffset + k] = input[(i8 + k) * nbyte_row + j];
4662 for (
int i = 0; i < 8 * element_size; i += 8) {
4663 for (
int j = 0; j + 8 * element_size - 1 < nbytes; j += 8 * element_size) {
4664 uint64_t x = *((uint64_t*)&buffer[j + i]);
4665 uint64_t t = (x ^ (x >> 7)) & 0x00AA00AA00AA00AALL;
4666 x = x ^ t ^ (t << 7);
4667 t = (x ^ (x >> 14)) & 0x0000CCCC0000CCCCLL;
4668 x = x ^ t ^ (t << 14);
4669 t = (x ^ (x >> 28)) & 0x00000000F0F0F0F0LL;
4670 x = x ^ t ^ (t << 28);
4671 for (
int k = 0; k < 8; ++k) {
4672 *((uint8_t*)&output[j + i / 8 + k * element_size]) = x;
4681 for (
int i = 0; i < 8 * element_size; i += 8) {
4682 for (
int j = 0; j + 8 * element_size - 1 < nbytes; j += 8 * element_size) {
4683 uint64_t x = *((uint64_t*)&buffer[j + i]);
4684 uint64_t t = (x ^ (x >> 9)) & 0x0055005500550055LL;
4685 x = x ^ t ^ (t << 9);
4686 t = (x ^ (x >> 18)) & 0x0000333300003333LL;
4687 x = x ^ t ^ (t << 18);
4688 t = (x ^ (x >> 36)) & 0x000000000F0F0F0FLL;
4689 x = x ^ t ^ (t << 36);
4690 for (
int k = 0; k < 8; ++k) {
4691 *((uint8_t*)&output[j + i / 8 + (7-k) * element_size]) = x;
4722 const size_t& srcSize,
4723 const size_t& outputSize)
4726 const int minmatch = 4;
4727 const int wildcopylength = 8;
4728 const int lastliterals = 5;
4729 const int mflimit = 12;
4730 const int match_safeguard_distance = ((2*wildcopylength) - minmatch);
4731 const int fastloop_safe_distance = 64;
4732 const int ml_bits = 4;
4733 const int ml_mask = ((1U<<ml_bits)-1);
4734 const int run_bits = (8-ml_bits);
4735 const int run_mask = ((1U<<run_bits)-1);
4736 const unsigned inc32table[8] = {0, 1, 2, 1, 0, 4, 4, 4};
4737 const int dec64table[8] = {0, 0, 0, -1, -4, 1, 2, 3};
4740 const uint8_t* lowPrefix = (uint8_t*)dst;
4743 const uint8_t* ip = (
const uint8_t*)src;
4744 const uint8_t* iend = ip + srcSize;
4747 uint8_t* op = (uint8_t*)dst;
4748 uint8_t* oend = op + outputSize;
4752 const uint8_t* shortiend = iend - 14 - 2 ;
4753 const uint8_t* shortoend = oend - 14 - 18 ;
4756 const uint8_t* match;
4762 if ((oend - op) >= fastloop_safe_distance) {
4773 length = token >> ml_bits;
4776 if (length == run_mask) {
4782 if (((uintptr_t)(op)+length < (uintptr_t)(op)) ||
4783 ((uintptr_t)(ip)+length < (uintptr_t)(ip))) {
4784 std::string msg =
"Overflow detection.";
4791 if ((op+length > oend-32) || (ip+length > iend-32)) {
4792 goto safe_literal_copy;
4807 else if (ip <= iend-(16 + 1)) {
4810 std::memcpy(op, ip, 16);
4820 goto safe_literal_copy;
4826 match = op - offset;
4830 length = token & ml_mask;
4833 if (length == ml_mask) {
4840 if ((uintptr_t)(op)+length < (uintptr_t)(op)) {
4841 std::string msg =
"Overflow detection.";
4846 if (op + length >= oend - fastloop_safe_distance) {
4847 goto safe_match_copy;
4855 if (op + length >= oend - fastloop_safe_distance) {
4857 goto safe_match_copy;
4861 if ((match >= lowPrefix)) {
4866 std::memcpy(op, match, 8);
4867 std::memcpy(op+8, match+8, 8);
4868 std::memcpy(op+16, match+16, 2);
4877 if (match < lowPrefix) {
4878 std::string msg =
"Position outside buffers.";
4909 length = token >> ml_bits;
4919 if ((length != run_mask) && (ip < shortiend) & (op <= shortoend)) {
4922 std::memcpy(op, ip, 16);
4928 length = token & ml_mask;
4931 match = op - offset;
4935 if ((length != ml_mask) && (offset >= 8) && (match >= lowPrefix)) {
4936 std::memcpy(op + 0, match + 0, 8);
4937 std::memcpy(op + 8, match + 8, 8);
4938 std::memcpy(op +16, match +16, 2);
4939 op += length + minmatch;
4951 if (length == run_mask) {
4953 if (((uintptr_t)(op)+length < (uintptr_t)(op)) ||
4954 ((uintptr_t)(ip)+length < (uintptr_t)(ip))) {
4955 std::string msg =
"Overflow detection.";
4965 if ((cpy>oend-mflimit) || (ip+length>iend-(2+1+lastliterals))) {
4974 if ((ip+length != iend) || (cpy > oend)) {
4975 std::string msg =
"Overrun output buffer.";
4979 std::memmove(op, ip, length);
4987 if ((cpy == oend) || (ip >= (iend-2))) {
5000 match = op - offset;
5003 length = token & ml_mask;
5006 if (length == ml_mask) {
5012 if ((uintptr_t)(op)+length < (uintptr_t)(op)) {
5013 std::string msg =
"Overflow detection.";
5022 if (match < lowPrefix) {
5023 std::string msg =
"Offset outside buffers.";
5037 match += inc32table[offset];
5038 std::memcpy(op+4, match, 4);
5039 match -= dec64table[offset];
5042 std::memcpy(op, match, 8);
5048 if (cpy > oend-match_safeguard_distance) {
5051 uint8_t* oCopyLimit = oend - (wildcopylength-1);
5054 if (cpy > oend-lastliterals) {
5055 std::string msg =
"Last 5 Bytes were not uncompressed literals.";
5060 if (op < oCopyLimit) {
5062 match += oCopyLimit - op;
5072 std::memcpy(op, match, 8);
5084 return (
int)(((
char*)op)-dst);
5111 const uint8_t* ilimit,
5112 const bool& initial_check)
5119 if (initial_check && (*ip) >= ilimit) {
5120 std::string msg =
"Initial check revealed that read limit was reached.";
5138 if ((*ip) > ilimit) {
5139 std::string msg =
"Read limit was reached.";
5144 if ((
sizeof(length) < 8) && length > ((
size_t)(-1)/2)) {
5145 std::string msg =
"Accumulator overflow detected.";
5176 result = *(
const uint16_t*)(memPtr);
5181 const uint8_t* p = (
const uint8_t*)memPtr;
5182 result = (uint16_t)((uint16_t)p[0] | (p[1]<<8));
5206 const size_t& offset)
5210 if (dstEnd < dstPtr + 4) {
5211 std::string msg =
"Destination end pointer "+
5213 " is not at least 4 Bytes behind start pointer "+
5223 std::memset(v, *srcPtr, 8);
5226 std::memcpy(v, srcPtr, 2);
5227 std::memcpy(&v[2], srcPtr, 2);
5228 std::memcpy(&v[4], v, 4);
5231 std::memcpy(v, srcPtr, 4);
5232 std::memcpy(&v[4], srcPtr, 4);
5235 static const unsigned inc32table[8] = {0, 1, 2, 1, 0, 4, 4, 4};
5236 static const int dec64table[8] = {0, 0, 0, -1, -4, 1, 2, 3};
5239 *(uint32_t*)dstPtr = 0;
5240 dstPtr[0] = srcPtr[0];
5241 dstPtr[1] = srcPtr[1];
5242 dstPtr[2] = srcPtr[2];
5243 dstPtr[3] = srcPtr[3];
5244 srcPtr += inc32table[offset];
5245 std::memcpy(dstPtr+4, srcPtr, 4);
5246 srcPtr -= dec64table[offset];
5249 std::memcpy(dstPtr, srcPtr, 8);
5260 std::memcpy(dstPtr, v, 8);
5262 while (dstPtr < dstEnd) {
5263 std::memcpy(dstPtr, v, 8);
5292 std::memcpy(dstPtr, srcPtr, 8);
5295 }
while (dstPtr < dstEnd);
5320 std::memcpy(dstPtr, srcPtr, 16);
5323 std::memcpy(dstPtr, srcPtr, 16);
5326 }
while (dstPtr < dstEnd);
Exception handler interface definition.
#define G_READ_MESSAGE_ATTRIBUTE
#define G_READ_SUPERBLOCK
#define G_MEMCPY_USING_OFFSET
void bitshuffle_decompress(char *input, char *output, const size_t &elements, const size_t &element_size, size_t &block_size)
Decompress and bitshuffle data.
#define G_READ_MESSAGE_LAYOUT
uint16_t read_uint16(const void *memPtr)
Read unsigned 16 Bit integer stored as little endian.
#define G_READ_MESSAGE_DATATYPE
uint32_t bitshuffle_read_uint32(const char *buffer)
Read a 32 bit unsigned integer from a buffer big endian order.
#define G_DATA_FILTER_BITSHUFFLE
void memory_beyond32(const uint8_t *srcPtr, uint8_t *dstPtr, uint8_t *dstEnd)
Memory copy allowing to overwrite up to 32 Bytes beyond the end.
void memcpy_using_offset(const uint8_t *srcPtr, uint8_t *dstPtr, uint8_t *dstEnd, const size_t &offset)
Memory copy.
#define G_XML_MSG_ATTRIBUTE
void memcpy_beyond8(const uint8_t *srcPtr, uint8_t *dstPtr, uint8_t *dstEnd)
Memory copy allowing to overwrite up to 8 Bytes beyond the end.
#define G_READ_BTREE_CHUNKED
#define G_FREAD_DATA_CHUNK
size_t read_variable_length(const uint8_t **ip, const uint8_t *ilimit, const bool &initial_check)
Read the variable-length literal or match length.
#define G_READ_OBJECT_HEADER
#define G_READ_SYMBOL_TABLE_ENTRY
#define G_GLOBAL_HEAP_STRING
int decompress_lz4(const char *src, char *dst, const size_t &srcSize, const size_t &outputSize)
Decompress data using the LZ4 algorithm.
uint64_t bitshuffle_read_uint64(const char *buffer)
Read a 64 bit unsigned integer from a buffer big endian order.
#define G_READ_SYMBOL_TABLE_NODE
#define G_FREAD_DATA_AS_STRING
#define G_READ_OBJECT_HEADER_V2
#define G_READ_MESSAGE_FILTER
#define G_READ_VARIABLE_LENGTH
void bitshuffle_elements(const char *input, char *output, const size_t &elements, const size_t &element_size)
Untranspose bits within elements.
#define G_READ_OBJECT_HEADER_V1
HDF5 file handling class definition.
GNdarray sign(const GNdarray &array)
Computes sign of array elements.
int length(void) const
Return length of filename.
std::string url(void) const
Return Uniform Resource Locator (URL)
void clear(void)
Clear file name.
COSI instrument response function class.
GHdf5 * clone(void) const
Clone instance.
GHdf5 & operator=(const GHdf5 &file)
Assignment operator.
void read_group(FILE *fptr, const uint64_t &address_btree, const uint64_t &address_heap, GXmlElement *group, const int &indent)
Read and handle HDF5 group.
void read_object_header_v2(FILE *fptr, GXmlElement *header, const int &indent)
Read object header version 2.
void read_object_header_message(FILE *fptr, const int &type, GXmlElement *message, const int &indent)
Read one object header message.
std::string print(const GChatter &chatter=NORMAL) const
Print HDF5 file.
std::string global_heap_string(FILE *fptr, const uint64_t &address, const int &id, const uint32_t &length)
Get string from global heap.
void debug_msg(const std::string &msg, const int &indent)
Show debug message.
const GXmlElement * xml_hdf5_entry(const std::string &name) const
Return XML element to entry tag.
void read_message_attribute(FILE *fptr, GXmlElement *message, std::string &msg)
Read Attribute message.
void read_symbol_table_node(FILE *fptr, const uint64_t &address, const uint64_t &offset, const std::string &heap, GXmlElement *table, const int &indent)
Read HDF5 symbol table node.
GHdf5(void)
Void constructor.
void read_symbol_table_entry(FILE *fptr, const uint64_t &address, const uint64_t &offset, const std::string &heap, GXmlElement *entry, const int &indent)
Read and handle HDF5 symbol table entry.
void read_message_datatype(FILE *fptr, GXmlElement *message, std::string &msg)
Read datatype message.
std::string extract(const std::string &string, const int &pos)
Extract string from position until next null termination.
void read_message_layout(FILE *fptr, GXmlElement *message, std::string &msg)
Read Data Storage - Layout message.
int pad2eight(const int &nbytes)
Pad number of Bytes to 8 Bytes.
void load(const GFilename &filename)
Load data from HDF5 file into instance.
void read_message_filter(FILE *fptr, GXmlElement *message, std::string &msg)
Read Data Storage - Filter pipeline message.
void read_object_header_v1(FILE *fptr, GXmlElement *header, const int &indent)
Read object header version 1.
void copy_members(const GHdf5 &file)
Copy class members.
void clear(void)
Clear instance.
void read(FILE *fptr)
Read data from HDF5 file into instance.
void read_object_header(FILE *fptr, const uint64_t &address, GXmlElement *header, const int &indent)
Read object header.
void read_btree_chunked(FILE *fptr, const uint64_t &address, const int &dimensions, GXmlElement *btree)
Read HDF5 B-tree for chunked data.
virtual ~GHdf5(void)
Destructor.
void read_superblock(FILE *fptr)
Read HDF5 file superblock.
std::string hexaddress(const uint64_t &address)
Format address for debugging.
void free_members(void)
Delete class members.
void init_members(void)
Initialise class members.
void read_message_dataspace(FILE *fptr, GXmlElement *message, std::string &msg)
Read dataspace message.
const GXmlAttribute * attribute(const int &index) const
Return attribute.
int integer(void) const
Return integer value.
bool has_attribute(const std::string &name) const
Check if element has a given attribute.
virtual GXmlNode * append(const GXmlNode &node)
Append XML child node.
virtual GXmlElement * element(const int &index)
Return pointer to GXMLElement child.
virtual int elements(void) const
Return number of GXMLElement children of node.
void clear(void)
Clear XML object.
GXmlElement * element(const int &index)
Return pointer to child element.
GXmlNode * append(const GXmlNode &node)
Append child node to XML document root.
bool is_empty(void) const
Signals if document has no child nodes.
std::string data_filter_bitshuffle(const std::string &data, const GXmlElement *filter)
Filter data according to Bitshuffle algorithm.
const GXmlElement * xml_msg_type(const GXmlElement *header, const std::string &type, const int &number=0)
Return specific occurence of header message of given type.
std::string fread_data_chunk(FILE *fptr, const GXmlElement *chunk, const GXmlElement *dataspace, const GXmlElement *datatype, const GXmlElement *datalayout, const GXmlElement *datafilter=NULL)
Read data chunk.
int data_to_int(const char *data, const GXmlElement *datatype)
Convert data into integer value.
std::string fread_data(FILE *fptr, const int &nbytes)
Read data from HDF5 file.
int fread_int(FILE *fptr, const int &nbytes)
Read data as integer from HDF5 file.
int xml_msg_attributes(const GXmlElement *header, const std::string &name="")
Return number of "Attribute" messages in header.
void fread_zero(FILE *fptr, const int &nbytes)
Read zero data from HDF5 file.
double data_to_double(const char *data, const GXmlElement *datatype)
Convert data into double precision floating point value.
bool xml_has_msg_type(const GXmlElement *header, const std::string &type, const int &number=0)
Checks if specific occurence of header message of given type exists.
std::string classname(const int &cls)
Convert datatype class into classname.
std::string data_to_string(const char *data, const GXmlElement *datatype)
Convert data into string.
std::string data_filter(const std::string &data, const GXmlElement *datafilter)
Filter data.
std::string fread_string(FILE *fptr, const int &nbytes)
Read string data from HDF5 file.
const GXmlElement * xml_msg_attribute(const GXmlElement *header, const std::string &name, const int &number=0)
Return "Attribute" message XML element with specified name.
uint32_t fread_uint32(FILE *fptr, const int &nbytes)
Read data as unsiged 32 Bit integer from HDF5 file.
bool xml_has_msg_attribute(const GXmlElement *header, const std::string &name, const int &number=0)
Checks if "Attribute" message XML element with specified name exists.
uint64_t fread_uint64(FILE *fptr, const int &nbytes)
Read data as unsiged 64 Bit integer from HDF5 file.
std::string fread_data_as_string(FILE *fptr, const GXmlElement *datatype)
Read data with any data type as a string.
std::string parformat(const std::string &s, const int &indent=0)
Convert string in parameter format.
std::string number(const std::string &noun, const int &number)
Convert singular noun into number noun.
std::string str(const unsigned short int &value)
Convert unsigned short integer value into string.
std::string order(const int &number)
Convert number into order noun.
bool little_endian(void)
Signal if architecture stores integers as little endian.
unsigned long long toulonglong(const std::string &arg)
Convert string into unsigned long long value.
int toint(const std::string &arg)
Convert string into integer value.
std::string expand_env(const std::string &arg)
Expand environment variables in string.
const GXmlElement * xml_get_element_by_attribute(const GXmlElement *element, const std::string &tag, const std::string &name, const std::string &value)
Return XML element for a given tag and name/value attribute.