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
38using namespace std;
39using namespace libdap;
40
45// variable length string is handled by function read_vlen_string.
50void 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
115void 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
148int
149get_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
244bool 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
368bool 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
382void 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