74 if (H5Gget_info(pid, &g_info) < 0) {
75 string msg =
"h5_das handler: unable to obtain the HDF5 group info. for ";
77 throw InternalErr(__FILE__, __LINE__, msg);
79 nelems = g_info.nlinks;
81 ssize_t oname_size = 0;
82 for (hsize_t i = 0; i < nelems; i++) {
85 oname_size = H5Lget_name_by_idx(pid,
".", H5_INDEX_NAME, H5_ITER_NATIVE, i,
nullptr, (
size_t)
DODS_NAMELEN,
88 if (oname_size <= 0) {
89 string msg =
"hdf5 object name error from: ";
91 throw InternalErr(__FILE__, __LINE__, msg);
94 vector<char> oname(oname_size + 1);
95 if (H5Lget_name_by_idx(pid,
".", H5_INDEX_NAME, H5_ITER_NATIVE, i, oname.data(), (
size_t) (oname_size + 1),
97 string msg =
"hdf5 object name error from: ";
99 throw InternalErr(__FILE__, __LINE__, msg);
104 if (H5Lget_info(pid, oname.data(), &linfo, H5P_DEFAULT) < 0) {
105 string msg =
"hdf5 link name error from: ";
107 throw InternalErr(__FILE__, __LINE__, msg);
111 if (linfo.type == H5L_TYPE_SOFT) {
113 size_t val_size = linfo.u.val_size;
114 get_softlink(das, pid, gname, oname.data(), slinkindex, val_size);
120 if (H5OGET_INFO_BY_IDX(pid,
".", H5_INDEX_NAME, H5_ITER_NATIVE, i, &oinfo, H5P_DEFAULT) < 0) {
121 string msg =
"Cannot obtain the object info ";
123 throw InternalErr(__FILE__, __LINE__, msg);
125 H5O_type_t obj_type = oinfo.type;
129 case H5O_TYPE_GROUP: {
131 BESDEBUG(
"h5",
"=depth_first():H5G_GROUP " << oname.data() << endl);
134 add_group_structure_info(das, gname, oname.data(),
true);
136 string full_path_name = string(gname) + string(oname.data()) +
"/";
138 hid_t cgroup = H5Gopen(pid, full_path_name.c_str(), H5P_DEFAULT);
140 string msg =
"opening hdf5 group failed for ";
141 msg += full_path_name;
142 throw InternalErr(__FILE__, __LINE__, msg);
147 if (H5OGET_INFO(cgroup, &obj_info) < 0) {
149 string msg =
"Obtaining the hdf5 group info. failed for ";
150 msg += full_path_name;
151 throw InternalErr(__FILE__, __LINE__, msg);
155 auto num_attr = (
int)obj_info.num_attrs;
158 string msg =
"Fail to get the number of attributes for group ";
159 msg += full_path_name;
160 throw InternalErr(__FILE__, __LINE__, msg);
165 read_objects(das, full_path_name.c_str(), cgroup, num_attr);
173 string oid =
get_hardlink(cgroup, full_path_name.c_str());
184 AttrTable *at = das.get_table(full_path_name);
186 at = das.add_table(full_path_name,
new AttrTable);
191 at->append_attr(
"HDF5_HARDLINK", STRING,
paths.
get_name(oid));
194 if (H5Gclose(cgroup) < 0) {
195 throw InternalErr(__FILE__, __LINE__,
"H5Gclose() failed.");
200 case H5O_TYPE_DATASET: {
202 BESDEBUG(
"h5",
"=depth_first():H5G_DATASET " << oname.data() << endl);
205 add_group_structure_info(das, gname, oname.data(),
false);
207 string full_path_name = string(gname) + string(oname.data());
211 if ((dset = H5Dopen(pid, full_path_name.c_str(), H5P_DEFAULT)) < 0) {
212 string msg =
"unable to open the hdf5 dataset of the group ";
214 throw InternalErr(__FILE__, __LINE__, msg);
219 if (H5OGET_INFO(dset, &obj_info) < 0) {
221 string msg =
"Obtaining the info. failed for the dataset ";
222 msg += full_path_name;
223 throw InternalErr(__FILE__, __LINE__, msg);
227 auto num_attr = (
int)(obj_info.num_attrs);
230 string msg =
"Fail to get the number of attributes for dataset ";
231 msg += full_path_name;
232 throw InternalErr(__FILE__, __LINE__, msg);
253 AttrTable *at = das.get_table(full_path_name);
255 at = das.add_table(full_path_name,
new AttrTable);
260 at->append_attr(
"HDF5_HARDLINK", STRING,
paths.
get_name(oid));
263 if (H5Dclose(dset) < 0) {
264 throw InternalErr(__FILE__, __LINE__,
"Could not close the dataset.");
269 case H5O_TYPE_NAMED_DATATYPE:
278 BESDEBUG(
"h5",
"<depth_first():" << gname << endl);
295void read_objects(DAS & das,
const string & varname, hid_t oid,
int num_attr)
298 BESDEBUG(
"h5",
">read_objects():" <<
"varname=" << varname <<
" id=" << oid << endl);
305 AttrTable *attr_table_ptr = das.get_table(varname);
306 if (!attr_table_ptr) {
307 BESDEBUG(
"h5",
"=read_objects(): adding a table with name " << varname << endl);
308 attr_table_ptr = das.add_table(varname,
new AttrTable);
312 attr_table_ptr->append_attr(hdf5_path.c_str(), STRING, varname);
317 vector<char> temp_buf;
319 bool ignore_attr =
false;
321 for (
int j = 0; j < num_attr; j++) {
329 attr_id =
get_attr_info(oid, j,
false, &attr_inst, &ignore_attr);
330 if (
true == ignore_attr) {
337 hid_t ty_id = H5Aget_type(attr_id);
339 string attr_name = attr_inst.
name;
342 if (H5Tis_variable_str(ty_id)) {
344 write_vlen_str_attrs(attr_id,ty_id,&attr_inst,
nullptr,attr_table_ptr,
false);
347 BESDEBUG(
"h5",
"attribute name " << attr_name <<endl);
348 BESDEBUG(
"h5",
"attribute size " <<attr_inst.
need <<endl);
349 BESDEBUG(
"h5",
"attribute type size " <<(
int)(H5Tget_size(ty_id))<<endl);
351 hid_t temp_space_id = H5Aget_space(attr_id);
353 "attribute calculated size "<<(
int)(H5Tget_size(ty_id)) *(
int)(H5Sget_simple_extent_npoints(temp_space_id)) <<endl);
354 if (temp_space_id < 0) {
357 throw InternalErr(__FILE__, __LINE__,
"unable to read HDF5 attribute data");
362 temp_buf.resize((
size_t) attr_inst.
need);
364 if (H5Aread(attr_id, ty_id, temp_buf.data()) < 0) {
365 H5Sclose(temp_space_id);
368 throw InternalErr(__FILE__, __LINE__,
"unable to read HDF5 attribute data");
372 temp_bp = temp_buf.data();
374 for (
unsigned int temp_i = 0; temp_i < attr_inst.
nelmts; temp_i++) {
377 onestring = *(
char **) temp_bp;
380 if (onestring !=
nullptr) {
381 string tempstring(onestring);
382 attr_table_ptr->append_attr(attr_name, dap_type, tempstring);
386 temp_bp += H5Tget_size(ty_id);
388 if (temp_buf.empty() !=
true) {
390 herr_t ret_vlen_claim;
391 ret_vlen_claim = H5Dvlen_reclaim(ty_id, temp_space_id, H5P_DEFAULT, temp_buf.data());
392 if(ret_vlen_claim < 0) {
393 H5Sclose(temp_space_id);
394 throw InternalErr(__FILE__, __LINE__,
"Cannot reclaim the memory buffer of the HDF5 variable length string.");
398 H5Sclose(temp_space_id);
403 value.resize(attr_inst.
need);
404 BESDEBUG(
"h5",
"arttr_inst.need=" << attr_inst.
need << endl);
406 hid_t memtype = H5Tget_native_type(ty_id, H5T_DIR_ASCEND);
408 if (H5Aread(attr_id, memtype, (
void *) (value.data())) < 0)
409 throw InternalErr(__FILE__, __LINE__,
"unable to read HDF5 attribute data");
414 if (attr_inst.
ndims == 0) {
415 for (
int loc = 0; loc < (
int) attr_inst.
nelmts; loc++) {
416 print_rep =
print_attr(ty_id, loc, value.data());
417 if (print_rep.c_str() !=
nullptr) {
418 attr_table_ptr->append_attr(attr_name, dap_type, print_rep.c_str());
426 BESDEBUG(
"h5",
"=read_objects(): ndims=" << (
int) attr_inst. ndims << endl);
429 auto elesize = (
int) H5Tget_size(ty_id);
431 BESDEBUG(
"h5",
"=read_objects(): elesize=0" << endl);
434 throw InternalErr(__FILE__, __LINE__,
"unable to get attibute size");
439 char *tempvalue = value.data();
443 for (hsize_t temp_index = 0; temp_index < attr_inst.
nelmts; temp_index++) {
445 if (print_rep.c_str() !=
nullptr) {
446 attr_table_ptr->append_attr(attr_name, dap_type, print_rep.c_str());
447 tempvalue = tempvalue + elesize;
449 BESDEBUG(
"h5",
"tempvalue=" << tempvalue <<
"elesize=" << elesize << endl);
455 throw InternalErr(__FILE__, __LINE__,
"unable to convert attibute value to DAP");
460 if (H5Tclose(ty_id) < 0) {
462 throw InternalErr(__FILE__, __LINE__,
"unable to close HDF5 type id");
464 if (H5Aclose(attr_id) < 0) {
465 throw InternalErr(__FILE__, __LINE__,
"unable to close attibute id");
468 BESDEBUG(
"h5",
"<read_objects()" << endl);
484 BESDEBUG(
"h5",
">find_gloattr()" << endl);
486 hid_t root = H5Gopen(file,
"/", H5P_DEFAULT);
488 if (root < 0)
throw InternalErr(__FILE__, __LINE__,
"unable to open the HDF5 root group");
495 das.add_table(
"HDF5_ROOT_GROUP",
new AttrTable);
506 if (H5OGET_INFO(root, &obj_info) < 0) {
508 string msg =
"Obtaining the info. failed for the root group ";
509 throw InternalErr(__FILE__, __LINE__, msg);
513 num_attrs = obj_info.num_attrs;
516 throw InternalErr(__FILE__, __LINE__,
"unable to get the number of attributes for the HDF root group ");
519 if (num_attrs == 0) {
520 if (H5Gclose(root) < 0) {
521 throw InternalErr(__FILE__, __LINE__,
"Could not close the group.");
523 BESDEBUG(
"h5",
"<find_gloattr():no attributes" << endl);
532 BESDEBUG(
"h5",
"=find_gloattr(): H5Gclose()" << endl);
533 if (H5Gclose(root) < 0) {
534 throw InternalErr(__FILE__, __LINE__,
"Could not close the group.");
536 BESDEBUG(
"h5",
"<find_gloattr()" << endl);
539 if (H5Gclose(root) < 0) {
540 throw InternalErr(__FILE__, __LINE__,
"Could not close the group.");
560void get_softlink(DAS & das, hid_t pgroup,
const char *gname,
const string & oname,
int index,
size_t val_size)
562 BESDEBUG(
"h5",
">get_softlink():" << oname << endl);
565 oss << string(
"HDF5_SOFTLINK");
568 string temp_varname = oss.str();
571 BESDEBUG(
"h5",
"=get_softlink():" << temp_varname << endl);
572 AttrTable *attr_table_ptr = das.get_table(gname);
573 if (!attr_table_ptr) attr_table_ptr = das.add_table(gname,
new AttrTable);
575 AttrTable *attr_softlink_ptr;
576 attr_softlink_ptr = attr_table_ptr->append_container(temp_varname);
578 string softlink_name =
"linkname";
579 attr_softlink_ptr->append_attr(softlink_name, STRING, oname);
580 string softlink_value_name =
"LINKTARGET";
583 vector<char>buf((val_size + 1) *
sizeof(
char));
586 if (H5Lget_val(pgroup, oname.c_str(), (
void*) buf.data(), val_size + 1, H5P_DEFAULT) < 0)
587 throw InternalErr(__FILE__, __LINE__,
"unable to get link value");
588 attr_softlink_ptr->append_attr(softlink_value_name, STRING, buf.data());
607 BESDEBUG(
"h5",
">get_hardlink():" << oname << endl);
611 if (H5OGET_INFO(pgroup, &obj_info) < 0) {
612 throw InternalErr(__FILE__, __LINE__,
"H5OGET_INFO() failed.");
619 if (obj_info.rc > 1) {
622#if (H5_VERS_MAJOR == 1 && ((H5_VERS_MINOR == 12) || (H5_VERS_MINOR == 13)))
623 char *obj_tok_str =
nullptr;
624 if(H5Otoken_to_str(pgroup, &(obj_info.token), &obj_tok_str) <0) {
625 throw InternalErr(__FILE__, __LINE__,
"H5Otoken_to_str failed.");
627 objno.assign(obj_tok_str,obj_tok_str+strlen(obj_tok_str));
628 H5free_memory(obj_tok_str);
631 oss << hex << obj_info.addr;
636 BESDEBUG(
"h5",
"=get_hardlink() objno=" << objno << endl);
665 comment_size = (
int) (H5Oget_comment(oid,
nullptr, 0));
666 if (comment_size < 0) {
667 throw InternalErr(__FILE__, __LINE__,
"Could not retrieve the comment size.");
670 if (comment_size > 0) {
671 vector<char> comment;
672 comment.resize(comment_size + 1);
673 if (H5Oget_comment(oid, comment.data(), comment_size + 1) < 0) {
674 throw InternalErr(__FILE__, __LINE__,
"Could not retrieve the comment.");
678 AttrTable *at = das.get_table(varname);
679 if (!at) at = das.add_table(varname,
new AttrTable);
680 at->append_attr(
"HDF5_COMMENT", STRING, comment.data());
704void add_group_structure_info(DAS & das,
const char *gname,
const char *oname,
bool is_group)
707 string h5_spec_char(
"/");
708 string dap_notion(
".");
709 string::size_type pos = 1;
711 if (gname ==
nullptr) {
712 throw InternalErr(__FILE__, __LINE__,
"The wrong HDF5 group name.");
715 auto full_path = string(gname);
719 while ((pos = full_path.find(h5_spec_char, pos)) != string::npos) {
720 full_path.replace(pos, h5_spec_char.size(), dap_notion);
729 if (strncmp(gname,
"/", strlen(gname)) == 0) {
730 full_path.replace(0, 1,
"HDF5_ROOT_GROUP");
733 full_path.replace(0, 1,
"HDF5_ROOT_GROUP.");
734 full_path = full_path.substr(0, full_path.length() - 1);
737 BESDEBUG(
"h5", full_path << endl);
739 AttrTable *at = das.get_table(full_path);
741 throw InternalErr(__FILE__, __LINE__,
742 "Failed to add group structure information for " + full_path +
" attribute table."
743 +
"This happens when a group name has . character.");
748 at->append_container(oname);
751 at->append_attr(
"Dataset",
"String", oname);
bool add(const std::string &id, const std::string &name)
std::string get_name(const std::string &id)
string get_hardlink(hid_t pgroup, const string &oname)
void depth_first(hid_t pid, const char *gname, DAS &das)
HDF5PathFinder paths
A variable for remembering visited paths to break cyclic HDF5 groups.
void find_gloattr(hid_t file, DAS &das)
void read_objects(DAS &das, const string &varname, hid_t oid, int num_attr)
void read_comments(DAS &das, const string &varname, hid_t oid)
string print_attr(hid_t type, int loc, void *sm_buf)
string get_dap_type(hid_t type, bool is_dap4)
hid_t get_attr_info(hid_t dset, int index, bool is_dap4, DSattr_t *attr_inst_ptr, bool *ignore_attr_ptr)
The main header of the HDF5 OPeNDAP handler.
const int DODS_NAMELEN
Maximum length of variable or attribute name(default option only).
const std::string HDF5_OBJ_FULLPATH
The special DAS attribute name for HDF5 path information from the top(root) group.
A structure for DAS generation.
char name[DODS_NAMELEN]
Name of HDF5 group or dataset.
int ndims
Number of dimensions.
hsize_t nelmts
Number of elements.
hsize_t need
Memory space needed to hold nelmts type.