61 visit_obj_cb(hid_t o_id,
const char *name,
const H5O_info_t *oinfo,
65 static herr_t attr_info_dimscale(hid_t loc_id,
const char *name,
const H5A_info_t *ainfo,
void *opdata);
85 bool *ignore_attr_ptr)
91 *ignore_attr_ptr =
false;
93 if ((attrid = H5Aopen_by_idx(dset,
".", H5_INDEX_CRT_ORDER, H5_ITER_INC,(hsize_t)index, H5P_DEFAULT, H5P_DEFAULT)) < 0) {
94 string msg =
"unable to open attribute by index ";
95 throw InternalErr(__FILE__, __LINE__, msg);
99 ssize_t name_size = H5Aget_name(attrid, 0, NULL);
102 string msg =
"unable to obtain the size of the hdf5 attribute name ";
103 throw InternalErr(__FILE__, __LINE__, msg);
106 vector<char> attr_name;
107 attr_name.resize(name_size+1);
109 if ((H5Aget_name(attrid, name_size+1, &attr_name[0])) < 0) {
111 string msg =
"unable to obtain the hdf5 attribute name ";
112 throw InternalErr(__FILE__, __LINE__, msg);
117 if ((ty_id = H5Aget_type(attrid)) < 0) {
118 string msg =
"unable to obtain hdf5 datatype for the attribute ";
119 string attrnamestr(attr_name.begin(),attr_name.end());
122 throw InternalErr(__FILE__, __LINE__, msg);
125 H5T_class_t ty_class = H5Tget_class(ty_id);
127 string msg =
"cannot get hdf5 attribute datatype class for the attribute ";
128 string attrnamestr(attr_name.begin(),attr_name.end());
131 throw InternalErr(__FILE__, __LINE__, msg);
144 if ((ty_class == H5T_TIME) || (ty_class == H5T_BITFIELD)
145 || (ty_class == H5T_OPAQUE) || (ty_class == H5T_ENUM)
146 || (ty_class == H5T_REFERENCE) ||(ty_class == H5T_COMPOUND)
147 || (ty_class == H5T_VLEN) || (ty_class == H5T_ARRAY)){
149 *ignore_attr_ptr =
true;
156 if (
false == is_dap4) {
157 if((ty_class == H5T_INTEGER) && (H5Tget_size(ty_id)== 8)) {
158 *ignore_attr_ptr =
true;
165 if (
true == is_dap4 && HDF5RequestHandler::get_default_handle_dimension() ==
true) {
167 string attr_name_str(attr_name.begin(),attr_name.end()-1);
168 if(attr_name_str ==
"CLASS" || attr_name_str ==
"NAME" || attr_name_str ==
"_Netcdf4Dimid"
169 || attr_name_str ==
"_nc3_strict" || attr_name_str==
"_NCProperties" || attr_name_str==
"_Netcdf4Coordinates") {
170 *ignore_attr_ptr =
true;
176 hid_t aspace_id = -1;
177 if ((aspace_id = H5Aget_space(attrid)) < 0) {
178 string msg =
"cannot get hdf5 dataspace id for the attribute ";
179 string attrnamestr(attr_name.begin(),attr_name.end());
182 throw InternalErr(__FILE__, __LINE__, msg);
190 int ndims = H5Sget_simple_extent_ndims(aspace_id);
192 string msg =
"cannot get hdf5 dataspace number of dimension for attribute ";
193 string attrnamestr(attr_name.begin(),attr_name.end());
197 throw InternalErr(__FILE__, __LINE__, msg);
202 string msg =
"number of dimensions exceeds allowed for attribute ";
203 string attrnamestr(attr_name.begin(),attr_name.end());
207 throw InternalErr(__FILE__, __LINE__, msg);
215 if (H5Sget_simple_extent_dims(aspace_id, size, maxsize)<0){
216 string msg =
"cannot obtain the dim. info for the attribute ";
217 string attrnamestr(attr_name.begin(),attr_name.end());
221 throw InternalErr(__FILE__, __LINE__, msg);
227 for (
int j = 0; j < ndims; j++)
231 size_t ty_size = H5Tget_size(ty_id);
233 string msg =
"cannot obtain the dtype size for the attribute ";
234 string attrnamestr(attr_name.begin(),attr_name.end());
238 throw InternalErr(__FILE__, __LINE__, msg);
241 size_t need = nelmts * H5Tget_size(ty_id);
244 hid_t memtype = H5Tget_native_type(ty_id, H5T_DIR_ASCEND);
246 string msg =
"cannot obtain the memory dtype for the attribute ";
247 string attrnamestr(attr_name.begin(),attr_name.end());
251 throw InternalErr(__FILE__, __LINE__, msg);
255 (*attr_inst_ptr).type = memtype;
256 (*attr_inst_ptr).ndims = ndims;
257 (*attr_inst_ptr).nelmts = nelmts;
258 (*attr_inst_ptr).need = need;
259 strncpy((*attr_inst_ptr).name, &attr_name[0], name_size+1);
261 for (
int j = 0; j < ndims; j++) {
262 (*attr_inst_ptr).size[j] = size[j];
265 if(H5Sclose(aspace_id)<0) {
267 throw InternalErr(__FILE__,__LINE__,
"Cannot close HDF5 dataspace ");
289 BESDEBUG(
"h5",
">get_dap_type(): type=" << type << endl);
290 H5T_class_t class_t = H5Tget_class(type);
291 if (H5T_NO_CLASS == class_t)
292 throw InternalErr(__FILE__, __LINE__,
293 "The HDF5 datatype doesn't belong to any Class.");
298 size = H5Tget_size(type);
300 throw InternalErr(__FILE__, __LINE__,
301 "size of datatype is invalid");
304 sign = H5Tget_sign(type);
306 throw InternalErr(__FILE__, __LINE__,
307 "sign of datatype is invalid");
310 BESDEBUG(
"h5",
"=get_dap_type(): H5T_INTEGER" <<
311 " sign = " << sign <<
312 " size = " << size <<
316 if(
true == is_dap4) {
317 if (sign == H5T_SGN_NONE)
323 if (sign == H5T_SGN_NONE)
331 if (sign == H5T_SGN_NONE)
338 if (sign == H5T_SGN_NONE)
346 if (
true == is_dap4) {
347 if (sign == H5T_SGN_NONE)
359 size = H5Tget_size(type);
361 throw InternalErr(__FILE__, __LINE__,
362 "size of the datatype is invalid");
365 BESDEBUG(
"h5",
"=get_dap_type(): FLOAT size = " << size << endl);
374 BESDEBUG(
"h5",
"<get_dap_type(): H5T_STRING" << endl);
378 BESDEBUG(
"h5",
"<get_dap_type(): H5T_REFERENCE" << endl);
384 BESDEBUG(
"h5",
"<get_dap_type(): COMPOUND" << endl);
391 BESDEBUG(
"h5",
"<get_dap_type(): Unmappable Type" << endl);
392 return "Unmappable Type";
407 hid_t fileid = H5Fopen(filename, H5F_ACC_RDONLY, H5P_DEFAULT);
409 string msg =
"cannot open the HDF5 file ";
410 string filenamestr(filename);
412 throw InternalErr(__FILE__, __LINE__, msg);
429 if (H5Fclose(fid) < 0)
430 throw Error(unknown_error,
431 string(
"Could not close the HDF5 file."));
438 bool is_pure_dim =
false;
439 get_dataset(pid,dname,dt_inst_ptr,
false,is_pure_dim);
452 void get_dataset(hid_t pid,
const string &dname,
DS_t * dt_inst_ptr,
bool use_dimscale,
bool &is_pure_dim)
455 BESDEBUG(
"h5",
">get_dataset()" << endl);
459 if ((dset = H5Dopen(pid, dname.c_str(),H5P_DEFAULT)) < 0) {
460 string msg =
"cannot open the HDF5 dataset ";
462 throw InternalErr(__FILE__, __LINE__, msg);
467 if ((dtype = H5Dget_type(dset)) < 0) {
469 string msg =
"cannot get the the datatype of HDF5 dataset ";
471 throw InternalErr(__FILE__, __LINE__, msg);
475 H5T_class_t ty_class = H5Tget_class(dtype);
479 string msg =
"cannot get the datatype class of HDF5 dataset ";
481 throw InternalErr(__FILE__, __LINE__, msg);
487 if ((ty_class == H5T_TIME) || (ty_class == H5T_BITFIELD)
488 || (ty_class == H5T_OPAQUE) || (ty_class == H5T_ENUM) || (ty_class == H5T_VLEN)) {
489 string msg =
"unexpected datatype of HDF5 dataset ";
491 throw InternalErr(__FILE__, __LINE__, msg);
495 if ((dspace = H5Dget_space(dset)) < 0) {
498 string msg =
"cannot get the the dataspace of HDF5 dataset ";
500 throw InternalErr(__FILE__, __LINE__, msg);
508 int ndims = H5Sget_simple_extent_ndims(dspace);
513 string msg =
"cannot get hdf5 dataspace number of dimension for dataset ";
515 throw InternalErr(__FILE__, __LINE__, msg);
520 string msg =
"number of dimensions exceeds allowed for dataset ";
525 throw InternalErr(__FILE__, __LINE__, msg);
532 if (H5Sget_simple_extent_dims(dspace, size, maxsize)<0){
533 string msg =
"cannot obtain the dim. info for the dataset ";
538 throw InternalErr(__FILE__, __LINE__, msg);
544 for (
int j = 0; j < ndims; j++)
548 size_t dtype_size = H5Tget_size(dtype);
549 if (dtype_size == 0) {
550 string msg =
"cannot obtain the data type size for the dataset ";
555 throw InternalErr(__FILE__, __LINE__, msg);
558 size_t need = nelmts * dtype_size;
560 hid_t memtype = H5Tget_native_type(dtype, H5T_DIR_ASCEND);
562 string msg =
"cannot obtain the memory data type for the dataset ";
567 throw InternalErr(__FILE__, __LINE__, msg);
570 (*dt_inst_ptr).type = memtype;
571 (*dt_inst_ptr).ndims = ndims;
572 (*dt_inst_ptr).nelmts = nelmts;
573 (*dt_inst_ptr).need = need;
574 strncpy((*dt_inst_ptr).name, dname.c_str(), dname.length());
575 (*dt_inst_ptr).name[dname.length()] =
'\0';
576 for (
int j = 0; j < ndims; j++)
577 (*dt_inst_ptr).size[j] = size[j];
580 if(
true == use_dimscale) {
581 BESDEBUG(
"h5",
"<h5get.cc: get_dataset() use dim scale is true." << endl);
584 bool is_dimscale =
false;
589 bool has_ds_attr =
false;
592 has_ds_attr = has_dimscale_attr(dset);
598 throw InternalErr(__FILE__, __LINE__,
"Fail to check dim. scale.");
601 if(
true == has_ds_attr) {
607 int dim_attr_mark[3];
608 for(
int i = 0;i<3;i++)
609 dim_attr_mark[i] = 0;
613 herr_t ret = H5Aiterate2(dset, H5_INDEX_NAME, H5_ITER_INC, NULL, attr_info_dimscale, dim_attr_mark);
615 string msg =
"cannot interate the attributes of the dataset ";
620 throw InternalErr(__FILE__, __LINE__, msg);
623 for (
int i = 0; i<3;i++)
624 BESDEBUG(
"h5",
"dim_attr_mark is "<<dim_attr_mark[i] <<endl);
632 if (((dim_attr_mark[0] && !dim_attr_mark[1]) || dim_attr_mark[2]))
634 else if(dim_attr_mark[1])
639 if(
true == is_dimscale) {
640 BESDEBUG(
"h5",
"<h5get.cc: dname is " << dname << endl);
641 BESDEBUG(
"h5",
"<h5get.cc: get_dataset() this is dim scale." << endl);
642 BESDEBUG(
"h5",
"<h5get.cc: dataset storage size is: " <<H5Dget_storage_size(dset)<< endl);
648 (*dt_inst_ptr).dimnames.push_back(dname.substr(dname.find_last_of(
"/")+1));
649 (*dt_inst_ptr).dimnames_path.push_back(dname);
656 else if(
false == is_pure_dim)
660 if(H5Tclose(dtype)<0) {
663 throw InternalErr(__FILE__, __LINE__,
"Cannot close the HDF5 datatype.");
666 if(H5Sclose(dspace)<0) {
668 throw InternalErr(__FILE__, __LINE__,
"Cannot close the HDF5 dataspace.");
671 if(H5Dclose(dset)<0) {
672 throw InternalErr(__FILE__, __LINE__,
"Cannot close the HDF5 dataset.");
687 if (H5Tget_class(h5type) == H5T_STRING)
711 unsigned short *tusp;
722 switch (H5Tget_class(type)) {
726 size_t size = H5Tget_size(type);
728 throw InternalErr(__FILE__, __LINE__,
729 "size of datatype is invalid");
732 H5T_sign_t sign = H5Tget_sign(type);
734 throw InternalErr(__FILE__, __LINE__,
735 "sign of datatype is invalid");
738 BESDEBUG(
"h5",
"=get_dap_type(): H5T_INTEGER" <<
739 " sign = " << sign <<
740 " size = " << size <<
750 if(sign == H5T_SGN_NONE) {
751 gp.ucp = (
unsigned char *) sm_buf;
752 unsigned char tuchar = *(gp.ucp + loc);
753 snprintf(&rep[0], 32,
"%u", tuchar);
757 gp.tcp = (
char *) sm_buf;
758 snprintf(&rep[0], 32,
"%d", *(gp.tcp + loc));
762 else if (size == 2) {
764 if(sign == H5T_SGN_NONE) {
765 gp.tusp = (
unsigned short *) sm_buf;
766 snprintf(&rep[0], 32,
"%hu", *(gp.tusp + loc));
770 gp.tsp = (
short *) sm_buf;
771 snprintf(&rep[0], 32,
"%hd", *(gp.tsp + loc));
776 else if (size == 4) {
778 if(sign == H5T_SGN_NONE) {
779 gp.tuip = (
unsigned int *) sm_buf;
780 snprintf(&rep[0], 32,
"%u", *(gp.tuip + loc));
784 gp.tip = (
int *) sm_buf;
785 snprintf(&rep[0], 32,
"%d", *(gp.tip + loc));
788 else if (size == 8) {
790 if(sign == H5T_SGN_NONE) {
791 gp.tulp = (
unsigned long *) sm_buf;
792 snprintf(&rep[0], 32,
"%lu", *(gp.tulp + loc));
795 gp.tlp = (
long *) sm_buf;
796 snprintf(&rep[0], 32,
"%ld", *(gp.tlp + loc));
800 throw InternalErr(__FILE__, __LINE__,
"Unsupported integer type, check the size of datatype.");
809 if (H5Tget_size(type) == 4) {
811 float attr_val = *(
float*)sm_buf;
812 bool is_a_fin = isfinite(attr_val);
815 gp.tfp = (
float *) sm_buf;
816 int ll = snprintf(gps, 30,
"%.10g", *(gp.tfp + loc));
820 if (!strchr(gps,
'.') && !strchr(gps,
'e') && !strchr(gps,
'E')
821 && (
true == is_a_fin)){
826 snprintf(&rep[0], 32,
"%s", gps);
828 else if (H5Tget_size(type) == 8) {
830 double attr_val = *(
double*)sm_buf;
831 bool is_a_fin = isfinite(attr_val);
832 gp.tdp = (
double *) sm_buf;
833 int ll = snprintf(gps, 30,
"%.17g", *(gp.tdp + loc));
837 if (!strchr(gps,
'.') && !strchr(gps,
'e')&& !strchr(gps,
'E')
838 && (
true == is_a_fin)) {
842 snprintf(&rep[0], 32,
"%s", gps);
844 else if (H5Tget_size(type) == 0){
845 throw InternalErr(__FILE__, __LINE__,
"H5Tget_size() failed.");
851 int str_size = H5Tget_size(type);
852 if(H5Tis_variable_str(type)>0) {
853 throw InternalErr(__FILE__, __LINE__,
854 "print_attr function doesn't handle variable length string, variable length string should be handled separately.");
857 throw InternalErr(__FILE__, __LINE__,
"H5Tget_size() failed.");
859 BESDEBUG(
"h5",
"=print_attr(): H5T_STRING sm_buf=" << (
char *) sm_buf
860 <<
" size=" << str_size << endl);
864 buf =
new char[str_size + 1];
865 strncpy(buf, (
char *) sm_buf, str_size);
866 buf[str_size] =
'\0';
868 rep.resize(str_size+3);
869 snprintf(&rep[0], str_size + 3,
"%s", buf);
870 rep[str_size + 2] =
'\0';
871 delete[] buf; buf = 0;
874 if( buf )
delete[] buf;
884 string rep_str(rep.begin(),rep.end());
888 D4AttributeType daptype_strrep_to_dap4_attrtype(std::string s){
892 else if (s ==
"Int8")
894 else if (s ==
"UInt8")
896 else if (s ==
"Int16")
898 else if (s ==
"UInt16")
899 return attr_uint16_c;
900 else if (s ==
"Int32")
902 else if (s ==
"UInt32")
903 return attr_uint32_c;
904 else if (s ==
"Int64")
906 else if (s ==
"UInt64")
907 return attr_uint64_c;
908 else if (s ==
"Float32")
909 return attr_float32_c;
910 else if (s ==
"Float64")
911 return attr_float64_c;
912 else if (s ==
"String")
937 BaseType *Get_bt(
const string &vname,
939 const string &dataset,
940 hid_t datatype,
bool is_dap4)
942 BaseType *btp = NULL;
946 BESDEBUG(
"h5",
">Get_bt varname=" << vname <<
" datatype=" << datatype
950 H5T_sign_t sign = H5T_SGN_ERROR;
951 switch (H5Tget_class(datatype)) {
955 size = H5Tget_size(datatype);
956 sign = H5Tget_sign(datatype);
957 BESDEBUG(
"h5",
"=Get_bt() H5T_INTEGER size = " << size <<
" sign = "
960 if (sign == H5T_SGN_ERROR) {
961 throw InternalErr(__FILE__, __LINE__,
"cannot retrieve the sign type of the integer");
964 throw InternalErr(__FILE__, __LINE__,
"cannot return the size of the datatype");
966 else if (size == 1) {
968 if (sign == H5T_SGN_2) {
969 if (
false == is_dap4)
970 btp =
new HDF5Int16(vname, vpath, dataset);
972 btp =
new HDF5Int8(vname,vpath,dataset);
975 btp =
new HDF5Byte(vname, vpath,dataset);
977 else if (size == 2) {
978 if (sign == H5T_SGN_2)
979 btp =
new HDF5Int16(vname, vpath,dataset);
983 else if (size == 4) {
984 if (sign == H5T_SGN_2){
985 btp =
new HDF5Int32(vname, vpath,dataset);
990 else if (size == 8) {
991 if(
true == is_dap4) {
992 if(sign == H5T_SGN_2)
993 btp =
new HDF5Int64(vname,vpath, dataset);
999 InternalErr(__FILE__, __LINE__,
1000 string(
"Unsupported HDF5 64-bit Integer type:")
1009 size = H5Tget_size(datatype);
1010 BESDEBUG(
"h5",
"=Get_bt() H5T_FLOAT size = " << size << endl);
1013 throw InternalErr(__FILE__, __LINE__,
"cannot return the size of the datatype");
1015 else if (size == 4) {
1018 else if (size == 8) {
1025 btp =
new HDF5Str(vname, vpath,dataset);
1032 BaseType *ar_bt = 0;
1035 "=Get_bt() H5T_ARRAY datatype = " << datatype
1039 hid_t dtype_base = H5Tget_super(datatype);
1040 ar_bt = Get_bt(vname, dataset, dtype_base);
1041 btp =
new HDF5Array(vname, dataset, ar_bt);
1042 delete ar_bt; ar_bt = 0;
1045 int ndim = H5Tget_array_ndims(datatype);
1046 size = H5Tget_size(datatype);
1049 if (dtype_base < 0) {
1050 throw InternalErr(__FILE__, __LINE__,
"cannot return the base datatype");
1053 throw InternalErr(__FILE__, __LINE__,
"cannot return the rank of the array datatype");
1056 throw InternalErr(__FILE__, __LINE__,
"cannot return the size of the datatype");
1059 <<
"=Get_bt()" <<
" Dim = " << ndim
1060 <<
" Size = " << size
1064 if(H5Tget_array_dims(datatype, size2) < 0){
1066 InternalErr(__FILE__, __LINE__,
1067 string(
"Could not get array dims for: ")
1073 for (
int dim_index = 0; dim_index < ndim; dim_index++) {
1074 h5_ar.append_dim(size2[dim_index]);
1075 BESDEBUG(
"h5",
"=Get_bt() " << size2[dim_index] << endl);
1076 nelement = nelement * size2[dim_index];
1079 h5_ar.set_did(dt_inst.dset);
1081 h5_ar.set_tid(datatype);
1085 h5_ar.set_length(nelement);
1086 h5_ar.d_type = H5Tget_class(dtype_base);
1087 if (h5_ar.d_type == H5T_NO_CLASS){
1088 throw InternalErr(__FILE__, __LINE__,
"cannot return the datatype class identifier");
1092 if( ar_bt )
delete ar_bt;
1093 if( btp )
delete btp;
1102 btp =
new HDF5Url(vname, vpath,dataset);
1106 throw InternalErr(__FILE__, __LINE__,
1107 string(
"Unsupported HDF5 type: ") + vname);
1111 if( btp )
delete btp;
1116 throw InternalErr(__FILE__, __LINE__,
1117 string(
"Could not make a DAP variable for: ")
1120 BESDEBUG(
"h5",
"<Get_bt()" << endl);
1142 Structure *Get_structure(
const string &varname,
const string &vpath,
1143 const string &dataset,
1144 hid_t datatype,
bool is_dap4)
1147 char* memb_name = NULL;
1148 hid_t memb_type = -1;
1150 BESDEBUG(
"h5",
">Get_structure()" << datatype << endl);
1152 if (H5Tget_class(datatype) != H5T_COMPOUND)
1153 throw InternalErr(__FILE__, __LINE__,
1154 string(
"Compound-to-structure mapping error for ")
1161 int nmembs = H5Tget_nmembers(datatype);
1162 BESDEBUG(
"h5",
"=Get_structure() has " << nmembs << endl);
1164 throw InternalErr(__FILE__, __LINE__,
"cannot retrieve the number of elements");
1166 for (
int i = 0; i < nmembs; i++) {
1167 memb_name = H5Tget_member_name(datatype, i);
1168 H5T_class_t memb_cls = H5Tget_member_class(datatype, i);
1169 memb_type = H5Tget_member_type(datatype, i);
1170 if (memb_name == NULL){
1171 throw InternalErr(__FILE__, __LINE__,
"cannot retrieve the name of the member");
1173 if ((memb_cls < 0) || (memb_type < 0)) {
1174 throw InternalErr(__FILE__, __LINE__,
1175 string(
"Type mapping error for ")
1176 +
string(memb_name) );
1179 if (memb_cls == H5T_COMPOUND) {
1180 Structure *s = Get_structure(memb_name, memb_name, dataset, memb_type,is_dap4);
1181 structure_ptr->add_var(s);
1184 else if(memb_cls == H5T_ARRAY) {
1186 BaseType *ar_bt = 0;
1189 hid_t dtype_base = 0;
1194 dtype_base = H5Tget_super(memb_type);
1197 int ndim = H5Tget_array_ndims(memb_type);
1198 size_t size = H5Tget_size(memb_type);
1201 if (dtype_base < 0) {
1202 throw InternalErr(__FILE__, __LINE__,
"cannot return the base memb_type");
1205 throw InternalErr(__FILE__, __LINE__,
"cannot return the rank of the array memb_type");
1208 throw InternalErr(__FILE__, __LINE__,
"cannot return the size of the memb_type");
1212 if(H5Tget_array_dims(memb_type, size2) < 0){
1214 InternalErr(__FILE__, __LINE__,
1215 string(
"Could not get array dims for: ")
1216 +
string(memb_name));
1219 H5T_class_t array_memb_cls = H5Tget_class(dtype_base);
1220 if(array_memb_cls == H5T_NO_CLASS) {
1221 throw InternalErr(__FILE__, __LINE__,
1222 string(
"cannot get the correct class for compound type member")
1223 +
string(memb_name));
1225 if(H5T_COMPOUND == array_memb_cls) {
1227 s = Get_structure(memb_name, memb_name,dataset, dtype_base,is_dap4);
1230 for (
int dim_index = 0; dim_index < ndim; dim_index++) {
1231 h5_ar->append_dim(size2[dim_index]);
1232 nelement = nelement * size2[dim_index];
1238 h5_ar->set_length(nelement);
1240 structure_ptr->add_var(h5_ar);
1244 else if (H5T_INTEGER == array_memb_cls || H5T_FLOAT == array_memb_cls || H5T_STRING == array_memb_cls) {
1245 ar_bt = Get_bt(memb_name, memb_name,dataset, dtype_base,is_dap4);
1248 for (
int dim_index = 0; dim_index < ndim; dim_index++) {
1249 h5_ar->append_dim(size2[dim_index]);
1250 nelement = nelement * size2[dim_index];
1256 h5_ar->set_length(nelement);
1258 structure_ptr->add_var(h5_ar);
1261 if( ar_bt )
delete ar_bt;
1262 if( btp )
delete btp;
1264 H5Tclose(dtype_base);
1268 if( ar_bt )
delete ar_bt;
1269 if( btp )
delete btp;
1271 H5Tclose(dtype_base);
1276 else if (memb_cls == H5T_INTEGER || memb_cls == H5T_FLOAT || memb_cls == H5T_STRING) {
1277 BaseType *bt = Get_bt(memb_name, memb_name,dataset, memb_type,is_dap4);
1278 structure_ptr->add_var(bt);
1284 throw InternalErr(__FILE__, __LINE__,
"unsupported field datatype inside a compound datatype");
1287 if(memb_name != NULL)
1293 delete structure_ptr;
1294 if(memb_name!= NULL)
1297 H5Tclose(memb_type);
1301 BESDEBUG(
"h5",
"<Get_structure()" << endl);
1303 return structure_ptr;
1324 bool check_dimscale(hid_t fileid) {
1326 bool ret_value =
false;
1327 herr_t ret_o= H5Ovisit(fileid, H5_INDEX_NAME, H5_ITER_INC, visit_obj_cb, NULL);
1329 throw InternalErr(__FILE__, __LINE__,
"H5Ovisit fails");
1331 ret_value =(ret_o >0)?
true:
false;
1337 visit_obj_cb(hid_t group_id,
const char *name,
const H5O_info_t *oinfo,
1342 if(oinfo->type == H5O_TYPE_DATASET) {
1345 dataset = H5Dopen2(group_id,name,H5P_DEFAULT);
1347 throw InternalErr(__FILE__, __LINE__,
"H5Dopen2 fails in the H5Ovisit call back function.");
1350 dspace = H5Dget_space(dataset);
1353 throw InternalErr(__FILE__, __LINE__,
"H5Dget_space fails in the H5Ovisit call back function.");
1357 if(H5Sget_simple_extent_ndims(dspace) == 1) {
1359 if(
true == has_dimscale_attr(dataset))
1372 int dim_attr_mark[4];
1373 for(
int i =0;i<4;i++)
1374 dim_attr_mark[i] = 0;
1379 herr_t ret = H5Aiterate2(dataset, H5_INDEX_NAME, H5_ITER_INC, NULL, attr_info, dim_attr_mark);
1383 throw InternalErr(__FILE__, __LINE__,
"H5Aiterate2 fails in the H5Ovisit call back function.");
1386 BESDEBUG(
"h5",
"<dset name is " << name <<endl);
1389 if (dim_attr_mark[0] && dim_attr_mark[1]){
1408 bool has_dimscale_attr(hid_t dataset) {
1410 bool ret_value =
false;
1411 string dimscale_attr_name=
"CLASS";
1412 string dimscale_attr_value=
"DIMENSION_SCALE";
1413 htri_t dimscale_attr_exist = H5Aexists_by_name(dataset,
".",dimscale_attr_name.c_str(),H5P_DEFAULT);
1414 if(dimscale_attr_exist <0)
1415 throw InternalErr(__FILE__, __LINE__,
"H5Aexists_by_name fails when checking the CLASS attribute.");
1416 else if(dimscale_attr_exist > 0) {
1419 hid_t atype_id = -1;
1422 attr_id = H5Aopen(dataset,dimscale_attr_name.c_str(), H5P_DEFAULT);
1424 throw InternalErr(__FILE__, __LINE__,
"H5Aopen fails in the attr_info call back function.");
1427 atype_id = H5Aget_type(attr_id);
1430 throw InternalErr(__FILE__, __LINE__,
"H5Aget_type fails in the attr_info call back function.");
1435 if (H5T_STRING == H5Tget_class(atype_id))
1436 ret_value = check_str_attr_value(attr_id,atype_id,dimscale_attr_value,
false);
1469 attr_info_dimscale(hid_t loc_id,
const char *name,
const H5A_info_t *ainfo,
void *opdata)
1471 int *countp = (
int*)opdata;
1474 hid_t atype_id = -1;
1477 attr_id = H5Aopen(loc_id, name, H5P_DEFAULT);
1479 throw InternalErr(__FILE__, __LINE__,
"H5Aopen fails in the attr_info call back function.");
1482 atype_id = H5Aget_type(attr_id);
1485 throw InternalErr(__FILE__, __LINE__,
"H5Aget_type fails in the attr_info call back function.");
1492 if ((H5T_COMPOUND == H5Tget_class(atype_id)) && (strcmp(name,
"REFERENCE_LIST")==0)) {
1499 if (H5T_STRING == H5Tget_class(atype_id)) {
1500 if (strcmp(name,
"CLASS") == 0) {
1501 string dim_scale_mark =
"DIMENSION_SCALE";
1502 bool is_dim_scale = check_str_attr_value(attr_id,atype_id,dim_scale_mark,
false);
1503 if(
true == is_dim_scale)
1540 attr_info_dimscale(hid_t loc_id,
const char *name,
const H5A_info_t *ainfo,
void *opdata)
1544 int *dimattr_p = (
int*)opdata;
1547 bool has_reference_list =
false;
1548 bool has_dimscale =
false;
1549 bool has_name_as_var =
false;
1550 bool has_name_as_nc4_purdim =
false;
1555 hid_t atype_id = -1;
1558 attr_id = H5Aopen(loc_id, name, H5P_DEFAULT);
1560 throw InternalErr(__FILE__, __LINE__,
"H5Aopen fails in the attr_info call back function.");
1563 atype_id = H5Aget_type(attr_id);
1566 throw InternalErr(__FILE__, __LINE__,
"H5Aget_type fails in the attr_info call back function.");
1573 if ((H5T_COMPOUND == H5Tget_class(atype_id)) && (strcmp(name,
"REFERENCE_LIST")==0)) {
1580 if (H5T_STRING == H5Tget_class(atype_id)) {
1581 if (strcmp(name,
"NAME") == 0) {
1583 string pure_dimname_mark =
"This is a netCDF dimension but not a netCDF variable";
1584 bool is_pure_dim = check_str_attr_value(attr_id,atype_id,pure_dimname_mark,
true);
1586 BESDEBUG(
"h5",
"pure dimension name yes" << is_pure_dim <<endl);
1587 if(
true == is_pure_dim)
1593 ssize_t objnamelen = -1;
1594 if ((objnamelen= H5Iget_name(loc_id,NULL,0))<=0) {
1595 string msg =
"Cannot obtain the variable name length." ;
1596 throw InternalErr(__FILE__,__LINE__,msg);
1598 vector<char> objname;
1599 objname.resize(objnamelen+1);
1600 if ((objnamelen= H5Iget_name(loc_id,&objname[0],objnamelen+1))<=0) {
1601 string msg =
"Cannot obtain the variable name." ;
1602 throw InternalErr(__FILE__,__LINE__,msg);
1605 string objname_str = string(objname.begin(),objname.end());
1608 objname_str = objname_str.substr(0,objnamelen);
1610 string normal_dimname_mark = objname_str.substr(objname_str.find_last_of(
"/")+1);
1611 bool is_normal_dim = check_str_attr_value(attr_id,atype_id,normal_dimname_mark,
false);
1612 if(
true == is_normal_dim)
1620 H5T_str_t str_pad = H5Tget_strpad(atype_id);
1622 hid_t aspace_id = -1;
1623 aspace_id = H5Aget_space(attr_id);
1625 throw InternalErr(__FILE__, __LINE__,
"H5Aget_space fails in the attr_info call back function.");
1628 int ndims = H5Sget_simple_extent_ndims(aspace_id);
1634 vector<hsize_t> asize;
1635 vector<hsize_t> maxsize;
1636 asize.resize(ndims);
1637 maxsize.resize(ndims);
1643 if (H5Sget_simple_extent_dims(aspace_id, &asize[0], &maxsize[0])<0) {
1644 H5Sclose(aspace_id);
1645 throw InternalErr(__FILE__, __LINE__,
"Cannot obtain the dim. info in the H5Aiterate2 call back function.");
1649 for (
int j = 0; j < ndims; j++)
1653 size_t ty_size = H5Tget_size(atype_id);
1655 H5Sclose(aspace_id);
1656 throw InternalErr(__FILE__, __LINE__,
"Cannot obtain the type size in the H5Aiterate2 call back function.");
1659 size_t total_bytes = nelmts * ty_size;
1660 string total_vstring =
"";
1661 if(H5Tis_variable_str(atype_id) > 0) {
1664 vector<char> temp_buf;
1665 temp_buf.resize(total_bytes);
1667 if (H5Aread(attr_id, atype_id, &temp_buf[0]) < 0){
1668 H5Sclose(aspace_id);
1669 throw InternalErr(__FILE__,__LINE__,
"Cannot read the attribute in the H5Aiterate2 call back function");
1672 char *temp_bp = NULL;
1673 temp_bp = &temp_buf[0];
1674 char* onestring = NULL;
1676 for (
unsigned int temp_i = 0; temp_i <nelmts; temp_i++) {
1679 onestring =*(
char **)temp_bp;
1681 if(onestring!= NULL)
1682 total_vstring +=string(onestring);
1688 if ((&temp_buf[0]) != NULL) {
1690 if (H5Dvlen_reclaim(atype_id,aspace_id,H5P_DEFAULT,&temp_buf[0]) < 0) {
1691 H5Sclose(aspace_id);
1692 throw InternalErr(__FILE__,__LINE__,
"Cannot reclaim VL memory in the H5Aiterate2 call back function.");
1700 vector<char> temp_buf;
1701 temp_buf.resize(total_bytes);
1702 if (H5Aread(attr_id, atype_id, &temp_buf[0]) < 0){
1703 H5Sclose(aspace_id);
1704 throw InternalErr(__FILE__,__LINE__,
"Cannot read the attribute in the H5Aiterate2 call back function");
1706 string temp_buf_string(temp_buf.begin(),temp_buf.end());
1707 total_vstring = temp_buf_string.substr(0,total_bytes);
1710 if(str_pad != H5T_STR_ERROR)
1711 total_vstring = total_vstring.substr(0,total_vstring.size()-1);
1716 H5Sclose(aspace_id);
1717 if(total_vstring ==
"DIMENSION_SCALE"){
1750 htri_t has_dimension_list = -1;
1752 string dimlist_name =
"DIMENSION_LIST";
1753 has_dimension_list = H5Aexists(dset,dimlist_name.c_str());
1755 if(has_dimension_list > 0 && ndims > 0) {
1758 vector<hvl_t> vlbuf;
1759 vlbuf.resize(ndims);
1762 hid_t atype_id = -1;
1763 hid_t amemtype_id = -1;
1764 hid_t aspace_id = -1;
1765 hid_t ref_dset = -1;
1768 attr_id = H5Aopen(dset,dimlist_name.c_str(),H5P_DEFAULT);
1770 string msg =
"Cannot open the attribute " + dimlist_name +
" of HDF5 dataset "+ string(dt_inst_ptr->
name);
1771 throw InternalErr(__FILE__, __LINE__, msg);
1774 atype_id = H5Aget_type(attr_id);
1776 string msg =
"Cannot get the datatype of the attribute " + dimlist_name +
" of HDF5 dataset "+ string(dt_inst_ptr->
name);
1777 throw InternalErr(__FILE__, __LINE__, msg);
1780 amemtype_id = H5Tget_native_type(atype_id, H5T_DIR_ASCEND);
1781 if (amemtype_id < 0) {
1782 string msg =
"Cannot get the memory datatype of the attribute " + dimlist_name +
" of HDF5 dataset "+ string(dt_inst_ptr->
name);
1783 throw InternalErr(__FILE__, __LINE__, msg);
1787 if (H5Aread(attr_id,amemtype_id,&vlbuf[0]) <0) {
1788 string msg =
"Cannot obtain the referenced object for the variable " + string(dt_inst_ptr->
name);
1789 throw InternalErr(__FILE__, __LINE__, msg);
1792 vector<char> objname;
1795 for (
int i = 0; i < ndims; i++) {
1797 if(vlbuf[i].p == NULL) {
1798 stringstream sindex ;
1800 string msg =
"For variable " + string(dt_inst_ptr->
name) +
"; ";
1801 msg = msg +
"the dimension of which the index is "+ sindex.str() +
" doesn't exist. ";
1802 throw InternalErr(__FILE__, __LINE__, msg);
1805 rbuf =((hobj_ref_t*)vlbuf[i].p)[0];
1808 if ((ref_dset = H5RDEREFERENCE(attr_id, H5R_OBJECT, &rbuf)) < 0) {
1809 string msg =
"Cannot dereference from the DIMENSION_LIST attribute for the variable " + string(dt_inst_ptr->
name);
1810 throw InternalErr(__FILE__, __LINE__, msg);
1813 ssize_t objnamelen = -1;
1814 if ((objnamelen= H5Iget_name(ref_dset,NULL,0))<=0) {
1815 string msg =
"Cannot obtain the dimension name length for the variable " + string(dt_inst_ptr->
name);
1816 throw InternalErr(__FILE__,__LINE__,msg);
1819 objname.resize(objnamelen+1);
1820 if ((objnamelen= H5Iget_name(ref_dset,&objname[0],objnamelen+1))<=0) {
1822 string msg =
"Cannot obtain the dimension name for the variable " + string(dt_inst_ptr->
name);
1823 throw InternalErr(__FILE__,__LINE__,msg);
1826 string objname_str = string(objname.begin(),objname.end());
1829 string trim_objname = objname_str.substr(0,objnamelen);
1832 dt_inst_ptr->dimnames.push_back(trim_objname.substr(trim_objname.find_last_of(
"/")+1));
1833 dt_inst_ptr->dimnames_path.push_back(trim_objname);
1835 if(H5Dclose(ref_dset)<0) {
1836 throw InternalErr(__FILE__,__LINE__,
"Cannot close the HDF5 dataset in the function obtain_dimnames().");
1840 if(vlbuf.empty()==
false) {
1842 if ((aspace_id = H5Aget_space(attr_id)) < 0) {
1843 string msg =
"Cannot close the HDF5 attribute space successfully for <DIMENSION_LIST> of the variable "+string(dt_inst_ptr->
name);
1844 throw InternalErr(__FILE__,__LINE__,msg);
1847 if (H5Dvlen_reclaim(amemtype_id,aspace_id,H5P_DEFAULT,(
void*)&vlbuf[0])<0) {
1848 throw InternalErr(__FILE__,__LINE__,
"Cannot reclaim the variable length memory in the function obtain_dimnames()");
1851 H5Sclose(aspace_id);
1856 H5Tclose(amemtype_id);
1866 if(amemtype_id != -1)
1867 H5Tclose(amemtype_id);
1870 H5Sclose(aspace_id);
1882 void write_vlen_str_attrs(hid_t attr_id,hid_t ty_id,
DSattr_t * attr_inst_ptr,D4Attribute *d4_attr, AttrTable* d2_attr,
bool is_dap4){
1884 BESDEBUG(
"h5",
"attribute name " << attr_inst_ptr->
name <<endl);
1885 BESDEBUG(
"h5",
"attribute size " <<attr_inst_ptr->
need <<endl);
1886 BESDEBUG(
"h5",
"attribute type size " <<(
int)(H5Tget_size(ty_id))<<endl);
1888 hid_t temp_space_id = H5Aget_space(attr_id);
1889 BESDEBUG(
"h5",
"attribute calculated size "<<(
int)(H5Tget_size(ty_id)) *(
int)(H5Sget_simple_extent_npoints(temp_space_id)) <<endl);
1890 if(temp_space_id <0) {
1895 throw InternalErr(__FILE__, __LINE__,
"unable to read HDF5 attribute data");
1898 vector<char> temp_buf;
1900 temp_buf.resize((
size_t)attr_inst_ptr->
need);
1902 if (H5Aread(attr_id, ty_id, &temp_buf[0]) < 0) {
1905 H5Sclose(temp_space_id);
1908 throw InternalErr(__FILE__, __LINE__,
"unable to read HDF5 attribute data");
1912 temp_bp = &temp_buf[0];
1914 for (
unsigned int temp_i = 0; temp_i <attr_inst_ptr->
nelmts; temp_i++) {
1917 onestring =*(
char **)temp_bp;
1920 if (onestring !=NULL) {
1921 string tempstring(onestring);
1923 d4_attr->add_value(tempstring);
1925 d2_attr->append_attr(attr_inst_ptr->
name,
"String",tempstring);
1928 temp_bp +=H5Tget_size(ty_id);
1930 if (temp_buf.empty() !=
true) {
1933 herr_t ret_vlen_claim;
1934 ret_vlen_claim = H5Dvlen_reclaim(ty_id,temp_space_id,H5P_DEFAULT,&temp_buf[0]);
1935 if(ret_vlen_claim < 0){
1938 H5Sclose(temp_space_id);
1941 throw InternalErr(__FILE__, __LINE__,
"Cannot reclaim the memory buffer of the HDF5 variable length string.");
1946 H5Sclose(temp_space_id);
1949 bool check_str_attr_value(hid_t attr_id,hid_t atype_id,
const string & value_to_compare,
bool check_substr) {
1951 bool ret_value =
false;
1953 H5T_str_t str_pad = H5Tget_strpad(atype_id);
1954 if(str_pad == H5T_STR_ERROR)
1955 throw InternalErr(__FILE__, __LINE__,
"Fail to obtain string pad.");
1957 hid_t aspace_id = -1;
1958 aspace_id = H5Aget_space(attr_id);
1960 throw InternalErr(__FILE__, __LINE__,
"Fail to obtain attribute space.");
1962 int ndims = H5Sget_simple_extent_ndims(aspace_id);
1964 H5Sclose(aspace_id);
1965 throw InternalErr(__FILE__, __LINE__,
"Fail to obtain number of dimensions.");
1973 vector<hsize_t> asize;
1974 asize.resize(ndims);
1975 if (H5Sget_simple_extent_dims(aspace_id, &asize[0], NULL)<0) {
1976 H5Sclose(aspace_id);
1977 throw InternalErr(__FILE__, __LINE__,
"Fail to obtain the dimension info.");
1981 for (
int j = 0; j < ndims; j++)
1985 size_t ty_size = H5Tget_size(atype_id);
1987 H5Sclose(aspace_id);
1988 throw InternalErr(__FILE__, __LINE__,
"Fail to obtain the type size.");
1991 size_t total_bytes = nelmts * ty_size;
1992 string total_vstring =
"";
1993 if(H5Tis_variable_str(atype_id) > 0) {
1996 vector<char> temp_buf;
1997 temp_buf.resize(total_bytes);
1999 if (H5Aread(attr_id, atype_id, &temp_buf[0]) < 0){
2000 H5Sclose(aspace_id);
2001 throw InternalErr(__FILE__,__LINE__,
"Fail to read the attribute.");
2004 char *temp_bp = NULL;
2005 temp_bp = &temp_buf[0];
2006 char* onestring = NULL;
2008 for (
unsigned int temp_i = 0; temp_i <nelmts; temp_i++) {
2011 onestring =*(
char **)temp_bp;
2013 if(onestring!= NULL)
2014 total_vstring +=string(onestring);
2020 if ((&temp_buf[0]) != NULL) {
2022 if (H5Dvlen_reclaim(atype_id,aspace_id,H5P_DEFAULT,&temp_buf[0]) < 0) {
2023 H5Sclose(aspace_id);
2024 throw InternalErr(__FILE__,__LINE__,
"Fail to reclaim VL memory.");
2032 vector<char> temp_buf;
2033 temp_buf.resize(total_bytes);
2034 if (H5Aread(attr_id, atype_id, &temp_buf[0]) < 0){
2035 H5Sclose(aspace_id);
2036 throw InternalErr(__FILE__,__LINE__,
"Fail to read the attribute.");
2038 string temp_buf_string(temp_buf.begin(),temp_buf.end());
2039 total_vstring = temp_buf_string.substr(0,total_bytes);
2042 if(str_pad != H5T_STR_ERROR)
2043 total_vstring = total_vstring.substr(0,total_vstring.size()-1);
2048 H5Sclose(aspace_id);
2050 if(
false == check_substr) {
2051 if(total_vstring == value_to_compare)
2055 if(total_vstring.size()>=value_to_compare.size()) {
2056 if( 0 == total_vstring.compare(0,value_to_compare.size(),value_to_compare))
A class for handling all types of array in HDF5 for the default option.
This class provides a way to map HDF5 byte to DAP Byte for the default option.
A class for mapping HDF5 32-bit float to DAP for the default option.
A class for mapping HDF5 64-bit float to DAP for the default option.
A class for HDF5 signed 16 bit integer type.
This class provides a way to map HDF5 32 bit integer to DAP Int32 for the default option.
This class provides a way to map HDF5 Int64 to DAP Int64 for the default option.
This class provides a way to map HDF5 int8 to DAP Int8 for the default option.
include the entry functions to execute the handlers
This class that translates HDF5 string into DAP string for the default option.
This class converts HDF5 compound type into DAP structure for the default option.
This class provides a way to map unsigned HDF5 16 bit integer to DAP UInt16 for the default option.
This class provides a way to map unsigned HDF5 32 bit integer to DAP UInt32.
This class provides a way to map HDF5 uint64 to DAP UInt64 for the default option.
This class generates DAP URL type for the default option.
void set_numdim(int ndims)
remembers number of dimensions of this array.
void set_numelm(int nelms)
remembers number of elements in this array.
void set_memneed(size_t need)
remembers memory size needed.
string print_attr(hid_t type, int loc, void *sm_buf)
bool check_h5str(hid_t h5type)
hid_t get_fileid(const char *filename)
string get_dap_type(hid_t type, bool is_dap4)
void close_fileid(hid_t fid)
void obtain_dimnames(hid_t dset, int ndims, DS_t *dt_inst_ptr)
void get_dataset(hid_t pid, const string &dname, DS_t *dt_inst_ptr)
hid_t get_attr_info(hid_t dset, int index, bool is_dap4, DSattr_t *attr_inst_ptr, bool *ignore_attr_ptr)
const int DODS_MAX_RANK
Maximum number of dimensions in an array(default option only).
A structure for DDS generation.
char name[DODS_NAMELEN]
Name of HDF5 group or dataset.
A structure for DAS generation.
char name[DODS_NAMELEN]
Name of HDF5 group or dataset.
hsize_t nelmts
Number of elements.
hsize_t need
Memory space needed to hold nelmts type.