35 #include "config_hdf5.h"
45 #include <InternalErr.h>
65 HDF5Array::~HDF5Array() {
68 int HDF5Array::format_constraint(
int *offset,
int *step,
int *count) {
77 Dim_iter p = dim_begin();
79 while (p != dim_end()) {
81 int start = dimension_start(p,
true);
82 int stride = dimension_stride(p,
true);
83 int stop = dimension_stop(p,
true);
89 oss <<
"Array/Grid hyperslab start point "<< start <<
90 " is greater than stop point " << stop <<
".";
91 throw Error(malformed_expr, oss.str());
96 count[id] = ((stop - start) / stride) + 1;
100 "=format_constraint():"
101 <<
"id=" <<
id <<
" offset=" << offset[
id]
102 <<
" step=" << step[
id]
103 <<
" count=" << count[
id]
117 ">read() dataset=" << dataset()
118 <<
" dimension=" << d_num_dim
119 <<
" data_size=" << d_memneed <<
" length=" << length()
122 hid_t file_id = H5Fopen(dataset().c_str(),H5F_ACC_RDONLY,H5P_DEFAULT);
124 BESDEBUG(
"h5",
"after H5Fopen "<<endl);
125 BESDEBUG(
"h5",
"variable name is "<<name() <<endl);
126 BESDEBUG(
"h5",
"variable path is "<<var_path <<endl);
130 if(
true == is_dap4())
131 dset_id = H5Dopen2(file_id,var_path.c_str(),H5P_DEFAULT);
133 dset_id = H5Dopen2(file_id,name().c_str(),H5P_DEFAULT);
135 BESDEBUG(
"h5",
"after H5Dopen2 "<<endl);
138 hid_t dspace_id = H5Dget_space(dset_id);
142 throw InternalErr(__FILE__,__LINE__,
"Fail to obtain the dataspace .");
145 int num_dim = H5Sget_simple_extent_ndims(dspace_id);
150 throw InternalErr(__FILE__,__LINE__,
"Fail to obtain the datatype .");
156 hid_t dtype_id = H5Dget_type(dset_id);
160 throw InternalErr(__FILE__,__LINE__,
"Fail to obtain the datatype .");
164 vector<int> offset(d_num_dim);
165 vector<int> count(d_num_dim);
166 vector<int> step(d_num_dim);
167 int nelms = format_constraint(&offset[0], &step[0], &count[0]);
173 bool ret_ref =
false;
175 ret_ref = m_array_of_reference(dset_id,dtype_id);
192 do_array_read(dset_id,dtype_id,values,
false,0,nelms,&offset[0],&count[0],&step[0]);
208 void HDF5Array::do_array_read(hid_t dset_id,hid_t dtype_id,vector<char>&values,
bool has_values,
int values_offset,
209 int nelms,
int* offset,
int* count,
int* step)
212 H5T_class_t tcls = H5Tget_class(dtype_id);
214 if(H5T_COMPOUND == tcls)
215 m_array_of_structure(dset_id,values,has_values,values_offset,nelms,offset,count,step);
216 else if(H5T_INTEGER == tcls || H5T_FLOAT == tcls || H5T_STRING == tcls)
217 m_array_of_atomic(dset_id,dtype_id,nelms,offset,count,step);
219 throw InternalErr(__FILE__,__LINE__,
"Fail to read the data for Unsupported datatype.");
224 void HDF5Array:: m_array_of_atomic(hid_t dset_id, hid_t dtype_id,
225 int nelms,
int* offset,
int* count,
int* step)
229 if((memtype = H5Tget_native_type(dtype_id, H5T_DIR_ASCEND))<0) {
230 throw InternalErr (__FILE__, __LINE__,
"Fail to obtain memory datatype.");
234 if (H5Tis_variable_str(memtype) && H5Tget_class(memtype) == H5T_STRING) {
236 vector<hsize_t> hoffset;
237 vector<hsize_t>hcount;
238 vector<hsize_t>hstep;
239 hoffset.resize(d_num_dim);
240 hcount.resize(d_num_dim);
241 hstep.resize(d_num_dim);
242 for (
int i = 0; i <d_num_dim; i++) {
243 hoffset[i] = (hsize_t) offset[i];
244 hcount[i] = (hsize_t) count[i];
245 hstep[i] = (hsize_t) step[i];
248 vector<string>finstrval;
249 finstrval.resize(nelms);
251 read_vlen_string(dset_id, nelms, &hoffset[0], &hstep[0], &hcount[0],finstrval);
255 throw InternalErr(__FILE__,__LINE__,
"Fail to read variable-length string.");
257 set_value(finstrval,nelms);
263 if (nelms == d_num_elm) {
265 vector<char> convbuf(d_memneed);
266 get_data(dset_id, (
void *) &convbuf[0]);
269 if(
false == is_dap4()) {
270 if (1 == H5Tget_size(memtype) && H5T_SGN_2 == H5Tget_sign(memtype))
272 vector<short> convbuf2(nelms);
273 for (
int i = 0; i < nelms; i++) {
274 convbuf2[i] = (
signed char) (convbuf[i]);
275 BESDEBUG(
"h5",
"convbuf[" << i <<
"]="
276 << (
signed char)convbuf[i] << endl);
277 BESDEBUG(
"h5",
"convbuf2[" << i <<
"]="
278 << convbuf2[i] << endl)
282 m_intern_plain_array_data((
char*) &convbuf2[0],memtype);
285 m_intern_plain_array_data(&convbuf[0],memtype);
288 m_intern_plain_array_data(&convbuf[0],memtype);
291 size_t data_size = nelms * H5Tget_size(memtype);
292 if (data_size == 0) {
293 throw InternalErr(__FILE__, __LINE__,
"get_size failed");
295 vector<char> convbuf(data_size);
296 get_slabdata(dset_id, &offset[0], &step[0], &count[0], d_num_dim, &convbuf[0]);
299 if(
false == is_dap4()){
300 if (1 == H5Tget_size(memtype) && H5T_SGN_2 == H5Tget_sign(memtype)) {
301 vector<short> convbuf2(data_size);
302 for (
int i = 0; i < (int)data_size; i++) {
303 convbuf2[i] =
static_cast<signed char> (convbuf[i]);
305 m_intern_plain_array_data((
char*) &convbuf2[0],memtype);
308 m_intern_plain_array_data(&convbuf[0],memtype);
312 m_intern_plain_array_data(&convbuf[0],memtype);
324 bool HDF5Array::m_array_of_structure(hid_t dsetid, vector<char>&values,
bool has_values,
int values_offset,
325 int nelms,
int* offset,
int* count,
int* step) {
327 BESDEBUG(
"h5",
"=read() Array of Structure length=" << length() << endl);
334 if((dtypeid = H5Dget_type(dsetid)) < 0)
335 throw InternalErr (__FILE__, __LINE__,
"Cannot obtain the datatype.");
337 if((memtype = H5Tget_native_type(dtypeid, H5T_DIR_ASCEND))<0) {
339 throw InternalErr (__FILE__, __LINE__,
"Fail to obtain memory datatype.");
342 ty_size = H5Tget_size(memtype);
346 throw InternalErr (__FILE__, __LINE__,
"Fail to obtain the size of HDF5 compound datatype.");
349 if(
false == has_values) {
353 if ((dspace = H5Dget_space(dsetid))<0) {
356 throw InternalErr (__FILE__, __LINE__,
"Cannot obtain data space.");
359 d_num_dim = H5Sget_simple_extent_ndims(dspace);
364 throw InternalErr (__FILE__, __LINE__,
"Cannot obtain the number of dimensions of the data space.");
367 vector<hsize_t> hoffset;
368 vector<hsize_t>hcount;
369 vector<hsize_t>hstep;
370 hoffset.resize(d_num_dim);
371 hcount.resize(d_num_dim);
372 hstep.resize(d_num_dim);
373 for (
int i = 0; i <d_num_dim; i++) {
374 hoffset[i] = (hsize_t) offset[i];
375 hcount[i] = (hsize_t) count[i];
376 hstep[i] = (hsize_t) step[i];
379 if (H5Sselect_hyperslab(dspace, H5S_SELECT_SET,
380 &hoffset[0], &hstep[0],
381 &hcount[0], NULL) < 0) {
385 throw InternalErr (__FILE__, __LINE__,
"Cannot generate the hyperslab of the HDF5 dataset.");
388 mspace = H5Screate_simple(d_num_dim, &hcount[0],NULL);
393 throw InternalErr (__FILE__, __LINE__,
"Cannot create the memory space.");
396 values.resize(nelms*ty_size);
398 read_ret = H5Dread(dsetid,memtype,mspace,dspace,H5P_DEFAULT,(
void*)&values[0]);
403 throw InternalErr (__FILE__, __LINE__,
"Fail to read the HDF5 compound datatype dataset.");
412 char* memb_name = NULL;
417 for (
int element = 0; element < nelms; ++element) {
420 H5T_class_t memb_cls = H5T_NO_CLASS;
422 size_t memb_offset = 0;
424 if((nmembs = H5Tget_nmembers(memtype)) < 0)
425 throw InternalErr (__FILE__, __LINE__,
"Fail to obtain number of HDF5 compound datatype.");
427 for(
unsigned int u = 0; u < (unsigned)nmembs; u++) {
430 if((memb_id = H5Tget_member_type(memtype, u)) < 0)
431 throw InternalErr (__FILE__, __LINE__,
"Fail to obtain the datatype of an HDF5 compound datatype member.");
434 if((memb_cls = H5Tget_member_class (memtype, u)) < 0)
435 throw InternalErr (__FILE__, __LINE__,
"Fail to obtain the datatype class of an HDF5 compound datatype member.");
440 memb_offset= H5Tget_member_offset(memtype,u);
443 memb_name = H5Tget_member_name(memtype,u);
444 if(memb_name == NULL)
445 throw InternalErr (__FILE__, __LINE__,
"Fail to obtain the name of an HDF5 compound datatype member.");
447 BaseType *field = h5s->var(memb_name);
448 if (memb_cls == H5T_COMPOUND) {
450 memb_h5s.do_structure_read(dsetid, memb_id,values,has_values,memb_offset+values_offset+ty_size*element);
453 else if(memb_cls == H5T_ARRAY) {
456 int at_ndims = H5Tget_array_ndims(memb_id);
458 throw InternalErr (__FILE__, __LINE__,
"Fail to obtain number of dimensions of the array datatype.");
464 vector<int> at_offset(at_ndims,0);
465 vector<int> at_count(at_ndims,0);
466 vector<int> at_step(at_ndims,0);
468 int at_nelms = h5_array_type.format_constraint(&at_offset[0],&at_step[0],&at_count[0]);
471 h5_array_type.do_h5_array_type_read(dsetid,memb_id,values,has_values,memb_offset+values_offset+ty_size*element,
472 at_nelms,&at_offset[0],&at_count[0],&at_step[0]);
475 else if(memb_cls == H5T_INTEGER || memb_cls == H5T_FLOAT) {
477 if(
true == promote_char_to_short(memb_cls,memb_id)) {
478 void *src = (
void*)(&values[0] + (element*ty_size) + values_offset +memb_offset);
480 memcpy(&val_int8,src,1);
481 short val_short=(short)val_int8;
482 field->val2buf(&val_short);
485 field->val2buf(&values[0] + (element*ty_size) + values_offset +memb_offset);
489 else if(memb_cls == H5T_STRING) {
492 if(
true == H5Tis_variable_str(memb_id)) {
493 void *src = (
void*)(&values[0]+(element*ty_size)+values_offset + memb_offset);
495 get_vlen_str_data((
char*)src,final_str);
496 field->val2buf(&final_str);
499 void *src = (
void*)(&values[0]+(element*ty_size)+values_offset + memb_offset);
500 vector<char> str_val;
501 size_t memb_size = H5Tget_size(memb_id);
502 if (memb_size == 0) {
504 H5free_memory(memb_name);
506 throw InternalErr (__FILE__, __LINE__,
"Fail to obtain the size of HDF5 compound datatype.");
508 str_val.resize(memb_size);
509 memcpy(&str_val[0],src,memb_size);
510 string temp_string(str_val.begin(),str_val.end());
511 field->val2buf(&temp_string);
515 H5free_memory(memb_name);
518 throw InternalErr (__FILE__, __LINE__,
519 "Only support the field of compound datatype when the field type class is integer, float, string, array or compound..");
525 H5free_memory(memb_name);
526 field->set_read_p(
true);
528 h5s->set_read_p(
true);
529 set_vec(element,h5s);
533 if(
true == has_values) {
535 throw InternalErr(__FILE__, __LINE__,
"memory type and memory space for this compound datatype should be valid.");
537 if(H5Dvlen_reclaim(memtype,mspace,H5P_DEFAULT,(
void*)&values[0])<0)
538 throw InternalErr(__FILE__, __LINE__,
"Unable to reclaim the compound datatype array.");
551 if(memb_name != NULL)
552 H5free_memory(memb_name);
555 if(
true == has_values) {
556 if(H5Dvlen_reclaim(memtype,mspace,H5P_DEFAULT,(
void*)(&values[0]))<0) {
574 bool HDF5Array::m_array_of_reference(hid_t dset_id,hid_t dtype_id)
577 hid_t memtype = H5Tget_native_type(dtype_id, H5T_DIR_ASCEND);
579 throw InternalErr(__FILE__, __LINE__,
"cannot obtain the memory data type for the dataset.");
581 hid_t d_ty_id = memtype;
582 hid_t d_dset_id = dset_id;
583 hdset_reg_ref_t *rbuf = NULL;
586 vector<int> offset(d_num_dim);
587 vector<int> count(d_num_dim);
588 vector<int> step(d_num_dim);
591 int nelms = format_constraint(&offset[0], &step[0], &count[0]);
592 vector<string> v_str(nelms);
594 BESDEBUG(
"h5",
"=read() URL type is detected. "
595 <<
"nelms=" << nelms <<
" full_size=" << d_num_elm << endl);
598 if (H5Tequal(d_ty_id, H5T_STD_REF_DSETREG) < 0) {
599 throw InternalErr(__FILE__, __LINE__,
"H5Tequal() failed");
602 if (H5Tequal(d_ty_id, H5T_STD_REF_DSETREG) > 0) {
603 BESDEBUG(
"h5",
"=read() Got regional reference. " << endl);
605 rbuf =
new hdset_reg_ref_t[d_num_elm];
607 throw InternalErr(__FILE__, __LINE__,
"new() failed.");
609 if (H5Dread(d_dset_id, H5T_STD_REF_DSETREG, H5S_ALL, H5S_ALL, H5P_DEFAULT, &rbuf[0]) < 0) {
610 throw InternalErr(__FILE__, __LINE__,
"H5Dread() failed.");
613 for (
int i = 0; i < nelms; i++) {
615 BESDEBUG(
"h5",
"=read() rbuf[" << i <<
"]" <<
616 rbuf[offset[0] + i * step[0]] << endl);
618 if (rbuf[offset[0] + i * step[0]][0] !=
'\0') {
621 hid_t did_r = H5RDEREFERENCE(d_dset_id, H5R_DATASET_REGION, rbuf[offset[0] + i * step[0]]);
623 throw InternalErr(__FILE__, __LINE__,
"H5RDEREFERENCE() failed.");
627 if (H5Iget_name(did_r, (
char *) r_name,
DODS_NAMELEN) < 0) {
628 throw InternalErr(__FILE__, __LINE__,
"H5Iget_name() failed.");
630 BESDEBUG(
"h5",
"=read() dereferenced name is " << r_name
633 string varname(r_name);
634 hid_t space_id = H5Rget_region(did_r, H5R_DATASET_REGION, rbuf[offset[0] + i * step[0]]);
636 throw InternalErr(__FILE__, __LINE__,
"H5Rget_region() failed.");
640 int ndim = H5Sget_simple_extent_ndims(space_id);
642 throw InternalErr(__FILE__, __LINE__,
"H5Sget_simple_extent_ndims() failed.");
645 BESDEBUG(
"h5",
"=read() dim is " << ndim << endl);
648 switch (H5Sget_select_type(space_id)) {
651 BESDEBUG(
"h5",
"=read() None selected." << endl);
654 case H5S_SEL_POINTS: {
655 BESDEBUG(
"h5",
"=read() Points selected." << endl);
656 hssize_t npoints = H5Sget_select_npoints(space_id);
658 throw InternalErr(__FILE__, __LINE__,
659 "Cannot determine number of elements in the dataspace selection");
662 BESDEBUG(
"h5",
"=read() npoints are " << npoints
664 vector<hsize_t> buf(npoints * ndim);
665 if (H5Sget_select_elem_pointlist(space_id, 0, npoints, &buf[0]) < 0) {
666 throw InternalErr(__FILE__, __LINE__,
"H5Sget_select_elem_pointlist() failed.");
670 for (
int j = 0; j < npoints * ndim; j++) {
671 "h5",
"=read() npoints buf[0] =" << buf[j] <<endl;
675 for (
int j = 0; j < (int) npoints; j++) {
677 expression.append(varname);
678 for (
int k = 0; k < ndim; k++) {
680 oss <<
"[" << (int) buf[j * ndim + k] <<
"]";
681 expression.append(oss.str());
683 if (j != (
int) (npoints - 1)) {
684 expression.append(
",");
687 v_str[i].append(expression);
691 case H5S_SEL_HYPERSLABS: {
692 vector<hsize_t> start(ndim);
693 vector<hsize_t> end(ndim);
695 BESDEBUG(
"h5",
"=read() Slabs selected." << endl);
696 BESDEBUG(
"h5",
"=read() nblock is " <<
697 H5Sget_select_hyper_nblocks(space_id) << endl);
699 if (H5Sget_select_bounds(space_id, &start[0], &end[0]) < 0) {
700 throw InternalErr(__FILE__, __LINE__,
"H5Sget_select_bounds() failed.");
703 for (
int j = 0; j < ndim; j++) {
705 BESDEBUG(
"h5",
"=read() start is " << start[j]
706 <<
"=read() end is " << end[j] << endl);
707 oss <<
"[" << (int) start[j] <<
":" << (
int) end[j] <<
"]";
708 expression.append(oss.str());
709 BESDEBUG(
"h5",
"=read() expression is "
710 << expression << endl)
714 if (!expression.empty()) {
715 v_str[i].append(expression);
721 BESDEBUG(
"h5",
"=read() All selected." << endl);
725 BESDEBUG(
"h5",
"Unknown space type." << endl);
738 if (H5Tequal(d_ty_id, H5T_STD_REF_OBJ) < 0) {
739 throw InternalErr(__FILE__, __LINE__,
"H5Tequal() failed.");
742 if (H5Tequal(d_ty_id, H5T_STD_REF_OBJ) > 0) {
743 BESDEBUG(
"h5",
"=read() Got object reference. " << endl);
744 vector<hobj_ref_t> orbuf;
745 orbuf.resize(d_num_elm);
746 if (H5Dread(d_dset_id, H5T_STD_REF_OBJ, H5S_ALL, H5S_ALL, H5P_DEFAULT, &orbuf[0]) < 0) {
747 throw InternalErr(__FILE__, __LINE__,
"H5Dread failed()");
750 for (
int i = 0; i < nelms; i++) {
752 hid_t did_r = H5RDEREFERENCE(d_dset_id, H5R_OBJECT, &orbuf[offset[0] + i * step[0]]);
754 throw InternalErr(__FILE__, __LINE__,
"H5RDEREFERENCE() failed.");
757 if (H5Iget_name(did_r, (
char *) r_name,
DODS_NAMELEN) < 0) {
758 throw InternalErr(__FILE__, __LINE__,
"H5Iget_name() failed.");
762 string varname(r_name);
764 BESDEBUG(
"h5",
"=read() dereferenced name is " << r_name <<endl);
768 set_value(&v_str[0], nelms);
781 void HDF5Array::m_intern_plain_array_data(
char *convbuf,hid_t memtype)
784 vector<string> v_str(d_num_elm);
785 size_t elesize = H5Tget_size(memtype);
787 throw InternalErr(__FILE__, __LINE__,
"H5Tget_size() failed.");
789 vector<char> strbuf(elesize + 1);
790 BESDEBUG(
"h5",
"=read()<check_h5str() element size=" << elesize
791 <<
" d_num_elm=" << d_num_elm << endl);
793 for (
int strindex = 0; strindex < d_num_elm; strindex++) {
794 get_strdata(strindex, &convbuf[0], &strbuf[0], elesize);
795 BESDEBUG(
"h5",
"=read()<get_strdata() strbuf=" << &strbuf[0] << endl);
796 v_str[strindex] = &strbuf[0];
799 val2buf((
void *) &v_str[0]);
803 val2buf((
void *) convbuf);
808 bool HDF5Array::do_h5_array_type_read(hid_t dsetid, hid_t memb_id,vector<char>&values,
bool has_values,
int values_offset,
809 int at_nelms,
int* at_offset,
int* at_count,
int* at_step){
812 if(has_values !=
true)
813 throw InternalErr (__FILE__, __LINE__,
"Only support the retrieval of HDF5 Array datatype values from the parent compound datatype read.");
815 hid_t at_base_type = H5Tget_super(memb_id);
816 if(at_base_type < 0) {
817 throw InternalErr (__FILE__, __LINE__,
"Fail to obtain the basetype of the array datatype.");
821 int at_ndims = H5Tget_array_ndims(memb_id);
823 H5Tclose(at_base_type);
824 throw InternalErr (__FILE__, __LINE__,
"Fail to obtain number of dimensions of the array datatype.");
827 vector<hsize_t>at_dims_h(at_ndims,0);
830 if(H5Tget_array_dims(memb_id,&at_dims_h[0])<0) {
831 H5Tclose(at_base_type);
832 throw InternalErr (__FILE__, __LINE__,
"Fail to obtain dimensions of the array datatype.");
834 vector<int>at_dims(at_ndims,0);
835 for(
int i = 0;i<at_ndims;i++) {
836 at_dims[i] = (int)at_dims_h[i];
838 int at_total_nelms = 1;
839 for (
int i = 0; i <at_ndims; i++)
840 at_total_nelms = at_total_nelms*at_dims[i];
842 H5T_class_t array_cls = H5Tget_class(at_base_type);
843 if(H5T_NO_CLASS == array_cls) {
844 H5Tclose(at_base_type);
845 throw InternalErr (__FILE__, __LINE__,
"Fail to obtain the datatype class of the array base type.");
848 size_t at_base_type_size = H5Tget_size(at_base_type);
849 if(0 == at_base_type_size){
850 H5Tclose(at_base_type);
851 throw InternalErr (__FILE__, __LINE__,
"Fail to obtain the size of the array base type.");
855 if(H5T_COMPOUND == array_cls) {
858 vector<int>at_end(at_ndims,0);
859 vector<int>at_pos(at_ndims,0);
860 for (
int i = 0; i< at_ndims; i++){
861 at_pos[i] = at_offset[i];
862 at_end[i] = at_offset[i] + (at_count[i] -1)*at_step[i];
865 int at_orig_index = INDEX_nD_TO_1D(at_dims,at_pos);
868 for (
int array_index = 0; array_index <at_nelms; array_index++) {
873 H5T_class_t child_memb_cls;
875 size_t child_memb_offset;
878 if((child_nmembs = H5Tget_nmembers(at_base_type)) < 0) {
879 H5Tclose(at_base_type);
881 throw InternalErr (__FILE__, __LINE__,
"Fail to obtain number of HDF5 compound datatype.");
884 for(child_u = 0; child_u < (unsigned)child_nmembs; child_u++) {
887 if((child_memb_id = H5Tget_member_type(at_base_type, child_u)) < 0) {
888 H5Tclose(at_base_type);
890 throw InternalErr (__FILE__, __LINE__,
"Fail to obtain the datatype of an HDF5 compound datatype member.");
894 if((child_memb_cls = H5Tget_member_class (at_base_type, child_u)) < 0) {
895 H5Tclose(child_memb_id);
896 H5Tclose(at_base_type);
898 throw InternalErr (__FILE__, __LINE__,
"Fail to obtain the datatype class of an HDF5 compound datatype member.");
902 child_memb_offset= H5Tget_member_offset(at_base_type,child_u);
905 char *child_memb_name = H5Tget_member_name(at_base_type,child_u);
906 if(child_memb_name == NULL) {
907 H5Tclose(child_memb_id);
908 H5Tclose(at_base_type);
910 throw InternalErr (__FILE__, __LINE__,
"Fail to obtain the name of an HDF5 compound datatype member.");
913 BaseType *field = h5s->var(child_memb_name);
914 if (child_memb_cls == H5T_COMPOUND) {
921 if(at_total_nelms == at_nelms) {
922 memb_h5s.do_structure_read(dsetid,child_memb_id, values,has_values,values_offset+at_base_type_size*array_index+child_memb_offset);
929 memb_h5s.do_structure_read(dsetid, child_memb_id, values,has_values,values_offset+at_base_type_size*at_orig_index+child_memb_offset);
934 else if(child_memb_cls == H5T_ARRAY) {
937 int child_at_ndims = H5Tget_array_ndims(child_memb_id);
938 if(child_at_ndims <= 0) {
939 H5Tclose(at_base_type);
940 H5Tclose(child_memb_id);
941 H5free_memory(child_memb_name);
943 throw InternalErr (__FILE__, __LINE__,
"Fail to obtain number of dimensions of the array datatype.");
948 vector<int> child_at_offset(child_at_ndims,0);
949 vector<int> child_at_count(child_at_ndims,0);
950 vector<int> child_at_step(child_at_ndims,0);
952 int child_at_nelms = h5_array_type.format_constraint(&child_at_offset[0],&child_at_step[0],&child_at_count[0]);
954 if(at_total_nelms == at_nelms) {
955 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,
956 child_at_nelms,&child_at_offset[0],&child_at_count[0],&child_at_step[0]);
959 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,
960 child_at_nelms,&child_at_offset[0],&child_at_count[0],&child_at_step[0]);
965 else if(H5T_INTEGER == child_memb_cls || H5T_FLOAT == child_memb_cls){
967 int number_index =((at_total_nelms == at_nelms)?array_index:at_orig_index);
968 if(
true == promote_char_to_short(child_memb_cls,child_memb_id)) {
969 void *src = (
void*)(&values[0] + (number_index*at_base_type_size) + values_offset +child_memb_offset);
971 memcpy(&val_int8,src,1);
972 short val_short=(short)val_int8;
973 field->val2buf(&val_short);
976 field->val2buf(&values[0] + (number_index * at_base_type_size) + values_offset+child_memb_offset);
980 else if(H5T_STRING == child_memb_cls){
982 int string_index =((at_total_nelms == at_nelms)?array_index:at_orig_index);
985 if(
true == H5Tis_variable_str(child_memb_id)) {
988 void *src = (
void*)(&values[0]+(string_index *at_base_type_size)+values_offset+child_memb_offset);
990 char*temp_bp =(
char*)src;
991 get_vlen_str_data(temp_bp,final_str);
992 field->val2buf(&final_str[0]);
996 void *src = (
void*)(&values[0]+(string_index *at_base_type_size)+values_offset+child_memb_offset);
997 vector<char> str_val;
998 size_t memb_size = H5Tget_size(child_memb_id);
999 if (memb_size == 0) {
1000 H5Tclose(child_memb_id);
1001 H5Tclose(at_base_type);
1002 H5free_memory(child_memb_name);
1004 throw InternalErr (__FILE__, __LINE__,
"Fail to obtain the size of HDF5 compound datatype.");
1006 str_val.resize(memb_size);
1007 memcpy(&str_val[0],src,memb_size);
1008 field->val2buf(&str_val[0]);
1013 H5Tclose(child_memb_id);
1014 H5Tclose(at_base_type);
1015 H5free_memory(child_memb_name);
1017 throw InternalErr (__FILE__, __LINE__,
"Unsupported datatype class for the array base type.");
1021 field->set_read_p(
true);
1022 H5free_memory(child_memb_name);
1023 H5Tclose(child_memb_id);
1026 h5s->set_read_p(
true);
1029 set_vec(array_index,h5s);
1032 vector<int>at_offsetv(at_pos.size(),0);
1033 vector<int>at_stepv(at_pos.size(),0);
1034 for (
unsigned int at_index = 0; at_index<at_pos.size();at_index++){
1035 at_offsetv[at_index] = at_offset[at_index];
1036 at_stepv[at_index] = at_step[at_index];
1039 obtain_next_pos(at_pos,at_offsetv,at_end,at_stepv,(
int)(at_pos.size()));
1040 at_orig_index = INDEX_nD_TO_1D(at_dims,at_pos);
1048 else if(H5T_INTEGER == array_cls|| H5T_FLOAT == array_cls) {
1051 if(at_total_nelms == at_nelms) {
1054 if(
true == promote_char_to_short(array_cls ,at_base_type)) {
1055 vector<char> val_int8;
1056 val_int8.resize(at_nelms);
1057 void*src = (
void*)(&values[0] +values_offset);
1058 memcpy(&val_int8[0],src,at_nelms);
1060 vector<short> val_short;
1061 for (
int i = 0; i<at_nelms; i++)
1062 val_short[i] = (
short)val_int8[i];
1064 val2buf(&val_short[0]);
1068 val2buf(&values[0] + values_offset);
1074 string dap_type =
get_dap_type(at_base_type,is_dap4());
1077 void*src = (
void*)(&values[0] + values_offset);
1080 vector<int>at_pos(at_ndims,0);
1081 for (
int i = 0; i< at_ndims; i++)
1082 at_pos[i] = at_offset[i];
1084 if( BYTE == dap_type) {
1086 vector<unsigned char>total_val;
1087 total_val.resize(at_total_nelms);
1088 memcpy(&total_val[0],src,at_total_nelms*at_base_type_size);
1090 vector<unsigned char>final_val;
1091 subset<unsigned char>(
1103 set_value((dods_byte*)&final_val[0],at_nelms);
1107 else if( INT16 == dap_type) {
1110 if(
true == promote_char_to_short(array_cls,at_base_type)) {
1111 vector<char>total_val;
1112 total_val.resize(at_total_nelms);
1113 memcpy(&total_val[0],src,at_total_nelms*at_base_type_size);
1115 vector<char>final_val;
1128 vector<short> final_val_short;
1129 final_val_short.resize(at_nelms);
1130 for(
int i = 0; i<at_nelms; i++)
1131 final_val_short[i] = final_val[i];
1133 val2buf(&final_val_short[0]);
1138 vector<short>total_val;
1139 total_val.resize(at_total_nelms);
1140 memcpy(&total_val[0],src,at_total_nelms*at_base_type_size);
1142 vector<short>final_val;
1155 val2buf(&final_val[0]);
1159 else if( UINT16 == dap_type) {
1160 vector<unsigned short>total_val;
1161 total_val.resize(at_total_nelms);
1162 memcpy(&total_val[0],src,at_total_nelms*at_base_type_size);
1164 vector<unsigned short>final_val;
1165 subset<unsigned short>(
1177 val2buf(&final_val[0]);
1180 else if(UINT32 == dap_type) {
1181 vector<unsigned int>total_val;
1182 total_val.resize(at_total_nelms);
1183 memcpy(&total_val[0],src,at_total_nelms*at_base_type_size);
1185 vector<unsigned int>final_val;
1186 subset<unsigned int>(
1197 val2buf(&final_val[0]);
1201 else if(INT32 == dap_type) {
1202 vector<int>total_val;
1203 total_val.resize(at_total_nelms);
1204 memcpy(&total_val[0],src,at_total_nelms*at_base_type_size);
1206 vector<int>final_val;
1219 val2buf(&final_val[0]);
1222 else if(FLOAT32 == dap_type) {
1223 vector<float>total_val;
1224 total_val.resize(at_total_nelms);
1225 memcpy(&total_val[0],src,at_total_nelms*at_base_type_size);
1227 vector<float>final_val;
1240 val2buf(&final_val[0]);
1243 else if(FLOAT64 == dap_type) {
1244 vector<double>total_val;
1245 total_val.resize(at_total_nelms);
1246 memcpy(&total_val[0],src,at_total_nelms*at_base_type_size);
1248 vector<double>final_val;
1263 val2buf(&final_val[0]);
1267 H5Tclose(at_base_type);
1268 throw InternalErr (__FILE__, __LINE__,
1269 "Non-supported integer or float datatypes");
1274 else if(H5T_STRING == array_cls) {
1277 vector<int>at_pos(at_ndims,0);
1278 for (
int i = 0; i< at_ndims; i++)
1279 at_pos[i] = at_offset[i];
1281 vector<string>total_strval;
1282 total_strval.resize(at_total_nelms);
1284 if(
true == H5Tis_variable_str(at_base_type)) {
1285 void *src = (
void*)(&values[0]+values_offset);
1286 char*temp_bp =(
char*)src;
1287 for(
int i = 0;i <at_total_nelms; i++){
1289 get_vlen_str_data(temp_bp,tempstrval);
1290 total_strval[i] = tempstrval;
1291 temp_bp += at_base_type_size;
1293 if(at_total_nelms == at_nelms) {
1297 set_value(total_strval,at_total_nelms);
1303 vector<string>final_val;
1316 set_value(final_val,at_nelms);
1322 void *src = (
void*)(&values[0]+values_offset);
1323 for(
int i = 0; i <at_total_nelms; i++)
1324 total_strval[i].resize(at_base_type_size);
1326 vector<char> str_val;
1327 str_val.resize(at_total_nelms*at_base_type_size);
1328 memcpy((
void*)&str_val[0],src,at_total_nelms*at_base_type_size);
1329 string total_in_one_string(str_val.begin(),str_val.end());
1330 for(
int i = 0; i<at_total_nelms;i++)
1331 total_strval[i] = total_in_one_string.substr(i*at_base_type_size,at_base_type_size);
1333 if(at_total_nelms == at_nelms)
1334 set_value(total_strval,at_total_nelms);
1336 vector<string>final_val;
1348 set_value(final_val,at_nelms);
1355 H5Tclose(at_base_type);
1356 throw InternalErr (__FILE__, __LINE__,
1357 "Only support the field of compound datatype when the field type class is integer, float, string, array or compound..");
1361 H5Tclose(at_base_type);
1368 HDF5Array::INDEX_nD_TO_1D (
const std::vector < int > &dims,
1369 const std::vector < int > &pos)
1375 assert (dims.size () == pos.size ());
1379 for (
unsigned int p = 0; p < pos.size (); p++) {
1382 for (
unsigned int j = start; j < dims.size (); j++)
1391 bool HDF5Array::obtain_next_pos(vector<int>& pos, vector<int>&start,vector<int>&end,vector<int>&step,
int rank_change) {
1393 if((pos[rank_change-1] + step[rank_change-1])<=end[rank_change-1]) {
1394 pos[rank_change-1] = pos[rank_change-1] + step[rank_change-1];
1398 if( 1 == rank_change)
1400 pos[rank_change-1] = start[rank_change-1];
1401 obtain_next_pos(pos,start,end,step,rank_change-1);
1417 template<
typename T>
1418 int HDF5Array::subset(
1425 std::vector<T> *poutput,
1429 for(
int k=0; k<edge[index]; k++)
1431 pos[index] = start[index] + k*stride[index];
1433 subset(input, rank, dim, start, stride, edge, poutput,pos,index+1);
1436 poutput->push_back(input[INDEX_nD_TO_1D( dim, pos)]);
1458 hid_t HDF5Array::mkstr(
int size, H5T_str_t pad)
1463 if ((str_type = H5Tcopy(H5T_C_S1)) < 0)
1465 if (H5Tset_size(str_type, (
size_t) size) < 0)
1467 if (H5Tset_strpad(str_type, pad) < 0)
1474 BaseType* HDF5Array::h5dims_transform_to_dap4(D4Group *grp) {
1484 for (Array::Dim_iter d = dest->dim_begin(), e = dest->dim_end(); d != e; ++d) {
1485 if (
false == (*d).name.empty()) {
1487 D4Group *temp_grp = grp;
1488 D4Dimension *d4_dim = NULL;
1491 D4Dimensions *temp_dims = temp_grp->dims();
1494 d4_dim = temp_dims->find_dim((*d).name);
1500 if(temp_grp->get_parent())
1501 temp_grp =
static_cast<D4Group*
>(temp_grp->get_parent());
1510 bool d4_dim_null = ((d4_dim==NULL)?
true:
false);
1511 if(d4_dim_null ==
true) {
1512 d4_dim =
new D4Dimension((*d).name, (*d).size);
1513 D4Dimensions * dims = grp->dims();
1514 dims->add_dim_nocopy(d4_dim);
1520 dest->set_is_dap4(
true);