bes  Updated for version 3.20.13
HDFCFStr.cc
Go to the documentation of this file.
1 // This file is part of the hdf4_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 
33 #include <iostream>
34 #include <sstream>
35 
36 #include <libdap/InternalErr.h>
37 #include "HDFCFStr.h"
38 #include <BESDebug.h>
39 #include "HDFCFUtil.h"
40 #include "HDF4RequestHandler.h"
41 
42 using namespace std;
43 using namespace libdap;
44 HDFCFStr::HDFCFStr(const int this_h4fd, int32 sds_field_ref,const string &h4_filename,const string &sds_varname,const string &sds_varnewname, bool is_h4_vdata)
45  : Str(sds_varnewname, h4_filename),
46  filename(h4_filename),
47  varname(sds_varname),
48  h4fd(this_h4fd),
49  field_ref(sds_field_ref),
50  is_vdata(is_h4_vdata)
51 {
52 }
53 
54 BaseType *HDFCFStr::ptr_duplicate()
55 {
56  return new HDFCFStr(*this);
57 }
58 
59 bool HDFCFStr::read()
60 {
61 
62  BESDEBUG("h4","Coming to HDFCFStr read "<<endl);
63  bool check_pass_fileid_key = HDF4RequestHandler::get_pass_fileid();
64 
65  // SDS
66  if(false == is_vdata) {
67 
68  int32 sdid = -1;
69  if(false == check_pass_fileid_key) {
70  sdid = SDstart (filename.c_str (), DFACC_READ);
71  if (sdid < 0) {
72  ostringstream eherr;
73  eherr << "File " << filename.c_str () << " cannot be open.";
74  throw InternalErr (__FILE__, __LINE__, eherr.str ());
75  }
76  }
77  else
78  sdid = h4fd;
79 
80  int32 sdsid = 0;
81 
82  int32 sdsindex = SDreftoindex (sdid, field_ref);
83  if (sdsindex == -1) {
84  HDFCFUtil::close_fileid(sdid,-1,-1,-1,check_pass_fileid_key);
85  ostringstream eherr;
86  eherr << "SDS index " << sdsindex << " is not right.";
87  throw InternalErr (__FILE__, __LINE__, eherr.str ());
88  }
89 
90  // Obtain this SDS ID.
91  sdsid = SDselect (sdid, sdsindex);
92  if (sdsid < 0) {
93  HDFCFUtil::close_fileid(sdid,-1,-1,-1,check_pass_fileid_key);
94  ostringstream eherr;
95  eherr << "SDselect failed.";
96  throw InternalErr (__FILE__, __LINE__, eherr.str ());
97  }
98 
99  int32 dim_sizes[H4_MAX_VAR_DIMS];
100  int32 sds_rank;
101  int32 data_type;
102  int32 n_attrs;
103  char name[H4_MAX_NC_NAME];
104 
105  int32 r = 0;
106  r = SDgetinfo (sdsid, name, &sds_rank, dim_sizes,
107  &data_type, &n_attrs);
108  if(r == FAIL) {
109  SDendaccess(sdsid);
110  HDFCFUtil::close_fileid(sdid,-1,-1,-1,check_pass_fileid_key);
111  ostringstream eherr;
112  eherr << "SDgetinfo failed.";
113  throw InternalErr (__FILE__, __LINE__, eherr.str ());
114  }
115 
116  if(sds_rank != 1) {
117  SDendaccess(sdsid);
118  HDFCFUtil::close_fileid(sdid,-1,-1,-1,check_pass_fileid_key);
119  ostringstream eherr;
120  eherr << "The rank of string doesn't match with the rank of character array";
121  throw InternalErr (__FILE__, __LINE__, eherr.str ());
122 
123  }
124 
125  vector<int32>offset32;
126  offset32.resize(1);
127  vector<int32>count32;
128  count32.resize(1);
129  vector<int32>step32;
130  step32.resize(1);
131  offset32[0] = 0;
132  count32[0] = dim_sizes[0];
133  step32[0] = 1;
134 
135  vector<char>val;
136  val.resize(count32[0]);
137 
138  r = SDreaddata (sdsid, offset32.data(), step32.data(), count32.data(), val.data());
139  if (r != 0) {
140  SDendaccess (sdsid);
141  HDFCFUtil::close_fileid(sdid,-1,-1,-1,check_pass_fileid_key);
142  ostringstream eherr;
143  eherr << "SDreaddata failed.";
144  throw InternalErr (__FILE__, __LINE__, eherr.str ());
145  }
146 
147  string final_str(val.begin(),val.end());
148  set_value(final_str);
149  SDendaccess(sdsid);
150  HDFCFUtil::close_fileid(sdid,-1,-1,-1,check_pass_fileid_key);
151  }
152  else {
153 
154  int32 file_id = -1;
155 
156  if(true == check_pass_fileid_key)
157  file_id = h4fd;
158  else {
159  // Open the file
160  file_id = Hopen (filename.c_str (), DFACC_READ, 0);
161  if (file_id < 0) {
162  ostringstream eherr;
163  eherr << "File " << filename.c_str () << " cannot be open.";
164  throw InternalErr (__FILE__, __LINE__, eherr.str ());
165  }
166  }
167 
168 
169  // Start the Vdata interface
170  if (Vstart (file_id) < 0) {
171  HDFCFUtil::close_fileid(-1,file_id,-1,-1,check_pass_fileid_key);
172  ostringstream eherr;
173  eherr << "This file cannot be open.";
174  throw InternalErr (__FILE__, __LINE__, eherr.str ());
175  }
176 
177  // Attach the vdata
178  int32 vdref = field_ref;
179  int32 vdata_id = VSattach (file_id, vdref, "r");
180  if (vdata_id == -1) {
181  Vend (file_id);
182  HDFCFUtil::close_fileid(-1,file_id,-1,-1,check_pass_fileid_key);
183  ostringstream eherr;
184  eherr << "Vdata cannot be attached.";
185  throw InternalErr (__FILE__, __LINE__, eherr.str ());
186  }
187 
188  int32 num_rec = VSelts(vdata_id);
189  if (num_rec == -1) {
190  VSdetach (vdata_id);
191  Vend (file_id);
192 
193  HDFCFUtil::close_fileid(-1,file_id,-1,-1,check_pass_fileid_key);
194  ostringstream eherr;
195  eherr << "The number of elements from this vdata cannot be obtained.";
196  throw InternalErr (__FILE__, __LINE__, eherr.str ());
197  }
198 
199 
200  //int32 r = -1; //unused variable. SBL 2/7/20
201 
202  // Seek the position of the starting point
203  if (VSseek (vdata_id, 0) == -1) {
204  VSdetach (vdata_id);
205  Vend (file_id);
206  HDFCFUtil::close_fileid(-1,file_id,-1,-1,check_pass_fileid_key);
207  ostringstream eherr;
208  eherr << "VSseek failed at " << 0;
209  throw InternalErr (__FILE__, __LINE__, eherr.str ());
210  }
211 
212  // Prepare the vdata field
213  if (VSsetfields (vdata_id, varname.c_str ()) == -1) {
214  VSdetach (vdata_id);
215  Vend (file_id);
216  HDFCFUtil::close_fileid(-1,file_id,-1,-1,check_pass_fileid_key);
217  ostringstream eherr;
218  eherr << "VSsetfields failed with the name " << varname;
219  throw InternalErr (__FILE__, __LINE__, eherr.str ());
220  }
221  vector <char> val;
222  val.resize(num_rec);
223 
224  // Read the data
225  if(VSread (vdata_id, (uint8 *) val.data(), num_rec,
226  FULL_INTERLACE) == -1) {
227  VSdetach (vdata_id);
228  Vend (file_id);
229  HDFCFUtil::close_fileid(-1,file_id,-1,-1,check_pass_fileid_key);
230  ostringstream eherr;
231  eherr << "VSread failed.";
232  throw InternalErr (__FILE__, __LINE__, eherr.str ());
233  }
234 
235  string final_str(val.begin(),val.end());
236  set_value(final_str);
237  if (VSdetach (vdata_id) == -1) {
238  Vend (file_id);
239  HDFCFUtil::close_fileid(-1,file_id,-1,-1,check_pass_fileid_key);
240  ostringstream eherr;
241  eherr << "VSdetach failed.";
242  throw InternalErr (__FILE__, __LINE__, eherr.str ());
243  }
244 
245  if (Vend (file_id) == -1) {
246  HDFCFUtil::close_fileid(-1,file_id,-1,-1,check_pass_fileid_key);
247  ostringstream eherr;
248  eherr << "VSdetach failed.";
249  throw InternalErr (__FILE__, __LINE__, eherr.str ());
250  }
251 
252  HDFCFUtil::close_fileid(-1,file_id,-1,-1,check_pass_fileid_key);
253  }
254  return true;
255 }
This class provides a way to map HDF4 1-D character array to DAP Str for the CF option.
static void close_fileid(int32 sdfd, int32 file_id, int32 gridfd, int32 swathfd, bool pass_fileid_key)
Definition: HDFCFUtil.cc:3650