bes Updated for version 3.21.1
The Backend Server (BES) is the lower two tiers of the Hyrax data server
HDF5CFStr.cc
Go to the documentation of this file.
1// This file is part of the hdf5_handler implementing for the CF-compliant
2// Copyright (c) 2011-2023 The HDF Group, Inc. and OPeNDAP, Inc.
3//
4// This is free software; you can redistribute it and/or modify it under the
5// terms of the GNU Lesser General Public License as published by the Free
6// Software Foundation; either version 2.1 of the License, or (at your
7// option) any later version.
8//
9// This software is distributed in the hope that it will be useful, but
10// WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
11// or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public
12// License for more details.
13//
14// You should have received a copy of the GNU Lesser General Public
15// License along with this library; if not, write to the Free Software
16// Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
17//
18// You can contact OPeNDAP, Inc. at PO Box 112, Saunderstown, RI. 02874-0112.
19// You can contact The HDF Group, Inc. at 410 E University Ave,
20// Suite 200, Champaign, IL 61820
21
30
31
32#include "config_hdf5.h"
33
34#include <iostream>
35#include <sstream>
36
37#include <BESDebug.h>
38
39#include <libdap/InternalErr.h>
40#include "HDF5RequestHandler.h"
41#include "h5cfdaputil.h"
42#include "HDF5CFStr.h"
43#include <hdf5.h>
44
45using namespace std;
46using namespace libdap;
47
48HDF5CFStr::HDF5CFStr(const string &n, const string &d,const string &h5_varname)
49 : Str(n, d), varname(h5_varname)
50{
51}
52
53BaseType *HDF5CFStr::ptr_duplicate()
54{
55 auto HDF5CFStr_unique = make_unique<HDF5CFStr>(*this);
56 return HDF5CFStr_unique.release();
57}
58
59bool HDF5CFStr::read()
60{
61
62 BESDEBUG("h5","Coming to HDF5CFStr read "<<endl);
63 hid_t fileid = -1;
64 hid_t dsetid = -1;
65 hid_t dspace = -1;
66 hid_t dtypeid = -1;
67 hid_t memtype = -1;
68
69 if ((fileid = H5Fopen(dataset().c_str(),H5F_ACC_RDONLY,H5P_DEFAULT))<0) {
70 ostringstream eherr;
71 eherr << "HDF5 File " << dataset()
72 << " cannot be opened. "<<endl;
73 throw InternalErr (__FILE__, __LINE__, eherr.str ());
74 }
75
76 if ((dsetid = H5Dopen(fileid,varname.c_str(),H5P_DEFAULT))<0) {
77 H5Fclose(fileid);
78 ostringstream eherr;
79 eherr << "HDF5 dataset " << name()
80 << " cannot be opened. "<<endl;
81 throw InternalErr (__FILE__, __LINE__, eherr.str ());
82 }
83
84 if ((dspace = H5Dget_space(dsetid))<0) {
85
86 H5Dclose(dsetid);
87 H5Fclose(fileid);
88 ostringstream eherr;
89 eherr << "Space id of the HDF5 dataset " << name()
90 << " cannot be obtained. "<<endl;
91 throw InternalErr (__FILE__, __LINE__, eherr.str ());
92 }
93
94 if (H5S_SCALAR != H5Sget_simple_extent_type(dspace)) {
95
96 H5Dclose(dsetid);
97 H5Fclose(fileid);
98 ostringstream eherr;
99 eherr << " The HDF5 dataset " << name()
100 << " is not scalar. "<<endl;
101 throw InternalErr (__FILE__, __LINE__, eherr.str ());
102
103 }
104
105
106 if ((dtypeid = H5Dget_type(dsetid)) < 0) {
107
108 H5Sclose(dspace);
109 H5Dclose(dsetid);
110 H5Fclose(fileid);
111 ostringstream eherr;
112 eherr << "Obtaining the datatype of the HDF5 dataset " << name()
113 << " fails. "<<endl;
114 throw InternalErr (__FILE__, __LINE__, eherr.str ());
115
116 }
117
118 if ((memtype = H5Tget_native_type(dtypeid, H5T_DIR_ASCEND))<0) {
119
120 H5Tclose(dtypeid);
121 H5Sclose(dspace);
122 H5Dclose(dsetid);
123 H5Fclose(fileid);
124 ostringstream eherr;
125 eherr << "Obtaining the memory type of the HDF5 dataset " << name()
126 << " fails. "<<endl;
127 throw InternalErr (__FILE__, __LINE__, eherr.str ());
128
129 }
130
131 htri_t is_vlen_str = H5Tis_variable_str(dtypeid);
132 if (is_vlen_str > 0) {
133 size_t ty_size = H5Tget_size(memtype);
134 if (ty_size == 0) {
135 H5Tclose(memtype);
136 H5Tclose(dtypeid);
137 H5Sclose(dspace);
138 H5Dclose(dsetid);
139 H5Fclose(fileid);
140 ostringstream eherr;
141 eherr << "Cannot obtain the size of the fixed size HDF5 string of the dataset "
142 << name() <<endl;
143 throw InternalErr (__FILE__, __LINE__, eherr.str ());
144 }
145 vector <char> strval;
146 strval.resize(ty_size);
147 hid_t read_ret = -1;
148 read_ret = H5Dread(dsetid,memtype,H5S_ALL,H5S_ALL,H5P_DEFAULT,(void*)strval.data());
149
150 if (read_ret < 0) {
151 H5Tclose(memtype);
152 H5Tclose(dtypeid);
153 H5Sclose(dspace);
154 H5Dclose(dsetid);
155 H5Fclose(fileid);
156 ostringstream eherr;
157 eherr << "Cannot read the HDF5 dataset " << name()
158 << " with the type of the HDF5 variable length string "<<endl;
159 throw InternalErr (__FILE__, __LINE__, eherr.str ());
160 }
161
162 char*temp_bp = strval.data();
163 char*onestring = nullptr;
164 string final_str ="";
165
166 onestring = *(char**)temp_bp;
167 if(onestring!=nullptr )
168 final_str =string(onestring);
169
170 else // We will add a nullptr is onestring is nullptr.
171 final_str="";
172
173 if (""!=final_str) {
174 herr_t ret_vlen_claim = 0;
175 ret_vlen_claim = H5Dvlen_reclaim(memtype,dspace,H5P_DEFAULT,(void*)strval.data());
176 if (ret_vlen_claim < 0){
177 H5Tclose(memtype);
178 H5Tclose(dtypeid);
179 H5Sclose(dspace);
180 H5Dclose(dsetid);
181 H5Fclose(fileid);
182 ostringstream eherr;
183 eherr << "Cannot reclaim the memory buffer of the HDF5 variable length string of the dataset "
184 << name() <<endl;
185 throw InternalErr (__FILE__, __LINE__, eherr.str ());
186
187 }
188 }
189
190 // If the string size is longer than the current netCDF JAVA
191 // string and the "EnableDropLongString" key is turned on,
192 // No string is generated.
193 if (true == HDF5RequestHandler::get_drop_long_string()) {
194 if( final_str.size() > NC_JAVA_STR_SIZE_LIMIT)
195 final_str = "";
196 }
197 set_value(final_str);
198 }
199
200 else if (0 == is_vlen_str) {
201 size_t ty_size = H5Tget_size(dtypeid);
202 if (ty_size == 0) {
203 H5Tclose(memtype);
204 H5Tclose(dtypeid);
205 H5Sclose(dspace);
206 H5Dclose(dsetid);
207 H5Fclose(fileid);
208 ostringstream eherr;
209 eherr << "Cannot obtain the size of the fixed size HDF5 string of the dataset "
210 << name() <<endl;
211 throw InternalErr (__FILE__, __LINE__, eherr.str ());
212 }
213
214 vector <char> strval;
215 strval.resize(1+ty_size);
216 hid_t read_ret = -1;
217 read_ret = H5Dread(dsetid,memtype,H5S_ALL,H5S_ALL,H5P_DEFAULT,(void*)strval.data());
218
219 if (read_ret < 0) {
220 H5Tclose(memtype);
221 H5Tclose(dtypeid);
222 H5Sclose(dspace);
223 H5Dclose(dsetid);
224 H5Fclose(fileid);
225 ostringstream eherr;
226 eherr << "Cannot read the HDF5 dataset " << name()
227 << " with the type of the fixed size HDF5 string "<<endl;
228 throw InternalErr (__FILE__, __LINE__, eherr.str ());
229 }
230
231 string total_string(strval.begin(),strval.end());
232 strval.clear();//release some memory
233
234 // Need to trim the null parameters
235 size_t temp_pos;
236 if (H5Tget_strpad(dtypeid) == H5T_STR_NULLTERM)
237 temp_pos = total_string.find_first_of('\0');
238 else if (H5Tget_strpad(dtypeid) == H5T_STR_SPACEPAD)
239 temp_pos = total_string.find_last_not_of(' ')+1;
240 else
241 temp_pos = total_string.find_last_not_of('0')+1;
242
243 string trim_string = total_string.substr(0,temp_pos);
244
245 // If the string size is longer than the current netCDF JAVA
246 // string and the "EnableDropLongString" key is turned on,
247 // No string is generated.
248 if (true == HDF5RequestHandler::get_drop_long_string()) {
249 if( trim_string.size() > NC_JAVA_STR_SIZE_LIMIT)
250 trim_string = "";
251 }
252 set_value(trim_string);
253 }
254 else {
255
256 H5Tclose(memtype);
257 H5Tclose(dtypeid);
258 H5Sclose(dspace);
259 H5Dclose(dsetid);
260 H5Fclose(fileid);
261
262 throw InternalErr (__FILE__, __LINE__, "H5Tis_variable_str returns negative value" );
263 }
264
265 H5Tclose(memtype);
266 H5Tclose(dtypeid);
267 H5Sclose(dspace);
268 H5Dclose(dsetid);
269 H5Fclose(fileid);
270
271
272 return true;
273}
This class provides a way to map HDF5 Str to DAP Str for the CF option.
include the entry functions to execute the handlers
Helper functions for generating DAS attributes and a function to check BES Key.