bes Updated for version 3.21.1
The Backend Server (BES) is the lower two tiers of the Hyrax data server
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) 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 410 E University Ave,
20// Suite 200, 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
42using namespace std;
43using namespace libdap;
44HDFCFStr::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
54BaseType *HDFCFStr::ptr_duplicate()
55{
56 return new HDFCFStr(*this);
57}
58
59bool 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 vector<int32> dim_sizes(H4_MAX_VAR_DIMS);
100 int32 sds_rank;
101 int32 data_type;
102 int32 n_attrs;
103 vector<char> name(H4_MAX_NC_NAME);
104
105 int32 r = 0;
106 r = SDgetinfo (sdsid, name.data(), &sds_rank, dim_sizes.data(),
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)