38#include <libdap/Error.h> 
   39#include <libdap/InternalErr.h> 
   49    auto HDF5Array_unique = make_unique<HDF5Array>(*
this);
 
   50    return HDF5Array_unique.release();
 
 
   57int64_t HDF5Array::format_constraint(int64_t *offset, int64_t *step, int64_t *count) {
 
   66    Dim_iter p = dim_begin();
 
   68    while (p != dim_end()) {
 
   70        int64_t start = dimension_start_ll(p, 
true);
 
   71        int64_t stride = dimension_stride_ll(p, 
true);
 
   72        int64_t stop = dimension_stop_ll(p, 
true);
 
   78            oss << 
"Array/Grid hyperslab start point "<< start <<
 
   79                " is greater than stop point " <<  stop <<
".";
 
   80            throw Error(malformed_expr, oss.str());
 
   85        count[id] = ((stop - start) / stride) + 1; 
 
   89            "=format_constraint():" 
   90            << 
"id=" << 
id << 
" offset=" << offset[
id]
 
   91            << 
" step=" << step[
id]
 
   92            << 
" count=" << count[
id]
 
  106        ">read() dataset=" << dataset()
 
  107        << 
" dimension=" << d_num_dim
 
  108        << 
" data_size=" << d_memneed << 
" length=" << length()
 
  111    hid_t file_id = H5Fopen(dataset().c_str(),H5F_ACC_RDONLY,H5P_DEFAULT);
 
  113    BESDEBUG(
"h5",
"variable name is "<<name() <<endl);
 
  114    BESDEBUG(
"h5",
"variable path is  "<<var_path <<endl);
 
  118    if (
true == is_dap4())
 
  119        dset_id = H5Dopen2(file_id,var_path.c_str(),H5P_DEFAULT);
 
  121        dset_id = H5Dopen2(file_id,name().c_str(),H5P_DEFAULT);
 
  123    BESDEBUG(
"h5",
"after H5Dopen2 "<<endl);
 
  125    hid_t dtype_id = H5Dget_type(dset_id);
 
  129        throw InternalErr(__FILE__,__LINE__, 
"Fail to obtain the datatype .");
 
  133    vector<int64_t> offset(d_num_dim);
 
  134    vector<int64_t> count(d_num_dim);
 
  135    vector<int64_t> step(d_num_dim);
 
  136    int64_t nelms = format_constraint(offset.data(), step.data(), count.data()); 
 
  140    if (get_dap_type(dtype_id,is_dap4()) == 
"Url") {
 
  141        bool ret_ref = 
false;
 
  143        ret_ref = m_array_of_reference(dset_id,dtype_id);
 
  160        do_array_read(dset_id,dtype_id,values,nelms,offset.data(),count.data(),step.data());
 
 
  176void HDF5Array::do_array_read(hid_t dset_id,hid_t dtype_id,vector<char>&values,
 
  177                                   int64_t nelms,
const int64_t* offset,
const int64_t* count, 
const int64_t* step)
 
  180    H5T_class_t  tcls = H5Tget_class(dtype_id);
 
  181    bool has_values = 
false;
 
  182    size_t values_offset = 0;
 
  184    if (H5T_COMPOUND == tcls)
 
  185        m_array_of_structure(dset_id,values,has_values,values_offset,nelms,offset,count,step);
 
  186    else if(H5T_INTEGER == tcls || H5T_FLOAT == tcls || H5T_STRING == tcls) 
 
  187        m_array_of_atomic(dset_id,dtype_id,nelms,offset,count,step);
 
  188    else if (H5T_ENUM == tcls) {
 
  189        hid_t basetype = H5Tget_super(dtype_id);
 
  190        m_array_of_atomic(dset_id,basetype,nelms,offset,count,step);
 
  194        throw InternalErr(__FILE__,__LINE__,
"Fail to read the data for Unsupported datatype.");
 
  199void HDF5Array:: m_array_of_atomic(hid_t dset_id, hid_t dtype_id, int64_t nelms,
const int64_t* offset,
 
  200                                   const int64_t* count, 
const int64_t* step)
 
  204    if((memtype = H5Tget_native_type(dtype_id, H5T_DIR_ASCEND))<0) {
 
  205        throw InternalErr (__FILE__, __LINE__, 
"Fail to obtain memory datatype.");
 
  209    if (H5Tis_variable_str(memtype) && H5Tget_class(memtype) == H5T_STRING) {
 
  211        vector<hsize_t> hoffset;
 
  212        vector<hsize_t>hcount;
 
  213        vector<hsize_t>hstep;
 
  214        hoffset.resize(d_num_dim);
 
  215        hcount.resize(d_num_dim);
 
  216        hstep.resize(d_num_dim);
 
  217        for (
int i = 0; i <d_num_dim; i++) {
 
  218            hoffset[i] = (hsize_t) offset[i];
 
  219            hcount[i] = (hsize_t) count[i];
 
  220            hstep[i] = (hsize_t) step[i];
 
  222        handle_vlen_string(dset_id, memtype, nelms, hoffset, hcount, hstep);
 
  227        if (nelms == (int64_t) d_num_elm)
 
  228            handle_array_read_whole(dset_id, memtype, nelms);
 
  230            handle_array_read_slab(dset_id, memtype, nelms, offset, step, count);
 
  241void HDF5Array::handle_array_read_whole(hid_t dset_id, hid_t memtype, int64_t nelms) {
 
  243    vector<char> convbuf(d_memneed);
 
  244    get_data(dset_id, (
void *) convbuf.data());
 
  247    if (
false == is_dap4() && (1 == H5Tget_size(memtype) && H5T_SGN_2 == H5Tget_sign(memtype))) {
 
  248        vector<short> convbuf2(nelms);
 
  249        for (int64_t i = 0; i < nelms; i++) {
 
  250            convbuf2[i] = (
signed char) (convbuf[i]);
 
  251            BESDEBUG(
"h5", 
"convbuf[" << i << 
"]=" 
  252                                      << (
signed char) convbuf[i] << endl);
 
  253            BESDEBUG(
"h5", 
"convbuf2[" << i << 
"]=" 
  254                                       << convbuf2[i] << endl);
 
  256        m_intern_plain_array_data((
char *) convbuf2.data(), memtype);
 
  259        m_intern_plain_array_data(convbuf.data(), memtype);
 
  263void HDF5Array::handle_array_read_slab(hid_t dset_id, hid_t memtype, int64_t nelms,
 
  264                                       const int64_t *offset, 
const int64_t *step, 
const int64_t *count)
 
  266    size_t data_size = nelms * H5Tget_size(memtype);
 
  268        throw InternalErr(__FILE__, __LINE__, 
"get_size failed");
 
  270    vector<char> convbuf(data_size);
 
  271    get_slabdata(dset_id, offset, step, count, d_num_dim, convbuf.data());
 
  274    if (
false == is_dap4() && (1 == H5Tget_size(memtype) && H5T_SGN_2 == H5Tget_sign(memtype))) {
 
  275        vector<short> convbuf2(data_size);
 
  276        for (int64_t i = 0; i < (int)data_size; i++)
 
  277            convbuf2[i] = 
static_cast<signed char> (convbuf[i]);
 
  278        m_intern_plain_array_data((
char*) convbuf2.data(),memtype);
 
  281        m_intern_plain_array_data(convbuf.data(),memtype);
 
  284void HDF5Array::handle_vlen_string(hid_t dset_id, hid_t memtype, int64_t nelms, 
const vector<hsize_t>& hoffset,
 
  285                                   const vector<hsize_t>& hcount, 
const vector<hsize_t>& hstep){
 
  287    vector<string>finstrval;
 
  288    finstrval.resize(nelms);
 
  290        read_vlen_string(dset_id, nelms, hoffset.data(), hstep.data(), hcount.data(),finstrval);
 
  294        throw InternalErr(__FILE__,__LINE__,
"Fail to read variable-length string.");
 
  296    set_value_ll(finstrval,nelms);
 
  301bool HDF5Array::m_array_of_structure(hid_t dsetid, vector<char>&values,
bool has_values, 
size_t values_offset,
 
  302                                   int64_t nelms,
const int64_t* offset,
const int64_t* count, 
const int64_t* step) {
 
  304    BESDEBUG(
"h5", 
"=read() Array of Structure length=" << length() << endl);
 
  310    if ((dtypeid = H5Dget_type(dsetid)) < 0)
 
  311        throw InternalErr (__FILE__, __LINE__, 
"Cannot obtain the datatype.");
 
  313    if ((memtype = H5Tget_native_type(dtypeid, H5T_DIR_ASCEND))<0) {
 
  315        throw InternalErr (__FILE__, __LINE__, 
"Fail to obtain memory datatype.");
 
  318    ty_size = H5Tget_size(memtype);
 
  320    if (
false == has_values) {
 
  324        if ((dspace = H5Dget_space(dsetid))<0) {
 
  327            throw InternalErr (__FILE__, __LINE__, 
"Cannot obtain data space.");
 
  330        d_num_dim = H5Sget_simple_extent_ndims(dspace);
 
  335            throw InternalErr (__FILE__, __LINE__, 
"Cannot obtain the number of dimensions of the data space.");
 
  338        vector<hsize_t> hoffset;
 
  339        vector<hsize_t>hcount;
 
  340        vector<hsize_t>hstep;
 
  341        hoffset.resize(d_num_dim);
 
  342        hcount.resize(d_num_dim);
 
  343        hstep.resize(d_num_dim);
 
  344        for (
int i = 0; i <d_num_dim; i++) {
 
  345            hoffset[i] = (hsize_t) offset[i];
 
  346            hcount[i] = (hsize_t) count[i];
 
  347            hstep[i] = (hsize_t) step[i];
 
  350        if (H5Sselect_hyperslab(dspace, H5S_SELECT_SET,
 
  351                                hoffset.data(), hstep.data(),
 
  352                                hcount.data(), 
nullptr) < 0) {
 
  356            throw InternalErr (__FILE__, __LINE__, 
"Cannot generate the hyperslab of the HDF5 dataset.");
 
  359        mspace = H5Screate_simple(d_num_dim, hcount.data(),
nullptr);
 
  364            throw InternalErr (__FILE__, __LINE__, 
"Cannot create the memory space.");
 
  367        values.resize(nelms*ty_size);
 
  369        read_ret = H5Dread(dsetid,memtype,mspace,dspace,H5P_DEFAULT,
 
  370                           (
void*)values.data());
 
  375            throw InternalErr (__FILE__, __LINE__, 
"Fail to read the HDF5 compound datatype dataset.");
 
  382    HDF5Structure *h5s = 
nullptr;
 
  384    char* memb_name = 
nullptr;
 
  389        for (int64_t element = 0; element < nelms; ++element) { 
 
  391            h5s = 
dynamic_cast<HDF5Structure*
>(var()->ptr_duplicate());
 
  393            size_t              struct_elem_offset = values_offset + ty_size*element;
 
  395            if ((nmembs = H5Tget_nmembers(memtype)) < 0)
 
  396                throw InternalErr (__FILE__, __LINE__, 
"Fail to obtain number of HDF5 compound datatype.");
 
  398            for (
unsigned int u = 0; u < (unsigned)nmembs; u++) {
 
  400                memb_name = H5Tget_member_name(memtype,u);
 
  401                if (memb_name == 
nullptr)
 
  402                    throw InternalErr (__FILE__, __LINE__, 
"Fail to obtain the name of an HDF5 compound datatype member.");
 
  404                BaseType *field = h5s->var(memb_name);
 
  405                m_array_of_structure_member(field, memtype, u,dsetid, values, has_values, struct_elem_offset );
 
  406                H5free_memory(memb_name);
 
  409            h5s->set_read_p(
true);
 
  410            set_vec_ll((uint64_t)element,h5s);
 
  415        m_array_of_structure_close_hdf5_ids(values, has_values, mspace, dtypeid, memtype);
 
  419        m_array_of_structure_catch_close_hdf5_ids(memb_id, memb_name, values, has_values, mspace, dtypeid, memtype);
 
  430void HDF5Array:: m_array_of_structure_member(BaseType *field, hid_t memtype, 
unsigned int u, hid_t dsetid,
 
  431                                             vector<char>&values,
bool has_values, 
size_t struct_elem_offset )
 const 
  435    H5T_class_t         memb_cls         = H5T_NO_CLASS;
 
  436    size_t              memb_offset      = 0;
 
  438    if((memb_id = H5Tget_member_type(memtype, u)) < 0)
 
  439        throw InternalErr (__FILE__, __LINE__, 
"Fail to obtain the datatype of an HDF5 compound datatype member.");
 
  442    if((memb_cls = H5Tget_member_class (memtype, u)) < 0)
 
  443        throw InternalErr (__FILE__, __LINE__, 
"Fail to obtain the datatype class of an HDF5 compound datatype member.");
 
  448    memb_offset= H5Tget_member_offset(memtype,u);
 
  450    if (memb_cls == H5T_COMPOUND) {
 
  451        HDF5Structure &memb_h5s = 
dynamic_cast<HDF5Structure&
>(*field);
 
  452        memb_h5s.do_structure_read(dsetid, memb_id,values,has_values,(
int)(memb_offset+struct_elem_offset));
 
  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.");
 
  462        vector<int64_t> at_offset(at_ndims,0);
 
  463        vector<int64_t> at_count(at_ndims,0);
 
  464        vector<int64_t> at_step(at_ndims,0);
 
  466        int64_t at_nelms = h5_array_type.format_constraint(at_offset.data(),at_step.data(),at_count.data());
 
  469        h5_array_type.do_h5_array_type_read(dsetid,memb_id,values,has_values,(
int)(memb_offset+struct_elem_offset),
 
  470                                            at_nelms,at_offset.data(),at_count.data(),at_step.data());
 
  472    else if(memb_cls == H5T_INTEGER || memb_cls == H5T_FLOAT) {
 
  475        if (
true == promote_char_to_short(memb_cls,memb_id) && (field->is_dap4() == 
false)) {
 
  477            auto src = (
const void*)(values.data() + struct_elem_offset +memb_offset);
 
  479            memcpy(&val_int8,src,1);
 
  480            auto val_short=(short)val_int8;
 
  481            field->val2buf(&val_short);
 
  484            field->val2buf(values.data() + struct_elem_offset +memb_offset);
 
  487    else if(memb_cls == H5T_STRING) {
 
  490        if (
true == H5Tis_variable_str(memb_id)) {
 
  491            auto src = (
void*)(values.data()+struct_elem_offset + memb_offset);
 
  493            get_vlen_str_data((
char*)src,final_str);
 
  494            field->val2buf(&final_str);
 
  497            auto src = (
const void*)(values.data()+struct_elem_offset + memb_offset);
 
  498            vector<char> str_val;
 
  499            size_t memb_size = H5Tget_size(memb_id);
 
  500            if (memb_size == 0) {
 
  502                throw InternalErr (__FILE__, __LINE__,
"Fail to obtain the size of HDF5 compound datatype.");
 
  504            str_val.resize(memb_size);
 
  505            memcpy(str_val.data(),src,memb_size);
 
  506            string temp_string(str_val.begin(),str_val.end());
 
  507            field->val2buf(&temp_string);
 
  512        throw InternalErr (__FILE__, __LINE__,
 
  513         "Only support the field of compound datatype when the field type class is integer, float, string, array or compound..");
 
  518    field->set_read_p(
true);
 
  522void HDF5Array::m_array_of_structure_close_hdf5_ids(vector<char> &values, 
bool has_values, hid_t mspace,
 
  523                                                    hid_t dtypeid, hid_t memtype)
 const 
  525    if (
true == has_values) {
 
  527            throw InternalErr(__FILE__, __LINE__,
 
  528                              "memory type and memory space for this compound datatype should be valid.");
 
  530        if (H5Dvlen_reclaim(memtype,mspace,H5P_DEFAULT,(
void*)values.data())<0)
 
  531            throw InternalErr(__FILE__, __LINE__, 
"Unable to reclaim the compound datatype array.");
 
  540void HDF5Array:: m_array_of_structure_catch_close_hdf5_ids(hid_t memb_id, 
char * memb_name, vector<char> &values,
 
  541                                                           bool has_values, hid_t mspace, hid_t dtypeid, hid_t memtype)
 const {
 
  545    if (memb_name != 
nullptr)
 
  546        H5free_memory(memb_name);
 
  547    if (
true == has_values) {
 
  548        if(H5Dvlen_reclaim(memtype,mspace,H5P_DEFAULT,(
void*)(values.data()))<0) {
 
  560bool HDF5Array::m_array_of_reference(hid_t dset_id,hid_t dtype_id)
 
  563#if (H5_VERS_MAJOR == 1 && (H5_VERS_MINOR == 10 || H5_VERS_MINOR == 8 || H5_VERS_MINOR == 6)) 
  564    hid_t d_dset_id = dset_id;
 
  566    vector<int64_t> offset(d_num_dim);
 
  567    vector<int64_t> count(d_num_dim);
 
  568    vector<int64_t> step(d_num_dim);
 
  570    int64_t nelms = format_constraint(offset.data(), step.data(), count.data());
 
  571    vector<string> v_str(nelms);
 
  573    BESDEBUG(
"h5", 
"=read() URL type is detected. " 
  574        << 
"nelms=" << nelms << 
" full_size=" << d_num_elm << endl);
 
  577    if (H5Tequal(dtype_id, H5T_STD_REF_DSETREG) < 0) {
 
  578        throw InternalErr(__FILE__, __LINE__, 
"H5Tequal() failed");
 
  581    if (H5Tequal(dtype_id, H5T_STD_REF_DSETREG) > 0)
 
  582        m_array_of_region_reference(d_dset_id,v_str, nelms, offset, step);
 
  585    if (H5Tequal(dtype_id, H5T_STD_REF_OBJ) < 0)
 
  586        throw InternalErr(__FILE__, __LINE__, 
"H5Tequal() failed.");
 
  588    if (H5Tequal(dtype_id, H5T_STD_REF_OBJ) > 0)
 
  589        m_array_of_object_reference( d_dset_id,  v_str, nelms,offset,step);
 
  591    set_value_ll(v_str.data(), nelms);
 
  595    return m_array_of_reference_new_h5_apis(dset_id,dtype_id);
 
  600void HDF5Array:: m_array_of_region_reference(hid_t d_dset_id, vector<string>& v_str,
 
  601                                             int64_t nelms, 
const vector<int64_t>& offset,
 
  602                                             const vector<int64_t> &step) {
 
  604    hdset_reg_ref_t *rbuf = 
nullptr;
 
  605    BESDEBUG(
"h5", 
"=read() Got regional reference. " << endl);
 
  608    rbuf = 
new hdset_reg_ref_t[d_num_elm];
 
  609    if (rbuf == 
nullptr){
 
  610        throw InternalErr(__FILE__, __LINE__, 
"new() failed.");
 
  612    if (H5Dread(d_dset_id, H5T_STD_REF_DSETREG, H5S_ALL, H5S_ALL, H5P_DEFAULT, rbuf) < 0)
 
  613        throw InternalErr(__FILE__, __LINE__, 
"H5Dread() failed.");
 
  615    for (int64_t i = 0; i < nelms; i++) {
 
  617        hdset_reg_ref_t *temp_rbuf = rbuf + offset[0]+i*step[0];
 
  620        if (temp_rbuf!= 
nullptr) {
 
  624            hid_t did_r = H5RDEREFERENCE(d_dset_id, H5R_DATASET_REGION, (
const void*)(temp_rbuf));
 
  626                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 << endl);
 
  633            string varname(r_name);
 
  634            hid_t space_id = H5Rget_region(did_r, H5R_DATASET_REGION, (
const void*)(temp_rbuf));
 
  636                throw InternalErr(__FILE__, __LINE__, 
"H5Rget_region() failed.");
 
  638            int ndim = H5Sget_simple_extent_ndims(space_id);
 
  640                throw InternalErr(__FILE__, __LINE__, 
"H5Sget_simple_extent_ndims() failed.");
 
  643            BESDEBUG(
"h5", 
"=read() dim is " << ndim << endl);
 
  646            switch (H5Sget_select_type(space_id)) {
 
  649                    BESDEBUG(
"h5", 
"=read() None selected." << endl);
 
  652                case H5S_SEL_POINTS: {
 
  653                    m_array_of_region_reference_point_selection(space_id, ndim,varname,v_str, i);
 
  656                case H5S_SEL_HYPERSLABS: {
 
  657                    m_array_of_region_reference_hyperslab_selection(space_id, ndim, varname, v_str, i);
 
  661                    BESDEBUG(
"h5", 
"=read() All selected." << endl);
 
  665                    BESDEBUG(
"h5", 
"Unknown space type." << endl);
 
  676void HDF5Array:: m_array_of_region_reference_point_selection(hid_t space_id, 
int ndim, 
const string &varname,
 
  677                                                             vector<string> &v_str,int64_t i)
 const {
 
  681    BESDEBUG(
"h5", 
"=read() Points selected." << endl);
 
  682    hssize_t npoints = H5Sget_select_npoints(space_id);
 
  684        throw InternalErr(__FILE__, __LINE__,
 
  685                          "Cannot determine number of elements in the dataspace selection");
 
  688    BESDEBUG(
"h5", 
"=read() npoints are " << npoints << endl);
 
  690    vector<hsize_t> buf(npoints * ndim);
 
  691    if (H5Sget_select_elem_pointlist(space_id, 0, npoints, buf.data()) < 0)
 
  692        throw InternalErr(__FILE__, __LINE__, 
"H5Sget_select_elem_pointlist() failed.");
 
  694    for (int64_t j = 0; j < (int) npoints; j++) {
 
  696        expression.append(varname);
 
  697        for (
int k = 0; k < ndim; k++) {
 
  699            oss << 
"[" << (int) buf[j * ndim + k] << 
"]";
 
  700            expression.append(oss.str());
 
  702        if (j != (int64_t) (npoints - 1)) {
 
  703            expression.append(
",");
 
  706    v_str[i].append(expression);
 
  710void HDF5Array:: m_array_of_region_reference_hyperslab_selection(hid_t space_id, 
int ndim, 
const string &varname,
 
  711                                                                 vector<string> &v_str,int64_t i)
 const 
  715    vector<hsize_t> start(ndim);
 
  716    vector<hsize_t> end(ndim);
 
  717    vector<hsize_t> stride(ndim);
 
  718    vector<hsize_t> s_count(ndim);
 
  719    vector<hsize_t> block(ndim);
 
  721    BESDEBUG(
"h5", 
"=read() Slabs selected." << endl);
 
  722    BESDEBUG(
"h5", 
"=read() nblock is " << H5Sget_select_hyper_nblocks(space_id) << endl);
 
  724#if (H5_VERS_MAJOR == 1 && H5_VERS_MINOR == 8) 
  725    if (H5Sget_select_bounds(space_id, start.data(), end.data()) < 0) {
 
  726        throw InternalErr(__FILE__, __LINE__, 
"H5Sget_select_bounds() failed.");
 
  729    if (H5Sget_regular_hyperslab(space_id, start.data(), stride.data(), s_count.data(),
 
  731        throw InternalErr(__FILE__, __LINE__, 
"H5Sget_regular_hyperslab() failed.");
 
  735    for (
int j = 0; j < ndim; j++) {
 
  737        BESDEBUG(
"h5", 
"start " << start[j]
 
  738                                << 
"stride " << stride[j]
 
  739                                << 
"count " << s_count[j]
 
  740                                << 
"block " << block[j]
 
  744        end[j] = start[j] + stride[j] * (s_count[j] - 1) + (block[j] - 1);
 
  745        BESDEBUG(
"h5", 
"=read() start is " << start[j]
 
  746                                           << 
"=read() end is " << end[j] << endl);
 
  747        oss << 
"[" << start[j] << 
":" << stride[j] << 
":" << end[j] << 
"]";
 
  748        expression.append(oss.str());
 
  749        BESDEBUG(
"h5", 
"=read() expression is " << expression << endl);
 
  752    if (!expression.empty())
 
  753        v_str[i].append(expression);
 
  756void HDF5Array:: m_array_of_object_reference(hid_t d_dset_id, vector<string>& v_str,
 
  757                                             int64_t nelms, 
const vector<int64_t>& offset,
 
  758                                             const vector<int64_t> &step)
 const 
  761    BESDEBUG(
"h5", 
"=read() Got object reference. " << endl);
 
  762    vector<hobj_ref_t> orbuf;
 
  763    orbuf.resize(d_num_elm);
 
  764    if (H5Dread(d_dset_id, H5T_STD_REF_OBJ, H5S_ALL, H5S_ALL,
 
  765                H5P_DEFAULT, orbuf.data()) < 0) {
 
  766        throw InternalErr(__FILE__, __LINE__, 
"H5Dread failed()");
 
  769    for (int64_t i = 0; i < nelms; i++) {
 
  772        hid_t did_r = H5RDEREFERENCE(d_dset_id, H5R_OBJECT, &orbuf[offset[0] + i * step[0]]);
 
  774            throw InternalErr(__FILE__, __LINE__, 
"H5RDEREFERENCE() failed.");
 
  777        if (H5Iget_name(did_r, (
char *) r_name, 
DODS_NAMELEN) < 0)
 
  778            throw InternalErr(__FILE__, __LINE__, 
"H5Iget_name() failed.");
 
  781        string varname(r_name);
 
  783        BESDEBUG(
"h5", 
"=read() dereferenced name is " << r_name <<endl);
 
  788bool HDF5Array::m_array_of_reference_new_h5_apis(hid_t dset_id,hid_t dtype_id) {
 
  790#if (H5_VERS_MAJOR == 1 && (H5_VERS_MINOR == 10 || H5_VERS_MINOR == 8 || H5_VERS_MINOR == 6)) 
  791    throw InternalErr(__FILE__, __LINE__, 
 
  792       "The HDF5 handler compiled with earlier version (<=110)of the HDF5 library should not call method that uses new reference APIs");
 
  796    H5R_ref_t *rbuf = 
nullptr;
 
  797    hid_t  mem_space_id = 0;
 
  803    vector<int64_t> offset(d_num_dim);
 
  804    vector<int64_t> count(d_num_dim);
 
  805    vector<int64_t> step(d_num_dim);
 
  806        vector<hsize_t> hoffset(d_num_dim);
 
  807        vector<hsize_t>hcount(d_num_dim);
 
  808        vector<hsize_t>hstep(d_num_dim);
 
  810    int64_t nelms = format_constraint(offset.data(), step.data(), count.data());
 
  811        for (
int i = 0; i <d_num_dim; i++) {
 
  812            hoffset[i] = (hsize_t) offset[i];
 
  813            hcount[i] = (hsize_t) count[i];
 
  814            hstep[i] = (hsize_t) step[i];
 
  817    BESDEBUG(
"h5", 
"=read() URL type is detected. " 
  818        << 
"nelms=" << nelms << endl);
 
  820        rbuf = 
new H5R_ref_t[nelms];
 
  822    file_space_id = H5Dget_space(dset_id);
 
  823        if(file_space_id < 0)
 
  824            throw InternalErr(__FILE__, __LINE__, 
"Fail to obtain reference dataset file space.");
 
  826        if (H5Sselect_hyperslab(file_space_id, H5S_SELECT_SET,
 
  827                               hoffset.data(), hstep.data(),
 
  828                               hcount.data(), 
nullptr) < 0)
 
  829            throw InternalErr (__FILE__, __LINE__, 
"Fail to select the hyperslab for reference dataset.");
 
  832        mem_space_id = H5Screate_simple(d_num_dim,hcount.data(),
nullptr);
 
  834            throw InternalErr(__FILE__, __LINE__, 
"Fail to obtain reference dataset memory space.");
 
  836        if(H5Dread(dset_id,H5T_STD_REF,mem_space_id,file_space_id,H5P_DEFAULT,&rbuf[0])<0)
 
  837            throw InternalErr(__FILE__, __LINE__, 
"Fail to read hyperslab reference dataset.");
 
  839        H5Sclose(mem_space_id);
 
  840        H5Sclose(file_space_id);
 
  843        vector<string> v_str;
 
  845        H5R_type_t ref_type = H5Rget_type((
const H5R_ref_t *)&rbuf[0]);
 
  848        if(ref_type != H5R_OBJECT2 && ref_type !=H5R_DATASET_REGION2)
 
  849            throw InternalErr(__FILE__, __LINE__, 
"Unsupported reference: neither object nor region references");
 
  851        for (int64_t i = 0; i < nelms; i++) {
 
  853            hid_t obj_id = H5Ropen_object((H5R_ref_t *)&rbuf[i], H5P_DEFAULT, H5P_DEFAULT);
 
  855                throw InternalErr(__FILE__, __LINE__, 
"Cannot open the object the reference points to");
 
  857            vector<char> objname;
 
  858            ssize_t objnamelen = -1;
 
  859            if ((objnamelen= H5Iget_name(obj_id,
nullptr,0))<=0) {
 
  861                throw InternalErr(__FILE__, __LINE__, 
"Cannot obtain the name length of the object the reference points to");
 
  863            objname.resize(objnamelen+1);
 
  864            if ((objnamelen= H5Iget_name(obj_id,objname.data(),objnamelen+1))<=0) {
 
  866                throw InternalErr(__FILE__, __LINE__, 
"Cannot obtain the name length of the object the reference points to");
 
  869            string objname_str = string(objname.begin(),objname.end());
 
  870            string trim_objname = objname_str.substr(0,objnamelen);
 
  873            if(ref_type == H5R_OBJECT2) 
 
  874                v_str.push_back(trim_objname);
 
  877                if(H5Rget_obj_type3((H5R_ref_t *)&rbuf[i], H5P_DEFAULT, &obj_type) < 0){
 
  879                    throw InternalErr(__FILE__, __LINE__, 
"H5Rget_obj_type3() failed.");
 
  881                if(obj_type != H5O_TYPE_DATASET) {
 
  883                    throw InternalErr(__FILE__, __LINE__, 
"Region reference must point to a dataset.");
 
  885                hid_t region_space_id = H5Ropen_region(&rbuf[i],H5P_DEFAULT,H5P_DEFAULT);
 
  886                if (region_space_id < 0) {
 
  888                    throw InternalErr(__FILE__, __LINE__, 
"Cannot obtain the space ID the reference points to");
 
  891                int ndim = H5Sget_simple_extent_ndims(region_space_id);
 
  893                    H5Sclose(region_space_id);
 
  895                    throw InternalErr(__FILE__, __LINE__, 
"H5Sget_simple_extent_ndims() failed.");
 
  899        switch (H5Sget_select_type(region_space_id)) {
 
  902            BESDEBUG(
"h5", 
"=read() None selected." << endl);
 
  905            case H5S_SEL_POINTS: {
 
  906            BESDEBUG(
"h5", 
"=read() Points selected." << endl);
 
  907            hssize_t npoints = H5Sget_select_npoints(region_space_id);
 
  909                            H5Sclose(region_space_id);
 
  911                throw InternalErr(__FILE__, __LINE__,
 
  912                    "Cannot determine number of elements in the dataspace selection");
 
  915            BESDEBUG(
"h5", 
"=read() npoints are " << npoints
 
  917            vector<hsize_t> buf(npoints * ndim);
 
  918            if (H5Sget_select_elem_pointlist(region_space_id, 0, npoints, buf.data()) < 0) {
 
  919                            H5Sclose(region_space_id);
 
  921                throw InternalErr(__FILE__, __LINE__, 
"H5Sget_select_elem_pointlist() failed.");
 
  925            for (
int j = 0; j < npoints * ndim; j++) {
 
  926                            "h5", 
"=read() npoints buf[0] =" << buf[j] <<endl;
 
  930            for (int64_t j = 0; j < (int) npoints; j++) {
 
  932                expression.append(trim_objname);
 
  933                for (
int k = 0; k < ndim; k++) {
 
  935                oss << 
"[" << (int) buf[j * ndim + k] << 
"]";
 
  936                expression.append(oss.str());
 
  938                if (j != (int64_t) (npoints - 1)) {
 
  939                expression.append(
",");
 
  942            v_str.push_back(expression);
 
  946            case H5S_SEL_HYPERSLABS: {
 
  947            vector<hsize_t> start(ndim);
 
  948            vector<hsize_t> end(ndim);
 
  949                        vector<hsize_t>stride(ndim);
 
  950                        vector<hsize_t>s_count(ndim);
 
  951                        vector<hsize_t>block(ndim);
 
  953            BESDEBUG(
"h5", 
"=read() Slabs selected." << endl);
 
  954            BESDEBUG(
"h5", 
"=read() nblock is " <<
 
  955                H5Sget_select_hyper_nblocks(region_space_id) << endl);
 
  957            if (H5Sget_regular_hyperslab(region_space_id, start.data(), stride.data(), s_count.data(), block.data()) < 0) {
 
  958                        H5Sclose(region_space_id);
 
  960                throw InternalErr(__FILE__, __LINE__, 
"H5Sget_regular_hyperslab() failed.");
 
  963            expression.append(trim_objname);
 
  964            for (
int j = 0; j < ndim; j++) {
 
  966                BESDEBUG(
"h5", 
"start " << start[j]
 
  967                                     << 
"stride "<<stride[j] 
 
  968                                     << 
"count "<< s_count[j]
 
  969                                     << 
"block "<< block[j] 
 
  973                            end[j] = start[j] + stride[j]*(s_count[j]-1)+(block[j]-1);
 
  974                BESDEBUG(
"h5", 
"=read() start is " << start[j]
 
  975                    << 
"=read() end is " << end[j] << endl);
 
  976                oss << 
"[" << start[j] << 
":" << stride[j] << 
":" << end[j] << 
"]";
 
  977                expression.append(oss.str());
 
  978                BESDEBUG(
"h5", 
"=read() expression is " 
  979                    << expression << endl)
 
  982            v_str.push_back(expression);
 
  987            BESDEBUG(
"h5", 
"=read() All selected." << endl);
 
  991            BESDEBUG(
"h5", 
"Unknown space type." << endl);
 
  994                H5Sclose(region_space_id);
 
  998        for (int64_t i = 0; i<nelms; i++)
 
  999            H5Rdestroy(&rbuf[i]);
 
 1001        H5Sclose(mem_space_id);
 
 1002        H5Sclose(file_space_id);
 
 1003    set_value_ll(v_str.data(), nelms);
 
 1009        H5Sclose(mem_space_id);
 
 1010        H5Sclose(file_space_id);
 
 1017void HDF5Array::m_intern_plain_array_data(
char *convbuf,hid_t memtype)
 
 1019    if (check_h5str(memtype)) {
 
 1021        vector<string> v_str(d_num_elm);
 
 1022        size_t elesize = H5Tget_size(memtype);
 
 1024            throw InternalErr(__FILE__, __LINE__, 
"H5Tget_size() failed.");
 
 1026        vector<char> strbuf(elesize + 1);
 
 1027        BESDEBUG(
"h5", 
"=read()<check_h5str()  element size=" << elesize
 
 1028                 << 
" d_num_elm=" << d_num_elm << endl);
 
 1030        for (int64_t strindex = 0; strindex < (int64_t)d_num_elm; strindex++) {
 
 1031            get_strdata(strindex, convbuf, strbuf.data(), (
int)elesize);
 
 1032            BESDEBUG(
"h5", 
"=read()<get_strdata() strbuf=" << strbuf.data() << endl);
 
 1033            v_str[strindex] = strbuf.data();
 
 1036        val2buf((
void *) v_str.data());
 
 1040        val2buf((
void *) convbuf);
 
 1044bool HDF5Array::do_h5_array_type_read(hid_t dsetid, hid_t memb_id,vector<char>&values,
bool has_values,
size_t values_offset,
 
 1045                                      int64_t at_nelms,int64_t* at_offset,int64_t* at_count, int64_t* at_step){
 
 1049    if(has_values != 
true) 
 
 1050        throw InternalErr (__FILE__, __LINE__,
 
 1051                           "Only support the retrieval of HDF5 Array datatype values from the parent compound datatype read.");
 
 1053    hid_t at_base_type = H5Tget_super(memb_id);
 
 1054    if (at_base_type < 0)
 
 1055        throw InternalErr (__FILE__, __LINE__, 
"Fail to obtain the basetype of the array datatype.");
 
 1058    int at_ndims = H5Tget_array_ndims(memb_id);
 
 1059    if (at_ndims <= 0) {
 
 1060        H5Tclose(at_base_type);
 
 1061        throw InternalErr (__FILE__, __LINE__, 
"Fail to obtain number of dimensions of the array datatype.");
 
 1064    vector<hsize_t>at_dims_h(at_ndims,0);
 
 1067    if (H5Tget_array_dims(memb_id,at_dims_h.data())<0) {
 
 1068        H5Tclose(at_base_type);
 
 1069        throw InternalErr (__FILE__, __LINE__, 
"Fail to obtain dimensions of the array datatype.");
 
 1071    vector<int64_t>at_dims(at_ndims,0);
 
 1072    for (int64_t i = 0;i<at_ndims;i++)
 
 1073        at_dims[i] = (int64_t)at_dims_h[i];
 
 1075    int64_t at_total_nelms = 1;
 
 1076    for (
int i = 0; i <at_ndims; i++) 
 
 1077        at_total_nelms = at_total_nelms*at_dims[i];
 
 1079    H5T_class_t array_cls = H5Tget_class(at_base_type);
 
 1080    size_t at_base_type_size = H5Tget_size(at_base_type);
 
 1083    if(H5T_COMPOUND == array_cls) {
 
 1086        vector<int64_t> at_end(at_ndims, 0);
 
 1087        vector<int64_t> at_pos(at_ndims, 0);
 
 1088        for (
int i = 0; i < at_ndims; i++) {
 
 1089            at_pos[i] = at_offset[i];
 
 1090            at_end[i] = at_offset[i] + (at_count[i] - 1) * at_step[i];
 
 1093        int64_t at_orig_index = INDEX_nD_TO_1D(at_dims, at_pos);
 
 1096        for (int64_t array_index = 0; array_index < at_nelms; array_index++) {
 
 1099            auto h5s = 
dynamic_cast<HDF5Structure *
>(var()->ptr_duplicate());
 
 1100            hid_t child_memb_id;
 
 1101            H5T_class_t child_memb_cls;
 
 1103            size_t child_memb_offset;
 
 1105            if ((child_nmembs = H5Tget_nmembers(at_base_type)) < 0) {
 
 1106                H5Tclose(at_base_type);
 
 1108                throw InternalErr(__FILE__, __LINE__, 
"Fail to obtain number of HDF5 compound datatype.");
 
 1111            for (
unsigned child_u = 0; child_u < (unsigned) child_nmembs; child_u++) {
 
 1114                if ((child_memb_id = H5Tget_member_type(at_base_type, child_u)) < 0) {
 
 1115                    H5Tclose(at_base_type);
 
 1117                    throw InternalErr(__FILE__, __LINE__,
 
 1118                                      "Fail to obtain the datatype of an HDF5 compound datatype member.");
 
 1122                if ((child_memb_cls = H5Tget_member_class(at_base_type, child_u)) < 0) {
 
 1123                    H5Tclose(child_memb_id);
 
 1124                    H5Tclose(at_base_type);
 
 1126                    throw InternalErr(__FILE__, __LINE__,
 
 1127                                      "Fail to obtain the datatype class of an HDF5 compound datatype member.");
 
 1131                child_memb_offset = H5Tget_member_offset(at_base_type, child_u);
 
 1134                char *child_memb_name = H5Tget_member_name(at_base_type, child_u);
 
 1135                if (child_memb_name == 
nullptr) {
 
 1136                    H5Tclose(child_memb_id);
 
 1137                    H5Tclose(at_base_type);
 
 1139                    throw InternalErr(__FILE__, __LINE__,
 
 1140                                      "Fail to obtain the name of an HDF5 compound datatype member.");
 
 1143                BaseType *field = h5s->var(child_memb_name);
 
 1144                H5free_memory(child_memb_name);
 
 1146                    do_h5_array_type_read_base_compound_member(dsetid, field, child_memb_id, child_memb_cls, values,
 
 1147                                           has_values, values_offset, at_nelms, at_total_nelms, at_base_type_size,
 
 1148                                           array_index, at_orig_index, child_memb_offset);
 
 1155            h5s->set_read_p(
true);
 
 1158            set_vec_ll((uint64_t) array_index, h5s);
 
 1161            vector<int64_t> at_offsetv(at_pos.size(), 0);
 
 1162            vector<int64_t> at_stepv(at_pos.size(), 0);
 
 1163            for (int64_t at_index = 0; at_index < (int64_t) (at_pos.size()); at_index++) {
 
 1164                at_offsetv[at_index] = at_offset[at_index];
 
 1165                at_stepv[at_index] = at_step[at_index];
 
 1168            obtain_next_pos(at_pos, at_offsetv, at_end, at_stepv, (
int) (at_pos.size()));
 
 1169            at_orig_index = INDEX_nD_TO_1D(at_dims, at_pos);
 
 1173    else if(H5T_INTEGER == array_cls|| H5T_FLOAT == array_cls) {
 
 1174        do_h5_array_type_read_base_atomic(array_cls, at_base_type, at_base_type_size, values, values_offset, at_nelms,
 
 1175                                          at_total_nelms,at_ndims, at_dims, at_offset, at_step, at_count);
 
 1177    else if(H5T_STRING == array_cls) {
 
 1180        vector<int64_t>at_pos(at_ndims,0);
 
 1181        for (
int i = 0; i< at_ndims; i++)
 
 1182            at_pos[i] = at_offset[i];
 
 1184        vector<string>total_strval;
 
 1185        total_strval.resize(at_total_nelms);
 
 1187        if (
true == H5Tis_variable_str(at_base_type)) {
 
 1188            auto src = (
void*)(values.data()+values_offset);
 
 1189            auto temp_bp =(
char*)src;
 
 1190            for (int64_t i = 0;i <at_total_nelms; i++){
 
 1192                get_vlen_str_data(temp_bp,tempstrval);
 
 1193                total_strval[i] = tempstrval;
 
 1194                temp_bp += at_base_type_size;
 
 1196            if (at_total_nelms == at_nelms)
 
 1197                set_value_ll(total_strval,at_total_nelms);
 
 1199                vector<string>final_val;
 
 1201                              total_strval.data(),
 
 1212                set_value_ll(final_val,at_nelms);
 
 1218            auto src = (
void*)(values.data()+values_offset);
 
 1219            for(int64_t i = 0; i <at_total_nelms; i++)
 
 1220                total_strval[i].resize(at_base_type_size);
 
 1222            vector<char> str_val;
 
 1223            str_val.resize(at_total_nelms*at_base_type_size);
 
 1224            memcpy((
void*)str_val.data(),src,at_total_nelms*at_base_type_size);
 
 1225            string total_in_one_string(str_val.begin(),str_val.end());
 
 1226            for (int64_t i = 0; i<at_total_nelms;i++)
 
 1227                total_strval[i] = total_in_one_string.substr(i*at_base_type_size,at_base_type_size);
 
 1229            if (at_total_nelms == at_nelms)
 
 1230                set_value_ll(total_strval,at_total_nelms);
 
 1232                vector<string>final_val;
 
 1234                               total_strval.data(),
 
 1244                set_value_ll(final_val,at_nelms);
 
 1250        H5Tclose(at_base_type);
 
 1251        throw InternalErr (__FILE__, __LINE__, 
 
 1252                     "Only support the field of compound datatype when the field type class is integer, float, string, array or compound..");
 
 1255    H5Tclose(at_base_type);
 
 1260void HDF5Array:: do_h5_array_type_read_base_compound_member(hid_t dsetid, BaseType *field, hid_t child_memb_id,
 
 1261                                                            H5T_class_t child_memb_cls, vector<char>&values,
 
 1262                                                            bool has_values, 
size_t values_offset, int64_t at_nelms,
 
 1263                                                            int64_t at_total_nelms, 
size_t at_base_type_size,
 
 1264                                                            int64_t array_index, int64_t at_orig_index,
 
 1265                                                            size_t child_memb_offset)
 const {
 
 1266    if (child_memb_cls == H5T_COMPOUND) {
 
 1267        HDF5Structure &memb_h5s = 
dynamic_cast<HDF5Structure &
>(*field);
 
 1272        if (at_total_nelms == at_nelms) {
 
 1273            memb_h5s.do_structure_read(dsetid, child_memb_id, values, has_values,
 
 1274                                       values_offset + at_base_type_size * array_index + child_memb_offset);
 
 1284            memb_h5s.do_structure_read(dsetid, child_memb_id, values, has_values,
 
 1285                                       values_offset + at_base_type_size * at_orig_index +
 
 1289    else if (child_memb_cls == H5T_ARRAY) {
 
 1292        int child_at_ndims = H5Tget_array_ndims(child_memb_id);
 
 1293        if (child_at_ndims <= 0) {
 
 1294            H5Tclose(child_memb_id);
 
 1295            throw InternalErr(__FILE__, __LINE__,
 
 1296                              "Fail to obtain number of dimensions of the array datatype.");
 
 1300        vector<int64_t> child_at_offset(child_at_ndims, 0);
 
 1301        vector<int64_t> child_at_count(child_at_ndims, 0);
 
 1302        vector<int64_t> child_at_step(child_at_ndims, 0);
 
 1304        int64_t child_at_nelms = h5_array_type.format_constraint(child_at_offset.data(),
 
 1305                                                                 child_at_step.data(),
 
 1306                                                                 child_at_count.data());
 
 1307        if (at_total_nelms == at_nelms) {
 
 1308            h5_array_type.do_h5_array_type_read(dsetid, child_memb_id, values, has_values,
 
 1309                                                child_memb_offset + values_offset +
 
 1310                                                at_base_type_size * array_index,
 
 1311                                                child_at_nelms, child_at_offset.data(),
 
 1312                                                child_at_count.data(), child_at_step.data());
 
 1314            h5_array_type.do_h5_array_type_read(dsetid, child_memb_id, values, has_values,
 
 1315                                                child_memb_offset + values_offset +
 
 1316                                                at_base_type_size * at_orig_index,
 
 1317                                                child_at_nelms, child_at_offset.data(),
 
 1318                                                child_at_count.data(), child_at_step.data());
 
 1322    else if (H5T_INTEGER == child_memb_cls || H5T_FLOAT == child_memb_cls) {
 
 1324        int64_t number_index = ((at_total_nelms == at_nelms) ? array_index : at_orig_index);
 
 1325        if (
true == promote_char_to_short(child_memb_cls, child_memb_id) && (field->is_dap4() == 
false)) {
 
 1326            auto src = (
const void *) (values.data() + (number_index * at_base_type_size) + values_offset +
 
 1329            memcpy(&val_int8, src, 1);
 
 1330            auto val_short = (short) val_int8;
 
 1331            field->val2buf(&val_short);
 
 1335                    values.data() + (number_index * at_base_type_size) + values_offset + child_memb_offset);
 
 1337    else if (H5T_STRING == child_memb_cls) {
 
 1339        int64_t string_index = ((at_total_nelms == at_nelms) ? array_index : at_orig_index);
 
 1340        size_t data_offset = (size_t)string_index * at_base_type_size + values_offset +
 
 1342        do_h5_array_type_read_base_compound_member_string(field, child_memb_id, values, data_offset);
 
 1346        H5Tclose(child_memb_id);
 
 1347        throw InternalErr(__FILE__, __LINE__, 
"Unsupported datatype class for the array base type.");
 
 1349    field->set_read_p(
true);
 
 1350    H5Tclose(child_memb_id);
 
 1353void HDF5Array:: do_h5_array_type_read_base_compound_member_string(BaseType *field, hid_t child_memb_id,
 
 1354                                                            const vector<char> &values, 
size_t data_offset)
 const 
 1357    auto src = (
void *) (values.data() + data_offset);
 
 1358    if (
true == H5Tis_variable_str(child_memb_id)) {
 
 1361        auto temp_bp = (
char *) src;
 
 1362        get_vlen_str_data(temp_bp, final_str);
 
 1363        field->val2buf(&final_str[0]);
 
 1366        vector<char> str_val;
 
 1367        size_t memb_size = H5Tget_size(child_memb_id);
 
 1368        if (memb_size == 0) {
 
 1369            H5Tclose(child_memb_id);
 
 1370            throw InternalErr(__FILE__, __LINE__, 
"Fail to obtain the size of HDF5 compound datatype.");
 
 1372        str_val.resize(memb_size);
 
 1373        memcpy(str_val.data(), src, memb_size);
 
 1374        field->val2buf(str_val.data());
 
 1378void HDF5Array::do_h5_array_type_read_base_atomic(H5T_class_t array_cls, hid_t at_base_type, 
size_t at_base_type_size,
 
 1379                                                   vector<char>&values,
 
 1380                                                    size_t values_offset, int64_t at_nelms,int64_t at_total_nelms,
 
 1381                                                    int at_ndims, vector<int64_t> &at_dims, int64_t* at_offset,
 
 1382                                                    int64_t* at_step, int64_t *at_count) {
 
 1385    if (at_total_nelms == at_nelms)
 
 1386        do_h5_array_type_read_base_atomic_whole_data(array_cls, at_base_type, at_nelms, values, values_offset);
 
 1390        string dap_type = get_dap_type(at_base_type, is_dap4());
 
 1393        auto src = (
void *) (values.data() + values_offset);
 
 1396        vector<int64_t> at_pos(at_ndims, 0);
 
 1397        for (int64_t i = 0; i < at_ndims; i++)
 
 1398            at_pos[i] = at_offset[i];
 
 1400        if (BYTE == dap_type) {
 
 1402            vector<unsigned char> total_val;
 
 1403            total_val.resize(at_total_nelms);
 
 1404            memcpy(total_val.data(), src, at_total_nelms * at_base_type_size);
 
 1406            vector<unsigned char> final_val;
 
 1407            subset<unsigned char>(
 
 1419            set_value_ll(final_val.data(), at_nelms);
 
 1421        } 
else if (INT16 == dap_type) {
 
 1424            if (
true == promote_char_to_short(array_cls, at_base_type) && (is_dap4() == 
false)) {
 
 1425                vector<char> total_val;
 
 1426                total_val.resize(at_total_nelms);
 
 1427                memcpy(total_val.data(), src, at_total_nelms * at_base_type_size);
 
 1429                vector<char> final_val;
 
 1442                vector<short> final_val_short;
 
 1443                final_val_short.resize(at_nelms);
 
 1444                for (int64_t i = 0; i < at_nelms; i++)
 
 1445                    final_val_short[i] = final_val[i];
 
 1447                val2buf(final_val_short.data());
 
 1451                vector<short> total_val;
 
 1452                total_val.resize(at_total_nelms);
 
 1453                memcpy(total_val.data(), src, at_total_nelms * at_base_type_size);
 
 1455                vector<short> final_val;
 
 1468                val2buf(final_val.data());
 
 1470        } 
else if (UINT16 == dap_type) {
 
 1471            vector<unsigned short> total_val;
 
 1472            total_val.resize(at_total_nelms);
 
 1473            memcpy(total_val.data(), src, at_total_nelms * at_base_type_size);
 
 1475            vector<unsigned short> final_val;
 
 1476            subset<unsigned short>(
 
 1488            val2buf(final_val.data());
 
 1490        } 
else if (UINT32 == dap_type) {
 
 1491            vector<unsigned int> total_val;
 
 1492            total_val.resize(at_total_nelms);
 
 1493            memcpy(total_val.data(), src, at_total_nelms * at_base_type_size);
 
 1495            vector<unsigned int> final_val;
 
 1496            subset<unsigned int>(
 
 1507            val2buf(final_val.data());
 
 1510        } 
else if (INT32 == dap_type) {
 
 1511            vector<int> total_val;
 
 1512            total_val.resize(at_total_nelms);
 
 1513            memcpy(total_val.data(), src, at_total_nelms * at_base_type_size);
 
 1515            vector<int> final_val;
 
 1528            val2buf(final_val.data());
 
 1530        } 
else if (FLOAT32 == dap_type) {
 
 1531            vector<float> total_val;
 
 1532            total_val.resize(at_total_nelms);
 
 1533            memcpy(total_val.data(), src, at_total_nelms * at_base_type_size);
 
 1535            vector<float> final_val;
 
 1548            val2buf(final_val.data());
 
 1550        } 
else if (FLOAT64 == dap_type) {
 
 1551            vector<double> total_val;
 
 1552            total_val.resize(at_total_nelms);
 
 1553            memcpy(total_val.data(), src, at_total_nelms * at_base_type_size);
 
 1555            vector<double> final_val;
 
 1567            val2buf(final_val.data());
 
 1570            H5Tclose(at_base_type);
 
 1571            throw InternalErr(__FILE__, __LINE__,
 
 1572                              "Non-supported integer or float datatypes");
 
 1577void HDF5Array::do_h5_array_type_read_base_atomic_whole_data(H5T_class_t array_cls, hid_t at_base_type,int64_t at_nelms,
 
 1578                                                             vector<char> &values, 
size_t values_offset)
 
 1581    if (
true == promote_char_to_short(array_cls, at_base_type) && is_dap4() == 
false) {
 
 1583        vector<char> val_int8;
 
 1584        val_int8.resize(at_nelms);
 
 1585        auto src = (
void *) (values.data() + values_offset);
 
 1586        memcpy(val_int8.data(), src, at_nelms);
 
 1588        vector<short> val_short;
 
 1589        for (int64_t i = 0; i < at_nelms; i++)
 
 1590            val_short[i] = (
short) val_int8[i];
 
 1592        val2buf(val_short.data());
 
 1596        val2buf(values.data() + values_offset);
 
 1600HDF5Array::INDEX_nD_TO_1D (
const std::vector < int64_t > &dims,
 
 1601                const std::vector < int64_t > &pos)
 const 
 1607    assert (dims.size () == pos.size ());
 
 1611    for (
const auto &apos:pos) {
 
 1613        for (
unsigned int j = start; j < dims.size (); j++)
 
 1622bool HDF5Array::obtain_next_pos(vector<int64_t>& pos, vector<int64_t>&start,vector<int64_t>&end,vector<int64_t>&step,
 
 1625    if((pos[rank_change-1] + step[rank_change-1])<=end[rank_change-1]) {
 
 1626        pos[rank_change-1] = pos[rank_change-1] + step[rank_change-1];
 
 1630        if( 1 == rank_change)
 
 1632        pos[rank_change-1] = start[rank_change-1];
 
 1633        obtain_next_pos(pos,start,end,step,rank_change-1);
 
 1650int HDF5Array::subset(
 
 1653    vector<int64_t> & dim,
 
 1657    std::vector<T> *poutput,
 
 1658    vector<int64_t>& pos,
 
 1661    for(int64_t k=0; k<edge[index]; k++) 
 
 1663        pos[index] = start[index] + k*stride[index];
 
 1665            subset(input, rank, dim, start, stride, edge, poutput,pos,index+1);         
 
 1668            poutput->push_back(input[INDEX_nD_TO_1D( dim, pos)]);
 
 1691BaseType* HDF5Array::h5dims_transform_to_dap4(D4Group *grp,
const vector<string> &dimpath) {
 
 1693    BESDEBUG(
"h5", 
"<h5dims_transform_to_dap4" << endl);
 
 1705    for (Array::Dim_iter d = dest->dim_begin(), e = dest->dim_end(); d != e; ++d) {
 
 1707        if (
false == (*d).name.empty()) {
 
 1709            BESDEBUG(
"h5", 
"<coming to the dimension loop, has name " << (*d).name<<endl);
 
 1710            BESDEBUG(
"h5", 
"<coming to the dimension loop, has dimpath " << dimpath[k] <<endl);
 
 1711            BESDEBUG(
"h5", 
"<coming to the dimension loop, has dimpath group " 
 1712                        << dimpath[k].substr(0,dimpath[k].find_last_of(
"/")+1) <<endl);
 
 1714            D4Group *temp_grp   = grp;
 
 1715            D4Dimension *d4_dim = 
nullptr;
 
 1716            bool is_dim_nonc4_grp = handle_one_dim(d,temp_grp, d4_dim, dimpath, k);
 
 1721            if (
true == is_dim_nonc4_grp) {
 
 1722                 string err= 
"The variable " + var_path +
" has dimension ";
 
 1723                 err += dimpath[k] + 
". This dimension is not under its ancestor or the current group.";
 
 1724                 err += 
" This is not supported.";
 
 1726                 throw InternalErr(__FILE__,__LINE__,err); 
 
 1729            bool d4_dim_null = ((d4_dim==
nullptr)?
true:
false);
 
 1730            if (d4_dim_null == 
true) {
 
 1731                auto d4_dim_unique = make_unique<D4Dimension>((*d).name, (*d).size);
 
 1732                D4Dimensions * dims = grp->dims();
 
 1733                BESDEBUG(
"h5", 
"<Just before adding D4 dimension to group" << grp->FQN() <<endl);
 
 1734                d4_dim = d4_dim_unique.release();
 
 1735                dims->add_dim_nocopy(d4_dim);
 
 1742    dest->set_is_dap4(
true);
 
 1748bool HDF5Array::handle_one_dim(Array::Dim_iter d, D4Group *temp_grp, D4Dimension * &d4_dim,
 
 1749                               const vector<string> &dimpath, 
int k)
 const 
 1751    bool is_dim_nonc4_grp = 
false;
 
 1754        BESDEBUG(
"h5", 
"<coming to the group  has name " << temp_grp->name()<<endl);
 
 1755        BESDEBUG(
"h5", 
"<coming to the group  has fullpath " << temp_grp->FQN()<<endl);
 
 1758        D4Dimensions *temp_dims = temp_grp->dims();
 
 1761        d4_dim = temp_dims->find_dim((*d).name);
 
 1764        string d4_dim_path = dimpath[k].substr(0,dimpath[k].find_last_of(
"/")+1);
 
 1765        BESDEBUG(
"h5", 
"d4_dim_path is " << d4_dim_path<<endl);
 
 1767        bool ancestor_grp = 
false;
 
 1770        if(d4_dim_path.find(temp_grp->FQN())==0 || temp_grp->FQN().find(d4_dim_path)==0)
 
 1771            ancestor_grp = 
true;
 
 1775        if(d4_dim && (temp_grp->FQN() == d4_dim_path)) {
 
 1776            BESDEBUG(
"h5", 
"<FInd dimension name " << (*d).name<<endl);
 
 1778            is_dim_nonc4_grp = 
false;
 
 1783        else if( ancestor_grp == 
false) {
 
 1784            is_dim_nonc4_grp = 
true;
 
 1790        if(temp_grp->get_parent())
 
 1791            temp_grp = 
static_cast<D4Group*
>(temp_grp->get_parent());
 
 1796    return is_dim_nonc4_grp;
 
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.
 
void set_numelm(hsize_t nelms)
remembers number of elements in this array.
 
libdap::BaseType * ptr_duplicate() override
 
bool read() override
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_memneed(size_t need)
remembers memory size needed.
 
void get_data(hid_t dset, void *buf)
 
const int DODS_NAMELEN
Maximum length of variable or attribute name(default option only).