45 #include <InternalErr.h>
71 int HDF5Array::format_constraint(
int *offset,
int *step,
int *count) {
75 Dim_iter p = dim_begin();
77 while (p != dim_end()) {
79 int start = dimension_start(p,
true);
80 int stride = dimension_stride(p,
true);
81 int stop = dimension_stop(p,
true);
84 if (stride <= 0 || start < 0 || stop < 0 || start > stop) {
87 oss <<
"Array/Grid hyperslab indices are bad: [" << start <<
88 ":" << stride <<
":" << stop <<
"]";
89 throw Error(malformed_expr, oss.str());
94 count[id] = ((stop - start) / stride) + 1;
98 <<
"=format_constraint():"
99 <<
"id=" <<
id <<
" offset=" << offset[
id]
100 <<
" step=" << step[
id]
101 <<
" count=" << count[
id]
111 bool HDF5Array::m_array_of_structure() {
112 DBG(cerr <<
"=read() Array of Structure length=" << length() << endl);
114 vector<int> offset(d_num_dim);
115 vector<int> count(d_num_dim);
116 vector<int> step(d_num_dim);
117 int nelms = format_constraint(&offset[0], &step[0], &count[0]);
120 vector<int> picks(nelms);
122 linearize_multi_dimensions(&offset[0], &step[0], &count[0], &picks[0]);
126 throw InternalErr(__FILE__, __LINE__,
"Not a HDF5Structure");
142 if (H5Tclose(d_ty_id) < 0) {
143 throw InternalErr(__FILE__, __LINE__,
"Unable to close the datatype.");
145 if (H5Dclose(d_dset_id) < 0) {
146 throw InternalErr(__FILE__, __LINE__,
"Unable to close the dset.");
159 void HDF5Array::m_insert_simple_array(hid_t s1_tid, hsize_t *size2) {
160 int size = d_memneed / length();
161 hid_t s1_array2 = -1;
162 if (
d_type == H5T_INTEGER) {
165 = H5Tarray_create(H5T_NATIVE_CHAR, d_num_dim,
169 s1_array2 = H5Tarray_create(H5T_NATIVE_SHORT,
174 = H5Tarray_create(H5T_NATIVE_INT, d_num_dim,
178 throw InternalErr(__FILE__, __LINE__,
179 "H5Tarray_create failed for H5T_INTEGER.");
183 if (
d_type == H5T_FLOAT) {
185 s1_array2 = H5Tarray_create(H5T_NATIVE_FLOAT,
189 s1_array2 = H5Tarray_create(H5T_NATIVE_DOUBLE,
193 throw InternalErr(__FILE__, __LINE__,
194 "H5Tarray_create failed for H5T_FLOAT.");
199 if (
d_type == H5T_STRING) {
200 DBG(cerr <<
"string array is detected" << endl);
201 hid_t str_type = mkstr(size, H5T_STR_SPACEPAD);
202 s1_array2 = H5Tarray_create(str_type, d_num_dim, size2);
204 throw InternalErr(__FILE__, __LINE__,
205 "H5Tarray_create failed for H5T_STRING.");
209 if(H5Tinsert(s1_tid, name().c_str(), 0, s1_array2) < 0){
210 throw InternalErr(__FILE__, __LINE__,
211 "H5Tinsert failed for " + name());
213 if(H5Tclose(s1_array2) < 0){
214 throw InternalErr(__FILE__, __LINE__,
215 "H5Tclose failed for " + name());
223 bool HDF5Array::m_array_in_structure()
225 DBG(cerr <<
"=read() Array in Structure of length=" << length() << endl);
227 int array_index = 0, array_size = 0, entire_array_size = 0;
228 hid_t s1_tid = H5Tcreate(H5T_COMPOUND, d_memneed);
230 throw InternalErr(__FILE__, __LINE__,
"H5Tcreate failed.");
235 vector<hsize_t> size2(d_num_dim);
236 if (H5Tget_array_dims(d_ty_id, &size2[0]) < 0) {
238 throw InternalErr(__FILE__, __LINE__,
"H5Tget_array_ndims failed.");
247 BaseType *q = get_parent();
248 if (q && q->is_constructor_type()) {
250 m_insert_simple_array(s1_tid, &size2[0]);
253 parent_name = q->name();
268 while (q && q->is_constructor_type()) {
269 DBG(cerr <<
": parent_name=" << parent_name << endl);
271 hid_t stemp_tid = H5Tcreate(H5T_COMPOUND, d_memneed);
273 throw InternalErr(__FILE__, __LINE__,
"H5Tcreate failed.");
275 if (H5Tinsert(stemp_tid, parent_name.c_str(), 0, s1_tid) < 0) {
277 throw InternalErr(__FILE__, __LINE__,
"H5Tinsert failed.");
282 parent_name = q->name();
293 DBG(cerr <<
"=read() parent's element count=" << array_size << endl);
294 DBG(cerr <<
"=read() parent's entire element count=" << entire_array_size << endl);
295 DBG(cerr <<
"=read() parent's index=" << array_index << endl);
299 if (!entire_array_size){
301 throw InternalErr(__FILE__, __LINE__,
"entire_array_size is zero.");
303 vector<char> buf(entire_array_size * d_memneed);
305 if (H5Dread(d_dset_id, s1_tid, H5S_ALL, H5S_ALL, H5P_DEFAULT, static_cast<void*> (&buf[0])) < 0){
308 throw InternalErr(__FILE__, __LINE__,
"H5Dread failed.");
311 if (H5Tclose(s1_tid) < 0)
312 throw InternalErr(__FILE__, __LINE__,
"H5Tclose failed.");
317 throw InternalErr(__FILE__, __LINE__,
"array_size is zero");
319 vector<char> convbuf(array_size * d_memneed);
321 for (
int l = 0; l < array_size; l++) {
322 for (
int i = 0; i < (int) d_memneed; i++) {
323 convbuf[l * d_memneed + i] = buf[array_index * d_memneed + i];
328 if (
d_type == H5T_STRING) {
329 vector<string> v_str(d_num_elm);
330 int size = d_memneed / length();
331 vector<char> strbuf(size + 1);
332 for (
int strindex = 0; strindex < d_num_elm; strindex++) {
333 get_strdata(strindex, &convbuf[0], &strbuf[0], size);
334 DBG(cerr <<
"=read()<get_strdata() strbuf=" << &strbuf[0] << endl);
335 v_str[strindex] = &strbuf[0];
338 val2buf((
void *) &v_str[0]);
342 val2buf((
void *) &convbuf[0]);
350 bool HDF5Array::m_array_of_reference()
353 vector<int> offset(d_num_dim);
354 vector<int> count(d_num_dim);
355 vector<int> step(d_num_dim);
358 int nelms = format_constraint(&offset[0], &step[0], &count[0]);
359 vector<string> v_str(nelms);
361 DBG(cerr <<
"=read() URL type is detected. "
362 <<
"nelms=" << nelms <<
" full_size=" << d_num_elm << endl);
365 if (H5Tequal(d_ty_id, H5T_STD_REF_DSETREG) < 0) {
366 throw InternalErr(__FILE__, __LINE__,
"H5Tequal() failed");
369 if (H5Tequal(d_ty_id, H5T_STD_REF_DSETREG) > 0) {
370 DBG(cerr <<
"=read() Got regional reference. " << endl);
373 hdset_reg_ref_t *rbuf =
new hdset_reg_ref_t[d_num_elm];
377 throw InternalErr(__FILE__, __LINE__,
"new() failed.");
379 if (H5Dread(d_dset_id, H5T_STD_REF_DSETREG, H5S_ALL, H5S_ALL, H5P_DEFAULT, &rbuf[0]) < 0) {
380 throw InternalErr(__FILE__, __LINE__,
"H5Dread() failed.");
383 for (
int i = 0; i < nelms; i++) {
385 DBG(cerr <<
"=read() rbuf[" << i <<
"]" <<
386 rbuf[offset[0] + i * step[0]] << endl);
388 if (rbuf[offset[0] + i * step[0]][0] !=
'\0') {
391 hid_t did_r = H5Rdereference(d_dset_id, H5R_DATASET_REGION, rbuf[offset[0] + i * step[0]]);
393 throw InternalErr(__FILE__, __LINE__,
"H5Rdereference() failed.");
397 if (H5Iget_name(did_r, (
char *) name,
DODS_NAMELEN) < 0) {
398 throw InternalErr(__FILE__, __LINE__,
"H5Iget_name() failed.");
400 DBG(cerr <<
"=read() dereferenced name is " << name
403 string varname(name);
404 hid_t space_id = H5Rget_region(did_r, H5R_DATASET_REGION, rbuf[offset[0] + i * step[0]]);
406 throw InternalErr(__FILE__, __LINE__,
"H5Rget_region() failed.");
410 int ndim = H5Sget_simple_extent_ndims(space_id);
412 throw InternalErr(__FILE__, __LINE__,
"H5Sget_simple_extent_ndims() failed.");
415 DBG(cerr <<
"=read() dim is " << ndim << endl);
418 switch (H5Sget_select_type(space_id)) {
421 DBG(cerr <<
"=read() None selected." << endl);
424 case H5S_SEL_POINTS: {
425 DBG(cerr <<
"=read() Points selected." << endl);
426 hssize_t npoints = H5Sget_select_npoints(space_id);
428 throw InternalErr(__FILE__, __LINE__,
429 "Cannot determine number of elements in the dataspace selection");
432 DBG(cerr <<
"=read() npoints are " << npoints
434 vector<hsize_t> buf(npoints * ndim);
435 if (H5Sget_select_elem_pointlist(space_id, 0, npoints, &buf[0]) < 0) {
436 throw InternalErr(__FILE__, __LINE__,
"H5Sget_select_elem_pointlist() failed.");
440 for (
int j = 0; j < npoints * ndim; j++) {
441 cerr <<
"=read() npoints buf[0] =" << buf[j] <<endl;
445 for (
int j = 0; j < (int) npoints; j++) {
447 expression.append(varname);
448 for (
int k = 0; k < ndim; k++) {
450 oss <<
"[" << (int) buf[j * ndim + k] <<
"]";
451 expression.append(oss.str());
453 if (j != (
int) (npoints - 1)) {
454 expression.append(
",");
457 v_str[i].append(expression);
461 case H5S_SEL_HYPERSLABS: {
462 vector<hsize_t> start(ndim);
463 vector<hsize_t> end(ndim);
465 DBG(cerr <<
"=read() Slabs selected." << endl);
466 DBG(cerr <<
"=read() nblock is " <<
467 H5Sget_select_hyper_nblocks(space_id) << endl);
469 if (H5Sget_select_bounds(space_id, &start[0], &end[0]) < 0) {
470 throw InternalErr(__FILE__, __LINE__,
"H5Sget_select_bounds() failed.");
473 for (
int j = 0; j < ndim; j++) {
475 DBG(cerr <<
"=read() start is " << start[j]
476 <<
"=read() end is " << end[j] << endl);
477 oss <<
"[" << (int) start[j] <<
":" << (
int) end[j] << "]";
478 expression.append(oss.str());
479 DBG(cerr << "=
read() expression is "
480 << expression << endl)
484 if (!expression.empty()) {
485 v_str[i].append(expression);
491 DBG(cerr <<
"=read() All selected." << endl);
495 DBG(cerr <<
"Unknown space type." << endl);
508 if (H5Tequal(d_ty_id, H5T_STD_REF_OBJ) < 0) {
509 throw InternalErr(__FILE__, __LINE__,
"H5Tequal() failed.");
512 if (H5Tequal(d_ty_id, H5T_STD_REF_OBJ) > 0) {
513 DBG(cerr <<
"=read() Got object reference. " << endl);
514 vector<hobj_ref_t> rbuf;
515 rbuf.resize(d_num_elm);
516 if (H5Dread(d_dset_id, H5T_STD_REF_OBJ, H5S_ALL, H5S_ALL, H5P_DEFAULT, &rbuf[0]) < 0) {
517 throw InternalErr(__FILE__, __LINE__,
"H5Dread failed()");
520 for (
int i = 0; i < nelms; i++) {
522 hid_t did_r = H5Rdereference(d_dset_id, H5R_OBJECT, &rbuf[offset[0] + i * step[0]]);
524 throw InternalErr(__FILE__, __LINE__,
"H5Rdereference() failed.");
527 if (H5Iget_name(did_r, (
char *) name,
DODS_NAMELEN) < 0) {
528 throw InternalErr(__FILE__, __LINE__,
"H5Iget_name() failed.");
532 string varname(name);
534 DBG(cerr <<
"=read() dereferenced name is " << name <<endl);
538 set_value(&v_str[0], nelms);
546 void HDF5Array::m_intern_plain_array_data(
char *convbuf)
549 vector<string> v_str(d_num_elm);
550 size_t elesize = H5Tget_size(d_ty_id);
552 throw InternalErr(__FILE__, __LINE__,
"H5Tget_size() failed.");
554 vector<char> strbuf(elesize + 1);
555 DBG(cerr <<
"=read()<check_h5str() element size=" << elesize
556 <<
" d_num_elm=" << d_num_elm << endl);
558 for (
int strindex = 0; strindex < d_num_elm; strindex++) {
559 get_strdata(strindex, &convbuf[0], &strbuf[0], elesize);
560 DBG(cerr <<
"=read()<get_strdata() strbuf=" << &strbuf[0] << endl);
561 v_str[strindex] = &strbuf[0];
567 if(H5Tclose(d_ty_id) <0) {
568 throw InternalErr(__FILE__,__LINE__,
"H5Tclose() failed.");
572 if (H5Dclose(d_dset_id) < 0) {
573 throw InternalErr(__FILE__, __LINE__,
"H5Dclose() failed.");
577 val2buf((
void *) &v_str[0]);
581 val2buf((
void *) convbuf);
589 <<
">read() dataset=" << dataset()
590 <<
" data_type_id=" << d_ty_id <<
" name=" << name()
592 <<
" dimension=" << d_num_dim
593 <<
" data_size=" << d_memneed <<
" length=" << length()
597 return m_array_of_structure();
607 return m_array_in_structure();
611 return m_array_of_reference();
613 vector<int> offset(d_num_dim);
614 vector<int> count(d_num_dim);
615 vector<int> step(d_num_dim);
616 int nelms = format_constraint(&offset[0], &step[0], &count[0]);
618 if (H5Tis_variable_str(d_ty_id) && H5Tget_class(d_ty_id) == H5T_STRING) {
620 bool status =
read_vlen_string(d_dset_id, d_ty_id, nelms, &offset[0], &step[0], &count[0]);
624 if (H5Tis_variable_str(d_ty_id) < 0) {
625 throw InternalErr(__FILE__, __LINE__,
"H5Tis_variable_str() failed.");
627 if (H5Tget_class(d_ty_id) < 0) {
628 throw InternalErr(__FILE__, __LINE__,
"H5Tget_class() failed.");
631 if (nelms == d_num_elm) {
632 vector<char> convbuf(d_memneed);
633 get_data(d_dset_id, (
void *) &convbuf[0]);
637 if (1 == H5Tget_size(d_ty_id) && H5T_SGN_2 == H5Tget_sign(d_ty_id))
639 vector<short> convbuf2(nelms);
640 for (
int i = 0; i < nelms; i++) {
641 convbuf2[i] = (
signed char) (convbuf[i]);
642 DBG(cerr <<
"convbuf[" << i <<
"]="
643 << (
signed char)convbuf[i] << endl);
644 DBG(cerr <<
"convbuf2[" << i <<
"]="
645 << convbuf2[i] << endl)
649 m_intern_plain_array_data((
char*) &convbuf2[0]);
653 m_intern_plain_array_data(&convbuf[0]);
656 size_t data_size = nelms * H5Tget_size(d_ty_id);
658 throw InternalErr(__FILE__, __LINE__,
"get_size failed");
659 vector<char> convbuf(data_size);
660 get_slabdata(d_dset_id, &offset[0], &step[0], &count[0], d_num_dim, &convbuf[0]);
664 vector<short> convbuf2(data_size);
665 for (
int i = 0; i < (int)data_size; i++) {
666 convbuf2[i] =
static_cast<signed char> (convbuf[i]);
668 m_intern_plain_array_data((
char*) &convbuf2[0]);
672 m_intern_plain_array_data(&convbuf[0]);
714 int HDF5Array::linearize_multi_dimensions(
int *start,
int *stride,
int *count,
int *picks)
716 DBG(cerr <<
">linearize_multi_dimensions()" << endl);
719 vector<int> dim(d_num_dim);
720 Dim_iter p2 = dim_begin();
722 while (p2 != dim_end()) {
723 int a_size = dimension_size(p2,
false);
724 DBG(cerr <<
"dimension[" <<
id <<
"] = " << a_size << endl);
726 total = total * a_size;
731 vector<int> temp_count(d_num_dim);
735 int temp_count_dim = 0;
738 for (i = 0; i < d_num_dim; i++)
741 int num_ele_so_far = 0;
743 for (i = 0; i < d_num_dim; i++)
744 total_ele = total_ele * count[i];
746 while (num_ele_so_far < total_ele) {
749 while (temp_count_dim < d_num_dim) {
750 temp_index = (start[d_num_dim - 1 - temp_count_dim] + (temp_count[d_num_dim - 1 - temp_count_dim] - 1)
751 * stride[d_num_dim - 1 - temp_count_dim]) * temp_dim;
752 array_index = array_index + temp_index;
753 temp_dim = temp_dim * dim[d_num_dim - 1 - temp_count_dim];
757 picks[num_ele_so_far] = array_index;
761 DBG(cerr <<
"number of element looped so far = " <<
762 num_ele_so_far << endl);
763 for (i = 0; i < d_num_dim; i++) {
764 DBG(cerr <<
"temp_count[" << i <<
"]=" << temp_count[i] <<
768 DBG(cerr <<
"index so far " << array_index << endl);
774 for (i = 0; i < d_num_dim; i++) {
775 if (temp_count[i] < count[i]) {
786 DBG(cerr <<
"<linearize_multi_dimensions()" << endl);
790 hid_t HDF5Array::mkstr(
int size, H5T_str_t pad)
795 if ((type = H5Tcopy(H5T_C_S1)) < 0)
797 if (H5Tset_size(type, (
size_t) size) < 0)
799 if (H5Tset_strpad(type, pad) < 0)
809 "=read_vlen_string(): variable string is detected with nelms = "
811 vector<char*> convbuf2(d_num_elm);
812 if (H5Dread(d_dset_id, d_ty_id, H5S_ALL, H5S_ALL, H5P_DEFAULT, &convbuf2[0]) < 0) {
813 throw InternalErr(__FILE__, __LINE__,
"H5Dread failed()");
818 for (
int strindex = 0; strindex < d_num_elm; strindex++) {
819 if (convbuf2[strindex] !=
'\0') {
820 size_max =
max(size_max, (
int) strlen(convbuf2[strindex]));
824 vector<char> strbuf(size_max + 1);
825 vector<string> v_str(d_num_elm);
827 for (
int strindex = 0; strindex < nelms; strindex++) {
828 memset(&strbuf[0], 0, size_max + 1);
830 int real_index = offset[0] + strindex * step[0];
831 if (convbuf2[real_index] !=
NULL) {
832 strncpy(&strbuf[0], convbuf2[real_index], size_max);
833 strbuf[size_max] =
'\0';
834 v_str[strindex] = &strbuf[0];
835 DBG(cerr <<
"v_str" << v_str[strindex] << endl)
839 v_str[strindex] = &strbuf[0];
843 if (H5Dclose(d_dset_id) < 0) {
844 throw InternalErr(__FILE__, __LINE__,
"H5Dclose() failed.");
847 set_value(v_str, d_num_elm);
void set_entire_array_size(int i)
returns the entire array size of this Structure if it's a part of array of structures.
hid_t get_tid()
returns HDF5 datatype id.
void set_memneed(size_t need)
remembers memory size needed.
This class converts HDF5 compound type into DAP structure for the default option. ...
HDF5Array(const string &n, const string &d, BaseType *v)
Constructor.
virtual bool read()
Reads HDF5 array data into local buffer.
H5T_class_t d_type
HDF5 data type class.
string get_dap_type(hid_t type)
returns the string representation of HDF5 type.
int get_array_index()
returns the array index of this Structure if it's a part of array of structures.
void set_numelm(int nelms)
remembers number of elements in this array.
virtual BaseType * ptr_duplicate()
Clone this instance.
void set_array_size(int i)
remembers the array size for subsetting if it's a part of array of structures.
void get_data(hid_t dset, void *buf)
will get all data of a dset dataset and put it into buf.
#define DODS_NAMELEN
Maximum length of variable or attribute name(default option only).
bool read_vlen_string(hid_t d_dset_id, hid_t d_ty_id, int nelms, int *offset, int *step, int *count)
Reads HDF5 variable length string array data into local buffer.
hid_t get_did()
returns HDF5 dataset id.
bool check_h5str(hid_t h5type)
checks if type is HDF5 string type
void set_numdim(int ndims)
remembers number of dimensions of this array.
void set_array_index(int i)
remembers the array index of this Structure if it's a part of array of structures.
This class that translates HDF5 string into DAP string for the default option.
void set_tid(hid_t type)
remembers HDF5 datatype id.
void get_strdata(int strindex, char *allbuf, char *buf, int elesize)
will get an individual string data from all string data elements and put it into buf.
int get_array_size()
returns the array size for subsetting if it's a part of array of structures.
void set_did(hid_t dset)
remembers HDF5 dataset id.
int get_slabdata(hid_t dset, int *offset, int *step, int *count, int num_dim, void *buf)
will get hyperslab data of a dataset and put it into buf.
int get_entire_array_size()
returns the entire array size of this Structure if it's a part of array of structures.
A class for handling all types of array in HDF5 for the default option.