libdap Updated for version 3.21.0
libdap4 is an implementation of OPeNDAP's DAP protocol.
GSEClause.cc
1
2// -*- mode: c++; c-basic-offset:4 -*-
3
4// This file is part of libdap, A C++ implementation of the OPeNDAP Data
5// Access Protocol.
6
7// Copyright (c) 2002,2003 OPeNDAP, Inc.
8// Author: James Gallagher <jgallagher@opendap.org>
9//
10// This library is free software; you can redistribute it and/or
11// modify it under the terms of the GNU Lesser General Public
12// License as published by the Free Software Foundation; either
13// version 2.1 of the License, or (at your option) any later version.
14//
15// This library is distributed in the hope that it will be useful,
16// but WITHOUT ANY WARRANTY; without even the implied warranty of
17// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
18// Lesser General Public License for more details.
19//
20// You should have received a copy of the GNU Lesser General Public
21// License along with this library; if not, write to the Free Software
22// Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
23//
24// You can contact OPeNDAP, Inc. at PO Box 112, Saunderstown, RI. 02874-0112.
25
26// (c) COPYRIGHT URI/MIT 1999
27// Please read the full copyright statement in the file COPYRIGHT_URI.
28//
29// Authors:
30// jhrg,jimg James Gallagher <jgallagher@gso.uri.edu>
31
32// The Grid Selection Expression Clause class.
33
34
35#include "config.h"
36
37#include <iostream>
38#include <sstream>
39
40#include <Array.h>
41#include <Grid.h>
42#include <dods-datatypes.h>
43#include <Error.h>
44#include <InternalErr.h>
45#include <debug.h>
46
47#include "GSEClause.h"
48#include "parser.h"
49#include "gse.tab.hh"
50
51using namespace std;
52using namespace libdap;
53
54namespace functions {
55
56// For the comparisons here, we should use an epsilon to catch issues
57// with floating point values. jhrg 01/12/06
58template<class T>
59static bool
60compare(T elem, relop op, double value)
61{
62 switch (op) {
63 case dods_greater_op:
64 return elem > value;
65 case dods_greater_equal_op:
66 return elem >= value;
67 case dods_less_op:
68 return elem < value;
69 case dods_less_equal_op:
70 return elem <= value;
71 case dods_equal_op:
72 return elem == value;
73 case dods_not_equal_op:
74 return elem != value;
75 case dods_nop_op:
76 throw Error(malformed_expr, "Attempt to use NOP in Grid selection.");
77 default:
78 throw Error(malformed_expr, "Unknown relational operator in Grid selection.");
79 }
80}
81
82// These values are used in error messages, hence the strings.
83template<class T>
84void
85GSEClause::set_map_min_max_value(T min, T max)
86{
87 DBG(cerr << "Inside set map min max value " << min << ", " << max << endl);
88 std::ostringstream oss1;
89 oss1 << min;
90 d_map_min_value = oss1.str();
91
92 std::ostringstream oss2;
93 oss2 << max;
94 d_map_max_value = oss2.str();
95}
96
97// Read the map array, scan, set start and stop.
98template<class T>
99void
100GSEClause::set_start_stop()
101{
102 T *vals = new T[d_map->length()];
103 d_map->value(vals);
104
105 // Set the map's max and min values for use in error messages (it's a lot
106 // easier to do here, now, than later... 9/20/2001 jhrg)
107 set_map_min_max_value<T>(vals[d_start], vals[d_stop]);
108
109 // Starting at the current start point in the map (initially index position
110 // zero), scan forward until the comparison is true. Set the new value
111 // of d_start to that location. Note that each clause applies to exactly
112 // one map. The 'i <= end' test keeps us from setting start _past_ the
113 // end ;-)
114 int i = d_start;
115 int end = d_stop;
116 while (i <= end && !compare<T>(vals[i], d_op1, d_value1))
117 i++;
118
119 d_start = i;
120
121 // Now scan backward from the end. We scan all the way to the actual start
122 // although it would probably work to stop at 'i >= d_start'.
123 i = end;
124 while (i >= 0 && !compare<T>(vals[i], d_op1, d_value1))
125 i--;
126 d_stop = i;
127
128 // Every clause must have one operator but the second is optional since
129 // the more complex form of a clause is optional. That is, the above two
130 // loops took care of constraints like 'x < 7' but we need the following
131 // for ones like '3 < x < 7'.
132 if (d_op2 != dods_nop_op) {
133 int i = d_start;
134 int end = d_stop;
135 while (i <= end && !compare<T>(vals[i], d_op2, d_value2))
136 i++;
137
138 d_start = i;
139
140 i = end;
141 while (i >= 0 && !compare<T>(vals[i], d_op2, d_value2))
142 i--;
143
144 d_stop = i;
145 }
146
147 delete[] vals;
148}
149
150void
151GSEClause::compute_indices()
152{
153 switch (d_map->var()->type()) {
154 case dods_byte_c:
155 set_start_stop<dods_byte>();
156 break;
157 case dods_int16_c:
158 set_start_stop<dods_int16>();
159 break;
160 case dods_uint16_c:
161 set_start_stop<dods_uint16>();
162 break;
163 case dods_int32_c:
164 set_start_stop<dods_int32>();
165 break;
166 case dods_uint32_c:
167 set_start_stop<dods_uint32>();
168 break;
169 case dods_float32_c:
170 set_start_stop<dods_float32>();
171 break;
172 case dods_float64_c:
173 set_start_stop<dods_float64>();
174 break;
175 default:
176 throw Error(malformed_expr,
177 "Grid selection using non-numeric map vectors is not supported");
178 }
179
180}
181
182// Public methods
183
185GSEClause::GSEClause(Grid *grid, const string &map, const double value,
186 const relop op)
187 : d_map(0),
188 d_value1(value), d_value2(0), d_op1(op), d_op2(dods_nop_op),
189 d_map_min_value(""), d_map_max_value("")
190{
191 d_map = dynamic_cast<Array *>(grid->var(map));
192 if (!d_map)
193 throw Error(string("The map variable '") + map
194 + string("' does not exist in the grid '")
195 + grid->name() + string("'."));
196
197 DBG(cerr << d_map->toString());
198
199 // Initialize the start and stop indices.
200 Array::Dim_iter iter = d_map->dim_begin();
201 d_start = d_map->dimension_start(iter);
202 d_stop = d_map->dimension_stop(iter);
203
204 compute_indices();
205}
206
208GSEClause::GSEClause(Grid *grid, const string &map, const double value1,
209 const relop op1, const double value2, const relop op2)
210 : d_map(0),
211 d_value1(value1), d_value2(value2), d_op1(op1), d_op2(op2),
212 d_map_min_value(""), d_map_max_value("")
213{
214 d_map = dynamic_cast<Array *>(grid->var(map));
215 if (!d_map)
216 throw Error(string("The map variable '") + map
217 + string("' does not exist in the grid '")
218 + grid->name() + string("'."));
219
220 DBG(cerr << d_map->toString());
221
222 // Initialize the start and stop indices.
223 Array::Dim_iter iter = d_map->dim_begin();
224 d_start = d_map->dimension_start(iter);
225 d_stop = d_map->dimension_stop(iter);
226
227 compute_indices();
228}
229
230GSEClause::~GSEClause()
231{
232 delete d_map;
233}
234
237bool
238GSEClause::OK() const
239{
240 if (!d_map)
241 return false;
242
243 // More ...
244
245 return true;
246}
247
250Array *
251GSEClause::get_map() const
252{
253 return d_map;
254}
255
260void
261GSEClause::set_map(Array *map)
262{
263 d_map = map;
264}
265
268string
269GSEClause::get_map_name() const
270{
271 return d_map->name();
272}
273
277int
278GSEClause::get_start() const
279{
280 return d_start;
281}
282
285void
286GSEClause::set_start(int start)
287{
288 d_start = start;
289}
290
294int
295GSEClause::get_stop() const
296{
297 DBG(cerr << "Returning stop index value of: " << d_stop << endl);
298 return d_stop;
299}
300
303void
304GSEClause::set_stop(int stop)
305{
306 d_stop = stop;
307}
308
313string
314GSEClause::get_map_min_value() const
315{
316 return d_map_min_value;
317}
318
323string
324GSEClause::get_map_max_value() const
325{
326 return d_map_max_value;
327}
328
329} // namespace functions
330
A multidimensional array of identical data types.
Definition Array.h:123
std::vector< dimension >::iterator Dim_iter
Definition Array.h:241
virtual string name() const
Returns the name of the class instance.
Definition BaseType.cc:317
virtual Type type() const
Returns the type of the class instance.
Definition BaseType.cc:362
A class for error processing.
Definition Error.h:94
Holds the Grid data type.
Definition Grid.h:123
int length() const override
Returns the number of elements in the vector. Note that some child classes of Vector use the length o...
Definition Vector.h:218
BaseType * var(const string &name="", bool exact_match=true, btp_stack *s=nullptr) override
Definition Vector.cc:486
top level DAP object to house generic methods
Definition AISConnect.cc:30