bes Updated for version 3.21.1
The Backend Server (BES) is the lower two tiers of the Hyrax data server
dmrpp_module/h5common.cc
Go to the documentation of this file.
1// data server.
2
3// Copyright (c) 2007-2023 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 410 E University Ave,
21// Suite 200, Champaign, IL 61820
22
30
31#include "h5common.h"
32
33#include <cstring>
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(int64_t 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 int64_t *offset, const int64_t *step, const int64_t *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, buf) < 0) {
212 H5Tclose(dtype);
213 H5Tclose(memtype);
214 H5Sclose(dspace);
215 H5Sclose(memspace);
216 throw InternalErr(__FILE__, __LINE__, "could not get data");
217 }
218
219 if (H5Sclose(dspace) < 0){
220 H5Tclose(dtype);
221 H5Tclose(memtype);
222 H5Sclose(memspace);
223 throw InternalErr(__FILE__, __LINE__, "Unable to close the dspace.");
224 }
225 if (H5Sclose(memspace) < 0){
226 H5Tclose(dtype);
227 H5Tclose(memtype);
228 throw InternalErr(__FILE__, __LINE__, "Unable to close the memspace.");
229 }
230 if (H5Tclose(dtype) < 0){
231 H5Tclose(memtype);
232 throw InternalErr(__FILE__, __LINE__, "Unable to close the dtype.");
233 }
234
235 if (H5Tclose(memtype) < 0){
236 throw InternalErr(__FILE__, __LINE__, "Unable to close the memtype.");
237 }
238
239 BESDEBUG("h5", "<get_slabdata() " << endl);
240 return 0;
241}
242
243bool read_vlen_string(hid_t dsetid, const int64_t nelms, const hsize_t *hoffset, const hsize_t *hstep,
244 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 (!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 (!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 (!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
305 vector <char> strval;
306 strval.resize(nelms*ty_size);
307 hid_t read_ret = -1;
308 if (is_scalar)
309 read_ret = H5Dread(dsetid,
310 memtype,
311 H5S_ALL,
312 H5S_ALL,
313 H5P_DEFAULT,
314 (void*)strval.data());
315 else
316 read_ret = H5Dread(dsetid,
317 memtype,
318 mspace,
319 dspace,
320 H5P_DEFAULT,
321 (void*)strval.data());
322
323 if (read_ret < 0) {
324 if (!is_scalar)
325 H5Sclose(mspace);
326 H5Tclose(memtype);
327 H5Tclose(dtypeid);
328 H5Sclose(dspace);
329 throw InternalErr (__FILE__, __LINE__, "Fail to read the HDF5 variable length string dataset.");
330 }
331
332#if 0
333 // For scalar, nelms is 1.
334 char *temp_bp = strval.data();
335 for (int i =0;i<nelms;i++) {
336 char *onestring = *(char**)temp_bp;
337 if (onestring != nullptr )
338 finstrval[i] =string(onestring);
339 else // We will add a nullptr if onestring is nullptr.
340 finstrval[i]="";
341 temp_bp +=ty_size;
342 }
343#endif
344 read_vlen_string_value(nelms, strval, finstrval, ty_size);
345 claim_vlen_string_memory(memtype, dspace, dtypeid, mspace, strval, is_scalar);
346#if 0
347 if (false == strval.empty()) {
348 herr_t ret_vlen_claim;
349 if (true == is_scalar)
350 ret_vlen_claim = H5Dvlen_reclaim(memtype,dspace,H5P_DEFAULT,(void*)strval.data());
351 else
352 ret_vlen_claim = H5Dvlen_reclaim(memtype,mspace,H5P_DEFAULT,(void*)strval.data());
353 if (ret_vlen_claim < 0){
354 if (false == is_scalar)
355 H5Sclose(mspace);
356 H5Tclose(memtype);
357 H5Tclose(dtypeid);
358 H5Sclose(dspace);
359 throw InternalErr (__FILE__, __LINE__, "Cannot reclaim the memory buffer of the HDF5 variable length string.");
360
361 }
362 }
363#endif
364 if (false == is_scalar)
365 H5Sclose(mspace);
366 H5Tclose(memtype);
367 H5Tclose(dtypeid);
368 H5Sclose(dspace);
369
370 return true;
371
372}
373
374void read_vlen_string_value(const int64_t nelms, vector<char> &strval, vector<string>&finstrval, size_t ty_size ) {
375 // For scalar, nelms is 1.
376 const char *temp_bp = strval.data();
377 for (int i =0;i<nelms;i++) {
378 string finalstr_val;
379 get_vlen_str_data(temp_bp, finalstr_val);
380 finstrval[i] = finalstr_val;
381#if 0
382 char *onestring = *(char**)temp_bp;
383 if (onestring != nullptr )
384 finstrval[i] =string(onestring);
385 else // We will add a nullptr if onestring is nullptr.
386 finstrval[i]="";
387#endif
388 temp_bp +=ty_size;
389 }
390
391}
392
393void claim_vlen_string_memory(hid_t memtype, hid_t dspace, hid_t dtypeid, hid_t mspace, vector<char> &strval,
394 bool is_scalar) {
395
396 if (false == strval.empty()) {
397 herr_t ret_vlen_claim;
398 if (true == is_scalar)
399 ret_vlen_claim = H5Dvlen_reclaim(memtype,dspace,H5P_DEFAULT,(void*)strval.data());
400 else
401 ret_vlen_claim = H5Dvlen_reclaim(memtype,mspace,H5P_DEFAULT,(void*)strval.data());
402 if (ret_vlen_claim < 0){
403 if (false == is_scalar)
404 H5Sclose(mspace);
405 H5Tclose(memtype);
406 H5Tclose(dtypeid);
407 H5Sclose(dspace);
408 throw InternalErr (__FILE__, __LINE__, "Cannot reclaim the memory buffer of the HDF5 variable length string.");
409
410 }
411 }
412}
413bool promote_char_to_short(H5T_class_t type_cls, hid_t type_id) {
414
415 bool ret_value = false;
416 if(type_cls == H5T_INTEGER) {
417 size_t size = H5Tget_size(type_id);
418 int sign = H5Tget_sign(type_id);
419 if(size == 1 && sign == H5T_SGN_2)
420 ret_value = true;
421 }
422
423 return ret_value;
424
425}
426
427void get_vlen_str_data(const char*temp_bp,string &finalstr_val) {
428
429 const char *onestring = *(const char**)temp_bp;
430 if(onestring!=nullptr )
431 finalstr_val =string(onestring);
432 else // We will add a nullptr is onestring is nullptr.
433 finalstr_val="";
434
435}
void get_data(hid_t dset, void *buf)