bes  Updated for version 3.20.6
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 <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  for (int i = 0; i < strindex; i++) {
124  tempvalue = tempvalue + elesize;
125  }
126 
127  strncpy(buf, tempvalue, elesize);
128  buf[elesize] = '\0';
129 }
130 
143 int
144 get_slabdata(hid_t dset, int *offset, int *step, int *count, int num_dim,
145  void *buf)
146 {
147  BESDEBUG("h5", ">get_slabdata() " << endl);
148 
149  hid_t dtype = H5Dget_type(dset);
150  if (dtype < 0) {
151  throw InternalErr(__FILE__, __LINE__, "could not get data type");
152  }
153  // Using H5T_get_native_type API
154  hid_t memtype = H5Tget_native_type(dtype, H5T_DIR_ASCEND);
155  if (memtype < 0) {
156  H5Tclose(dtype);
157  throw InternalErr(__FILE__, __LINE__, "could not get memory type");
158  }
159 
160  hid_t dspace = H5Dget_space(dset);
161  if (dspace < 0) {
162  H5Tclose(dtype);
163  H5Tclose(memtype);
164  throw InternalErr(__FILE__, __LINE__, "could not get data space");
165  }
166 
167 
168  vector<hsize_t>dyn_count;
169  vector<hsize_t>dyn_step;
170  vector<hssize_t>dyn_offset;
171  dyn_count.resize(num_dim);
172  dyn_step.resize(num_dim);
173  dyn_offset.resize(num_dim);
174 
175  for (int i = 0; i < num_dim; i++) {
176  dyn_count[i] = (hsize_t) (*count);
177  dyn_step[i] = (hsize_t) (*step);
178  dyn_offset[i] = (hssize_t) (*offset);
179  BESDEBUG("h5",
180  "count:" << dyn_count[i]
181  << " step:" << dyn_step[i]
182  << " offset:" << dyn_step[i]
183  << endl);
184  count++;
185  step++;
186  offset++;
187  }
188 
189  if (H5Sselect_hyperslab(dspace, H5S_SELECT_SET,
190  (const hsize_t *)&dyn_offset[0], &dyn_step[0],
191  &dyn_count[0], NULL) < 0) {
192  H5Tclose(dtype);
193  H5Tclose(memtype);
194  H5Sclose(dspace);
195  throw InternalErr(__FILE__, __LINE__, "could not select hyperslab");
196  }
197 
198  hid_t memspace = H5Screate_simple(num_dim, &dyn_count[0], NULL);
199  if (memspace < 0) {
200  H5Tclose(dtype);
201  H5Tclose(memtype);
202  H5Sclose(dspace);
203  throw InternalErr(__FILE__, __LINE__, "could not open space");
204  }
205 
206  if (H5Dread(dset, memtype, memspace, dspace, H5P_DEFAULT,
207  (void *) buf) < 0) {
208  H5Tclose(dtype);
209  H5Tclose(memtype);
210  H5Sclose(dspace);
211  H5Sclose(memspace);
212  throw InternalErr(__FILE__, __LINE__, "could not get data");
213  }
214 
215  if (H5Sclose(dspace) < 0){
216  H5Tclose(dtype);
217  H5Tclose(memtype);
218  H5Sclose(memspace);
219  throw InternalErr(__FILE__, __LINE__, "Unable to close the dspace.");
220  }
221  if (H5Sclose(memspace) < 0){
222  H5Tclose(dtype);
223  H5Tclose(memtype);
224  throw InternalErr(__FILE__, __LINE__, "Unable to close the memspace.");
225  }
226  if (H5Tclose(dtype) < 0){
227  H5Tclose(memtype);
228  throw InternalErr(__FILE__, __LINE__, "Unable to close the dtype.");
229  }
230 
231  if (H5Tclose(memtype) < 0){
232  throw InternalErr(__FILE__, __LINE__, "Unable to close the memtype.");
233  }
234 
235  BESDEBUG("h5", "<get_slabdata() " << endl);
236  return 0;
237 }
238 
239 bool read_vlen_string(hid_t dsetid, int nelms, hsize_t *hoffset, hsize_t *hstep, hsize_t *hcount,vector<string> &finstrval)
240 {
241 
242  hid_t dspace = -1;
243  hid_t mspace = -1;
244  hid_t dtypeid = -1;
245  hid_t memtype = -1;
246  bool is_scalar = false;
247 
248 
249  if ((dspace = H5Dget_space(dsetid))<0) {
250  throw InternalErr (__FILE__, __LINE__, "Cannot obtain data space.");
251  }
252 
253  if(H5S_SCALAR == H5Sget_simple_extent_type(dspace))
254  is_scalar = true;
255 
256 
257  if (false == is_scalar) {
258  if (H5Sselect_hyperslab(dspace, H5S_SELECT_SET,
259  hoffset, hstep,
260  hcount, NULL) < 0) {
261  H5Sclose(dspace);
262  throw InternalErr (__FILE__, __LINE__, "Cannot generate the hyperslab of the HDF5 dataset.");
263  }
264 
265  int d_num_dim = H5Sget_simple_extent_ndims(dspace);
266  if(d_num_dim < 0) {
267  H5Sclose(dspace);
268  throw InternalErr (__FILE__, __LINE__, "Cannot obtain the number of dimensions of the data space.");
269  }
270 
271  mspace = H5Screate_simple(d_num_dim, hcount,NULL);
272  if (mspace < 0) {
273  H5Sclose(dspace);
274  throw InternalErr (__FILE__, __LINE__, "Cannot create the memory space.");
275  }
276  }
277 
278 
279  if ((dtypeid = H5Dget_type(dsetid)) < 0) {
280 
281  if (false == is_scalar)
282  H5Sclose(mspace);
283  H5Sclose(dspace);
284  throw InternalErr (__FILE__, __LINE__, "Cannot obtain the datatype.");
285 
286  }
287 
288  if ((memtype = H5Tget_native_type(dtypeid, H5T_DIR_ASCEND))<0) {
289 
290  if (false == is_scalar)
291  H5Sclose(mspace);
292  H5Tclose(dtypeid);
293  H5Sclose(dspace);
294  throw InternalErr (__FILE__, __LINE__, "Fail to obtain memory datatype.");
295 
296  }
297 
298  size_t ty_size = H5Tget_size(memtype);
299  if (ty_size == 0) {
300  if (false == is_scalar)
301  H5Sclose(mspace);
302  H5Tclose(memtype);
303  H5Tclose(dtypeid);
304  H5Sclose(dspace);
305  throw InternalErr (__FILE__, __LINE__,"Fail to obtain the size of HDF5 string.");
306  }
307 
308  vector <char> strval;
309  strval.resize(nelms*ty_size);
310  hid_t read_ret = -1;
311  if (true == is_scalar)
312  read_ret = H5Dread(dsetid,memtype,H5S_ALL,H5S_ALL,H5P_DEFAULT,(void*)&strval[0]);
313  else
314  read_ret = H5Dread(dsetid,memtype,mspace,dspace,H5P_DEFAULT,(void*)&strval[0]);
315 
316  if (read_ret < 0) {
317  if (false == is_scalar)
318  H5Sclose(mspace);
319  H5Tclose(memtype);
320  H5Tclose(dtypeid);
321  H5Sclose(dspace);
322  throw InternalErr (__FILE__, __LINE__, "Fail to read the HDF5 variable length string dataset.");
323  }
324 
325  // For scalar, nelms is 1.
326  char*temp_bp = &strval[0];
327  char*onestring = NULL;
328  for (int i =0;i<nelms;i++) {
329  onestring = *(char**)temp_bp;
330  if(onestring!=NULL )
331  finstrval[i] =string(onestring);
332  else // We will add a NULL if onestring is NULL.
333  finstrval[i]="";
334  temp_bp +=ty_size;
335  }
336 
337  if (false == strval.empty()) {
338  herr_t ret_vlen_claim;
339  if (true == is_scalar)
340  ret_vlen_claim = H5Dvlen_reclaim(memtype,dspace,H5P_DEFAULT,(void*)&strval[0]);
341  else
342  ret_vlen_claim = H5Dvlen_reclaim(memtype,mspace,H5P_DEFAULT,(void*)&strval[0]);
343  if (ret_vlen_claim < 0){
344  if (false == is_scalar)
345  H5Sclose(mspace);
346  H5Tclose(memtype);
347  H5Tclose(dtypeid);
348  H5Sclose(dspace);
349  throw InternalErr (__FILE__, __LINE__, "Cannot reclaim the memory buffer of the HDF5 variable length string.");
350 
351  }
352  }
353 
354  if (false == is_scalar)
355  H5Sclose(mspace);
356  H5Tclose(memtype);
357  H5Tclose(dtypeid);
358  H5Sclose(dspace);
359 
360  return true;
361 
362 }
363 
364 bool promote_char_to_short(H5T_class_t type_cls, hid_t type_id) {
365 
366  bool ret_value = false;
367  if(type_cls == H5T_INTEGER) {
368  size_t size = H5Tget_size(type_id);
369  int sign = H5Tget_sign(type_id);
370  if(size == 1 && sign == H5T_SGN_2)
371  ret_value = true;
372  }
373 
374  return ret_value;
375 
376 }
377 
378 void get_vlen_str_data(char*temp_bp,string &finalstr_val) {
379 
380  char*onestring = NULL;
381  onestring = *(char**)temp_bp;
382  if(onestring!=NULL )
383  finalstr_val =string(onestring);
384  else // We will add a NULL is onestring is NULL.
385  finalstr_val="";
386 
387 }
get_data
void get_data(hid_t dset, void *buf)
Definition: h5common.cc:50
libdap
Definition: BESDapFunctionResponseCache.h:35
get_strdata
void get_strdata(int strindex, char *allbuf, char *buf, int elesize)
Definition: h5common.cc:115
get_slabdata
int get_slabdata(hid_t dset, int *offset, int *step, int *count, int num_dim, void *buf)
Definition: h5common.cc:144
h5common.h