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);
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).