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