OPeNDAP Hyrax Back End Server (BES)  Updated for version 3.8.3
HDFEOS2CFStrField.cc
Go to the documentation of this file.
1 // This file is part of the hdf4 data handler for the OPeNDAP data server.
3 // It retrieves HDF-EOS2 swath/grid one dimensional character(DFNT_CHAR) array to DAP String for the CF option.
4 // Authors: MuQun Yang <myang6@hdfgroup.org> Eunsoo Seo
5 // Copyright (c) 2010-2012 The HDF Group
7 
8 #ifdef USE_HDFEOS2_LIB
9 #include <iostream>
10 #include <sstream>
11 #include <cassert>
12 #include <debug.h>
13 #include "InternalErr.h"
14 #include <BESDebug.h>
15 #include <BESLog.h>
16 
17 #include "HDFCFUtil.h"
18 #include "HDFEOS2CFStrField.h"
19 
20 using namespace std;
21 
22 
23 bool
24 HDFEOS2CFStrField::read ()
25 {
26 
27  BESDEBUG("h4","Coming to HDFEOS2CFStrField read "<<endl);
28 
29  string check_pass_fileid_key_str="H4.EnablePassFileID";
30  bool check_pass_fileid_key = false;
31  check_pass_fileid_key = HDFCFUtil::check_beskeys(check_pass_fileid_key_str);
32 
33  // Note that one dimensional character array is one string,
34  // so the rank for character arrays should be rank from string+1
35  // offset32,step32 and count32 will be new subsetting parameters for
36  // character arrays.
37  vector<int32>offset32;
38  offset32.resize(rank+1);
39  vector<int32>count32;
40  count32.resize(rank+1);
41  vector<int32>step32;
42  step32.resize(rank+1);
43  int nelms = 1;
44 
45  if (rank != 0) {
46 
47  // Declare offset, count and step,
48  vector<int>offset;
49  offset.resize(rank);
50  vector<int>count;
51  count.resize(rank);
52  vector<int>step;
53  step.resize(rank);
54 
55  // Declare offset, count and step,
56  // Note that one dimensional character array is one string,
57  // so the rank for character arrays should be rank from string+1
58  // Obtain offset,step and count from the client expression constraint
59  nelms = format_constraint (&offset[0], &step[0], &count[0]);
60 
61  // Assign the offset32,count32 and step32 up to the dimension rank-1.
62  // Will assign the dimension rank later.
63  for (int i = 0; i < rank; i++) {
64  offset32[i] = (int32) offset[i];
65  count32[i] = (int32) count[i];
66  step32[i] = (int32) step[i];
67  }
68  }
69 
70  int32 (*openfunc) (char *, intn);
71  intn (*closefunc) (int32);
72  int32 (*attachfunc) (int32, char *);
73  intn (*detachfunc) (int32);
74  intn (*fieldinfofunc) (int32, char *, int32 *, int32 *, int32 *, char *);
75  intn (*readfieldfunc) (int32, char *, int32 *, int32 *, int32 *, void *);
76  int32 (*inqfunc) (char *, char *, int32 *);
77 
78 
79  // Define function pointers to handle the swath
80  if(grid_or_swath == 0) {
81  openfunc = GDopen;
82  closefunc = GDclose;
83  attachfunc = GDattach;
84  detachfunc = GDdetach;
85  fieldinfofunc = GDfieldinfo;
86  readfieldfunc = GDreadfield;
87  inqfunc = GDinqgrid;
88 
89  }
90  else {
91  openfunc = SWopen;
92  closefunc = SWclose;
93  attachfunc = SWattach;
94  detachfunc = SWdetach;
95  fieldinfofunc = SWfieldinfo;
96  readfieldfunc = SWreadfield;
97  inqfunc = SWinqswath;
98  }
99 
100  int32 gfid = -1;
101  if (false == check_pass_fileid_key) {
102 
103  // Obtain the EOS object ID(either grid or swath)
104  gfid = openfunc (const_cast < char *>(filename.c_str ()), DFACC_READ);
105  if (gfid < 0) {
106  ostringstream eherr;
107  eherr << "File " << filename.c_str () << " cannot be open.";
108  throw InternalErr (__FILE__, __LINE__, eherr.str ());
109  }
110 
111  }
112  else
113  gfid = gsfd;
114 
115  int32 gsid = attachfunc (gfid, const_cast < char *>(objname.c_str ()));
116  if (gsid < 0) {
117  if(false == check_pass_fileid_key)
118  closefunc(gfid);
119  ostringstream eherr;
120  eherr << "Grid/Swath " << objname.c_str () << " cannot be attached.";
121  throw InternalErr (__FILE__, __LINE__, eherr.str ());
122  }
123 
124  // Initialize the temp. returned value.
125  intn r = 0;
126  int32 tmp_rank = 0;
127  char tmp_dimlist[1024];
128  int32 tmp_dims[rank];
129  int32 field_dtype = 0;
130 
131  r = fieldinfofunc (gsid, const_cast < char *>(varname.c_str ()),
132  &tmp_rank, tmp_dims, &field_dtype, tmp_dimlist);
133  if (r != 0) {
134  detachfunc(gsid);
135  if(false == check_pass_fileid_key)
136  closefunc(gfid);
137  ostringstream eherr;
138  eherr << "Field " << varname.c_str () << " information cannot be obtained.";
139  throw InternalErr (__FILE__, __LINE__, eherr.str ());
140  }
141 
142  offset32[rank] = 0;
143  count32[rank] = tmp_dims[rank];
144  step32[rank] = 1;
145  int32 last_dim_size = tmp_dims[rank];
146 
147  vector<char>val;
148  val.resize(nelms*count32[rank]);
149 
150  r = readfieldfunc(gsid,const_cast<char*>(varname.c_str()),
151  &offset32[0], &step32[0], &count32[0], &val[0]);
152 
153  if (r != 0) {
154  detachfunc(gsid);
155  if(false == check_pass_fileid_key)
156  closefunc(gfid);
157  ostringstream eherr;
158  eherr << "swath or grid readdata failed.";
159  throw InternalErr (__FILE__, __LINE__, eherr.str ());
160  }
161 
162  vector<string>final_val;
163  final_val.resize(nelms);
164  vector<char> temp_buf;
165  temp_buf.resize(last_dim_size+1);
166 
167  // The array values of the last dimension should be saved as the
168  // string.
169  for (int i = 0; i<nelms;i++) {
170  strncpy(&temp_buf[0],&val[0]+last_dim_size*i,last_dim_size);
171  temp_buf[last_dim_size]='\0';
172  final_val[i] = &temp_buf[0];
173  }
174  set_value(&final_val[0],nelms);
175 
176  detachfunc(gsid);
177  if(false == check_pass_fileid_key)
178  closefunc(gfid);
179 
180  return false;
181 }
182 
183 int
184 HDFEOS2CFStrField::format_constraint (int *offset, int *step, int *count)
185 {
186  long nels = 1;
187  int id = 0;
188 
189  Dim_iter p = dim_begin ();
190 
191  while (p != dim_end ()) {
192 
193  int start = dimension_start (p, true);
194  int stride = dimension_stride (p, true);
195  int stop = dimension_stop (p, true);
196 
197 
198  // Check for illegical constraint
199  if (stride < 0 || start < 0 || stop < 0 || start > stop) {
200  ostringstream oss;
201 
202  oss << "Array/Grid hyperslab indices are bad: [" << start <<
203  ":" << stride << ":" << stop << "]";
204  throw Error (malformed_expr, oss.str ());
205  }
206 
207  // Check for an empty constraint and use the whole dimension if so.
208  if (start == 0 && stop == 0 && stride == 0) {
209  start = dimension_start (p, false);
210  stride = dimension_stride (p, false);
211  stop = dimension_stop (p, false);
212  }
213 
214  offset[id] = start;
215  step[id] = stride;
216  count[id] = ((stop - start) / stride) + 1;// count of elements
217  nels *= count[id];// total number of values for variable
218 
219  BESDEBUG ("h4",
220  "=format_constraint():"
221  << "id=" << id << " offset=" << offset[id]
222  << " step=" << step[id]
223  << " count=" << count[id]
224  << endl);
225 
226  id++;
227  p++;
228  }
229 
230  return nels;
231 }
232 
233 #endif
STL namespace.
This class provides a way to map HDFEOS2 character >1D array to DAP Str array for the CF option...
static bool check_beskeys(const std::string &key)
Check the BES key. This function will check a BES key specified at the file h4.conf.in. If the key's value is either true or yes. The handler claims to find a key and will do some operations. Otherwise, will do different operations. For example, One may find a line H4.EnableCF=true at h4.conf.in. That means, the HDF4 handler will handle the HDF4 files by following CF conventions.
Definition: HDFCFUtil.cc:17
#define BESDEBUG(x, y)
macro used to send debug information to the debug stream
Definition: BESDebug.h:64