bes  Updated for version 3.20.13
h5common.cc
Go to the documentation of this file.
1 // data server.
2 
3 // Copyright (c) 2007-2016 The HDF Group, Inc. and OPeNDAP, Inc.
4 //
5 // This is free software; you can redistribute it and/or modify it under the
6 // terms of the GNU Lesser General Public License as published by the Free
7 // Software Foundation; either version 2.1 of the License, or (at your
8 // option) any later version.
9 //
10 // This software is distributed in the hope that it will be useful, but
11 // WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
12 // or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public
13 // License for more details.
14 //
15 // You should have received a copy of the GNU Lesser General Public
16 // License along with this library; if not, write to the Free Software
17 // Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
18 //
19 // You can contact OPeNDAP, Inc. at PO Box 112, Saunderstown, RI. 02874-0112.
20 // You can contact The HDF Group, Inc. at 1800 South Oak Street,
21 // Suite 203, Champaign, IL 61820
22 
30 
31 #include "h5common.h"
32 
33 #include<string.h>
34 #include <libdap/InternalErr.h>
35 #include <BESDebug.h>
36 
37 
38 using namespace std;
39 using namespace libdap;
40 
45 // variable length string is handled by function read_vlen_string.
50 void get_data(hid_t dset, void *buf)
51 {
52  BESDEBUG("h5", ">get_data()" << endl);
53 
54  hid_t dtype = -1;
55  if ((dtype = H5Dget_type(dset)) < 0) {
56  throw InternalErr(__FILE__, __LINE__, "Failed to get the datatype of the dataset");
57  }
58  hid_t dspace = -1;
59  if ((dspace = H5Dget_space(dset)) < 0) {
60  H5Tclose(dtype);
61  throw InternalErr(__FILE__, __LINE__, "Failed to get the data space of the dataset");
62  }
63  // Use HDF5 H5Tget_native_type API
64  hid_t memtype = H5Tget_native_type(dtype, H5T_DIR_ASCEND);
65  if (memtype < 0) {
66  H5Tclose(dtype);
67  H5Sclose(dspace);
68  throw InternalErr(__FILE__, __LINE__, "failed to get memory type");
69  }
70 
71  if (H5Dread(dset, memtype, dspace, dspace, H5P_DEFAULT, buf)
72  < 0) {
73  H5Tclose(dtype);
74  H5Tclose(memtype);
75  H5Sclose(dspace);
76  throw InternalErr(__FILE__, __LINE__, "failed to read data");
77  }
78 
79  if (H5Tclose(dtype) < 0){
80  H5Tclose(memtype);
81  H5Sclose(dspace);
82  throw InternalErr(__FILE__, __LINE__, "Unable to release the dtype.");
83  }
84 
85  if (H5Tclose(memtype) < 0){
86  H5Sclose(dspace);
87  throw InternalErr(__FILE__, __LINE__, "Unable to release the memtype.");
88  }
89 
90  if(H5Sclose(dspace)<0) {
91  throw InternalErr(__FILE__, __LINE__, "Unable to release the data space.");
92  }
93 #if 0
94  // Supposed to release the resource at the release at the HDF5Array destructor.
95  //if (H5Dclose(dset) < 0){
96  // throw InternalErr(__FILE__, __LINE__, "Unable to close the dataset.");
97  //}
98  }
99 #endif
100 
101  BESDEBUG("h5", "<get_data()" << endl);
102 }
103 
115 void get_strdata(int strindex, char *allbuf, char *buf, int elesize)
116 {
117  char *tempvalue = allbuf; // The beginning of entire buffer.
118 
119  BESDEBUG("h5", ">get_strdata(): "
120  << " strindex=" << strindex << " allbuf=" << allbuf << endl);
121 
122  // Tokenize the convbuf.
123  // The following line causes the degradation of the performance.
124  // The code seems a leftover of a debugging process.
125 #if 0
126  for (int i = 0; i < strindex; i++) {
127  tempvalue = tempvalue + elesize;
128  }
129 #endif
130  tempvalue = tempvalue +strindex *elesize;
131 
132  strncpy(buf, tempvalue, elesize);
133  buf[elesize] = '\0';
134 }
135 
148 int
149 get_slabdata(hid_t dset, const int *offset, const int *step, const int *count, const int num_dim,
150  void *buf)
151 {
152  BESDEBUG("h5", ">get_slabdata() " << endl);
153 
154  hid_t dtype = H5Dget_type(dset);
155  if (dtype < 0) {
156  throw InternalErr(__FILE__, __LINE__, "could not get data type");
157  }
158  // Using H5T_get_native_type API
159  hid_t memtype = H5Tget_native_type(dtype, H5T_DIR_ASCEND);
160  if (memtype < 0) {
161  H5Tclose(dtype);
162  throw InternalErr(__FILE__, __LINE__, "could not get memory type");
163  }
164 
165  hid_t dspace = H5Dget_space(dset);
166  if (dspace < 0) {
167  H5Tclose(dtype);
168  H5Tclose(memtype);
169  throw InternalErr(__FILE__, __LINE__, "could not get data space");
170  }
171 
172 
173  vector<hsize_t>dyn_count;
174  vector<hsize_t>dyn_step;
175  vector<hssize_t>dyn_offset;
176  dyn_count.resize(num_dim);
177  dyn_step.resize(num_dim);
178  dyn_offset.resize(num_dim);
179 
180  for (int i = 0; i < num_dim; i++) {
181  dyn_count[i] = (hsize_t) (*count);
182  dyn_step[i] = (hsize_t) (*step);
183  dyn_offset[i] = (hssize_t) (*offset);
184  BESDEBUG("h5",
185  "count:" << dyn_count[i]
186  << " step:" << dyn_step[i]
187  << " offset:" << dyn_step[i]
188  << endl);
189  count++;
190  step++;
191  offset++;
192  }
193 
194  if (H5Sselect_hyperslab(dspace, H5S_SELECT_SET,
195  (const hsize_t *)dyn_offset.data(), dyn_step.data(),
196  dyn_count.data(), nullptr) < 0) {
197  H5Tclose(dtype);
198  H5Tclose(memtype);
199  H5Sclose(dspace);
200  throw InternalErr(__FILE__, __LINE__, "could not select hyperslab");
201  }
202 
203  hid_t memspace = H5Screate_simple(num_dim, dyn_count.data(), nullptr);
204  if (memspace < 0) {
205  H5Tclose(dtype);
206  H5Tclose(memtype);
207  H5Sclose(dspace);
208  throw InternalErr(__FILE__, __LINE__, "could not open space");
209  }
210 
211  if (H5Dread(dset, memtype, memspace, dspace, H5P_DEFAULT,
212  (void *) buf) < 0) {
213  H5Tclose(dtype);
214  H5Tclose(memtype);
215  H5Sclose(dspace);
216  H5Sclose(memspace);
217  throw InternalErr(__FILE__, __LINE__, "could not get data");
218  }
219 
220  if (H5Sclose(dspace) < 0){
221  H5Tclose(dtype);
222  H5Tclose(memtype);
223  H5Sclose(memspace);
224  throw InternalErr(__FILE__, __LINE__, "Unable to close the dspace.");
225  }
226  if (H5Sclose(memspace) < 0){
227  H5Tclose(dtype);
228  H5Tclose(memtype);
229  throw InternalErr(__FILE__, __LINE__, "Unable to close the memspace.");
230  }
231  if (H5Tclose(dtype) < 0){
232  H5Tclose(memtype);
233  throw InternalErr(__FILE__, __LINE__, "Unable to close the dtype.");
234  }
235 
236  if (H5Tclose(memtype) < 0){
237  throw InternalErr(__FILE__, __LINE__, "Unable to close the memtype.");
238  }
239 
240  BESDEBUG("h5", "<get_slabdata() " << endl);
241  return 0;
242 }
243 
244 bool read_vlen_string(hid_t dsetid, const int nelms, const hsize_t *hoffset, const hsize_t *hstep, const hsize_t *hcount,vector<string> &finstrval)
245 {
246 
247  hid_t dspace = -1;
248  hid_t mspace = -1;
249  hid_t dtypeid = -1;
250  hid_t memtype = -1;
251  bool is_scalar = false;
252 
253 
254  if ((dspace = H5Dget_space(dsetid))<0) {
255  throw InternalErr (__FILE__, __LINE__, "Cannot obtain data space.");
256  }
257 
258  if(H5S_SCALAR == H5Sget_simple_extent_type(dspace))
259  is_scalar = true;
260 
261 
262  if (false == is_scalar) {
263  if (H5Sselect_hyperslab(dspace, H5S_SELECT_SET,
264  hoffset, hstep,
265  hcount, nullptr) < 0) {
266  H5Sclose(dspace);
267  throw InternalErr (__FILE__, __LINE__, "Cannot generate the hyperslab of the HDF5 dataset.");
268  }
269 
270  int d_num_dim = H5Sget_simple_extent_ndims(dspace);
271  if(d_num_dim < 0) {
272  H5Sclose(dspace);
273  throw InternalErr (__FILE__, __LINE__, "Cannot obtain the number of dimensions of the data space.");
274  }
275 
276  mspace = H5Screate_simple(d_num_dim, hcount,nullptr);
277  if (mspace < 0) {
278  H5Sclose(dspace);
279  throw InternalErr (__FILE__, __LINE__, "Cannot create the memory space.");
280  }
281  }
282 
283 
284  if ((dtypeid = H5Dget_type(dsetid)) < 0) {
285 
286  if (false == is_scalar)
287  H5Sclose(mspace);
288  H5Sclose(dspace);
289  throw InternalErr (__FILE__, __LINE__, "Cannot obtain the datatype.");
290 
291  }
292 
293  if ((memtype = H5Tget_native_type(dtypeid, H5T_DIR_ASCEND))<0) {
294 
295  if (false == is_scalar)
296  H5Sclose(mspace);
297  H5Tclose(dtypeid);
298  H5Sclose(dspace);
299  throw InternalErr (__FILE__, __LINE__, "Fail to obtain memory datatype.");
300 
301  }
302 
303  size_t ty_size = H5Tget_size(memtype);
304  if (ty_size == 0) {
305  if (false == is_scalar)
306  H5Sclose(mspace);
307  H5Tclose(memtype);
308  H5Tclose(dtypeid);
309  H5Sclose(dspace);
310  throw InternalErr (__FILE__, __LINE__,"Fail to obtain the size of HDF5 string.");
311  }
312 
313  vector <char> strval;
314  strval.resize(nelms*ty_size);
315  hid_t read_ret = -1;
316  if (true == is_scalar)
317  read_ret = H5Dread(dsetid,memtype,H5S_ALL,H5S_ALL,H5P_DEFAULT,(void*)strval.data());
318  else
319  read_ret = H5Dread(dsetid,memtype,mspace,dspace,H5P_DEFAULT,(void*)strval.data());
320 
321  if (read_ret < 0) {
322  if (false == is_scalar)
323  H5Sclose(mspace);
324  H5Tclose(memtype);
325  H5Tclose(dtypeid);
326  H5Sclose(dspace);
327  throw InternalErr (__FILE__, __LINE__, "Fail to read the HDF5 variable length string dataset.");
328  }
329 
330  // For scalar, nelms is 1.
331  char *temp_bp = strval.data();
332  for (int i =0;i<nelms;i++) {
333  char *onestring = *(char**)temp_bp;
334  if(onestring!=nullptr )
335  finstrval[i] =string(onestring);
336  else // We will add a nullptr if onestring is nullptr.
337  finstrval[i]="";
338  temp_bp +=ty_size;
339  }
340 
341  if (false == strval.empty()) {
342  herr_t ret_vlen_claim;
343  if (true == is_scalar)
344  ret_vlen_claim = H5Dvlen_reclaim(memtype,dspace,H5P_DEFAULT,(void*)strval.data());
345  else
346  ret_vlen_claim = H5Dvlen_reclaim(memtype,mspace,H5P_DEFAULT,(void*)strval.data());
347  if (ret_vlen_claim < 0){
348  if (false == is_scalar)
349  H5Sclose(mspace);
350  H5Tclose(memtype);
351  H5Tclose(dtypeid);
352  H5Sclose(dspace);
353  throw InternalErr (__FILE__, __LINE__, "Cannot reclaim the memory buffer of the HDF5 variable length string.");
354 
355  }
356  }
357 
358  if (false == is_scalar)
359  H5Sclose(mspace);
360  H5Tclose(memtype);
361  H5Tclose(dtypeid);
362  H5Sclose(dspace);
363 
364  return true;
365 
366 }
367 
368 bool promote_char_to_short(H5T_class_t type_cls, hid_t type_id) {
369 
370  bool ret_value = false;
371  if(type_cls == H5T_INTEGER) {
372  size_t size = H5Tget_size(type_id);
373  int sign = H5Tget_sign(type_id);
374  if(size == 1 && sign == H5T_SGN_2)
375  ret_value = true;
376  }
377 
378  return ret_value;
379 
380 }
381 
382 void get_vlen_str_data(const char*temp_bp,string &finalstr_val) {
383 
384  char *onestring = *(char**)temp_bp;
385  if(onestring!=nullptr )
386  finalstr_val =string(onestring);
387  else // We will add a nullptr is onestring is nullptr.
388  finalstr_val="";
389 
390 }
void get_data(hid_t dset, void *buf)
Definition: h5common.cc:50
void get_strdata(int strindex, char *allbuf, char *buf, int elesize)
Definition: h5common.cc:115