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