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