bes  Updated for version 3.20.6
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 "InternalErr.h"
40 #include "HDF5RequestHandler.h"
41 #include "h5cfdaputil.h"
42 #include "HDF5CFStr.h"
43 #include <hdf5.h>
44 
45 using namespace std;
46 using namespace libdap;
47 
48 HDF5CFStr::HDF5CFStr(const string &n, const string &d,const string &h5_varname)
49  : Str(n, d), varname(h5_varname)
50 {
51 }
52 
53 HDF5CFStr::~HDF5CFStr()
54 {
55 }
56 BaseType *HDF5CFStr::ptr_duplicate()
57 {
58  return new HDF5CFStr(*this);
59 }
60 
61 bool 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 }
HDF5CFStr.h
This class provides a way to map HDF5 Str to DAP Str for the CF option.
HDF5CFStr
Definition: HDF5CFStr.h:42
libdap
Definition: BESDapFunctionResponseCache.h:35
HDF5RequestHandler.h
include the entry functions to execute the handlers
h5cfdaputil.h
Helper functions for generating DAS attributes and a function to check BES Key.