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