35#include "config_hdf5.h"
44#include <libdap/Error.h>
45#include <libdap/InternalErr.h>
65HDF5Array::~HDF5Array() {
68int HDF5Array::format_constraint(
int *offset,
int *step,
int *count) {
78 Dim_iter p = dim_begin();
80 while (p != dim_end()) {
82 int start = dimension_start(p,
true);
83 int stride = dimension_stride(p,
true);
84 int stop = dimension_stop(p,
true);
90 oss <<
"Array/Grid hyperslab start point "<< start <<
91 " is greater than stop point " << stop <<
".";
92 throw Error(malformed_expr, oss.str());
97 count[id] = ((stop - start) / stride) + 1;
101 "=format_constraint():"
102 <<
"id=" <<
id <<
" offset=" << offset[
id]
103 <<
" step=" << step[
id]
104 <<
" count=" << count[
id]
118 ">read() dataset=" << dataset()
119 <<
" dimension=" << d_num_dim
120 <<
" data_size=" << d_memneed <<
" length=" << length()
123 hid_t file_id = H5Fopen(dataset().c_str(),H5F_ACC_RDONLY,H5P_DEFAULT);
125 BESDEBUG(
"h5",
"after H5Fopen "<<endl);
126 BESDEBUG(
"h5",
"variable name is "<<name() <<endl);
127 BESDEBUG(
"h5",
"variable path is "<<var_path <<endl);
131 if(
true == is_dap4())
132 dset_id = H5Dopen2(file_id,var_path.c_str(),H5P_DEFAULT);
134 dset_id = H5Dopen2(file_id,name().c_str(),H5P_DEFAULT);
136 BESDEBUG(
"h5",
"after H5Dopen2 "<<endl);
139 hid_t dspace_id = H5Dget_space(dset_id);
143 throw InternalErr(__FILE__,__LINE__,
"Fail to obtain the dataspace .");
146 int num_dim = H5Sget_simple_extent_ndims(dspace_id);
151 throw InternalErr(__FILE__,__LINE__,
"Fail to obtain the datatype .");
157 hid_t dtype_id = H5Dget_type(dset_id);
161 throw InternalErr(__FILE__,__LINE__,
"Fail to obtain the datatype .");
165 vector<int> offset(d_num_dim);
166 vector<int> count(d_num_dim);
167 vector<int> step(d_num_dim);
168 int nelms = format_constraint(&offset[0], &step[0], &count[0]);
174 bool ret_ref =
false;
176 ret_ref = m_array_of_reference(dset_id,dtype_id);
193 do_array_read(dset_id,dtype_id,values,
false,0,nelms,&offset[0],&count[0],&step[0]);
209void HDF5Array::do_array_read(hid_t dset_id,hid_t dtype_id,vector<char>&values,
bool has_values,
int values_offset,
210 int nelms,
int* offset,
int* count,
int* step)
213 H5T_class_t tcls = H5Tget_class(dtype_id);
215 if(H5T_COMPOUND == tcls)
216 m_array_of_structure(dset_id,values,has_values,values_offset,nelms,offset,count,step);
217 else if(H5T_INTEGER == tcls || H5T_FLOAT == tcls || H5T_STRING == tcls)
218 m_array_of_atomic(dset_id,dtype_id,nelms,offset,count,step);
220 throw InternalErr(__FILE__,__LINE__,
"Fail to read the data for Unsupported datatype.");
225void HDF5Array:: m_array_of_atomic(hid_t dset_id, hid_t dtype_id,
226 int nelms,
int* offset,
int* count,
int* step)
230 if((memtype = H5Tget_native_type(dtype_id, H5T_DIR_ASCEND))<0) {
231 throw InternalErr (__FILE__, __LINE__,
"Fail to obtain memory datatype.");
235 if (H5Tis_variable_str(memtype) && H5Tget_class(memtype) == H5T_STRING) {
237 vector<hsize_t> hoffset;
238 vector<hsize_t>hcount;
239 vector<hsize_t>hstep;
240 hoffset.resize(d_num_dim);
241 hcount.resize(d_num_dim);
242 hstep.resize(d_num_dim);
243 for (
int i = 0; i <d_num_dim; i++) {
244 hoffset[i] = (hsize_t) offset[i];
245 hcount[i] = (hsize_t) count[i];
246 hstep[i] = (hsize_t) step[i];
249 vector<string>finstrval;
250 finstrval.resize(nelms);
252 read_vlen_string(dset_id, nelms, &hoffset[0], &hstep[0], &hcount[0],finstrval);
256 throw InternalErr(__FILE__,__LINE__,
"Fail to read variable-length string.");
258 set_value(finstrval,nelms);
264 if (nelms == d_num_elm) {
266 vector<char> convbuf(d_memneed);
267 get_data(dset_id, (
void *) &convbuf[0]);
270 if(
false == is_dap4()) {
271 if (1 == H5Tget_size(memtype) && H5T_SGN_2 == H5Tget_sign(memtype))
273 vector<short> convbuf2(nelms);
274 for (
int i = 0; i < nelms; i++) {
275 convbuf2[i] = (
signed char) (convbuf[i]);
276 BESDEBUG(
"h5",
"convbuf[" << i <<
"]="
277 << (
signed char)convbuf[i] << endl);
278 BESDEBUG(
"h5",
"convbuf2[" << i <<
"]="
279 << convbuf2[i] << endl)
283 m_intern_plain_array_data((
char*) &convbuf2[0],memtype);
286 m_intern_plain_array_data(&convbuf[0],memtype);
289 m_intern_plain_array_data(&convbuf[0],memtype);
292 size_t data_size = nelms * H5Tget_size(memtype);
293 if (data_size == 0) {
294 throw InternalErr(__FILE__, __LINE__,
"get_size failed");
296 vector<char> convbuf(data_size);
297 get_slabdata(dset_id, &offset[0], &step[0], &count[0], d_num_dim, &convbuf[0]);
300 if(
false == is_dap4()){
301 if (1 == H5Tget_size(memtype) && H5T_SGN_2 == H5Tget_sign(memtype)) {
302 vector<short> convbuf2(data_size);
303 for (
int i = 0; i < (
int)data_size; i++) {
304 convbuf2[i] =
static_cast<signed char> (convbuf[i]);
306 m_intern_plain_array_data((
char*) &convbuf2[0],memtype);
309 m_intern_plain_array_data(&convbuf[0],memtype);
313 m_intern_plain_array_data(&convbuf[0],memtype);
325bool HDF5Array::m_array_of_structure(hid_t dsetid, vector<char>&values,
bool has_values,
int values_offset,
326 int nelms,
int* offset,
int* count,
int* step) {
328 BESDEBUG(
"h5",
"=read() Array of Structure length=" << length() << endl);
335 if((dtypeid = H5Dget_type(dsetid)) < 0)
336 throw InternalErr (__FILE__, __LINE__,
"Cannot obtain the datatype.");
338 if((memtype = H5Tget_native_type(dtypeid, H5T_DIR_ASCEND))<0) {
340 throw InternalErr (__FILE__, __LINE__,
"Fail to obtain memory datatype.");
343 ty_size = H5Tget_size(memtype);
347 throw InternalErr (__FILE__, __LINE__,
"Fail to obtain the size of HDF5 compound datatype.");
350 if(
false == has_values) {
354 if ((dspace = H5Dget_space(dsetid))<0) {
357 throw InternalErr (__FILE__, __LINE__,
"Cannot obtain data space.");
360 d_num_dim = H5Sget_simple_extent_ndims(dspace);
365 throw InternalErr (__FILE__, __LINE__,
"Cannot obtain the number of dimensions of the data space.");
368 vector<hsize_t> hoffset;
369 vector<hsize_t>hcount;
370 vector<hsize_t>hstep;
371 hoffset.resize(d_num_dim);
372 hcount.resize(d_num_dim);
373 hstep.resize(d_num_dim);
374 for (
int i = 0; i <d_num_dim; i++) {
375 hoffset[i] = (hsize_t) offset[i];
376 hcount[i] = (hsize_t) count[i];
377 hstep[i] = (hsize_t) step[i];
380 if (H5Sselect_hyperslab(dspace, H5S_SELECT_SET,
381 &hoffset[0], &hstep[0],
382 &hcount[0], NULL) < 0) {
386 throw InternalErr (__FILE__, __LINE__,
"Cannot generate the hyperslab of the HDF5 dataset.");
389 mspace = H5Screate_simple(d_num_dim, &hcount[0],NULL);
394 throw InternalErr (__FILE__, __LINE__,
"Cannot create the memory space.");
397 values.resize(nelms*ty_size);
399 read_ret = H5Dread(dsetid,memtype,mspace,dspace,H5P_DEFAULT,(
void*)&values[0]);
404 throw InternalErr (__FILE__, __LINE__,
"Fail to read the HDF5 compound datatype dataset.");
413 char* memb_name = NULL;
418 for (
int element = 0; element < nelms; ++element) {
421 H5T_class_t memb_cls = H5T_NO_CLASS;
423 size_t memb_offset = 0;
425 if((nmembs = H5Tget_nmembers(memtype)) < 0)
426 throw InternalErr (__FILE__, __LINE__,
"Fail to obtain number of HDF5 compound datatype.");
428 for(
unsigned int u = 0; u < (unsigned)nmembs; u++) {
431 if((memb_id = H5Tget_member_type(memtype, u)) < 0)
432 throw InternalErr (__FILE__, __LINE__,
"Fail to obtain the datatype of an HDF5 compound datatype member.");
435 if((memb_cls = H5Tget_member_class (memtype, u)) < 0)
436 throw InternalErr (__FILE__, __LINE__,
"Fail to obtain the datatype class of an HDF5 compound datatype member.");
441 memb_offset= H5Tget_member_offset(memtype,u);
444 memb_name = H5Tget_member_name(memtype,u);
445 if(memb_name == NULL)
446 throw InternalErr (__FILE__, __LINE__,
"Fail to obtain the name of an HDF5 compound datatype member.");
448 BaseType *field = h5s->var(memb_name);
449 if (memb_cls == H5T_COMPOUND) {
451 memb_h5s.do_structure_read(dsetid, memb_id,values,has_values,memb_offset+values_offset+ty_size*element);
454 else if(memb_cls == H5T_ARRAY) {
457 int at_ndims = H5Tget_array_ndims(memb_id);
459 throw InternalErr (__FILE__, __LINE__,
"Fail to obtain number of dimensions of the array datatype.");
465 vector<int> at_offset(at_ndims,0);
466 vector<int> at_count(at_ndims,0);
467 vector<int> at_step(at_ndims,0);
469 int at_nelms = h5_array_type.format_constraint(&at_offset[0],&at_step[0],&at_count[0]);
472 h5_array_type.do_h5_array_type_read(dsetid,memb_id,values,has_values,memb_offset+values_offset+ty_size*element,
473 at_nelms,&at_offset[0],&at_count[0],&at_step[0]);
476 else if(memb_cls == H5T_INTEGER || memb_cls == H5T_FLOAT) {
478 if(
true == promote_char_to_short(memb_cls,memb_id)) {
479 void *src = (
void*)(&values[0] + (element*ty_size) + values_offset +memb_offset);
481 memcpy(&val_int8,src,1);
482 short val_short=(short)val_int8;
483 field->val2buf(&val_short);
486 field->val2buf(&values[0] + (element*ty_size) + values_offset +memb_offset);
490 else if(memb_cls == H5T_STRING) {
493 if(
true == H5Tis_variable_str(memb_id)) {
494 void *src = (
void*)(&values[0]+(element*ty_size)+values_offset + memb_offset);
496 get_vlen_str_data((
char*)src,final_str);
497 field->val2buf(&final_str);
500 void *src = (
void*)(&values[0]+(element*ty_size)+values_offset + memb_offset);
501 vector<char> str_val;
502 size_t memb_size = H5Tget_size(memb_id);
503 if (memb_size == 0) {
505 H5free_memory(memb_name);
507 throw InternalErr (__FILE__, __LINE__,
"Fail to obtain the size of HDF5 compound datatype.");
509 str_val.resize(memb_size);
510 memcpy(&str_val[0],src,memb_size);
511 string temp_string(str_val.begin(),str_val.end());
512 field->val2buf(&temp_string);
516 H5free_memory(memb_name);
519 throw InternalErr (__FILE__, __LINE__,
520 "Only support the field of compound datatype when the field type class is integer, float, string, array or compound..");
526 H5free_memory(memb_name);
527 field->set_read_p(
true);
529 h5s->set_read_p(
true);
530 set_vec(element,h5s);
534 if(
true == has_values) {
536 throw InternalErr(__FILE__, __LINE__,
"memory type and memory space for this compound datatype should be valid.");
538 if(H5Dvlen_reclaim(memtype,mspace,H5P_DEFAULT,(
void*)&values[0])<0)
539 throw InternalErr(__FILE__, __LINE__,
"Unable to reclaim the compound datatype array.");
552 if(memb_name != NULL)
553 H5free_memory(memb_name);
556 if(
true == has_values) {
557 if(H5Dvlen_reclaim(memtype,mspace,H5P_DEFAULT,(
void*)(&values[0]))<0) {
575bool HDF5Array::m_array_of_reference(hid_t dset_id,hid_t dtype_id)
578#if (H5_VERS_MAJOR == 1 && (H5_VERS_MINOR == 10 || H5_VERS_MINOR == 8 || H5_VERS_MINOR == 6))
579 hid_t d_dset_id = dset_id;
580 hdset_reg_ref_t *rbuf = NULL;
584 vector<int> offset(d_num_dim);
585 vector<int> count(d_num_dim);
586 vector<int> step(d_num_dim);
589 int nelms = format_constraint(&offset[0], &step[0], &count[0]);
590 vector<string> v_str(nelms);
592 BESDEBUG(
"h5",
"=read() URL type is detected. "
593 <<
"nelms=" << nelms <<
" full_size=" << d_num_elm << endl);
597 if (H5Tequal(dtype_id, H5T_STD_REF_DSETREG) < 0) {
598 throw InternalErr(__FILE__, __LINE__,
"H5Tequal() failed");
601 if (H5Tequal(dtype_id, H5T_STD_REF_DSETREG) > 0) {
602 BESDEBUG(
"h5",
"=read() Got regional reference. " << endl);
604 rbuf =
new hdset_reg_ref_t[d_num_elm];
606 throw InternalErr(__FILE__, __LINE__,
"new() failed.");
608 if (H5Dread(d_dset_id, H5T_STD_REF_DSETREG, H5S_ALL, H5S_ALL, H5P_DEFAULT, &rbuf[0]) < 0) {
609 throw InternalErr(__FILE__, __LINE__,
"H5Dread() failed.");
612 for (
int i = 0; i < nelms; i++) {
614 BESDEBUG(
"h5",
"=read() rbuf[" << i <<
"]" <<
615 rbuf[offset[0] + i * step[0]] << endl);
617 if (rbuf[offset[0] + i * step[0]][0] !=
'\0') {
620 hid_t did_r = H5RDEREFERENCE(d_dset_id, H5R_DATASET_REGION, rbuf[offset[0] + i * step[0]]);
622 throw InternalErr(__FILE__, __LINE__,
"H5RDEREFERENCE() failed.");
626 if (H5Iget_name(did_r, (
char *) r_name,
DODS_NAMELEN) < 0) {
627 throw InternalErr(__FILE__, __LINE__,
"H5Iget_name() failed.");
629 BESDEBUG(
"h5",
"=read() dereferenced name is " << r_name
632 string varname(r_name);
633 hid_t space_id = H5Rget_region(did_r, H5R_DATASET_REGION, rbuf[offset[0] + i * step[0]]);
635 throw InternalErr(__FILE__, __LINE__,
"H5Rget_region() failed.");
639 int ndim = H5Sget_simple_extent_ndims(space_id);
641 throw InternalErr(__FILE__, __LINE__,
"H5Sget_simple_extent_ndims() failed.");
644 BESDEBUG(
"h5",
"=read() dim is " << ndim << endl);
647 switch (H5Sget_select_type(space_id)) {
650 BESDEBUG(
"h5",
"=read() None selected." << endl);
653 case H5S_SEL_POINTS: {
654 BESDEBUG(
"h5",
"=read() Points selected." << endl);
655 hssize_t npoints = H5Sget_select_npoints(space_id);
657 throw InternalErr(__FILE__, __LINE__,
658 "Cannot determine number of elements in the dataspace selection");
661 BESDEBUG(
"h5",
"=read() npoints are " << npoints
663 vector<hsize_t> buf(npoints * ndim);
664 if (H5Sget_select_elem_pointlist(space_id, 0, npoints, &buf[0]) < 0) {
665 throw InternalErr(__FILE__, __LINE__,
"H5Sget_select_elem_pointlist() failed.");
669 for (
int j = 0; j < npoints * ndim; j++) {
670 "h5",
"=read() npoints buf[0] =" << buf[j] <<endl;
674 for (
int j = 0; j < (
int) npoints; j++) {
676 expression.append(varname);
677 for (
int k = 0; k < ndim; k++) {
679 oss <<
"[" << (
int) buf[j * ndim + k] <<
"]";
680 expression.append(oss.str());
682 if (j != (
int) (npoints - 1)) {
683 expression.append(
",");
686 v_str[i].append(expression);
690 case H5S_SEL_HYPERSLABS: {
691 vector<hsize_t> start(ndim);
692 vector<hsize_t> end(ndim);
693 vector<hsize_t>stride(ndim);
694 vector<hsize_t>count(ndim);
695 vector<hsize_t>block(ndim);
697 BESDEBUG(
"h5",
"=read() Slabs selected." << endl);
698 BESDEBUG(
"h5",
"=read() nblock is " <<
699 H5Sget_select_hyper_nblocks(space_id) << endl);
701#if (H5_VERS_MAJOR == 1 && H5_VERS_MINOR == 8)
702 if (H5Sget_select_bounds(space_id, &start[0], &end[0]) < 0) {
703 throw InternalErr(__FILE__, __LINE__,
"H5Sget_select_bounds() failed.");
706 if (H5Sget_regular_hyperslab(space_id, &start[0], &stride[0], &count[0], &block[0]) < 0) {
707 throw InternalErr(__FILE__, __LINE__,
"H5Sget_regular_hyperslab() failed.");
711 for (
int j = 0; j < ndim; j++) {
713 BESDEBUG(
"h5",
"start " << start[j]
714 <<
"stride "<<stride[j]
715 <<
"count "<< count[j]
716 <<
"block "<< block[j]
720 end[j] = start[j] + stride[j]*(count[j]-1)+(block[j]-1);
721 BESDEBUG(
"h5",
"=read() start is " << start[j]
722 <<
"=read() end is " << end[j] << endl);
723 oss <<
"[" << start[j] <<
":" << stride[j] <<
":" << end[j] <<
"]";
724 expression.append(oss.str());
725 BESDEBUG(
"h5",
"=read() expression is "
726 << expression << endl)
730 if (!expression.empty()) {
731 v_str[i].append(expression);
737 BESDEBUG(
"h5",
"=read() All selected." << endl);
741 BESDEBUG(
"h5",
"Unknown space type." << endl);
754 if (H5Tequal(dtype_id, H5T_STD_REF_OBJ) < 0) {
755 throw InternalErr(__FILE__, __LINE__,
"H5Tequal() failed.");
758 if (H5Tequal(dtype_id, H5T_STD_REF_OBJ) > 0) {
759 BESDEBUG(
"h5",
"=read() Got object reference. " << endl);
760 vector<hobj_ref_t> orbuf;
761 orbuf.resize(d_num_elm);
762 if (H5Dread(d_dset_id, H5T_STD_REF_OBJ, H5S_ALL, H5S_ALL, H5P_DEFAULT, &orbuf[0]) < 0) {
763 throw InternalErr(__FILE__, __LINE__,
"H5Dread failed()");
766 for (
int i = 0; i < nelms; i++) {
768 hid_t did_r = H5RDEREFERENCE(d_dset_id, H5R_OBJECT, &orbuf[offset[0] + i * step[0]]);
770 throw InternalErr(__FILE__, __LINE__,
"H5RDEREFERENCE() failed.");
773 if (H5Iget_name(did_r, (
char *) r_name,
DODS_NAMELEN) < 0) {
774 throw InternalErr(__FILE__, __LINE__,
"H5Iget_name() failed.");
778 string varname(r_name);
780 BESDEBUG(
"h5",
"=read() dereferenced name is " << r_name <<endl);
784 set_value(&v_str[0], nelms);
793 return m_array_of_reference_new_h5_apis(dset_id,dtype_id);
798bool HDF5Array::m_array_of_reference_new_h5_apis(hid_t dset_id,hid_t dtype_id) {
800#if (H5_VERS_MAJOR == 1 && (H5_VERS_MINOR == 10 || H5_VERS_MINOR == 8 || H5_VERS_MINOR == 6))
801 throw InternalErr(__FILE__, __LINE__,
802 "The HDF5 handler compiled with earlier version (<=110)of the HDF5 library should not call method that uses new reference APIs");
806 H5R_ref_t *rbuf = NULL;
813 vector<int> offset(d_num_dim);
814 vector<int> count(d_num_dim);
815 vector<int> step(d_num_dim);
816 vector<hsize_t> hoffset(d_num_dim);
817 vector<hsize_t>hcount(d_num_dim);
818 vector<hsize_t>hstep(d_num_dim);
820 int nelms = format_constraint(&offset[0], &step[0], &count[0]);
821 for (
int i = 0; i <d_num_dim; i++) {
822 hoffset[i] = (hsize_t) offset[i];
823 hcount[i] = (hsize_t) count[i];
824 hstep[i] = (hsize_t) step[i];
827 BESDEBUG(
"h5",
"=read() URL type is detected. "
828 <<
"nelms=" << nelms << endl);
830 rbuf =
new H5R_ref_t[nelms];
832 file_space_id = H5Dget_space(dset_id);
833 if(file_space_id < 0)
834 throw InternalErr(__FILE__, __LINE__,
"Fail to obtain reference dataset file space.");
836 if (H5Sselect_hyperslab(file_space_id, H5S_SELECT_SET,
837 &hoffset[0], &hstep[0],
838 &hcount[0], NULL) < 0)
839 throw InternalErr (__FILE__, __LINE__,
"Fail to select the hyperslab for reference dataset.");
842 mem_space_id = H5Screate_simple(d_num_dim,&hcount[0],NULL);
844 throw InternalErr(__FILE__, __LINE__,
"Fail to obtain reference dataset memory space.");
846 if(H5Dread(dset_id,H5T_STD_REF,mem_space_id,file_space_id,H5P_DEFAULT,&rbuf[0])<0)
847 throw InternalErr(__FILE__, __LINE__,
"Fail to read hyperslab reference dataset.");
849 H5Sclose(mem_space_id);
850 H5Sclose(file_space_id);
853 vector<string> v_str;
855 H5R_type_t ref_type = H5Rget_type((
const H5R_ref_t *)&rbuf[0]);
858 if(ref_type != H5R_OBJECT2 && ref_type !=H5R_DATASET_REGION2)
859 throw InternalErr(__FILE__, __LINE__,
"Unsupported reference: neither object nor region references");
861 for (
int i = 0; i < nelms; i++) {
863 hid_t obj_id = H5Ropen_object((H5R_ref_t *)&rbuf[i], H5P_DEFAULT, H5P_DEFAULT);
865 throw InternalErr(__FILE__, __LINE__,
"Cannot open the object the reference points to");
867 vector<char> objname;
868 ssize_t objnamelen = -1;
869 if ((objnamelen= H5Iget_name(obj_id,NULL,0))<=0) {
871 throw InternalErr(__FILE__, __LINE__,
"Cannot obtain the name length of the object the reference points to");
873 objname.resize(objnamelen+1);
874 if ((objnamelen= H5Iget_name(obj_id,&objname[0],objnamelen+1))<=0) {
876 throw InternalErr(__FILE__, __LINE__,
"Cannot obtain the name length of the object the reference points to");
879 string objname_str = string(objname.begin(),objname.end());
880 string trim_objname = objname_str.substr(0,objnamelen);
883 if(ref_type == H5R_OBJECT2)
884 v_str.push_back(trim_objname);
887 if(H5Rget_obj_type3((H5R_ref_t *)&rbuf[i], H5P_DEFAULT, &obj_type) < 0){
889 throw InternalErr(__FILE__, __LINE__,
"H5Rget_obj_type3() failed.");
891 if(obj_type != H5O_TYPE_DATASET) {
893 throw InternalErr(__FILE__, __LINE__,
"Region reference must point to a dataset.");
895 hid_t region_space_id = H5Ropen_region(&rbuf[i],H5P_DEFAULT,H5P_DEFAULT);
896 if (region_space_id < 0) {
898 throw InternalErr(__FILE__, __LINE__,
"Cannot obtain the space ID the reference points to");
901 int ndim = H5Sget_simple_extent_ndims(region_space_id);
903 H5Sclose(region_space_id);
905 throw InternalErr(__FILE__, __LINE__,
"H5Sget_simple_extent_ndims() failed.");
909 switch (H5Sget_select_type(region_space_id)) {
912 BESDEBUG(
"h5",
"=read() None selected." << endl);
915 case H5S_SEL_POINTS: {
916 BESDEBUG(
"h5",
"=read() Points selected." << endl);
917 hssize_t npoints = H5Sget_select_npoints(region_space_id);
919 H5Sclose(region_space_id);
921 throw InternalErr(__FILE__, __LINE__,
922 "Cannot determine number of elements in the dataspace selection");
925 BESDEBUG(
"h5",
"=read() npoints are " << npoints
927 vector<hsize_t> buf(npoints * ndim);
928 if (H5Sget_select_elem_pointlist(region_space_id, 0, npoints, &buf[0]) < 0) {
929 H5Sclose(region_space_id);
931 throw InternalErr(__FILE__, __LINE__,
"H5Sget_select_elem_pointlist() failed.");
935 for (
int j = 0; j < npoints * ndim; j++) {
936 "h5",
"=read() npoints buf[0] =" << buf[j] <<endl;
940 for (
int j = 0; j < (
int) npoints; j++) {
942 expression.append(trim_objname);
943 for (
int k = 0; k < ndim; k++) {
945 oss <<
"[" << (
int) buf[j * ndim + k] <<
"]";
946 expression.append(oss.str());
948 if (j != (
int) (npoints - 1)) {
949 expression.append(
",");
952 v_str.push_back(expression);
956 case H5S_SEL_HYPERSLABS: {
957 vector<hsize_t> start(ndim);
958 vector<hsize_t> end(ndim);
959 vector<hsize_t>stride(ndim);
960 vector<hsize_t>count(ndim);
961 vector<hsize_t>block(ndim);
963 BESDEBUG(
"h5",
"=read() Slabs selected." << endl);
964 BESDEBUG(
"h5",
"=read() nblock is " <<
965 H5Sget_select_hyper_nblocks(region_space_id) << endl);
967 if (H5Sget_regular_hyperslab(region_space_id, &start[0], &stride[0], &count[0], &block[0]) < 0) {
968 H5Sclose(region_space_id);
970 throw InternalErr(__FILE__, __LINE__,
"H5Sget_regular_hyperslab() failed.");
973 expression.append(trim_objname);
974 for (
int j = 0; j < ndim; j++) {
976 BESDEBUG(
"h5",
"start " << start[j]
977 <<
"stride "<<stride[j]
978 <<
"count "<< count[j]
979 <<
"block "<< block[j]
983 end[j] = start[j] + stride[j]*(count[j]-1)+(block[j]-1);
984 BESDEBUG(
"h5",
"=read() start is " << start[j]
985 <<
"=read() end is " << end[j] << endl);
986 oss <<
"[" << start[j] <<
":" << stride[j] <<
":" << end[j] <<
"]";
987 expression.append(oss.str());
988 BESDEBUG(
"h5",
"=read() expression is "
989 << expression << endl)
992 v_str.push_back(expression);
997 BESDEBUG(
"h5",
"=read() All selected." << endl);
1001 BESDEBUG(
"h5",
"Unknown space type." << endl);
1004 H5Sclose(region_space_id);
1008 for (
int i = 0; i<nelms; i++)
1009 H5Rdestroy(&rbuf[i]);
1011 H5Sclose(mem_space_id);
1012 H5Sclose(file_space_id);
1013 set_value(&v_str[0], nelms);
1019 H5Sclose(mem_space_id);
1020 H5Sclose(file_space_id);
1029 bool is_new_ref =
false;
1030 bool is_obj_ref =
false;
1031 bool is_reg_ref =
false;
1033 htri_t ref_ret = H5Tequal(dtype_id, H5T_STD_REF);
1037 throw InternalErr(__FILE__, __LINE__,
"H5Tequal() failed to compare H5T_STD_REF");
1038 else if (ref_ret > 0)
1041 if(
false == is_new_ref) {
1043 ref_ret = H5Tequal(dtype_id,H5T_STD_REF_OBJ);
1046 throw InternalErr(__FILE__, __LINE__,
"H5Tequal() failed to compare H5T_STD_REF_OBJ");
1047 else if (ref_ret > 0)
1052 ref_ret = H5Tequal(dtype_id,H5T_STD_REF_DSETREG);
1054 throw InternalErr(__FILE__, __LINE__,
"H5Tequal() failed to compare H5T_STD_REF_DSETREG");
1055 else if (ref_ret > 0)
1063 if(is_obj_ref ==
false && is_reg_ref ==
false)
1064 throw InternalErr(__FILE__, __LINE__,
"datatype must be either object ref. or region ref.");
1068void HDF5Array::m_intern_plain_array_data(
char *convbuf,hid_t memtype)
1071 vector<string> v_str(d_num_elm);
1072 size_t elesize = H5Tget_size(memtype);
1074 throw InternalErr(__FILE__, __LINE__,
"H5Tget_size() failed.");
1076 vector<char> strbuf(elesize + 1);
1077 BESDEBUG(
"h5",
"=read()<check_h5str() element size=" << elesize
1078 <<
" d_num_elm=" << d_num_elm << endl);
1080 for (
int strindex = 0; strindex < d_num_elm; strindex++) {
1081 get_strdata(strindex, &convbuf[0], &strbuf[0], elesize);
1082 BESDEBUG(
"h5",
"=read()<get_strdata() strbuf=" << &strbuf[0] << endl);
1083 v_str[strindex] = &strbuf[0];
1086 val2buf((
void *) &v_str[0]);
1090 val2buf((
void *) convbuf);
1095bool HDF5Array::do_h5_array_type_read(hid_t dsetid, hid_t memb_id,vector<char>&values,
bool has_values,
int values_offset,
1096 int at_nelms,
int* at_offset,
int* at_count,
int* at_step){
1099 if(has_values !=
true)
1100 throw InternalErr (__FILE__, __LINE__,
"Only support the retrieval of HDF5 Array datatype values from the parent compound datatype read.");
1102 hid_t at_base_type = H5Tget_super(memb_id);
1103 if(at_base_type < 0) {
1104 throw InternalErr (__FILE__, __LINE__,
"Fail to obtain the basetype of the array datatype.");
1108 int at_ndims = H5Tget_array_ndims(memb_id);
1110 H5Tclose(at_base_type);
1111 throw InternalErr (__FILE__, __LINE__,
"Fail to obtain number of dimensions of the array datatype.");
1114 vector<hsize_t>at_dims_h(at_ndims,0);
1117 if(H5Tget_array_dims(memb_id,&at_dims_h[0])<0) {
1118 H5Tclose(at_base_type);
1119 throw InternalErr (__FILE__, __LINE__,
"Fail to obtain dimensions of the array datatype.");
1121 vector<int>at_dims(at_ndims,0);
1122 for(
int i = 0;i<at_ndims;i++) {
1123 at_dims[i] = (
int)at_dims_h[i];
1125 int at_total_nelms = 1;
1126 for (
int i = 0; i <at_ndims; i++)
1127 at_total_nelms = at_total_nelms*at_dims[i];
1129 H5T_class_t array_cls = H5Tget_class(at_base_type);
1130 if(H5T_NO_CLASS == array_cls) {
1131 H5Tclose(at_base_type);
1132 throw InternalErr (__FILE__, __LINE__,
"Fail to obtain the datatype class of the array base type.");
1135 size_t at_base_type_size = H5Tget_size(at_base_type);
1136 if(0 == at_base_type_size){
1137 H5Tclose(at_base_type);
1138 throw InternalErr (__FILE__, __LINE__,
"Fail to obtain the size of the array base type.");
1142 if(H5T_COMPOUND == array_cls) {
1145 vector<int>at_end(at_ndims,0);
1146 vector<int>at_pos(at_ndims,0);
1147 for (
int i = 0; i< at_ndims; i++){
1148 at_pos[i] = at_offset[i];
1149 at_end[i] = at_offset[i] + (at_count[i] -1)*at_step[i];
1152 int at_orig_index = INDEX_nD_TO_1D(at_dims,at_pos);
1155 for (
int array_index = 0; array_index <at_nelms; array_index++) {
1159 hid_t child_memb_id;
1160 H5T_class_t child_memb_cls;
1162 size_t child_memb_offset;
1165 if((child_nmembs = H5Tget_nmembers(at_base_type)) < 0) {
1166 H5Tclose(at_base_type);
1168 throw InternalErr (__FILE__, __LINE__,
"Fail to obtain number of HDF5 compound datatype.");
1171 for(child_u = 0; child_u < (unsigned)child_nmembs; child_u++) {
1174 if((child_memb_id = H5Tget_member_type(at_base_type, child_u)) < 0) {
1175 H5Tclose(at_base_type);
1177 throw InternalErr (__FILE__, __LINE__,
"Fail to obtain the datatype of an HDF5 compound datatype member.");
1181 if((child_memb_cls = H5Tget_member_class (at_base_type, child_u)) < 0) {
1182 H5Tclose(child_memb_id);
1183 H5Tclose(at_base_type);
1185 throw InternalErr (__FILE__, __LINE__,
"Fail to obtain the datatype class of an HDF5 compound datatype member.");
1189 child_memb_offset= H5Tget_member_offset(at_base_type,child_u);
1192 char *child_memb_name = H5Tget_member_name(at_base_type,child_u);
1193 if(child_memb_name == NULL) {
1194 H5Tclose(child_memb_id);
1195 H5Tclose(at_base_type);
1197 throw InternalErr (__FILE__, __LINE__,
"Fail to obtain the name of an HDF5 compound datatype member.");
1200 BaseType *field = h5s->var(child_memb_name);
1201 if (child_memb_cls == H5T_COMPOUND) {
1208 if(at_total_nelms == at_nelms) {
1209 memb_h5s.do_structure_read(dsetid,child_memb_id, values,has_values,values_offset+at_base_type_size*array_index+child_memb_offset);
1216 memb_h5s.do_structure_read(dsetid, child_memb_id, values,has_values,values_offset+at_base_type_size*at_orig_index+child_memb_offset);
1221 else if(child_memb_cls == H5T_ARRAY) {
1224 int child_at_ndims = H5Tget_array_ndims(child_memb_id);
1225 if(child_at_ndims <= 0) {
1226 H5Tclose(at_base_type);
1227 H5Tclose(child_memb_id);
1228 H5free_memory(child_memb_name);
1230 throw InternalErr (__FILE__, __LINE__,
"Fail to obtain number of dimensions of the array datatype.");
1235 vector<int> child_at_offset(child_at_ndims,0);
1236 vector<int> child_at_count(child_at_ndims,0);
1237 vector<int> child_at_step(child_at_ndims,0);
1239 int child_at_nelms = h5_array_type.format_constraint(&child_at_offset[0],&child_at_step[0],&child_at_count[0]);
1241 if(at_total_nelms == at_nelms) {
1242 h5_array_type.do_h5_array_type_read(dsetid,child_memb_id,values,has_values,child_memb_offset+values_offset+at_base_type_size*array_index,
1243 child_at_nelms,&child_at_offset[0],&child_at_count[0],&child_at_step[0]);
1246 h5_array_type.do_h5_array_type_read(dsetid,child_memb_id,values,has_values,child_memb_offset+values_offset+at_base_type_size*at_orig_index,
1247 child_at_nelms,&child_at_offset[0],&child_at_count[0],&child_at_step[0]);
1252 else if(H5T_INTEGER == child_memb_cls || H5T_FLOAT == child_memb_cls){
1254 int number_index =((at_total_nelms == at_nelms)?array_index:at_orig_index);
1255 if(
true == promote_char_to_short(child_memb_cls,child_memb_id)) {
1256 void *src = (
void*)(&values[0] + (number_index*at_base_type_size) + values_offset +child_memb_offset);
1258 memcpy(&val_int8,src,1);
1259 short val_short=(short)val_int8;
1260 field->val2buf(&val_short);
1263 field->val2buf(&values[0] + (number_index * at_base_type_size) + values_offset+child_memb_offset);
1267 else if(H5T_STRING == child_memb_cls){
1269 int string_index =((at_total_nelms == at_nelms)?array_index:at_orig_index);
1272 if(
true == H5Tis_variable_str(child_memb_id)) {
1275 void *src = (
void*)(&values[0]+(string_index *at_base_type_size)+values_offset+child_memb_offset);
1277 char*temp_bp =(
char*)src;
1278 get_vlen_str_data(temp_bp,final_str);
1279 field->val2buf(&final_str[0]);
1283 void *src = (
void*)(&values[0]+(string_index *at_base_type_size)+values_offset+child_memb_offset);
1284 vector<char> str_val;
1285 size_t memb_size = H5Tget_size(child_memb_id);
1286 if (memb_size == 0) {
1287 H5Tclose(child_memb_id);
1288 H5Tclose(at_base_type);
1289 H5free_memory(child_memb_name);
1291 throw InternalErr (__FILE__, __LINE__,
"Fail to obtain the size of HDF5 compound datatype.");
1293 str_val.resize(memb_size);
1294 memcpy(&str_val[0],src,memb_size);
1295 field->val2buf(&str_val[0]);
1300 H5Tclose(child_memb_id);
1301 H5Tclose(at_base_type);
1302 H5free_memory(child_memb_name);
1304 throw InternalErr (__FILE__, __LINE__,
"Unsupported datatype class for the array base type.");
1308 field->set_read_p(
true);
1309 H5free_memory(child_memb_name);
1310 H5Tclose(child_memb_id);
1313 h5s->set_read_p(
true);
1316 set_vec(array_index,h5s);
1319 vector<int>at_offsetv(at_pos.size(),0);
1320 vector<int>at_stepv(at_pos.size(),0);
1321 for (
unsigned int at_index = 0; at_index<at_pos.size();at_index++){
1322 at_offsetv[at_index] = at_offset[at_index];
1323 at_stepv[at_index] = at_step[at_index];
1326 obtain_next_pos(at_pos,at_offsetv,at_end,at_stepv,(
int)(at_pos.size()));
1327 at_orig_index = INDEX_nD_TO_1D(at_dims,at_pos);
1335 else if(H5T_INTEGER == array_cls|| H5T_FLOAT == array_cls) {
1338 if(at_total_nelms == at_nelms) {
1341 if(
true == promote_char_to_short(array_cls ,at_base_type)) {
1342 vector<char> val_int8;
1343 val_int8.resize(at_nelms);
1344 void*src = (
void*)(&values[0] +values_offset);
1345 memcpy(&val_int8[0],src,at_nelms);
1347 vector<short> val_short;
1348 for (
int i = 0; i<at_nelms; i++)
1349 val_short[i] = (
short)val_int8[i];
1351 val2buf(&val_short[0]);
1355 val2buf(&values[0] + values_offset);
1361 string dap_type =
get_dap_type(at_base_type,is_dap4());
1364 void*src = (
void*)(&values[0] + values_offset);
1367 vector<int>at_pos(at_ndims,0);
1368 for (
int i = 0; i< at_ndims; i++)
1369 at_pos[i] = at_offset[i];
1371 if( BYTE == dap_type) {
1373 vector<unsigned char>total_val;
1374 total_val.resize(at_total_nelms);
1375 memcpy(&total_val[0],src,at_total_nelms*at_base_type_size);
1377 vector<unsigned char>final_val;
1378 subset<unsigned char>(
1390 set_value((dods_byte*)&final_val[0],at_nelms);
1394 else if( INT16 == dap_type) {
1397 if(
true == promote_char_to_short(array_cls,at_base_type)) {
1398 vector<char>total_val;
1399 total_val.resize(at_total_nelms);
1400 memcpy(&total_val[0],src,at_total_nelms*at_base_type_size);
1402 vector<char>final_val;
1415 vector<short> final_val_short;
1416 final_val_short.resize(at_nelms);
1417 for(
int i = 0; i<at_nelms; i++)
1418 final_val_short[i] = final_val[i];
1420 val2buf(&final_val_short[0]);
1425 vector<short>total_val;
1426 total_val.resize(at_total_nelms);
1427 memcpy(&total_val[0],src,at_total_nelms*at_base_type_size);
1429 vector<short>final_val;
1442 val2buf(&final_val[0]);
1446 else if( UINT16 == dap_type) {
1447 vector<unsigned short>total_val;
1448 total_val.resize(at_total_nelms);
1449 memcpy(&total_val[0],src,at_total_nelms*at_base_type_size);
1451 vector<unsigned short>final_val;
1452 subset<unsigned short>(
1464 val2buf(&final_val[0]);
1467 else if(UINT32 == dap_type) {
1468 vector<unsigned int>total_val;
1469 total_val.resize(at_total_nelms);
1470 memcpy(&total_val[0],src,at_total_nelms*at_base_type_size);
1472 vector<unsigned int>final_val;
1473 subset<unsigned int>(
1484 val2buf(&final_val[0]);
1488 else if(INT32 == dap_type) {
1489 vector<int>total_val;
1490 total_val.resize(at_total_nelms);
1491 memcpy(&total_val[0],src,at_total_nelms*at_base_type_size);
1493 vector<int>final_val;
1506 val2buf(&final_val[0]);
1509 else if(FLOAT32 == dap_type) {
1510 vector<float>total_val;
1511 total_val.resize(at_total_nelms);
1512 memcpy(&total_val[0],src,at_total_nelms*at_base_type_size);
1514 vector<float>final_val;
1527 val2buf(&final_val[0]);
1530 else if(FLOAT64 == dap_type) {
1531 vector<double>total_val;
1532 total_val.resize(at_total_nelms);
1533 memcpy(&total_val[0],src,at_total_nelms*at_base_type_size);
1535 vector<double>final_val;
1550 val2buf(&final_val[0]);
1554 H5Tclose(at_base_type);
1555 throw InternalErr (__FILE__, __LINE__,
1556 "Non-supported integer or float datatypes");
1561 else if(H5T_STRING == array_cls) {
1564 vector<int>at_pos(at_ndims,0);
1565 for (
int i = 0; i< at_ndims; i++)
1566 at_pos[i] = at_offset[i];
1568 vector<string>total_strval;
1569 total_strval.resize(at_total_nelms);
1571 if(
true == H5Tis_variable_str(at_base_type)) {
1572 void *src = (
void*)(&values[0]+values_offset);
1573 char*temp_bp =(
char*)src;
1574 for(
int i = 0;i <at_total_nelms; i++){
1576 get_vlen_str_data(temp_bp,tempstrval);
1577 total_strval[i] = tempstrval;
1578 temp_bp += at_base_type_size;
1580 if(at_total_nelms == at_nelms) {
1584 set_value(total_strval,at_total_nelms);
1590 vector<string>final_val;
1603 set_value(final_val,at_nelms);
1609 void *src = (
void*)(&values[0]+values_offset);
1610 for(
int i = 0; i <at_total_nelms; i++)
1611 total_strval[i].resize(at_base_type_size);
1613 vector<char> str_val;
1614 str_val.resize(at_total_nelms*at_base_type_size);
1615 memcpy((
void*)&str_val[0],src,at_total_nelms*at_base_type_size);
1616 string total_in_one_string(str_val.begin(),str_val.end());
1617 for(
int i = 0; i<at_total_nelms;i++)
1618 total_strval[i] = total_in_one_string.substr(i*at_base_type_size,at_base_type_size);
1620 if(at_total_nelms == at_nelms)
1621 set_value(total_strval,at_total_nelms);
1623 vector<string>final_val;
1635 set_value(final_val,at_nelms);
1642 H5Tclose(at_base_type);
1643 throw InternalErr (__FILE__, __LINE__,
1644 "Only support the field of compound datatype when the field type class is integer, float, string, array or compound..");
1648 H5Tclose(at_base_type);
1655HDF5Array::INDEX_nD_TO_1D (
const std::vector < int > &dims,
1656 const std::vector < int > &pos)
1662 assert (dims.size () == pos.size ());
1666 for (
unsigned int p = 0; p < pos.size (); p++) {
1669 for (
unsigned int j = start; j < dims.size (); j++)
1678bool HDF5Array::obtain_next_pos(vector<int>& pos, vector<int>&start,vector<int>&end,vector<int>&step,
int rank_change) {
1680 if((pos[rank_change-1] + step[rank_change-1])<=end[rank_change-1]) {
1681 pos[rank_change-1] = pos[rank_change-1] + step[rank_change-1];
1685 if( 1 == rank_change)
1687 pos[rank_change-1] = start[rank_change-1];
1688 obtain_next_pos(pos,start,end,step,rank_change-1);
1705int HDF5Array::subset(
1712 std::vector<T> *poutput,
1716 for(
int k=0; k<edge[index]; k++)
1718 pos[index] = start[index] + k*stride[index];
1720 subset(input, rank, dim, start, stride, edge, poutput,pos,index+1);
1723 poutput->push_back(input[INDEX_nD_TO_1D( dim, pos)]);
1745hid_t HDF5Array::mkstr(
int size, H5T_str_t pad)
1750 if ((str_type = H5Tcopy(H5T_C_S1)) < 0)
1752 if (H5Tset_size(str_type, (
size_t) size) < 0)
1754 if (H5Tset_strpad(str_type, pad) < 0)
1761BaseType* HDF5Array::h5dims_transform_to_dap4(D4Group *grp,
const vector<string> &dimpath) {
1763 BESDEBUG(
"h5",
"<h5dims_transform_to_dap4" << endl);
1775 for (Array::Dim_iter d = dest->dim_begin(), e = dest->dim_end(); d != e; ++d) {
1777 if (
false == (*d).name.empty()) {
1778 BESDEBUG(
"h5",
"<coming to the dimension loop, has name " << (*d).name<<endl);
1779 BESDEBUG(
"h5",
"<coming to the dimension loop, has dimpath " << dimpath[k] <<endl);
1780 BESDEBUG(
"h5",
"<coming to the dimension loop, has dimpath group " << dimpath[k].substr(0,dimpath[k].find_last_of(
"/")+1) <<endl);
1782 D4Group *temp_grp = grp;
1783 D4Dimension *d4_dim = NULL;
1784 bool is_dim_nonc4_grp =
false;
1788 BESDEBUG(
"h5",
"<coming to the group has name " << temp_grp->name()<<endl);
1789 BESDEBUG(
"h5",
"<coming to the group has fullpath " << temp_grp->FQN()<<endl);
1792 D4Dimensions *temp_dims = temp_grp->dims();
1795 d4_dim = temp_dims->find_dim((*d).name);
1798 string d4_dim_path = dimpath[k].substr(0,dimpath[k].find_last_of(
"/")+1);
1799 BESDEBUG(
"h5",
"d4_dim_path is " << d4_dim_path<<endl);
1801 bool ancestor_grp =
false;
1804 if(d4_dim_path.find(temp_grp->FQN())==0 || temp_grp->FQN().find(d4_dim_path)==0)
1805 ancestor_grp =
true;
1809 if(d4_dim && (temp_grp->FQN() == d4_dim_path)) {
1810 BESDEBUG(
"h5",
"<FInd dimension name " << (*d).name<<endl);
1812 is_dim_nonc4_grp =
false;
1818 else if( ancestor_grp ==
false) {
1819 is_dim_nonc4_grp =
true;
1825 if(temp_grp->get_parent())
1826 temp_grp =
static_cast<D4Group*
>(temp_grp->get_parent());
1835 if(
true == is_dim_nonc4_grp) {
1836 string err=
"The variable " + var_path +
" has dimension ";
1837 err += dimpath[k] +
". This dimension is not under its ancestor or the current group.";
1838 err +=
" This is not supported.";
1840 throw InternalErr(__FILE__,__LINE__,err);
1843 bool d4_dim_null = ((d4_dim==NULL)?
true:
false);
1844 if(d4_dim_null ==
true) {
1845 d4_dim =
new D4Dimension((*d).name, (*d).size);
1846 D4Dimensions * dims = grp->dims();
1847 BESDEBUG(
"h5",
"<Just before adding D4 dimension to group" << endl);
1848 dims->add_dim_nocopy(d4_dim);
1855 dest->set_is_dap4(
true);
A class for handling all types of array in HDF5 for the default option.
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.
virtual libdap::BaseType * ptr_duplicate()
virtual bool read()
Reads HDF5 array data into local buffer.
void set_numdim(int ndims)
remembers number of dimensions of this array.
HDF5Array(const std::string &n, const std::string &d, libdap::BaseType *v)
Constructor.
void set_numelm(int nelms)
remembers number of elements in this array.
void set_memneed(size_t need)
remembers memory size needed.
int get_slabdata(hid_t dset, int *offset, int *step, int *count, int num_dim, void *buf)
void get_data(hid_t dset, void *buf)
void get_strdata(int strindex, char *allbuf, char *buf, int elesize)
bool check_h5str(hid_t h5type)
string get_dap_type(hid_t type, bool is_dap4)
const int DODS_NAMELEN
Maximum length of variable or attribute name(default option only).