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