bes Updated for version 3.20.10
HDFEOS2CFStrField.cc
1
2// 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
24using namespace std;
25using namespace libdap;
26
27
28
29bool
30HDFEOS2CFStrField::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
192int
193HDFEOS2CFStrField::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.