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 
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 BaseType *HDF5CFStr::ptr_duplicate()
54 {
55  return new HDF5CFStr(*this);
56 }
57 
58 bool 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.