libdap Updated for version 3.21.1
libdap4 is an implementation of OPeNDAP's DAP protocol.
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#include "config.h"
35
36#include <iostream>
37#include <sstream>
38
39#include <Array.h>
40#include <Error.h>
41#include <Grid.h>
42#include <InternalErr.h>
43#include <debug.h>
44#include <dods-datatypes.h>
45
46#include "GSEClause.h"
47#include "gse.tab.hh"
48#include "parser.h"
49
50using namespace std;
51using namespace libdap;
52
53namespace functions {
54
55// For the comparisons here, we should use an epsilon to catch issues
56// with floating point values. jhrg 01/12/06
57template <class T> static bool compare(T elem, relop op, double value) {
58 switch (op) {
59 case dods_greater_op:
60 return elem > value;
62 return elem >= value;
63 case dods_less_op:
64 return elem < value;
66 return elem <= value;
67 case dods_equal_op:
68 return elem == value;
70 return elem != value;
71 case dods_nop_op:
72 throw Error(malformed_expr, "Attempt to use NOP in Grid selection.");
73 default:
74 throw Error(malformed_expr, "Unknown relational operator in Grid selection.");
75 }
76}
77
78// These values are used in error messages, hence the strings.
79template <class T> void GSEClause::set_map_min_max_value(T min, T max) {
80 DBG(cerr << "Inside set map min max value " << min << ", " << max << endl);
81 std::ostringstream oss1;
82 oss1 << min;
83 d_map_min_value = oss1.str();
84
85 std::ostringstream oss2;
86 oss2 << max;
87 d_map_max_value = oss2.str();
88}
89
90// Read the map array, scan, set start and stop.
91template <class T> void GSEClause::set_start_stop() {
92 T *vals = new T[d_map->length()];
93 d_map->value(vals);
94
95 // Set the map's max and min values for use in error messages (it's a lot
96 // easier to do here, now, than later... 9/20/2001 jhrg)
97 set_map_min_max_value<T>(vals[d_start], vals[d_stop]);
98
99 // Starting at the current start point in the map (initially index position
100 // zero), scan forward until the comparison is true. Set the new value
101 // of d_start to that location. Note that each clause applies to exactly
102 // one map. The 'i <= end' test keeps us from setting start _past_ the
103 // end ;-)
104 int i = d_start;
105 int end = d_stop;
106 while (i <= end && !compare<T>(vals[i], d_op1, d_value1))
107 i++;
108
109 d_start = i;
110
111 // Now scan backward from the end. We scan all the way to the actual start
112 // although it would probably work to stop at 'i >= d_start'.
113 i = end;
114 while (i >= 0 && !compare<T>(vals[i], d_op1, d_value1))
115 i--;
116 d_stop = i;
117
118 // Every clause must have one operator but the second is optional since
119 // the more complex form of a clause is optional. That is, the above two
120 // loops took care of constraints like 'x < 7' but we need the following
121 // for ones like '3 < x < 7'.
122 if (d_op2 != dods_nop_op) {
123 int i = d_start;
124 int end = d_stop;
125 while (i <= end && !compare<T>(vals[i], d_op2, d_value2))
126 i++;
127
128 d_start = i;
129
130 i = end;
131 while (i >= 0 && !compare<T>(vals[i], d_op2, d_value2))
132 i--;
133
134 d_stop = i;
135 }
136
137 delete[] vals;
138}
139
140void GSEClause::compute_indices() {
141 switch (d_map->var()->type()) {
142 case dods_byte_c:
143 set_start_stop<dods_byte>();
144 break;
145 case dods_int16_c:
146 set_start_stop<dods_int16>();
147 break;
148 case dods_uint16_c:
149 set_start_stop<dods_uint16>();
150 break;
151 case dods_int32_c:
152 set_start_stop<dods_int32>();
153 break;
154 case dods_uint32_c:
155 set_start_stop<dods_uint32>();
156 break;
157 case dods_float32_c:
158 set_start_stop<dods_float32>();
159 break;
160 case dods_float64_c:
161 set_start_stop<dods_float64>();
162 break;
163 default:
164 throw Error(malformed_expr, "Grid selection using non-numeric map vectors is not supported");
165 }
166}
167
168// Public methods
169
171GSEClause::GSEClause(Grid *grid, const string &map, const double value, const relop op)
172 : d_map(0), d_value1(value), d_value2(0), d_op1(op), d_op2(dods_nop_op), d_map_min_value(""), d_map_max_value("") {
173 d_map = dynamic_cast<Array *>(grid->var(map));
174 if (!d_map)
175 throw Error(string("The map variable '") + map + string("' does not exist in the grid '") + grid->name() +
176 string("'."));
177
178 DBG(cerr << d_map->toString());
179
180 // Initialize the start and stop indices.
181 Array::Dim_iter iter = d_map->dim_begin();
182 d_start = d_map->dimension_start(iter);
183 d_stop = d_map->dimension_stop(iter);
184
185 compute_indices();
186}
187
189GSEClause::GSEClause(Grid *grid, const string &map, const double value1, const relop op1, const double value2,
190 const relop op2)
191 : d_map(0), d_value1(value1), d_value2(value2), d_op1(op1), d_op2(op2), d_map_min_value(""), d_map_max_value("") {
192 d_map = dynamic_cast<Array *>(grid->var(map));
193 if (!d_map)
194 throw Error(string("The map variable '") + map + string("' does not exist in the grid '") + grid->name() +
195 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
207GSEClause::~GSEClause() { delete d_map; }
208
211bool GSEClause::OK() const {
212 if (!d_map)
213 return false;
214
215 // More ...
216
217 return true;
218}
219
222Array *GSEClause::get_map() const { return d_map; }
223
228void GSEClause::set_map(Array *map) { d_map = map; }
229
232string GSEClause::get_map_name() const { return d_map->name(); }
233
237int GSEClause::get_start() const { return d_start; }
238
241void GSEClause::set_start(int start) { d_start = start; }
242
247 DBG(cerr << "Returning stop index value of: " << d_stop << endl);
248 return d_stop;
249}
250
253void GSEClause::set_stop(int stop) { d_stop = stop; }
254
259string GSEClause::get_map_min_value() const { return d_map_min_value; }
260
265string GSEClause::get_map_max_value() const { return d_map_max_value; }
266
267} // namespace functions
#define malformed_expr
(400)
Definition Error.h:66
string get_map_name() const
Get the name of the map variable constrained by this clause.
Definition GSEClause.cc:232
libdap::Array * get_map() const
Get a pointer to the map variable constrained by this clause.
Definition GSEClause.cc:222
void set_stop(int stop)
Set the stopping index.
Definition GSEClause.cc:253
int get_stop() const
Get the stopping index of the clause's map variable as constrained by this clause.
Definition GSEClause.cc:246
void set_start(int start)
Set the starting index.
Definition GSEClause.cc:241
string get_map_max_value() const
Get the maximum map vector value.
Definition GSEClause.cc:265
int get_start() const
Get the starting index of the clause's map variable as constrained by this clause.
Definition GSEClause.cc:237
string get_map_min_value() const
Get the minimum map vector value.
Definition GSEClause.cc:259
void set_map(libdap::Array *map)
Set the pointer to the map vector contrained by this clause.
Definition GSEClause.cc:228
A multidimensional array of identical data types.
Definition Array.h:121
std::vector< dimension >::iterator Dim_iter
Definition Array.h:225
virtual string name() const
Returns the name of the class instance.
Definition BaseType.cc:296
BaseType * var(const string &name, bool exact_match=true, btp_stack *s=nullptr) override
btp_stack no longer needed; use back pointers (BaseType::get_parent())
A class for error processing.
Definition Error.h:92
Holds the Grid data type.
Definition Grid.h:121
#define DBG(x)
Definition debug.h:58
@ dods_greater_equal_op
Definition GSEClause.h:57
@ dods_greater_op
Definition GSEClause.h:56
@ dods_nop_op
Definition GSEClause.h:55
@ dods_not_equal_op
Definition GSEClause.h:61
@ dods_equal_op
Definition GSEClause.h:60
@ dods_less_op
Definition GSEClause.h:58
@ dods_less_equal_op
Definition GSEClause.h:59
top level DAP object to house generic methods
Definition AISConnect.cc:30
@ dods_uint32_c
Definition Type.h:100
@ dods_int16_c
Definition Type.h:97
@ dods_byte_c
Definition Type.h:96
@ dods_int32_c
Definition Type.h:99
@ dods_float32_c
Definition Type.h:101
@ dods_uint16_c
Definition Type.h:98
@ dods_float64_c
Definition Type.h:102