bes Updated for version 3.20.13
HDFSPArray_VDField.cc
1
2// This file is part of the hdf4 data handler for the OPeNDAP data server.
3// It retrieves the Vdata fields from NASA HDF4 data products.
4// Each Vdata will be decomposed into individual Vdata fields.
5// Each field will be mapped to A DAP variable.
6
7// Authors: MuQun Yang <myang6@hdfgroup.org>
8// Copyright (c) 2010-2012 The HDF Group
10
11#include "HDFSPArray_VDField.h"
12#include <iostream>
13#include <sstream>
14#include <cassert>
15#include <libdap/debug.h>
16#include "hdf.h"
17#include "mfhdf.h"
18#include <libdap/InternalErr.h>
19#include <BESDebug.h>
20#include "HDFCFUtil.h"
21#include "HDF4RequestHandler.h"
22
23using namespace std;
24using namespace libdap;
25#define SIGNED_BYTE_TO_INT32 1
26
27
28bool
29HDFSPArray_VDField::read ()
30{
31
32 BESDEBUG("h4","Coming to HDFSPArray_VDField read "<<endl);
33 if(length() == 0)
34 return true;
35
36#if 0
37 string check_pass_fileid_key_str="H4.EnablePassFileID";
38 bool check_pass_fileid_key = false;
39 check_pass_fileid_key = HDFCFUtil::check_beskeys(check_pass_fileid_key_str);
40#endif
41 bool check_pass_fileid_key = HDF4RequestHandler::get_pass_fileid();
42
43 // Declaration of offset,count and step
44 vector<int>offset;
45 offset.resize(rank);
46 vector<int>count;
47 count.resize(rank);
48 vector<int>step;
49 step.resize(rank);
50
51 // Obtain offset,step and count from the client expression constraint
52 int nelms = format_constraint(offset.data(),step.data(),count.data());
53
54 int32 file_id = -1;
55
56 if(true == check_pass_fileid_key)
57 file_id = fileid;
58
59 else {
60 // Open the file
61 file_id = Hopen (filename.c_str (), DFACC_READ, 0);
62 if (file_id < 0) {
63 ostringstream eherr;
64 eherr << "File " << filename.c_str () << " cannot be open.";
65 throw InternalErr (__FILE__, __LINE__, eherr.str ());
66 }
67 }
68
69 // Start the Vdata interface
70 int32 vdata_id = 0;
71 if (Vstart (file_id) < 0) {
72 HDFCFUtil::close_fileid(-1,file_id,-1,-1,check_pass_fileid_key);
73 ostringstream eherr;
74 eherr << "This file cannot be open.";
75 throw InternalErr (__FILE__, __LINE__, eherr.str ());
76 }
77
78 // Attach the vdata
79 vdata_id = VSattach (file_id, vdref, "r");
80 if (vdata_id == -1) {
81 Vend (file_id);
82 HDFCFUtil::close_fileid(-1,file_id,-1,-1,check_pass_fileid_key);
83 ostringstream eherr;
84 eherr << "Vdata cannot be attached.";
85 throw InternalErr (__FILE__, __LINE__, eherr.str ());
86 }
87
88 try {
89 int32 r = -1;
90
91 // Seek the position of the starting point
92 if (VSseek (vdata_id, (int32) offset[0]) == -1) {
93 ostringstream eherr;
94 eherr << "VSseek failed at " << offset[0];
95 throw InternalErr (__FILE__, __LINE__, eherr.str ());
96 }
97
98 // Prepare the vdata field
99 if (VSsetfields (vdata_id, fdname.c_str ()) == -1) {
100 ostringstream eherr;
101 eherr << "VSsetfields failed with the name " << fdname;
102 throw InternalErr (__FILE__, __LINE__, eherr.str ());
103 }
104
105 int32 vdfelms = fdorder * count[0] * step[0];
106
107 // Loop through each data type
108 switch (dtype) {
109 case DFNT_INT8:
110 {
111 vector<int8> val;
112 val.resize(nelms);
113
114 vector<int8>orival;
115 orival.resize(vdfelms);
116
117 // Read the data
118 r = VSread (vdata_id, (uint8 *) orival.data(), 1+(count[0] -1)* step[0],
119 FULL_INTERLACE);
120
121 if (r == -1) {
122 ostringstream eherr;
123 eherr << "VSread failed.";
124 throw InternalErr (__FILE__, __LINE__, eherr.str ());
125 }
126
127 // Obtain the subset portion of the data
128 if (fdorder > 1) {
129 for (int i = 0; i < count[0]; i++)
130 for (int j = 0; j < count[1]; j++)
131 val[i * count[1] + j] =
132 orival[i * fdorder * step[0] + offset[1] + j * step[1]];
133 }
134 else {
135 for (int i = 0; i < count[0]; i++)
136 val[i] = orival[i * step[0]];
137 }
138
139
140#ifndef SIGNED_BYTE_TO_INT32
141 set_value ((dods_byte *) val.data(), nelms);
142#else
143 vector<int32>newval;
144 newval.resize(nelms);
145
146 for (int counter = 0; counter < nelms; counter++)
147 newval[counter] = (int32) (val[counter]);
148
149 set_value ((dods_int32 *) newval.data(), nelms);
150
151#endif
152 }
153
154 break;
155 case DFNT_UINT8:
156 case DFNT_UCHAR8:
157 {
158
159 vector<uint8>val;
160 val.resize(nelms);
161
162 vector<uint8>orival;
163 orival.resize(vdfelms);
164
165 r = VSread (vdata_id, orival.data(), 1+(count[0] -1)* step[0], FULL_INTERLACE);
166 if (r == -1) {
167 ostringstream eherr;
168 eherr << "VSread failed.";
169 throw InternalErr (__FILE__, __LINE__, eherr.str ());
170 }
171
172 if (fdorder > 1) {
173 for (int i = 0; i < count[0]; i++)
174 for (int j = 0; j < count[1]; j++)
175 val[i * count[1] + j] = orival[i * fdorder * step[0] + offset[1] + j * step[1]];
176 }
177 else {
178 for (int i = 0; i < count[0]; i++)
179 val[i] = orival[i * step[0]];
180 }
181
182 set_value ((dods_byte *) val.data(), nelms);
183 }
184
185 break;
186
187 case DFNT_INT16:
188 {
189 vector<int16>val;
190 val.resize(nelms);
191 vector<int16>orival;
192 orival.resize(vdfelms);
193
194 r = VSread (vdata_id, (uint8 *) orival.data(), 1+(count[0] -1)* step[0],
195 FULL_INTERLACE);
196 if (r == -1) {
197 ostringstream eherr;
198 eherr << "VSread failed.";
199 throw InternalErr (__FILE__, __LINE__, eherr.str ());
200 }
201
202 if (fdorder > 1) {
203 for (int i = 0; i < count[0]; i++)
204 for (int j = 0; j < count[1]; j++)
205 val[i * count[1] + j] = orival[i * fdorder * step[0] + offset[1] + j * step[1]];
206 }
207 else {
208 for (int i = 0; i < count[0]; i++)
209 val[i] = orival[i * step[0]];
210 }
211
212 set_value ((dods_int16 *) val.data(), nelms);
213 }
214 break;
215
216 case DFNT_UINT16:
217
218 {
219 vector<uint16>val;
220 val.resize(nelms);
221
222 vector<uint16>orival;
223 orival.resize(vdfelms);
224
225 r = VSread (vdata_id, (uint8 *) orival.data(), 1+(count[0] -1)* step[0],
226 FULL_INTERLACE);
227 if (r == -1) {
228 ostringstream eherr;
229 eherr << "VSread failed.";
230 throw InternalErr (__FILE__, __LINE__, eherr.str ());
231 }
232
233 if (fdorder > 1) {
234 for (int i = 0; i < count[0]; i++)
235 for (int j = 0; j < count[1]; j++)
236 val[i * count[1] + j] = orival[i * fdorder * step[0] + offset[1] + j * step[1]];
237 }
238 else {
239 for (int i = 0; i < count[0]; i++)
240 val[i] = orival[i * step[0]];
241 }
242
243 set_value ((dods_uint16 *) val.data(), nelms);
244 }
245 break;
246 case DFNT_INT32:
247 {
248 vector<int32>val;
249 val.resize(nelms);
250 vector<int32>orival;
251 orival.resize(vdfelms);
252
253 r = VSread (vdata_id, (uint8 *) orival.data(), 1+(count[0] -1)* step[0],
254 FULL_INTERLACE);
255 if (r == -1) {
256 ostringstream eherr;
257 eherr << "VSread failed.";
258 throw InternalErr (__FILE__, __LINE__, eherr.str ());
259 }
260
261 if (fdorder > 1) {
262 for (int i = 0; i < count[0]; i++)
263 for (int j = 0; j < count[1]; j++)
264 val[i * count[1] + j] = orival[i * fdorder * step[0] + offset[1] + j * step[1]];
265 }
266 else {
267 for (int i = 0; i < count[0]; i++)
268 val[i] = orival[i * step[0]];
269 }
270
271 set_value ((dods_int32 *) val.data(), nelms);
272 }
273 break;
274
275 case DFNT_UINT32:
276 {
277
278 vector<uint32>val;
279 val.resize(nelms);
280
281 vector<uint32>orival;
282 orival.resize(vdfelms);
283
284 r = VSread (vdata_id, (uint8 *) orival.data(), 1+(count[0] -1)* step[0],
285 FULL_INTERLACE);
286 if (r == -1) {
287 ostringstream eherr;
288 eherr << "VSread failed.";
289 throw InternalErr (__FILE__, __LINE__, eherr.str ());
290 }
291
292 if (fdorder > 1) {
293 for (int i = 0; i < count[0]; i++)
294 for (int j = 0; j < count[1]; j++)
295 val[i * count[1] + j] = orival[i * fdorder * step[0] + offset[1] + j * step[1]];
296 }
297 else {
298 for (int i = 0; i < count[0]; i++)
299 val[i] = orival[i * step[0]];
300 }
301
302 set_value ((dods_uint32 *) val.data(), nelms);
303 }
304 break;
305 case DFNT_FLOAT32:
306 {
307 vector<float32>val;
308 val.resize(nelms);
309 vector<float32>orival;
310 orival.resize(vdfelms);
311
312 r = VSread (vdata_id, (uint8 *) orival.data(), 1+(count[0] -1)* step[0],
313 FULL_INTERLACE);
314 if (r == -1) {
315 ostringstream eherr;
316 eherr << "VSread failed.";
317 throw InternalErr (__FILE__, __LINE__, eherr.str ());
318 }
319
320 if (fdorder > 1) {
321 for (int i = 0; i < count[0]; i++)
322 for (int j = 0; j < count[1]; j++)
323 val[i * count[1] + j] = orival[i * fdorder * step[0] + offset[1] + j * step[1]];
324 }
325 else {
326 for (int i = 0; i < count[0]; i++)
327 val[i] = orival[i * step[0]];
328 }
329
330 set_value ((dods_float32 *) val.data(), nelms);
331 }
332 break;
333 case DFNT_FLOAT64:
334 {
335
336 vector<float64>val;
337 val.resize(nelms);
338
339 vector<float64>orival;
340 orival.resize(vdfelms);
341
342 r = VSread (vdata_id, (uint8 *) orival.data(), 1+(count[0] -1)* step[0],
343 FULL_INTERLACE);
344 if (r == -1) {
345 ostringstream eherr;
346 eherr << "VSread failed.";
347 throw InternalErr (__FILE__, __LINE__, eherr.str ());
348 }
349
350 if (fdorder > 1) {
351 for (int i = 0; i < count[0]; i++)
352 for (int j = 0; j < count[1]; j++)
353 val[i * count[1] + j] = orival[i * fdorder * step[0] + offset[1] + j * step[1]];
354 }
355 else {
356 for (int i = 0; i < count[0]; i++)
357 val[i] = orival[i * step[0]];
358 }
359
360 set_value ((dods_float64 *) val.data(), nelms);
361 }
362 break;
363 default:
364 throw InternalErr (__FILE__, __LINE__, "unsupported data type.");
365 }
366
367 if (VSdetach (vdata_id) == -1) {
368 ostringstream eherr;
369 eherr << "VSdetach failed.";
370 throw InternalErr (__FILE__, __LINE__, eherr.str ());
371 }
372
373 if (Vend (file_id) == -1) {
374 ostringstream eherr;
375
376 eherr << "VSdetach failed.";
377 throw InternalErr (__FILE__, __LINE__, eherr.str ());
378 }
379 HDFCFUtil::close_fileid(-1,file_id,-1,-1,check_pass_fileid_key);
380 }
381 catch(...) {
382 VSdetach(vdata_id);
383 Vend(file_id);
384 HDFCFUtil::close_fileid(-1,fileid,-1,-1,check_pass_fileid_key);
385 throw;
386
387 }
388
389#if 0
390 if (Hclose (file_id) == -1) {
391
392 ostringstream eherr;
393
394 eherr << "VSdetach failed.";
395 throw InternalErr (__FILE__, __LINE__, eherr.str ());
396 }
397#endif
398
399 return true;
400}
401
402// Standard way of DAP handlers to pass the coordinates of the subsetted region to the handlers
403// Return the number of elements to read.
404int
405HDFSPArray_VDField::format_constraint (int *offset, int *step, int *count)
406{
407 long nels = 1;
408 int id = 0;
409
410 Dim_iter p = dim_begin ();
411 while (p != dim_end ()) {
412
413 int start = dimension_start (p, true);
414 int stride = dimension_stride (p, true);
415 int stop = dimension_stop (p, true);
416
417 // Check for illegal constraint
418 if (start > stop) {
419 ostringstream oss;
420 oss << "Array/Grid hyperslab start point "<< start <<
421 " is greater than stop point " << stop <<".";
422 throw Error(malformed_expr, oss.str());
423 }
424
425 offset[id] = start;
426 step[id] = stride;
427 count[id] = ((stop - start) / stride) + 1; // count of elements
428 nels *= count[id]; // total number of values for variable
429
430 BESDEBUG ("h4",
431 "=format_constraint():"
432 << "id=" << id << " offset=" << offset[id]
433 << " step=" << step[id]
434 << " count=" << count[id]
435 << endl);
436
437 id++;
438 p++;
439 }// while (p != dim_end ())
440
441 return nels;
442}
443
444
static void close_fileid(int32 sdfd, int32 file_id, int32 gridfd, int32 swathfd, bool pass_fileid_key)
Definition: HDFCFUtil.cc:3650