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