OPeNDAP Hyrax Back End Server (BES)  Updated for version 3.8.3
GSEClause.cc
Go to the documentation of this file.
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 <dods-datatypes.h>
41 #include <Error.h>
42 #include <InternalErr.h>
43 #include <debug.h>
44 
45 #include "GSEClause.h"
46 #include "parser.h"
47 #include "gse.tab.hh"
48 
49 using namespace std;
50 
51 namespace libdap {
52 
53 // Private methods
54 
55 #if 0
56 // No need to actually define these; declaring them as private is good enough. jhrg 8/20/13
57 GSEClause::GSEClause()
58 {
59  throw InternalErr(__FILE__, __LINE__, "default ctor called for GSEClause");
60 }
61 
62 GSEClause::GSEClause(const GSEClause &)
63 {
64  throw InternalErr(__FILE__, __LINE__, "copy ctor called for GSEClause");
65 }
66 
67 GSEClause &GSEClause::operator=(GSEClause &)
68 {
69  throw InternalErr(__FILE__, __LINE__, "assigment called for GSEClause");
70 }
71 #endif
72 
73 // For the comparisons here, we should use an epsilon to catch issues
74 // with floating point values. jhrg 01/12/06
75 template<class T>
76 static bool
77 compare(T elem, relop op, double value)
78 {
79  switch (op) {
80  case dods_greater_op:
81  return elem > value;
83  return elem >= value;
84  case dods_less_op:
85  return elem < value;
86  case dods_less_equal_op:
87  return elem <= value;
88  case dods_equal_op:
89  return elem == value;
90  case dods_not_equal_op:
91  return elem != value;
92  case dods_nop_op:
93  throw Error(malformed_expr, "Attempt to use NOP in Grid selection.");
94  default:
95  throw Error(malformed_expr, "Unknown relational operator in Grid selection.");
96  }
97 }
98 
99 // These values are used in error messages, hence the strings.
100 template<class T>
101 void
102 GSEClause::set_map_min_max_value(T min, T max)
103 {
104  DBG(cerr << "Inside set map min max value " << min << ", " << max << endl);
105  std::ostringstream oss1;
106  oss1 << min;
107  d_map_min_value = oss1.str();
108 
109  std::ostringstream oss2;
110  oss2 << max;
111  d_map_max_value = oss2.str();
112 }
113 
114 // Read the map array, scan, set start and stop.
115 template<class T>
116 void
117 GSEClause::set_start_stop()
118 {
119  T *vals = new T[d_map->length()];
120  d_map->value(vals);
121 
122  // Set the map's max and min values for use in error messages (it's a lot
123  // easier to do here, now, than later... 9/20/2001 jhrg)
124  set_map_min_max_value<T>(vals[d_start], vals[d_stop]);
125 
126  // Starting at the current start point in the map (initially index position
127  // zero), scan forward until the comparison is true. Set the new value
128  // of d_start to that location. Note that each clause applies to exactly
129  // one map. The 'i <= end' test keeps us from setting start _past_ the
130  // end ;-)
131  int i = d_start;
132  int end = d_stop;
133  while (i <= end && !compare<T>(vals[i], d_op1, d_value1))
134  i++;
135 
136  d_start = i;
137 
138  // Now scan backward from the end. We scan all the way to the actual start
139  // although it would probably work to stop at 'i >= d_start'.
140  i = end;
141  while (i >= 0 && !compare<T>(vals[i], d_op1, d_value1))
142  i--;
143  d_stop = i;
144 
145  // Every clause must have one operator but the second is optional since
146  // the more complex form of a clause is optional. That is, the above two
147  // loops took care of constraints like 'x < 7' but we need the following
148  // for ones like '3 < x < 7'.
149  if (d_op2 != dods_nop_op) {
150  int i = d_start;
151  int end = d_stop;
152  while (i <= end && !compare<T>(vals[i], d_op2, d_value2))
153  i++;
154 
155  d_start = i;
156 
157  i = end;
158  while (i >= 0 && !compare<T>(vals[i], d_op2, d_value2))
159  i--;
160 
161  d_stop = i;
162  }
163 
164  delete[] vals;
165 }
166 
167 void
168 GSEClause::compute_indices()
169 {
170  switch (d_map->var()->type()) {
171  case dods_byte_c:
172  set_start_stop<dods_byte>();
173  break;
174  case dods_int16_c:
175  set_start_stop<dods_int16>();
176  break;
177  case dods_uint16_c:
178  set_start_stop<dods_uint16>();
179  break;
180  case dods_int32_c:
181  set_start_stop<dods_int32>();
182  break;
183  case dods_uint32_c:
184  set_start_stop<dods_uint32>();
185  break;
186  case dods_float32_c:
187  set_start_stop<dods_float32>();
188  break;
189  case dods_float64_c:
190  set_start_stop<dods_float64>();
191  break;
192  default:
193  throw Error(malformed_expr,
194  "Grid selection using non-numeric map vectors is not supported");
195  }
196 
197 }
198 
199 // Public methods
200 
202 GSEClause::GSEClause(Grid *grid, const string &map, const double value,
203  const relop op)
204  : d_map(0),
205  d_value1(value), d_value2(0), d_op1(op), d_op2(dods_nop_op),
206  d_map_min_value(""), d_map_max_value("")
207 {
208  d_map = dynamic_cast<Array *>(grid->var(map));
209  if (!d_map)
210  throw Error(string("The map variable '") + map
211  + string("' does not exist in the grid '")
212  + grid->name() + string("'."));
213 
214  DBG(cerr << d_map->toString());
215 
216  // Initialize the start and stop indices.
217  Array::Dim_iter iter = d_map->dim_begin();
218  d_start = d_map->dimension_start(iter);
219  d_stop = d_map->dimension_stop(iter);
220 
221  compute_indices();
222 }
223 
225 GSEClause::GSEClause(Grid *grid, const string &map, const double value1,
226  const relop op1, const double value2, const relop op2)
227  : d_map(0),
228  d_value1(value1), d_value2(value2), d_op1(op1), d_op2(op2),
229  d_map_min_value(""), d_map_max_value("")
230 {
231  d_map = dynamic_cast<Array *>(grid->var(map));
232  if (!d_map)
233  throw Error(string("The map variable '") + map
234  + string("' does not exist in the grid '")
235  + grid->name() + string("'."));
236 
237  DBG(cerr << d_map->toString());
238 
239  // Initialize the start and stop indices.
240  Array::Dim_iter iter = d_map->dim_begin();
241  d_start = d_map->dimension_start(iter);
242  d_stop = d_map->dimension_stop(iter);
243 
244  compute_indices();
245 }
246 
249 bool
251 {
252  if (!d_map)
253  return false;
254 
255  // More ...
256 
257  return true;
258 }
259 
262 Array *
264 {
265  return d_map;
266 }
267 
272 void
274 {
275  d_map = map;
276 }
277 
280 string
282 {
283  return d_map->name();
284 }
285 
289 int
291 {
292  return d_start;
293 }
294 
297 void
299 {
300  d_start = start;
301 }
302 
306 int
308 {
309  DBG(cerr << "Returning stop index value of: " << d_stop << endl);
310  return d_stop;
311 }
312 
315 void
317 {
318  d_stop = stop;
319 }
320 
325 string
327 {
328  return d_map_min_value;
329 }
330 
335 string
337 {
338  return d_map_max_value;
339 }
340 
341 } // namespace libdap
342 
Array * get_map() const
Get a pointer to the map variable constrained by this clause.
Definition: GSEClause.cc:263
bool OK() const
Class invariant.
Definition: GSEClause.cc:250
string get_map_max_value() const
Get the maximum map vector value.
Definition: GSEClause.cc:336
int get_start() const
Get the starting index of the clause's map variable as constrained by this clause.
Definition: GSEClause.cc:290
void set_start(int start)
Set the starting index.
Definition: GSEClause.cc:298
void set_stop(int stop)
Set the stopping index.
Definition: GSEClause.cc:316
int get_stop() const
Get the stopping index of the clause's map variable as constrained by this clause.
Definition: GSEClause.cc:307
string get_map_min_value() const
Get the minimum map vector value.
Definition: GSEClause.cc:326
void set_map(Array *map)
Set the pointer to the map vector contrained by this clause.
Definition: GSEClause.cc:273
string get_map_name() const
Get the name of the map variable constrained by this clause.
Definition: GSEClause.cc:281