35 #include "config_hdf5.h"
45 #include <InternalErr.h>
65 HDF5Array::~HDF5Array() {
68 int 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]);
209 void 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.");
225 void 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);
325 bool 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) {
575 bool HDF5Array::m_array_of_reference(hid_t dset_id,hid_t dtype_id)
578 hid_t memtype = H5Tget_native_type(dtype_id, H5T_DIR_ASCEND);
580 throw InternalErr(__FILE__, __LINE__,
"cannot obtain the memory data type for the dataset.");
582 hid_t d_ty_id = memtype;
583 hid_t d_dset_id = dset_id;
584 hdset_reg_ref_t *rbuf = NULL;
587 vector<int> offset(d_num_dim);
588 vector<int> count(d_num_dim);
589 vector<int> step(d_num_dim);
592 int nelms = format_constraint(&offset[0], &step[0], &count[0]);
593 vector<string> v_str(nelms);
595 BESDEBUG(
"h5",
"=read() URL type is detected. "
596 <<
"nelms=" << nelms <<
" full_size=" << d_num_elm << endl);
599 if (H5Tequal(d_ty_id, H5T_STD_REF_DSETREG) < 0) {
600 throw InternalErr(__FILE__, __LINE__,
"H5Tequal() failed");
603 if (H5Tequal(d_ty_id, H5T_STD_REF_DSETREG) > 0) {
604 BESDEBUG(
"h5",
"=read() Got regional reference. " << endl);
606 rbuf =
new hdset_reg_ref_t[d_num_elm];
608 throw InternalErr(__FILE__, __LINE__,
"new() failed.");
610 if (H5Dread(d_dset_id, H5T_STD_REF_DSETREG, H5S_ALL, H5S_ALL, H5P_DEFAULT, &rbuf[0]) < 0) {
611 throw InternalErr(__FILE__, __LINE__,
"H5Dread() failed.");
614 for (
int i = 0; i < nelms; i++) {
616 BESDEBUG(
"h5",
"=read() rbuf[" << i <<
"]" <<
617 rbuf[offset[0] + i * step[0]] << endl);
619 if (rbuf[offset[0] + i * step[0]][0] !=
'\0') {
622 hid_t did_r = H5RDEREFERENCE(d_dset_id, H5R_DATASET_REGION, rbuf[offset[0] + i * step[0]]);
624 throw InternalErr(__FILE__, __LINE__,
"H5RDEREFERENCE() failed.");
628 if (H5Iget_name(did_r, (
char *) r_name,
DODS_NAMELEN) < 0) {
629 throw InternalErr(__FILE__, __LINE__,
"H5Iget_name() failed.");
631 BESDEBUG(
"h5",
"=read() dereferenced name is " << r_name
634 string varname(r_name);
635 hid_t space_id = H5Rget_region(did_r, H5R_DATASET_REGION, rbuf[offset[0] + i * step[0]]);
637 throw InternalErr(__FILE__, __LINE__,
"H5Rget_region() failed.");
641 int ndim = H5Sget_simple_extent_ndims(space_id);
643 throw InternalErr(__FILE__, __LINE__,
"H5Sget_simple_extent_ndims() failed.");
646 BESDEBUG(
"h5",
"=read() dim is " << ndim << endl);
649 switch (H5Sget_select_type(space_id)) {
652 BESDEBUG(
"h5",
"=read() None selected." << endl);
655 case H5S_SEL_POINTS: {
656 BESDEBUG(
"h5",
"=read() Points selected." << endl);
657 hssize_t npoints = H5Sget_select_npoints(space_id);
659 throw InternalErr(__FILE__, __LINE__,
660 "Cannot determine number of elements in the dataspace selection");
663 BESDEBUG(
"h5",
"=read() npoints are " << npoints
665 vector<hsize_t> buf(npoints * ndim);
666 if (H5Sget_select_elem_pointlist(space_id, 0, npoints, &buf[0]) < 0) {
667 throw InternalErr(__FILE__, __LINE__,
"H5Sget_select_elem_pointlist() failed.");
671 for (
int j = 0; j < npoints * ndim; j++) {
672 "h5",
"=read() npoints buf[0] =" << buf[j] <<endl;
676 for (
int j = 0; j < (
int) npoints; j++) {
678 expression.append(varname);
679 for (
int k = 0; k < ndim; k++) {
681 oss <<
"[" << (
int) buf[j * ndim + k] <<
"]";
682 expression.append(oss.str());
684 if (j != (
int) (npoints - 1)) {
685 expression.append(
",");
688 v_str[i].append(expression);
692 case H5S_SEL_HYPERSLABS: {
693 vector<hsize_t> start(ndim);
694 vector<hsize_t> end(ndim);
696 BESDEBUG(
"h5",
"=read() Slabs selected." << endl);
697 BESDEBUG(
"h5",
"=read() nblock is " <<
698 H5Sget_select_hyper_nblocks(space_id) << endl);
700 if (H5Sget_select_bounds(space_id, &start[0], &end[0]) < 0) {
701 throw InternalErr(__FILE__, __LINE__,
"H5Sget_select_bounds() failed.");
704 for (
int j = 0; j < ndim; j++) {
706 BESDEBUG(
"h5",
"=read() start is " << start[j]
707 <<
"=read() end is " << end[j] << endl);
708 oss <<
"[" << (
int) start[j] <<
":" << (
int) end[j] <<
"]";
709 expression.append(oss.str());
710 BESDEBUG(
"h5",
"=read() expression is "
711 << expression << endl)
715 if (!expression.empty()) {
716 v_str[i].append(expression);
722 BESDEBUG(
"h5",
"=read() All selected." << endl);
726 BESDEBUG(
"h5",
"Unknown space type." << endl);
739 if (H5Tequal(d_ty_id, H5T_STD_REF_OBJ) < 0) {
740 throw InternalErr(__FILE__, __LINE__,
"H5Tequal() failed.");
743 if (H5Tequal(d_ty_id, H5T_STD_REF_OBJ) > 0) {
744 BESDEBUG(
"h5",
"=read() Got object reference. " << endl);
745 vector<hobj_ref_t> orbuf;
746 orbuf.resize(d_num_elm);
747 if (H5Dread(d_dset_id, H5T_STD_REF_OBJ, H5S_ALL, H5S_ALL, H5P_DEFAULT, &orbuf[0]) < 0) {
748 throw InternalErr(__FILE__, __LINE__,
"H5Dread failed()");
751 for (
int i = 0; i < nelms; i++) {
753 hid_t did_r = H5RDEREFERENCE(d_dset_id, H5R_OBJECT, &orbuf[offset[0] + i * step[0]]);
755 throw InternalErr(__FILE__, __LINE__,
"H5RDEREFERENCE() failed.");
758 if (H5Iget_name(did_r, (
char *) r_name,
DODS_NAMELEN) < 0) {
759 throw InternalErr(__FILE__, __LINE__,
"H5Iget_name() failed.");
763 string varname(r_name);
765 BESDEBUG(
"h5",
"=read() dereferenced name is " << r_name <<endl);
769 set_value(&v_str[0], nelms);
782 void HDF5Array::m_intern_plain_array_data(
char *convbuf,hid_t memtype)
785 vector<string> v_str(d_num_elm);
786 size_t elesize = H5Tget_size(memtype);
788 throw InternalErr(__FILE__, __LINE__,
"H5Tget_size() failed.");
790 vector<char> strbuf(elesize + 1);
791 BESDEBUG(
"h5",
"=read()<check_h5str() element size=" << elesize
792 <<
" d_num_elm=" << d_num_elm << endl);
794 for (
int strindex = 0; strindex < d_num_elm; strindex++) {
795 get_strdata(strindex, &convbuf[0], &strbuf[0], elesize);
796 BESDEBUG(
"h5",
"=read()<get_strdata() strbuf=" << &strbuf[0] << endl);
797 v_str[strindex] = &strbuf[0];
800 val2buf((
void *) &v_str[0]);
804 val2buf((
void *) convbuf);
809 bool HDF5Array::do_h5_array_type_read(hid_t dsetid, hid_t memb_id,vector<char>&values,
bool has_values,
int values_offset,
810 int at_nelms,
int* at_offset,
int* at_count,
int* at_step){
813 if(has_values !=
true)
814 throw InternalErr (__FILE__, __LINE__,
"Only support the retrieval of HDF5 Array datatype values from the parent compound datatype read.");
816 hid_t at_base_type = H5Tget_super(memb_id);
817 if(at_base_type < 0) {
818 throw InternalErr (__FILE__, __LINE__,
"Fail to obtain the basetype of the array datatype.");
822 int at_ndims = H5Tget_array_ndims(memb_id);
824 H5Tclose(at_base_type);
825 throw InternalErr (__FILE__, __LINE__,
"Fail to obtain number of dimensions of the array datatype.");
828 vector<hsize_t>at_dims_h(at_ndims,0);
831 if(H5Tget_array_dims(memb_id,&at_dims_h[0])<0) {
832 H5Tclose(at_base_type);
833 throw InternalErr (__FILE__, __LINE__,
"Fail to obtain dimensions of the array datatype.");
835 vector<int>at_dims(at_ndims,0);
836 for(
int i = 0;i<at_ndims;i++) {
837 at_dims[i] = (
int)at_dims_h[i];
839 int at_total_nelms = 1;
840 for (
int i = 0; i <at_ndims; i++)
841 at_total_nelms = at_total_nelms*at_dims[i];
843 H5T_class_t array_cls = H5Tget_class(at_base_type);
844 if(H5T_NO_CLASS == array_cls) {
845 H5Tclose(at_base_type);
846 throw InternalErr (__FILE__, __LINE__,
"Fail to obtain the datatype class of the array base type.");
849 size_t at_base_type_size = H5Tget_size(at_base_type);
850 if(0 == at_base_type_size){
851 H5Tclose(at_base_type);
852 throw InternalErr (__FILE__, __LINE__,
"Fail to obtain the size of the array base type.");
856 if(H5T_COMPOUND == array_cls) {
859 vector<int>at_end(at_ndims,0);
860 vector<int>at_pos(at_ndims,0);
861 for (
int i = 0; i< at_ndims; i++){
862 at_pos[i] = at_offset[i];
863 at_end[i] = at_offset[i] + (at_count[i] -1)*at_step[i];
866 int at_orig_index = INDEX_nD_TO_1D(at_dims,at_pos);
869 for (
int array_index = 0; array_index <at_nelms; array_index++) {
874 H5T_class_t child_memb_cls;
876 size_t child_memb_offset;
879 if((child_nmembs = H5Tget_nmembers(at_base_type)) < 0) {
880 H5Tclose(at_base_type);
882 throw InternalErr (__FILE__, __LINE__,
"Fail to obtain number of HDF5 compound datatype.");
885 for(child_u = 0; child_u < (unsigned)child_nmembs; child_u++) {
888 if((child_memb_id = H5Tget_member_type(at_base_type, child_u)) < 0) {
889 H5Tclose(at_base_type);
891 throw InternalErr (__FILE__, __LINE__,
"Fail to obtain the datatype of an HDF5 compound datatype member.");
895 if((child_memb_cls = H5Tget_member_class (at_base_type, child_u)) < 0) {
896 H5Tclose(child_memb_id);
897 H5Tclose(at_base_type);
899 throw InternalErr (__FILE__, __LINE__,
"Fail to obtain the datatype class of an HDF5 compound datatype member.");
903 child_memb_offset= H5Tget_member_offset(at_base_type,child_u);
906 char *child_memb_name = H5Tget_member_name(at_base_type,child_u);
907 if(child_memb_name == NULL) {
908 H5Tclose(child_memb_id);
909 H5Tclose(at_base_type);
911 throw InternalErr (__FILE__, __LINE__,
"Fail to obtain the name of an HDF5 compound datatype member.");
914 BaseType *field = h5s->var(child_memb_name);
915 if (child_memb_cls == H5T_COMPOUND) {
922 if(at_total_nelms == at_nelms) {
923 memb_h5s.do_structure_read(dsetid,child_memb_id, values,has_values,values_offset+at_base_type_size*array_index+child_memb_offset);
930 memb_h5s.do_structure_read(dsetid, child_memb_id, values,has_values,values_offset+at_base_type_size*at_orig_index+child_memb_offset);
935 else if(child_memb_cls == H5T_ARRAY) {
938 int child_at_ndims = H5Tget_array_ndims(child_memb_id);
939 if(child_at_ndims <= 0) {
940 H5Tclose(at_base_type);
941 H5Tclose(child_memb_id);
942 H5free_memory(child_memb_name);
944 throw InternalErr (__FILE__, __LINE__,
"Fail to obtain number of dimensions of the array datatype.");
949 vector<int> child_at_offset(child_at_ndims,0);
950 vector<int> child_at_count(child_at_ndims,0);
951 vector<int> child_at_step(child_at_ndims,0);
953 int child_at_nelms = h5_array_type.format_constraint(&child_at_offset[0],&child_at_step[0],&child_at_count[0]);
955 if(at_total_nelms == at_nelms) {
956 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,
957 child_at_nelms,&child_at_offset[0],&child_at_count[0],&child_at_step[0]);
960 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,
961 child_at_nelms,&child_at_offset[0],&child_at_count[0],&child_at_step[0]);
966 else if(H5T_INTEGER == child_memb_cls || H5T_FLOAT == child_memb_cls){
968 int number_index =((at_total_nelms == at_nelms)?array_index:at_orig_index);
969 if(
true == promote_char_to_short(child_memb_cls,child_memb_id)) {
970 void *src = (
void*)(&values[0] + (number_index*at_base_type_size) + values_offset +child_memb_offset);
972 memcpy(&val_int8,src,1);
973 short val_short=(short)val_int8;
974 field->val2buf(&val_short);
977 field->val2buf(&values[0] + (number_index * at_base_type_size) + values_offset+child_memb_offset);
981 else if(H5T_STRING == child_memb_cls){
983 int string_index =((at_total_nelms == at_nelms)?array_index:at_orig_index);
986 if(
true == H5Tis_variable_str(child_memb_id)) {
989 void *src = (
void*)(&values[0]+(string_index *at_base_type_size)+values_offset+child_memb_offset);
991 char*temp_bp =(
char*)src;
992 get_vlen_str_data(temp_bp,final_str);
993 field->val2buf(&final_str[0]);
997 void *src = (
void*)(&values[0]+(string_index *at_base_type_size)+values_offset+child_memb_offset);
998 vector<char> str_val;
999 size_t memb_size = H5Tget_size(child_memb_id);
1000 if (memb_size == 0) {
1001 H5Tclose(child_memb_id);
1002 H5Tclose(at_base_type);
1003 H5free_memory(child_memb_name);
1005 throw InternalErr (__FILE__, __LINE__,
"Fail to obtain the size of HDF5 compound datatype.");
1007 str_val.resize(memb_size);
1008 memcpy(&str_val[0],src,memb_size);
1009 field->val2buf(&str_val[0]);
1014 H5Tclose(child_memb_id);
1015 H5Tclose(at_base_type);
1016 H5free_memory(child_memb_name);
1018 throw InternalErr (__FILE__, __LINE__,
"Unsupported datatype class for the array base type.");
1022 field->set_read_p(
true);
1023 H5free_memory(child_memb_name);
1024 H5Tclose(child_memb_id);
1027 h5s->set_read_p(
true);
1030 set_vec(array_index,h5s);
1033 vector<int>at_offsetv(at_pos.size(),0);
1034 vector<int>at_stepv(at_pos.size(),0);
1035 for (
unsigned int at_index = 0; at_index<at_pos.size();at_index++){
1036 at_offsetv[at_index] = at_offset[at_index];
1037 at_stepv[at_index] = at_step[at_index];
1040 obtain_next_pos(at_pos,at_offsetv,at_end,at_stepv,(
int)(at_pos.size()));
1041 at_orig_index = INDEX_nD_TO_1D(at_dims,at_pos);
1049 else if(H5T_INTEGER == array_cls|| H5T_FLOAT == array_cls) {
1052 if(at_total_nelms == at_nelms) {
1055 if(
true == promote_char_to_short(array_cls ,at_base_type)) {
1056 vector<char> val_int8;
1057 val_int8.resize(at_nelms);
1058 void*src = (
void*)(&values[0] +values_offset);
1059 memcpy(&val_int8[0],src,at_nelms);
1061 vector<short> val_short;
1062 for (
int i = 0; i<at_nelms; i++)
1063 val_short[i] = (
short)val_int8[i];
1065 val2buf(&val_short[0]);
1069 val2buf(&values[0] + values_offset);
1075 string dap_type =
get_dap_type(at_base_type,is_dap4());
1078 void*src = (
void*)(&values[0] + values_offset);
1081 vector<int>at_pos(at_ndims,0);
1082 for (
int i = 0; i< at_ndims; i++)
1083 at_pos[i] = at_offset[i];
1085 if( BYTE == dap_type) {
1087 vector<unsigned char>total_val;
1088 total_val.resize(at_total_nelms);
1089 memcpy(&total_val[0],src,at_total_nelms*at_base_type_size);
1091 vector<unsigned char>final_val;
1092 subset<unsigned char>(
1104 set_value((dods_byte*)&final_val[0],at_nelms);
1108 else if( INT16 == dap_type) {
1111 if(
true == promote_char_to_short(array_cls,at_base_type)) {
1112 vector<char>total_val;
1113 total_val.resize(at_total_nelms);
1114 memcpy(&total_val[0],src,at_total_nelms*at_base_type_size);
1116 vector<char>final_val;
1129 vector<short> final_val_short;
1130 final_val_short.resize(at_nelms);
1131 for(
int i = 0; i<at_nelms; i++)
1132 final_val_short[i] = final_val[i];
1134 val2buf(&final_val_short[0]);
1139 vector<short>total_val;
1140 total_val.resize(at_total_nelms);
1141 memcpy(&total_val[0],src,at_total_nelms*at_base_type_size);
1143 vector<short>final_val;
1156 val2buf(&final_val[0]);
1160 else if( UINT16 == dap_type) {
1161 vector<unsigned short>total_val;
1162 total_val.resize(at_total_nelms);
1163 memcpy(&total_val[0],src,at_total_nelms*at_base_type_size);
1165 vector<unsigned short>final_val;
1166 subset<unsigned short>(
1178 val2buf(&final_val[0]);
1181 else if(UINT32 == dap_type) {
1182 vector<unsigned int>total_val;
1183 total_val.resize(at_total_nelms);
1184 memcpy(&total_val[0],src,at_total_nelms*at_base_type_size);
1186 vector<unsigned int>final_val;
1187 subset<unsigned int>(
1198 val2buf(&final_val[0]);
1202 else if(INT32 == dap_type) {
1203 vector<int>total_val;
1204 total_val.resize(at_total_nelms);
1205 memcpy(&total_val[0],src,at_total_nelms*at_base_type_size);
1207 vector<int>final_val;
1220 val2buf(&final_val[0]);
1223 else if(FLOAT32 == dap_type) {
1224 vector<float>total_val;
1225 total_val.resize(at_total_nelms);
1226 memcpy(&total_val[0],src,at_total_nelms*at_base_type_size);
1228 vector<float>final_val;
1241 val2buf(&final_val[0]);
1244 else if(FLOAT64 == dap_type) {
1245 vector<double>total_val;
1246 total_val.resize(at_total_nelms);
1247 memcpy(&total_val[0],src,at_total_nelms*at_base_type_size);
1249 vector<double>final_val;
1264 val2buf(&final_val[0]);
1268 H5Tclose(at_base_type);
1269 throw InternalErr (__FILE__, __LINE__,
1270 "Non-supported integer or float datatypes");
1275 else if(H5T_STRING == array_cls) {
1278 vector<int>at_pos(at_ndims,0);
1279 for (
int i = 0; i< at_ndims; i++)
1280 at_pos[i] = at_offset[i];
1282 vector<string>total_strval;
1283 total_strval.resize(at_total_nelms);
1285 if(
true == H5Tis_variable_str(at_base_type)) {
1286 void *src = (
void*)(&values[0]+values_offset);
1287 char*temp_bp =(
char*)src;
1288 for(
int i = 0;i <at_total_nelms; i++){
1290 get_vlen_str_data(temp_bp,tempstrval);
1291 total_strval[i] = tempstrval;
1292 temp_bp += at_base_type_size;
1294 if(at_total_nelms == at_nelms) {
1298 set_value(total_strval,at_total_nelms);
1304 vector<string>final_val;
1317 set_value(final_val,at_nelms);
1323 void *src = (
void*)(&values[0]+values_offset);
1324 for(
int i = 0; i <at_total_nelms; i++)
1325 total_strval[i].resize(at_base_type_size);
1327 vector<char> str_val;
1328 str_val.resize(at_total_nelms*at_base_type_size);
1329 memcpy((
void*)&str_val[0],src,at_total_nelms*at_base_type_size);
1330 string total_in_one_string(str_val.begin(),str_val.end());
1331 for(
int i = 0; i<at_total_nelms;i++)
1332 total_strval[i] = total_in_one_string.substr(i*at_base_type_size,at_base_type_size);
1334 if(at_total_nelms == at_nelms)
1335 set_value(total_strval,at_total_nelms);
1337 vector<string>final_val;
1349 set_value(final_val,at_nelms);
1356 H5Tclose(at_base_type);
1357 throw InternalErr (__FILE__, __LINE__,
1358 "Only support the field of compound datatype when the field type class is integer, float, string, array or compound..");
1362 H5Tclose(at_base_type);
1369 HDF5Array::INDEX_nD_TO_1D (
const std::vector < int > &dims,
1370 const std::vector < int > &pos)
1376 assert (dims.size () == pos.size ());
1380 for (
unsigned int p = 0; p < pos.size (); p++) {
1383 for (
unsigned int j = start; j < dims.size (); j++)
1392 bool HDF5Array::obtain_next_pos(vector<int>& pos, vector<int>&start,vector<int>&end,vector<int>&step,
int rank_change) {
1394 if((pos[rank_change-1] + step[rank_change-1])<=end[rank_change-1]) {
1395 pos[rank_change-1] = pos[rank_change-1] + step[rank_change-1];
1399 if( 1 == rank_change)
1401 pos[rank_change-1] = start[rank_change-1];
1402 obtain_next_pos(pos,start,end,step,rank_change-1);
1418 template<
typename T>
1419 int HDF5Array::subset(
1426 std::vector<T> *poutput,
1430 for(
int k=0; k<edge[index]; k++)
1432 pos[index] = start[index] + k*stride[index];
1434 subset(input, rank, dim, start, stride, edge, poutput,pos,index+1);
1437 poutput->push_back(input[INDEX_nD_TO_1D( dim, pos)]);
1459 hid_t HDF5Array::mkstr(
int size, H5T_str_t pad)
1464 if ((str_type = H5Tcopy(H5T_C_S1)) < 0)
1466 if (H5Tset_size(str_type, (
size_t) size) < 0)
1468 if (H5Tset_strpad(str_type, pad) < 0)
1475 BaseType* HDF5Array::h5dims_transform_to_dap4(D4Group *grp,
const vector<string> &dimpath) {
1477 BESDEBUG(
"h5",
"<h5dims_transform_to_dap4" << endl);
1489 for (Array::Dim_iter d = dest->dim_begin(), e = dest->dim_end(); d != e; ++d) {
1491 if (
false == (*d).name.empty()) {
1492 BESDEBUG(
"h5",
"<coming to the dimension loop, has name " << (*d).name<<endl);
1493 BESDEBUG(
"h5",
"<coming to the dimension loop, has dimpath " << dimpath[k] <<endl);
1494 BESDEBUG(
"h5",
"<coming to the dimension loop, has dimpath group " << dimpath[k].substr(0,dimpath[k].find_last_of(
"/")+1) <<endl);
1496 D4Group *temp_grp = grp;
1497 D4Dimension *d4_dim = NULL;
1498 bool is_dim_nonc4_grp =
false;
1502 BESDEBUG(
"h5",
"<coming to the group has name " << temp_grp->name()<<endl);
1503 BESDEBUG(
"h5",
"<coming to the group has fullpath " << temp_grp->FQN()<<endl);
1506 D4Dimensions *temp_dims = temp_grp->dims();
1509 d4_dim = temp_dims->find_dim((*d).name);
1512 string d4_dim_path = dimpath[k].substr(0,dimpath[k].find_last_of(
"/")+1);
1513 BESDEBUG(
"h5",
"d4_dim_path is " << d4_dim_path<<endl);
1515 bool ancestor_grp =
false;
1518 if(d4_dim_path.find(temp_grp->FQN())==0 || temp_grp->FQN().find(d4_dim_path)==0)
1519 ancestor_grp =
true;
1523 if(d4_dim && (temp_grp->FQN() == d4_dim_path)) {
1524 BESDEBUG(
"h5",
"<FInd dimension name " << (*d).name<<endl);
1526 is_dim_nonc4_grp =
false;
1532 else if( ancestor_grp ==
false) {
1533 is_dim_nonc4_grp =
true;
1539 if(temp_grp->get_parent())
1540 temp_grp =
static_cast<D4Group*
>(temp_grp->get_parent());
1549 if(
true == is_dim_nonc4_grp) {
1550 string err=
"The variable " + var_path +
" has dimension ";
1551 err += dimpath[k] +
". This dimension is not under its ancestor or the current group.";
1552 err +=
" This is not supported.";
1554 throw InternalErr(__FILE__,__LINE__,err);
1557 bool d4_dim_null = ((d4_dim==NULL)?
true:
false);
1558 if(d4_dim_null ==
true) {
1559 d4_dim =
new D4Dimension((*d).name, (*d).size);
1560 D4Dimensions * dims = grp->dims();
1561 BESDEBUG(
"h5",
"<Just before adding D4 dimension to group" << endl);
1562 dims->add_dim_nocopy(d4_dim);
1569 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).