72 if (H5Gget_info(pid,&g_info) <0) {
74 "h5_das handler: unable to obtain the HDF5 group info. for ";
76 throw InternalErr(__FILE__, __LINE__, msg);
78 nelems = g_info.nlinks;
81 for (hsize_t i = 0; i < nelems; i++) {
85 H5Lget_name_by_idx(pid,
".",H5_INDEX_NAME,H5_ITER_NATIVE,i,
NULL,
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[0],
96 (
size_t)(oname_size+1), H5P_DEFAULT)<0){
97 string msg =
"hdf5 object name error from: ";
99 throw InternalErr(__FILE__, __LINE__, msg);
104 if (H5Lget_info(pid,&oname[0],&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[0], slinkindex,val_size);
120 if (H5Oget_info_by_idx(pid,
".", H5_INDEX_NAME, H5_ITER_NATIVE,
121 i, &oinfo, H5P_DEFAULT)<0) {
122 string msg =
"Cannot obtain the object info ";
124 throw InternalErr(__FILE__, __LINE__, msg);
126 H5O_type_t obj_type = oinfo.type;
130 case H5O_TYPE_GROUP: {
132 DBG(cerr <<
"=depth_first():H5G_GROUP " << &oname[0] << endl);
137 string full_path_name = string(gname) + string(&oname[0]) +
"/";
139 hid_t cgroup = H5Gopen(pid, full_path_name.c_str(),H5P_DEFAULT);
141 string msg =
"opening hdf5 group failed for ";
142 msg += full_path_name;
143 throw InternalErr(__FILE__, __LINE__, msg);
150 if (H5Oget_info(cgroup, &obj_info) <0) {
152 string msg =
"Obtaining the hdf5 group info. failed for ";
153 msg += full_path_name;
154 throw InternalErr(__FILE__, __LINE__, msg);
158 num_attr = obj_info.num_attrs;
161 string msg =
"Fail to get the number of attributes for group ";
162 msg += full_path_name;
163 throw InternalErr(__FILE__, __LINE__,msg);
167 read_objects(das, full_path_name.c_str(), cgroup, num_attr);
170 string oid =
get_hardlink(cgroup, full_path_name.c_str());
181 AttrTable *at = das.get_table(full_path_name);
183 at = das.add_table(full_path_name,
new AttrTable);
188 at->append_attr(
"HDF5_HARDLINK", STRING, paths.
get_name(oid));
191 if (H5Gclose(cgroup) < 0) {
192 throw InternalErr(__FILE__, __LINE__,
"H5Gclose() failed.");
197 case H5O_TYPE_DATASET: {
199 DBG(cerr <<
"=depth_first():H5G_DATASET " << &oname[0] <<
205 string full_path_name = string(gname) + string(&oname[0]);
209 if ((dset = H5Dopen(pid, full_path_name.c_str(),H5P_DEFAULT)) < 0) {
210 string msg =
"unable to open the hdf5 dataset of the group ";
212 throw InternalErr(__FILE__, __LINE__, msg);
218 if (H5Oget_info(dset, &obj_info) <0) {
220 string msg =
"Obtaining the info. failed for the dataset ";
221 msg += full_path_name;
222 throw InternalErr(__FILE__, __LINE__, msg);
226 num_attr = obj_info.num_attrs;
229 string msg =
"Fail to get the number of attributes for dataset ";
230 msg += full_path_name;
231 throw InternalErr(__FILE__, __LINE__,msg);
246 AttrTable *at = das.get_table(full_path_name);
248 at = das.add_table(full_path_name,
new AttrTable);
253 at->append_attr(
"HDF5_HARDLINK", STRING, paths.
get_name(oid));
256 if (H5Dclose(dset) < 0) {
257 throw InternalErr(__FILE__, __LINE__,
"Could not close the dataset.");
262 case H5O_TYPE_NAMED_DATATYPE:
271 DBG(cerr <<
"<depth_first():" << gname << endl);
293 unsigned short *tusp;
304 switch (H5Tget_class(type)) {
314 if (H5Tequal(type, H5T_STD_U8BE) || H5Tequal(type, H5T_STD_U8LE)
315 || H5Tequal(type, H5T_NATIVE_UCHAR)) {
316 gp.tcp = (
char *) sm_buf;
317 unsigned char tuchar = *(gp.tcp + loc);
321 snprintf(&rep[0], 32,
"%u", tuchar);
324 else if (H5Tequal(type, H5T_STD_U16BE)
325 || H5Tequal(type, H5T_STD_U16LE)
326 || H5Tequal(type, H5T_NATIVE_USHORT)) {
327 gp.tusp = (
unsigned short *) sm_buf;
328 snprintf(&rep[0], 32,
"%hu", *(gp.tusp + loc));
331 else if (H5Tequal(type, H5T_STD_U32BE)
332 || H5Tequal(type, H5T_STD_U32LE)
333 || H5Tequal(type, H5T_NATIVE_UINT)) {
335 gp.tip = (
int *) sm_buf;
336 snprintf(&rep[0], 32,
"%u", *(gp.tip + loc));
339 else if (H5Tequal(type, H5T_STD_U64BE)
340 || H5Tequal(type, H5T_STD_U64LE)
341 || H5Tequal(type, H5T_NATIVE_ULONG)
342 || H5Tequal(type, H5T_NATIVE_ULLONG)) {
344 gp.tlp = (
long *) sm_buf;
345 snprintf(&rep[0], 32,
"%lu", *(gp.tlp + loc));
348 else if (H5Tequal(type, H5T_STD_I8BE)
349 || H5Tequal(type, H5T_STD_I8LE)
350 || H5Tequal(type, H5T_NATIVE_CHAR)) {
352 gp.tcp = (
char *) sm_buf;
360 snprintf(&rep[0], 32,
"%d", *(gp.tcp + loc));
363 else if (H5Tequal(type, H5T_STD_I16BE)
364 || H5Tequal(type, H5T_STD_I16LE)
365 || H5Tequal(type, H5T_NATIVE_SHORT)) {
367 gp.tsp = (
short *) sm_buf;
368 snprintf(&rep[0], 32,
"%hd", *(gp.tsp + loc));
371 else if (H5Tequal(type, H5T_STD_I32BE)
372 || H5Tequal(type, H5T_STD_I32LE)
373 || H5Tequal(type, H5T_NATIVE_INT)) {
375 gp.tip = (
int *) sm_buf;
376 snprintf(&rep[0], 32,
"%d", *(gp.tip + loc));
379 else if (H5Tequal(type, H5T_STD_I64BE)
380 || H5Tequal(type, H5T_STD_I64LE)
381 || H5Tequal(type, H5T_NATIVE_LONG)
382 || H5Tequal(type, H5T_NATIVE_LLONG)) {
384 gp.tlp = (
long *) sm_buf;
385 snprintf(&rep[0], 32,
"%ld", *(gp.tlp + loc));
395 if (H5Tget_size(type) == 4) {
399 gp.tfp = (
float *) sm_buf;
400 snprintf(gps, 30,
"%.10g", *(gp.tfp + loc));
401 int ll = strlen(gps);
404 if (!strchr(gps,
'.') && !strchr(gps,
'e'))
408 snprintf(&rep[0], 32,
"%s", gps);
410 else if (H5Tget_size(type) == 8) {
412 gp.tdp = (
double *) sm_buf;
413 snprintf(gps, 30,
"%.17g", *(gp.tdp + loc));
414 int ll = strlen(gps);
415 if (!strchr(gps,
'.') && !strchr(gps,
'e'))
418 snprintf(&rep[0], 32,
"%s", gps);
420 else if (H5Tget_size(type) == 0){
421 throw InternalErr(__FILE__, __LINE__,
"H5Tget_size() failed.");
427 int str_size = H5Tget_size(type);
428 if(H5Tis_variable_str(type) ==
true)
431 throw InternalErr(__FILE__, __LINE__,
"H5Tget_size() failed.");
433 DBG(cerr <<
"=print_attr(): H5T_STRING sm_buf=" << (
char *) sm_buf
434 <<
" size=" << str_size << endl);
438 buf =
new char[str_size + 1];
439 strncpy(buf, (
char *) sm_buf, str_size);
440 buf[str_size] =
'\0';
442 rep.resize(str_size+3);
443 snprintf(&rep[0], str_size + 3,
"%s", buf);
444 rep[str_size + 2] =
'\0';
445 delete[] buf; buf = 0;
448 if( buf )
delete[] buf;
463 string rep_str(rep.begin(),rep.end());
481 void read_objects(DAS & das,
const string & varname, hid_t oid,
int num_attr)
484 DBG(cerr <<
">read_objects():"
485 <<
"varname=" << varname <<
" id=" << oid << endl);
492 AttrTable *attr_table_ptr = das.get_table(varname);
493 if (!attr_table_ptr) {
494 DBG(cerr <<
"=read_objects(): adding a table with name " << varname
496 attr_table_ptr = das.add_table(varname,
new AttrTable);
500 attr_table_ptr->append_attr(hdf5_path.c_str(), STRING, varname);
506 vector<char>temp_buf;
509 bool ignore_attr =
false;
511 for (
int j = 0; j < num_attr; j++) {
520 if (ignore_attr)
continue;
524 hid_t ty_id = attr_inst.
type;
526 string attr_name = attr_inst.
name;
530 if (H5Tis_variable_str(attr_inst.
type)) {
532 DBG(cerr <<
"attribute name " << attr_name <<endl);
533 DBG(cerr <<
"attribute size " <<attr_inst.
need <<endl);
534 DBG(cerr <<
"attribute type size " <<(
int)(H5Tget_size(attr_inst.
type))<<endl);
536 hid_t temp_space_id = H5Aget_space(attr_id);
537 DBG(cerr <<
"attribute calculated size "<<(
int)(H5Tget_size(attr_inst.
type)) *(
int)(H5Sget_simple_extent_npoints(temp_space_id)) <<endl);
540 temp_buf.resize((
size_t)attr_inst.
need);
542 if (H5Aread(attr_id, ty_id, &temp_buf[0]) < 0) {
543 H5Sclose(temp_space_id);
545 throw InternalErr(__FILE__, __LINE__,
"unable to read HDF5 attribute data");
549 temp_bp = &temp_buf[0];
551 for (
unsigned int temp_i = 0; temp_i <attr_inst.
nelmts; temp_i++) {
554 onestring =*(
char **)temp_bp;
557 if (onestring !=
NULL) {
558 string tempstring(onestring);
560 attr_table_ptr->append_attr(attr_name, dap_type, tempstring);
564 temp_bp +=H5Tget_size(attr_inst.
type);
566 if (temp_buf.empty() !=
true) {
568 H5Dvlen_reclaim(attr_inst.
type,temp_space_id,H5P_DEFAULT,&temp_buf[0]);
571 H5Sclose(temp_space_id);
576 value.resize(attr_inst.
need +
sizeof(
char));
577 DBG(cerr <<
"arttr_inst.need=" << attr_inst.
need << endl);
580 if (H5Aread(attr_id, ty_id, (
void *) (&value[0])) < 0) {
583 throw InternalErr(__FILE__, __LINE__,
"unable to read HDF5 attribute data");
585 DBG(cerr <<
"H5Aread(" << attr_inst.
name <<
")=" << value << endl);
588 if (attr_inst.
ndims == 0) {
589 for (
int loc = 0; loc < (int) attr_inst.
nelmts; loc++) {
590 print_rep =
print_attr(ty_id, loc, &value[0]);
592 if (print_rep.c_str() !=
NULL) {
593 attr_table_ptr->append_attr(attr_name, dap_type, print_rep.c_str());
603 DBG(cerr <<
"=read_objects(): ndims=" << (
int) attr_inst.
607 int elesize = (int) H5Tget_size(attr_inst.
type);
609 DBG(cerr <<
"=read_objects(): elesize=0" << endl);
611 if (H5Aclose(attr_id) < 0) {
612 throw InternalErr(__FILE__, __LINE__,
"unable to close attibute id");
615 throw InternalErr(__FILE__, __LINE__,
"unable to get attibute size");
620 char *tempvalue = &value[0];
628 for( hsize_t temp_index = 0; temp_index < attr_inst.
nelmts; temp_index ++) {
631 if (print_rep.c_str() !=
NULL) {
632 attr_table_ptr->append_attr(attr_name, dap_type, print_rep.c_str());
633 tempvalue = tempvalue + elesize;
636 <<
"tempvalue=" << tempvalue
637 <<
"elesize=" << elesize
644 if (H5Aclose(attr_id) < 0) {
645 throw InternalErr(__FILE__, __LINE__,
"unable to close HDF5 attibute id");
648 throw InternalErr(__FILE__, __LINE__,
"unable to convert attibute value to DAP");
655 if (H5Aclose(attr_id) < 0) {
656 throw InternalErr(__FILE__, __LINE__,
"unable to close attibute id");
669 DBG(cerr <<
"<read_objects()" << endl);
685 DBG(cerr <<
">find_gloattr()" << endl);
687 hid_t root = H5Gopen(file,
"/",H5P_DEFAULT);
690 throw InternalErr(__FILE__, __LINE__,
691 "unable to open the HDF5 root group");
698 das.add_table(
"HDF5_ROOT_GROUP",
new AttrTable);
709 if (H5Oget_info(root, &obj_info) <0) {
711 string msg =
"Obtaining the info. failed for the root group ";
712 throw InternalErr(__FILE__, __LINE__, msg);
716 num_attrs = obj_info.num_attrs;
719 throw InternalErr(__FILE__, __LINE__,
720 "unable to get the number of attributes for the HDF root group ");
723 if (num_attrs == 0) {
724 if(H5Gclose(root) < 0){
725 throw InternalErr(__FILE__, __LINE__,
726 "Could not close the group.");
728 DBG(cerr <<
"<find_gloattr():no attributes" << endl);
737 DBG(cerr <<
"=find_gloattr(): H5Gclose()" << endl);
738 if(H5Gclose(root) < 0){
739 throw InternalErr(__FILE__, __LINE__,
"Could not close the group.");
741 DBG(cerr <<
"<find_gloattr()" << endl);
744 if(H5Gclose(root) < 0){
745 throw InternalErr(__FILE__, __LINE__,
"Could not close the group.");
765 void get_softlink(DAS & das, hid_t pgroup,
const char *gname,
const string & oname,
int index,
size_t val_size)
767 DBG(cerr <<
">get_softlink():" << oname << endl);
770 oss << string(
"HDF5_SOFTLINK");
773 string temp_varname = oss.str();
777 DBG(cerr <<
"=get_softlink():" << temp_varname << endl);
778 AttrTable *attr_table_ptr = das.get_table(gname);
780 attr_table_ptr = das.add_table(gname,
new AttrTable);
782 AttrTable *attr_softlink_ptr;
783 attr_softlink_ptr = attr_table_ptr->append_container(temp_varname);
785 string softlink_name =
"linkname";
786 attr_softlink_ptr->append_attr(softlink_name,STRING,oname);
787 string softlink_value_name =
"LINKTARGET";
796 buf =
new char[(val_size + 1) *
sizeof(
char)];
798 if (H5Lget_val(pgroup, oname.c_str(), (
void*) buf,val_size + 1, H5P_DEFAULT)
800 throw InternalErr(__FILE__, __LINE__,
"unable to get link value");
802 attr_softlink_ptr->append_attr(softlink_value_name, STRING, buf);
826 DBG(cerr <<
">get_hardlink():" << oname << endl);
830 if (H5Oget_info(pgroup, &obj_info) <0) {
831 throw InternalErr(__FILE__, __LINE__,
"H5Oget_info() failed.");
838 if (obj_info.rc >1) {
841 oss << hex << obj_info.addr;
842 string objno = oss.str();
844 DBG(cerr <<
"=get_hardlink() objno=" << objno << endl);
846 if (!paths.
add(objno, oname)) {
873 comment_size=(int)(H5Oget_comment(oid,
NULL,0));
874 if (comment_size <0) {
875 throw InternalErr(__FILE__, __LINE__,
876 "Could not retrieve the comment size.");
879 if (comment_size > 0) {
881 comment.resize(comment_size+1);
882 if (H5Oget_comment(oid,&comment[0],comment_size+1)<0) {
883 throw InternalErr(__FILE__, __LINE__,
884 "Could not retrieve the comment.");
888 AttrTable *at = das.get_table(varname);
890 at = das.add_table(varname,
new AttrTable);
891 at->append_attr(
"HDF5_COMMENT", STRING, &comment[0]);
921 string h5_spec_char(
"/");
922 string dap_notion(
".");
923 string::size_type pos = 1;
926 throw InternalErr(__FILE__, __LINE__,
927 "The wrong HDF5 group name.");
930 string full_path = string(gname);
934 while ((pos = full_path.find(h5_spec_char, pos)) != string::npos) {
935 full_path.replace(pos, h5_spec_char.size(), dap_notion);
945 if (strncmp(gname,
"/", strlen(gname)) == 0) {
946 full_path.replace(0, 1,
"HDF5_ROOT_GROUP");
949 full_path.replace(0, 1,
"HDF5_ROOT_GROUP.");
950 full_path = full_path.substr(0, full_path.length() - 1);
953 DBG(cerr << full_path << endl);
955 AttrTable *at = das.get_table(full_path);
957 throw InternalErr(__FILE__, __LINE__,
958 "Failed to add group structure information for "
960 +
" attribute table."
961 +
"This happens when a group name has . character.");
966 at->append_container(oname);
969 at->append_attr(
"Dataset",
"String", oname);
void add_group_structure_info(DAS &das, const char *gname, char *oname, bool is_group)
will insert group information in a structure format into DAS table.
string get_dap_type(hid_t type)
returns the string representation of HDF5 type.
HDF5PathFinder paths
A variable for remembering visited paths to break cyclic HDF5 groups.
string get_name(string id)
Get the object name of id object in the map.
bool add(string id, const string name)
Adds name and id object number into an internal map.
#define DODS_NAMELEN
Maximum length of variable or attribute name(default option only).
size_t need
Memory space needed to hold nelmts type.
void read_objects(DAS &das, const string &varname, hid_t oid, int num_attr)
will fill in attributes of a dataset or a group into one DAS table.
The main header of the HDF5 OPeNDAP handler.
string get_hardlink(hid_t pgroup, const string &oname)
will put hardlink information into a DAS table.
void find_gloattr(hid_t file, DAS &das)
will fill in attributes of the root group into one DAS table.
A structure for DAS generation.
#define HDF5_OBJ_FULLPATH
The special DAS attribute name for HDF5 path information from the top(root) group.
hid_t get_attr_info(hid_t dset, int index, DSattr_t *attr_inst_ptr, bool *ignore_attr_ptr)
void read_comments(DAS &das, const string &varname, hid_t oid)
will fill in attributes of a group's comment into DAS table.
void depth_first(hid_t pid, const char *gname, DAS &das)
depth first traversal of hdf5 file attributes.
hsize_t nelmts
Number of elements.
int ndims
Number of dimensions.
void get_softlink(DAS &das, hid_t pgroup, const char *gname, const string &oname, int index, size_t val_size)
char name[DODS_NAMELEN]
Name of HDF5 group or dataset.
string print_attr(hid_t type, int loc, void *sm_buf)
will get the printed representation of an attribute.