32#include <libdap/InternalErr.h>
40 auto HDF5Structure_unique = make_unique<HDF5Structure>(*
this);
41 return HDF5Structure_unique.release();
45 : Structure(n, d),var_path(vpath)
59 libdap::Structure::operator=(rhs);
69 ">read() dataset=" << dataset()<<endl);
74 hid_t file_id = H5Fopen(dataset().c_str(),H5F_ACC_RDONLY,H5P_DEFAULT);
76 throw InternalErr(__FILE__,__LINE__,
"Fail to obtain the HDF5 file ID .");
80 if (
true == is_dap4())
81 dset_id = H5Dopen2(file_id,var_path.c_str(),H5P_DEFAULT);
83 dset_id = H5Dopen2(file_id,name().c_str(),H5P_DEFAULT);
87 throw InternalErr(__FILE__,__LINE__,
"Fail to obtain the datatype .");
91 hid_t dtypeid = H5Dget_type(dset_id);
95 throw InternalErr(__FILE__,__LINE__,
"Fail to obtain the datatype .");
98 do_structure_read(dset_id,dtypeid,values,
false,0);
115void HDF5Structure::do_structure_read(hid_t dsetid, hid_t dtypeid,vector <char> &values,
bool has_values,
size_t values_offset) {
120 if ((memtype = H5Tget_native_type(dtypeid, H5T_DIR_ASCEND)) < 0) {
121 throw InternalErr(__FILE__, __LINE__,
"Fail to obtain memory datatype.");
124 if ((mspace = H5Dget_space(dsetid)) < 0) {
125 throw InternalErr(__FILE__, __LINE__,
"Fail to obtain memory datatype.");
127 if (
false == has_values) {
129 size_t ty_size = H5Tget_size(memtype);
130 values.resize(ty_size);
132 hid_t read_ret = H5Dread(dsetid, memtype, mspace, mspace, H5P_DEFAULT, (
void *) values.data());
135 throw InternalErr(__FILE__, __LINE__,
"Fail to read the HDF5 compound datatype dataset.");
142 H5T_class_t memb_cls = H5T_NO_CLASS;
144 size_t memb_offset = 0;
145 char *memb_name =
nullptr;
148 if ((nmembs = H5Tget_nmembers(memtype)) < 0) {
149 throw InternalErr(__FILE__, __LINE__,
"Fail to obtain number of HDF5 compound datatype.");
152 for (
unsigned int u = 0; u < (unsigned) nmembs; u++) {
154 if ((memb_id = H5Tget_member_type(memtype, u)) < 0)
155 throw InternalErr(__FILE__, __LINE__,
156 "Fail to obtain the datatype of an HDF5 compound datatype member.");
159 memb_cls = H5Tget_member_class(memtype, u);
162 memb_offset = H5Tget_member_offset(memtype, u);
165 memb_name = H5Tget_member_name(memtype, u);
166 if (memb_name ==
nullptr)
167 throw InternalErr(__FILE__, __LINE__,
"Fail to obtain the name of an HDF5 compound datatype member.");
169 if (memb_cls == H5T_COMPOUND) {
171 memb_h5s.do_structure_read(dsetid, memb_id, values, has_values, memb_offset + values_offset);
172 }
else if (memb_cls == H5T_ARRAY) {
175 int at_ndims = H5Tget_array_ndims(memb_id);
177 throw InternalErr(__FILE__, __LINE__,
"Fail to obtain number of dimensions of the array datatype.");
179 HDF5Array &h5_array_type =
dynamic_cast<HDF5Array &
>(*var(memb_name));
180 vector<int64_t> at_offset(at_ndims, 0);
181 vector<int64_t> at_count(at_ndims, 0);
182 vector<int64_t> at_step(at_ndims, 0);
184 int64_t at_nelms = h5_array_type.format_constraint(at_offset.data(), at_step.data(), at_count.data());
187 h5_array_type.do_h5_array_type_read(dsetid, memb_id, values, has_values, memb_offset + values_offset,
188 at_nelms, at_offset.data(), at_count.data(), at_step.data());
190 }
else if (memb_cls == H5T_INTEGER || memb_cls == H5T_FLOAT || memb_cls == H5T_STRING) {
191 do_structure_read_atomic(memb_id, memb_name, memb_cls, values, values_offset, memb_offset);
195 throw InternalErr(__FILE__, __LINE__,
196 "Only support the field of compound datatype when the field type class is integer, float, string, array or compound..");
200 var(memb_name)->set_read_p(
true);
207 catch_free(memb_name, memb_id, memtype, mspace, values);
211 if (H5Dvlen_reclaim(memtype, mspace, H5P_DEFAULT, (
void *) values.data()) < 0)
212 throw InternalErr(__FILE__, __LINE__,
"Unable to reclaim the compound datatype array.");
218void HDF5Structure::do_structure_read_atomic(hid_t memb_id,
char *memb_name, H5T_class_t memb_cls,
219 const vector<char> &values,
size_t values_offset,
220 size_t memb_offset) {
223 if (memb_cls == H5T_INTEGER || memb_cls == H5T_FLOAT) {
224 void *src = (
void *) (values.data() + values_offset + memb_offset);
226 if (
true == promote_char_to_short(memb_cls, memb_id) && is_dap4() ==
false) {
228 memcpy(&val_int8, src, 1);
229 auto val_short = (short) val_int8;
230 var(memb_name)->val2buf(&val_short);
232 var(memb_name)->val2buf(src);
234 }
else if (memb_cls == H5T_STRING) {
235 do_structure_read_string(memb_id, memb_name, values, values_offset, memb_offset);
240void HDF5Structure::do_structure_read_string(hid_t memb_id,
char *memb_name,
241 const vector<char> &values,
size_t values_offset,
242 size_t memb_offset) {
244 void *src = (
void *) (values.data() + values_offset + memb_offset);
247 if (
true == H5Tis_variable_str(memb_id)) {
249 auto temp_bp = (
char *) src;
251 get_vlen_str_data(temp_bp, final_str);
252 var(memb_name)->val2buf((
void *) &final_str);
256 vector<char> str_val;
257 size_t memb_size = H5Tget_size(memb_id);
258 if (memb_size == 0) {
261 throw InternalErr(__FILE__, __LINE__,
"Fail to obtain the size of HDF5 compound datatype.");
263 str_val.resize(memb_size);
264 memcpy(str_val.data(), src, memb_size);
265 string temp_string(str_val.begin(), str_val.end());
266 var(memb_name)->val2buf(&temp_string);
271void HDF5Structure::catch_free(
char *memb_name, hid_t memb_id, hid_t memtype, hid_t mspace, vector<char>&values)
const {
273 if ((memtype != -1) && (mspace != -1) && (H5Dvlen_reclaim(memtype, mspace,
274 H5P_DEFAULT, (
void *) values.data()) < 0)) {
275 throw InternalErr(__FILE__, __LINE__,
"Unable to reclaim the compound datatype array.");
285 if (memb_name !=
nullptr)
This class converts HDF5 compound type into DAP structure for the default option.
HDF5Structure(const std::string &n, const std::string &vpath, const std::string &d)
Constructor.
HDF5Structure & operator=(const HDF5Structure &rhs)
Assignment operator for dynamic cast into generic Structure.
libdap::BaseType * ptr_duplicate() override
bool read() override
Reads HDF5 structure data by calling each member's read method in this structure.
Data structure and retrieval processing header for the default option.