libdap++  Updated for version 3.8.2
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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 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 static char id[] not_used =
38  {"$Id: GSEClause.cc 18282 2008-03-01 01:36:12Z jimg $"
39  };
40 
41 #include <iostream>
42 #include <sstream>
43 
44 #include "dods-datatypes.h"
45 #include "Error.h"
46 #include "InternalErr.h"
47 
48 #include "debug.h"
49 #include "GSEClause.h"
50 #include "parser.h"
51 #include "gse.tab.hh"
52 
53 using namespace std;
54 
55 int gse_parse(void *arg);
56 void gse_restart(FILE *in);
57 
58 // Glue routines declared in gse.lex
59 void gse_switch_to_buffer(void *new_buffer);
60 void gse_delete_buffer(void * buffer);
61 void *gse_string(const char *yy_str);
62 
63 namespace libdap {
64 
65 // Private methods
66 
67 GSEClause::GSEClause()
68 {
69  throw InternalErr(__FILE__, __LINE__, "default ctor called for GSEClause");
70 }
71 
72 GSEClause::GSEClause(const GSEClause &)
73 {
74  throw InternalErr(__FILE__, __LINE__, "copy ctor called for GSEClause");
75 }
76 
77 GSEClause &GSEClause::operator=(GSEClause &)
78 {
79  throw InternalErr(__FILE__, __LINE__, "assigment called for GSEClause");
80 }
81 
82 // For the comparisions here, we should use an epsilon to catch issues
83 // with floating point values. jhrg 01/12/06
84 template<class T>
85 static bool
86 compare(T elem, relop op, double value)
87 {
88  switch (op) {
89  case dods_greater_op:
90  return elem > value;
92  return elem >= value;
93  case dods_less_op:
94  return elem < value;
95  case dods_less_equal_op:
96  return elem <= value;
97  case dods_equal_op:
98  return elem == value;
99  case dods_not_equal_op:
100  return elem != value;
101  case dods_nop_op:
102  throw Error(malformed_expr, "Attempt to use NOP in Grid selection.");
103  default:
104  throw Error(malformed_expr, "Unknown relational operator in Grid selection.");
105  }
106 }
107 
108 // These values are used in error messages, hence the strings.
109 template<class T>
110 void
111 GSEClause::set_map_min_max_value(T min, T max)
112 {
113  DBG(cerr << "Inside set map min max value " << min << ", " << max << endl);
114  std::ostringstream oss1;
115  oss1 << min;
116  d_map_min_value = oss1.str();
117 
118  std::ostringstream oss2;
119  oss2 << max;
120  d_map_max_value = oss2.str();
121 }
122 
123 // Read the map array, scan, set start and stop.
124 template<class T>
125 void
126 GSEClause::set_start_stop()
127 {
128  T *vals = new T[d_map->length()];
129  d_map->value(vals);
130 
131  // Set the map's max and min values for use in error messages (it's a lot
132  // easier to do here, now, than later... 9/20/2001 jhrg)
133  set_map_min_max_value<T>(vals[d_start], vals[d_stop]);
134 
135  // Starting at the current start point in the map (initially index position
136  // zero), scan forward until the comparison is true. Set the new value
137  // of d_start to that location. Note that each clause applies to exactly
138  // one map. The 'i <= end' test keeps us from setting start _past_ the
139  // end ;-)
140  int i = d_start;
141  int end = d_stop;
142  while (i <= end && !compare<T>(vals[i], d_op1, d_value1))
143  i++;
144 
145  d_start = i;
146 
147  // Now scan backward from the end. We scan all the way to the actual start
148  // although it would probably work to stop at 'i >= d_start'.
149  i = end;
150  while (i >= 0 && !compare<T>(vals[i], d_op1, d_value1))
151  i--;
152  d_stop = i;
153 
154  // Every clause must have one operator but the second is optional since
155  // the more complex form of a clause is optional. That is, the above two
156  // loops took care of constraints like 'x < 7' but we need the following
157  // for ones like '3 < x < 7'.
158  if (d_op2 != dods_nop_op) {
159  int i = d_start;
160  int end = d_stop;
161  while (i <= end && !compare<T>(vals[i], d_op2, d_value2))
162  i++;
163 
164  d_start = i;
165 
166  i = end;
167  while (i >= 0 && !compare<T>(vals[i], d_op2, d_value2))
168  i--;
169 
170  d_stop = i;
171  }
172 }
173 
174 void
175 GSEClause::compute_indices()
176 {
177  switch (d_map->var()->type()) {
178  case dods_byte_c:
179  set_start_stop<dods_byte>();
180  break;
181  case dods_int16_c:
182  set_start_stop<dods_int16>();
183  break;
184  case dods_uint16_c:
185  set_start_stop<dods_uint16>();
186  break;
187  case dods_int32_c:
188  set_start_stop<dods_int32>();
189  break;
190  case dods_uint32_c:
191  set_start_stop<dods_uint32>();
192  break;
193  case dods_float32_c:
194  set_start_stop<dods_float32>();
195  break;
196  case dods_float64_c:
197  set_start_stop<dods_float64>();
198  break;
199  default:
200  throw Error(malformed_expr,
201  "Grid selection using non-numeric map vectors is not supported");
202  }
203 
204 }
205 
206 // Public methods
207 
209 GSEClause::GSEClause(Grid *grid, const string &map, const double value,
210  const relop op)
211  : d_map(0),
212  d_value1(value), d_value2(0), d_op1(op), d_op2(dods_nop_op),
213  d_map_min_value(""), d_map_max_value("")
214 {
215  d_map = dynamic_cast<Array *>(grid->var(map));
216  if (!d_map)
217  throw Error(string("The map variable '") + map
218  + string("' does not exist in the grid '")
219  + grid->name() + string("'."));
220 
221  DBG(cerr << d_map->toString());
222 
223  // Initialize the start and stop indices.
224  Array::Dim_iter iter = d_map->dim_begin();
225  d_start = d_map->dimension_start(iter);
226  d_stop = d_map->dimension_stop(iter);
227 
228  compute_indices();
229 }
230 
232 GSEClause::GSEClause(Grid *grid, const string &map, const double value1,
233  const relop op1, const double value2, const relop op2)
234  : d_map(0),
235  d_value1(value1), d_value2(value2), d_op1(op1), d_op2(op2),
236  d_map_min_value(""), d_map_max_value("")
237 {
238  d_map = dynamic_cast<Array *>(grid->var(map));
239  if (!d_map)
240  throw Error(string("The map variable '") + map
241  + string("' does not exist in the grid '")
242  + grid->name() + string("'."));
243 
244  DBG(cerr << d_map->toString());
245 
246  // Initialize the start and stop indices.
247  Array::Dim_iter iter = d_map->dim_begin();
248  d_start = d_map->dimension_start(iter);
249  d_stop = d_map->dimension_stop(iter);
250 
251  compute_indices();
252 }
253 
256 bool
258 {
259  if (!d_map)
260  return false;
261 
262  // More ...
263 
264  return true;
265 }
266 
269 Array *
271 {
272  return d_map;
273 }
274 
279 void
281 {
282  d_map = map;
283 }
284 
287 string
289 {
290  return d_map->name();
291 }
292 
296 int
298 {
299  return d_start;
300 }
301 
304 void
306 {
307  d_start = start;
308 }
309 
313 int
315 {
316  DBG(cerr << "Returning stop index value of: " << d_stop << endl);
317  return d_stop;
318 }
319 
322 void
324 {
325  d_stop = stop;
326 }
327 
332 string
334 {
335  return d_map_min_value;
336 }
337 
342 string
344 {
345  return d_map_max_value;
346 }
347 
348 } // namespace libdap
349 
void gse_switch_to_buffer(void *new_buffer)
string name() const
Returns the name of the class instance.
Definition: BaseType.cc:210
#define not_used
Definition: config.h:521
#define malformed_expr
Definition: Error.h:64
bool OK() const
Definition: GSEClause.cc:257
virtual string toString()
Definition: BaseType.cc:161
string get_map_max_value() const
Get the maximum map vector value.
Definition: GSEClause.cc:343
int get_stop() const
Get the stopping index of the clause&#39;s map variable as constrained by this clause.
Definition: GSEClause.cc:314
#define DBG(x)
Definition: debug.h:58
void * gse_string(const char *yy_str)
std::vector< dimension >::iterator Dim_iter
Definition: Array.h:152
string get_map_min_value() const
Get the minimum map vector value.
Definition: GSEClause.cc:333
Holds the Grid data type.
Definition: Grid.h:123
void set_start(int start)
Set the starting index.
Definition: GSEClause.cc:305
void set_stop(int stop)
Set the stopping index.
Definition: GSEClause.cc:323
virtual int dimension_stop(Dim_iter i, bool constrained=false)
Return the stop index of the constraint.
Definition: Array.cc:447
virtual int dimension_start(Dim_iter i, bool constrained=false)
Return the start index of a dimension.
Definition: Array.cc:423
int get_start() const
Get the starting index of the clause&#39;s map variable as constrained by this clause.
Definition: GSEClause.cc:297
virtual BaseType * var(const string &n, bool exact=true, btp_stack *s=0)
Definition: Grid.cc:312
Dim_iter dim_begin()
Definition: Array.cc:340
Array * get_map() const
Get a pointer to the map variable constrained by this clause.
Definition: GSEClause.cc:270
void gse_restart(FILE *in)
A class for error processing.
Definition: Error.h:90
void gse_delete_buffer(void *buffer)
int gse_parse(void *arg)
A multidimensional array of identical data types.
Definition: Array.h:101
void set_map(Array *map)
Set the pointer to the map vector contrained by this clause.
Definition: GSEClause.cc:280
string get_map_name() const
Get the name of the map variable constrained by this clause.
Definition: GSEClause.cc:288