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