bes Updated for version 3.20.13
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-2016 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 1800 South Oak Street,
20// Suite 203, 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 return new HDF5CFStr(*this);
56}
57
58bool HDF5CFStr::read()
59{
60
61 BESDEBUG("h5","Coming to HDF5CFStr read "<<endl);
62 hid_t fileid = -1;
63 hid_t dsetid = -1;
64 hid_t dspace = -1;
65 hid_t dtypeid = -1;
66 hid_t memtype = -1;
67
68 if ((fileid = H5Fopen(dataset().c_str(),H5F_ACC_RDONLY,H5P_DEFAULT))<0) {
69 ostringstream eherr;
70 eherr << "HDF5 File " << dataset()
71 << " cannot be opened. "<<endl;
72 throw InternalErr (__FILE__, __LINE__, eherr.str ());
73 }
74
75 if ((dsetid = H5Dopen(fileid,varname.c_str(),H5P_DEFAULT))<0) {
76 H5Fclose(fileid);
77 ostringstream eherr;
78 eherr << "HDF5 dataset " << name()
79 << " cannot be opened. "<<endl;
80 throw InternalErr (__FILE__, __LINE__, eherr.str ());
81 }
82
83 if ((dspace = H5Dget_space(dsetid))<0) {
84
85 H5Dclose(dsetid);
86 H5Fclose(fileid);
87 ostringstream eherr;
88 eherr << "Space id of the HDF5 dataset " << name()
89 << " cannot be obtained. "<<endl;
90 throw InternalErr (__FILE__, __LINE__, eherr.str ());
91 }
92
93 if (H5S_SCALAR != H5Sget_simple_extent_type(dspace)) {
94
95 H5Dclose(dsetid);
96 H5Fclose(fileid);
97 ostringstream eherr;
98 eherr << " The HDF5 dataset " << name()
99 << " is not scalar. "<<endl;
100 throw InternalErr (__FILE__, __LINE__, eherr.str ());
101
102 }
103
104
105 if ((dtypeid = H5Dget_type(dsetid)) < 0) {
106
107 H5Sclose(dspace);
108 H5Dclose(dsetid);
109 H5Fclose(fileid);
110 ostringstream eherr;
111 eherr << "Obtaining the datatype of the HDF5 dataset " << name()
112 << " fails. "<<endl;
113 throw InternalErr (__FILE__, __LINE__, eherr.str ());
114
115 }
116
117 if ((memtype = H5Tget_native_type(dtypeid, H5T_DIR_ASCEND))<0) {
118
119 H5Tclose(dtypeid);
120 H5Sclose(dspace);
121 H5Dclose(dsetid);
122 H5Fclose(fileid);
123 ostringstream eherr;
124 eherr << "Obtaining the memory type of the HDF5 dataset " << name()
125 << " fails. "<<endl;
126 throw InternalErr (__FILE__, __LINE__, eherr.str ());
127
128 }
129
130 htri_t is_vlen_str = H5Tis_variable_str(dtypeid);
131 if (is_vlen_str > 0) {
132 size_t ty_size = H5Tget_size(memtype);
133 if (ty_size == 0) {
134 H5Tclose(memtype);
135 H5Tclose(dtypeid);
136 H5Sclose(dspace);
137 H5Dclose(dsetid);
138 H5Fclose(fileid);
139 ostringstream eherr;
140 eherr << "Cannot obtain the size of the fixed size HDF5 string of the dataset "
141 << name() <<endl;
142 throw InternalErr (__FILE__, __LINE__, eherr.str ());
143 }
144 vector <char> strval;
145 strval.resize(ty_size);
146 hid_t read_ret = -1;
147 read_ret = H5Dread(dsetid,memtype,H5S_ALL,H5S_ALL,H5P_DEFAULT,(void*)strval.data());
148
149 if (read_ret < 0) {
150 H5Tclose(memtype);
151 H5Tclose(dtypeid);
152 H5Sclose(dspace);
153 H5Dclose(dsetid);
154 H5Fclose(fileid);
155 ostringstream eherr;
156 eherr << "Cannot read the HDF5 dataset " << name()
157 << " with the type of the HDF5 variable length string "<<endl;
158 throw InternalErr (__FILE__, __LINE__, eherr.str ());
159 }
160
161 char*temp_bp = strval.data();
162 char*onestring = nullptr;
163 string final_str ="";
164
165 onestring = *(char**)temp_bp;
166 if(onestring!=nullptr )
167 final_str =string(onestring);
168
169 else // We will add a nullptr is onestring is nullptr.
170 final_str="";
171
172 if (""!=final_str) {
173 herr_t ret_vlen_claim = 0;
174 ret_vlen_claim = H5Dvlen_reclaim(memtype,dspace,H5P_DEFAULT,(void*)strval.data());
175 if (ret_vlen_claim < 0){
176 H5Tclose(memtype);
177 H5Tclose(dtypeid);
178 H5Sclose(dspace);
179 H5Dclose(dsetid);
180 H5Fclose(fileid);
181 ostringstream eherr;
182 eherr << "Cannot reclaim the memory buffer of the HDF5 variable length string of the dataset "
183 << name() <<endl;
184 throw InternalErr (__FILE__, __LINE__, eherr.str ());
185
186 }
187 }
188
189 // If the string size is longer than the current netCDF JAVA
190 // string and the "EnableDropLongString" key is turned on,
191 // No string is generated.
192 if (true == HDF5RequestHandler::get_drop_long_string()) {
193 if( final_str.size() > NC_JAVA_STR_SIZE_LIMIT)
194 final_str = "";
195 }
196 set_value(final_str);
197 }
198
199 else if (0 == is_vlen_str) {
200 size_t ty_size = H5Tget_size(dtypeid);
201 if (ty_size == 0) {
202 H5Tclose(memtype);
203 H5Tclose(dtypeid);
204 H5Sclose(dspace);
205 H5Dclose(dsetid);
206 H5Fclose(fileid);
207 ostringstream eherr;
208 eherr << "Cannot obtain the size of the fixed size HDF5 string of the dataset "
209 << name() <<endl;
210 throw InternalErr (__FILE__, __LINE__, eherr.str ());
211 }
212
213 vector <char> strval;
214 strval.resize(1+ty_size);
215 hid_t read_ret = -1;
216 read_ret = H5Dread(dsetid,memtype,H5S_ALL,H5S_ALL,H5P_DEFAULT,(void*)strval.data());
217
218 if (read_ret < 0) {
219 H5Tclose(memtype);
220 H5Tclose(dtypeid);
221 H5Sclose(dspace);
222 H5Dclose(dsetid);
223 H5Fclose(fileid);
224 ostringstream eherr;
225 eherr << "Cannot read the HDF5 dataset " << name()
226 << " with the type of the fixed size HDF5 string "<<endl;
227 throw InternalErr (__FILE__, __LINE__, eherr.str ());
228 }
229
230 string total_string(strval.begin(),strval.end());
231 strval.clear();//release some memory
232
233 // Need to trim the null parameters
234 size_t temp_pos;
235 if (H5Tget_strpad(dtypeid) == H5T_STR_NULLTERM)
236 temp_pos = total_string.find_first_of('\0');
237 else if (H5Tget_strpad(dtypeid) == H5T_STR_SPACEPAD)
238 temp_pos = total_string.find_last_not_of(' ')+1;
239 else
240 temp_pos = total_string.find_last_not_of('0')+1;
241
242 string trim_string = total_string.substr(0,temp_pos);
243
244 // If the string size is longer than the current netCDF JAVA
245 // string and the "EnableDropLongString" key is turned on,
246 // No string is generated.
247 if (true == HDF5RequestHandler::get_drop_long_string()) {
248 if( trim_string.size() > NC_JAVA_STR_SIZE_LIMIT)
249 trim_string = "";
250 }
251 set_value(trim_string);
252 }
253 else {
254
255 H5Tclose(memtype);
256 H5Tclose(dtypeid);
257 H5Sclose(dspace);
258 H5Dclose(dsetid);
259 H5Fclose(fileid);
260
261 throw InternalErr (__FILE__, __LINE__, "H5Tis_variable_str returns negative value" );
262 }
263
264 H5Tclose(memtype);
265 H5Tclose(dtypeid);
266 H5Sclose(dspace);
267 H5Dclose(dsetid);
268 H5Fclose(fileid);
269
270
271 return true;
272}
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.