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 1996,1998,1999
27 // Please first read the full copyright statement in the file COPYRIGHT_URI.
28 //
29 // Authors:
30 // jhrg,jimg James Gallagher <jgallagher@gso.uri.edu>
31
32 // Implementation for the CE Clause class.
33
34
35 #include "config.h"
36
37 #include "D4RValue.h"
38 #include "D4FilterClause.h"
39
40 using namespace std;
41
42 namespace libdap {
43
44 void
m_duplicate(const D4FilterClauseList & src)45 D4FilterClauseList::m_duplicate(const D4FilterClauseList &src)
46 {
47 //D4FilterClauseList &non_c_src = const_cast<D4FilterClauseList &>(src);
48
49 for (D4FilterClauseList::citer i = src.cbegin(), e = src.cend(); i != e; ++i) {
50 D4FilterClause *fc = *i;
51 d_clauses.push_back(new D4FilterClause(*fc));
52 }
53 }
54
~D4FilterClauseList()55 D4FilterClauseList::~D4FilterClauseList()
56 {
57 for (D4FilterClauseList::iter i = d_clauses.begin(), e = d_clauses.end(); i != e; ++i) {
58 delete *i;
59 }
60 }
61
62 /**
63 * @brief Evaluate the list of clauses
64 *
65 * Evaluate the list of clauses and return false when/if one is found to be false.
66 * This evaluates the clauses in the order they are stored and stops evaluation a
67 * the first false clause.
68 *
69 * @param dmr Use this DMR when evaluating clauses - for clauses that contain functions,
70 * not currently in the DAP4 specification.
71 * @return True if each of the clauses' value is true, otherwise false
72 */
73 bool
value(DMR & dmr)74 D4FilterClauseList::value(DMR &dmr)
75 {
76 for (D4FilterClauseList::iter i = d_clauses.begin(), e = d_clauses.end(); i != e; ++i) {
77 if ((*i)->value(dmr) == false)
78 return false;
79 }
80
81 return true;
82 }
83
84 /**
85 * @brief Evaluate the list of clauses
86 *
87 * This version of value() does not need a DMR parameter (but will not work
88 * if the clauses contain a function call (which is not currently supported
89 * by the spec).
90 *
91 * @return True if each clauses' value is true, false otherwise
92 * @see D4FilterClauseList::value(DMR &dmr)
93 */
94 bool
value()95 D4FilterClauseList::value()
96 {
97 for (D4FilterClauseList::iter i = d_clauses.begin(), e = d_clauses.end(); i != e; ++i) {
98 if ((*i)->value() == false)
99 return false;
100 }
101
102 return true;
103 }
104
m_duplicate(const D4FilterClause & rhs)105 void D4FilterClause::m_duplicate(const D4FilterClause &rhs) {
106 d_op = rhs.d_op;
107
108 d_arg1 = new D4RValue(*rhs.d_arg1);
109 d_arg2 = new D4RValue(*rhs.d_arg2);
110
111 #if 0
112 // Copy the D4RValue pointer if the 'value_kind' is a basetype,
113 // but build a new D4RValue if it is a constant (because the
114 // basetype is a weak pointer.
115 switch (rhs.d_arg1->get_kind()) {
116 case D4RValue::basetype:
117 d_arg1 = rhs.d_arg1;
118 break;
119 case D4RValue::constant:
120 d_arg1 = new D4RValue(*(rhs.d_arg1));
121 break;
122 default:
123 throw Error(malformed_expr, "found a filter clause with a function call.");
124 }
125
126 switch (rhs.d_arg2->get_kind()) {
127 case D4RValue::basetype:
128 d_arg2 = rhs.d_arg2;
129 break;
130 case D4RValue::constant:
131 d_arg2 = new D4RValue(*(rhs.d_arg2));
132 break;
133 default:
134 throw Error(malformed_expr, "found a filter clause with a function call.");
135 }
136 #endif
137 }
138
139 /**
140 * @brief Get the value of this relational expression.
141 * This version of value() works for function clauses, although that's
142 * not supported by the syntax at this time.
143 * @param dmr The DMR to use when evaluating a function
144 * @return True if the clause is true, false otherwise.
145 */
value(DMR & dmr)146 bool D4FilterClause::value(DMR &dmr)
147 {
148 switch (d_op) {
149 case null:
150 throw InternalErr(__FILE__, __LINE__, "While evaluating a constraint filter clause: Found a null operator");
151
152 case less:
153 case greater:
154 case less_equal:
155 case greater_equal:
156 case equal:
157 case not_equal:
158 case match:
159 return cmp(d_op, d_arg1->value(dmr), d_arg2->value(dmr));
160
161 case ND:
162 case map:
163 throw InternalErr(__FILE__, __LINE__, "While evaluating a constraint filter clause: Filter operator not implemented");
164
165 default:
166 throw InternalErr(__FILE__, __LINE__, "While evaluating a constraint filter clause: Unrecognized operator");
167 }
168 }
169
170 /**
171 * @brief Get the value of this relational expression.
172 * This version of value() will not work for clauses where one of the
173 * rvalues is a function call. This is not currently supported by the
174 * DAP4 specification, so it's probably no great loss.
175 * @return True if the clause is true, false otherwise.
176 */
value()177 bool D4FilterClause::value()
178 {
179 switch (d_op) {
180 case null:
181 throw InternalErr(__FILE__, __LINE__, "While evaluating a constraint filter clause: Found a null operator");
182
183 case less:
184 case greater:
185 case less_equal:
186 case greater_equal:
187 case equal:
188 case not_equal:
189 case match:
190 return cmp(d_op, d_arg1->value(), d_arg2->value());
191
192 case ND:
193 case map:
194 throw InternalErr(__FILE__, __LINE__, "While evaluating a constraint filter clause: Filter operator not implemented");
195
196 default:
197 throw InternalErr(__FILE__, __LINE__, "While evaluating a constraint filter clause: Unrecognized operator");
198 }
199 }
200
201 // It may be better to use the code in the Byte, ..., classes that was
202 // impl'd for DAP2 (with extensions). For now, test this and build the
203 // rest of the filter implementation. But there is certainly a more _compact_
204 // way to code this!
205 //
206 // Optimize the extraction of constant values.
cmp(ops op,BaseType * arg1,BaseType * arg2)207 bool D4FilterClause::cmp(ops op, BaseType *arg1, BaseType *arg2)
208 {
209 return arg1->d4_ops(arg2, op);
210 }
211
212 } // namespace libdap
213