bes  Updated for version 3.20.6
HDFSPArray_VDField.cc
1 // 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 <debug.h>
16 #include "hdf.h"
17 #include "mfhdf.h"
18 #include "InternalErr.h"
19 #include <BESDebug.h>
20 #include "HDFCFUtil.h"
21 #include "HDF4RequestHandler.h"
22 
23 using namespace std;
24 using namespace libdap;
25 #define SIGNED_BYTE_TO_INT32 1
26 
27 
28 bool
29 HDFSPArray_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[0],&step[0],&count[0]);
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[0], 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[0], 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[0], 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[0], 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[0], 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[0], 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[0], 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[0], 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[0], 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[0], 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[0], 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[0], 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[0], 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[0], 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[0], 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[0], 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[0], 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.
404 int
405 HDFSPArray_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 
libdap
Definition: BESDapFunctionResponseCache.h:35
Error
HDFCFUtil::close_fileid
static void close_fileid(int32 sdfd, int32 file_id, int32 gridfd, int32 swathfd, bool pass_fileid_key)
Definition: HDFCFUtil.cc:3685