31#include "config_hdf5.h"
35#include <libdap/InternalErr.h>
47 : Structure(n, d),var_path(vpath)
62 dynamic_cast < Structure &
>(*this) = rhs;
65 libdap::Structure::operator=(rhs);
75 ">read() dataset=" << dataset()<<endl);
80 hid_t file_id = H5Fopen(dataset().c_str(),H5F_ACC_RDONLY,H5P_DEFAULT);
82 throw InternalErr(__FILE__,__LINE__,
"Fail to obtain the HDF5 file ID .");
87 dset_id = H5Dopen2(file_id,var_path.c_str(),H5P_DEFAULT);
89 dset_id = H5Dopen2(file_id,name().c_str(),H5P_DEFAULT);
93 throw InternalErr(__FILE__,__LINE__,
"Fail to obtain the datatype .");
96 hid_t dtypeid = H5Dget_type(dset_id);
100 throw InternalErr(__FILE__,__LINE__,
"Fail to obtain the datatype .");
103 do_structure_read(dset_id,dtypeid,values,
false,0);
120void HDF5Structure::do_structure_read(hid_t dsetid, hid_t dtypeid,vector <char> &values,
bool has_values,
int values_offset) {
125 if ((memtype = H5Tget_native_type(dtypeid, H5T_DIR_ASCEND))<0) {
126 throw InternalErr (__FILE__, __LINE__,
"Fail to obtain memory datatype.");
129 if(
false == has_values) {
131 if((mspace = H5Dget_space(dsetid))<0) {
132 throw InternalErr (__FILE__, __LINE__,
"Fail to obtain memory datatype.");
135 size_t ty_size = H5Tget_size(memtype);
138 throw InternalErr (__FILE__, __LINE__,
"Fail to obtain the size of HDF5 compound datatype.");
141 values.resize(ty_size);
143 read_ret = H5Dread(dsetid,memtype,mspace,mspace,H5P_DEFAULT,(
void*)values.data());
146 throw InternalErr (__FILE__, __LINE__,
"Fail to read the HDF5 compound datatype dataset.");
153 H5T_class_t memb_cls = H5T_NO_CLASS;
155 size_t memb_offset = 0;
156 char* memb_name =
nullptr;
159 if((nmembs = H5Tget_nmembers(memtype)) < 0) {
160 throw InternalErr (__FILE__, __LINE__,
"Fail to obtain number of HDF5 compound datatype.");
163 for(
unsigned int u = 0; u < (unsigned)nmembs; u++) {
165 if((memb_id = H5Tget_member_type(memtype, u)) < 0)
166 throw InternalErr (__FILE__, __LINE__,
"Fail to obtain the datatype of an HDF5 compound datatype member.");
169 if((memb_cls = H5Tget_member_class (memtype, u)) < 0)
170 throw InternalErr (__FILE__, __LINE__,
"Fail to obtain the datatype class of an HDF5 compound datatype member.");
173 memb_offset= H5Tget_member_offset(memtype,u);
176 memb_name = H5Tget_member_name(memtype,u);
177 if(memb_name ==
nullptr)
178 throw InternalErr (__FILE__, __LINE__,
"Fail to obtain the name of an HDF5 compound datatype member.");
180 if (memb_cls == H5T_COMPOUND) {
182 memb_h5s.do_structure_read(dsetid,memb_id,values,has_values,memb_offset+values_offset);
184 else if(memb_cls == H5T_ARRAY) {
187 int at_ndims = H5Tget_array_ndims(memb_id);
189 throw InternalErr (__FILE__, __LINE__,
"Fail to obtain number of dimensions of the array datatype.");
192 vector<int> at_offset(at_ndims,0);
193 vector<int> at_count(at_ndims,0);
194 vector<int> at_step(at_ndims,0);
196 int at_nelms = h5_array_type.format_constraint(at_offset.data(),at_step.data(),at_count.data());
199 h5_array_type.do_h5_array_type_read(dsetid, memb_id,values,has_values,memb_offset+values_offset,
200 at_nelms,at_offset.data(),at_count.data(),at_step.data());
203 else if(memb_cls == H5T_INTEGER || memb_cls == H5T_FLOAT) {
204 if(
true == promote_char_to_short(memb_cls,memb_id)) {
205 void *src = (
void*)(values.data() + values_offset +memb_offset);
207 memcpy(&val_int8,src,1);
208 auto val_short=(short)val_int8;
209 var(memb_name)->val2buf(&val_short);
212 var(memb_name)->val2buf(values.data() + values_offset +memb_offset);
216 else if(memb_cls == H5T_STRING) {
219 if(
true == H5Tis_variable_str(memb_id)) {
221 void *src = (
void*)(values.data()+values_offset + memb_offset);
222 char*temp_bp = (
char*)src;
223 string final_str =
"";
224 get_vlen_str_data(temp_bp,final_str);
225 var(memb_name)->val2buf((
void*)&final_str);
230 void *src = (
void*)(values.data()+values_offset + memb_offset);
231 vector<char> str_val;
232 size_t memb_size = H5Tget_size(memb_id);
233 if (memb_size == 0) {
236 throw InternalErr (__FILE__, __LINE__,
"Fail to obtain the size of HDF5 compound datatype.");
238 str_val.resize(memb_size);
239 memcpy(str_val.data(),src,memb_size);
240 string temp_string(str_val.begin(),str_val.end());
241 var(memb_name)->val2buf(&temp_string);
254 throw InternalErr (__FILE__, __LINE__,
255 "Only support the field of compound datatype when the field type class is integer, float, string, array or compound..");
260 var(memb_name)->set_read_p(
true);
267 if((memtype != -1) && (mspace !=-1)) {
268 if(H5Dvlen_reclaim(memtype,mspace,H5P_DEFAULT,(
void*)values.data())<0)
269 throw InternalErr(__FILE__, __LINE__,
"Unable to reclaim the compound datatype array.");
279 if(memb_name !=
nullptr)
284 if((memtype != -1) && (mspace !=-1)) {
285 if(H5Dvlen_reclaim(memtype,mspace,H5P_DEFAULT,(
void*)values.data())<0)
286 throw InternalErr(__FILE__, __LINE__,
"Unable to reclaim the compound datatype array.");
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.