libdap  Updated for version 3.20.0
libdap4 is an implementation of OPeNDAP's DAP protocol.
Clause.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 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 <cassert>
38 #include <algorithm>
39 
40 #include "expr.h"
41 #include "Byte.h"
42 #include "Int16.h"
43 #include "UInt16.h"
44 #include "Int32.h"
45 #include "UInt32.h"
46 #include "DDS.h"
47 #include "Clause.h"
48 
49 using std::cerr;
50 using std::endl;
51 
52 namespace libdap {
53 
54 Clause::Clause(const int oper, rvalue *a1, rvalue_list *rv)
55  : _op(oper), _b_func(0), _bt_func(0), _argc(0), _arg1(a1), _args(rv)
56 {
57  assert(OK());
58 }
59 #if 1
60 Clause::Clause(bool_func func, rvalue_list *rv)
61  : _op(0), _b_func(func), _bt_func(0), _argc(0), _arg1(0), _args(rv)
62 {
63  assert(OK());
64 
65  if (_args) // account for null arg list
66  _argc = _args->size();
67  else
68  _argc = 0;
69 }
70 #endif
71 Clause::Clause(btp_func func, rvalue_list *rv)
72  : _op(0), _b_func(0), _bt_func(func), _argc(0), _arg1(0), _args(rv)
73 {
74  assert(OK());
75 
76  if (_args)
77  _argc = _args->size();
78  else
79  _argc = 0;
80 }
81 
82 Clause::Clause() : _op(0), _b_func(0), _bt_func(0), _argc(0), _arg1(0), _args(0)
83 {}
84 
85 static inline void
86 delete_rvalue(rvalue *rv)
87 {
88  delete rv; rv = 0;
89 }
90 
91 Clause::~Clause()
92 {
93  if (_arg1) {
94  delete _arg1; _arg1 = 0;
95  }
96 
97  if (_args) {
98  // _args is a pointer to a vector<rvalue*> and we must must delete
99  // each rvalue pointer here explicitly. 02/03/04 jhrg
100  for_each(_args->begin(), _args->end(), delete_rvalue);
101  delete _args; _args = 0;
102  }
103 }
104 
106 bool
108 {
109  // Each clause object can contain one of: a relational clause, a boolean
110  // function clause or a BaseType pointer function clause. It must have a
111  // valid argument list.
112  //
113  // But, a valid arg list might contain zero arguments! 10/16/98 jhrg
114  bool relational = (_op && !_b_func && !_bt_func);
115 #if 1
116  bool boolean = (!_op && _b_func && !_bt_func);
117 #endif
118  bool basetype = (!_op && !_b_func && _bt_func);
119 
120  if (relational)
121  return _arg1 && _args;
122  else if (boolean || basetype)
123  return true; // Until we check arguments...10/16/98 jhrg
124  else
125  return false;
126 }
127 
129 bool
131 {
132  assert(OK());
133 
134  return _op || _b_func;
135 }
136 
138 bool
140 {
141  assert(OK());
142 
143  return (_bt_func != 0);
144 }
145 
156 bool
158 {
159  assert(OK());
160  assert(_op || _b_func);
161 
162  if (_op) { // Is it a relational clause?
163  // rvalue::bvalue(...) returns the rvalue encapsulated in a
164  // BaseType *.
165  BaseType *btp = _arg1->bvalue(dds);
166  // The list of rvalues is an implicit logical OR, so assume
167  // FALSE and return TRUE for the first TRUE subclause.
168  bool result = false;
169  for (rvalue_list_iter i = _args->begin();
170  i != _args->end() && !result;
171  i++) {
172  result = result || btp->ops((*i)->bvalue(dds), _op);
173  }
174 
175  return result;
176  }
177  else if (_b_func) { // ...A bool function?
178  BaseType **argv = build_btp_args(_args, dds);
179 
180  bool result = false;
181  (*_b_func)(_argc, argv, dds, &result);
182  delete[] argv; // Cache me!
183  argv = 0;
184 
185  return result;
186  }
187  else {
188  throw InternalErr(__FILE__, __LINE__,
189  "A selection expression must contain only boolean clauses.");
190  }
191 }
192 
205 bool
206 Clause::value(DDS &dds, BaseType **value)
207 {
208  assert(OK());
209  assert(_bt_func);
210 
211  if (_bt_func) {
212  // build_btp_args() is a function defined in RValue.cc. It no longer
213  // reads the values as it builds the arguments, that is now left up
214  // to the functions themselves. 9/25/06 jhrg
215  BaseType **argv = build_btp_args(_args, dds);
216 
217  (*_bt_func)(_argc, argv, dds, value);
218 
219  delete[] argv; // Cache me!
220  argv = 0;
221 
222  if (*value) {
223  // FIXME This comment is likely wrong... 10/19/12
224  // This call to set_send_p was removed because new logic used
225  // in ResponseBuilder will handle it. See send_data(), ...
226  // When the second part of the CE is parsed, if it is null,
227  // then all the variables in the DDS that holds the function
228  // result variables will be sent. If there's a projection in
229  // that second CE, it will denote what is to be sent. Setting
230  // set_send_p(true) here had the affect of overriding that
231  // second CE. Note, however, that the code in send_data() clears
232  // all of the send_p properties for variables in the DDS, so
233  // removing the call here is just removing something that will
234  // actually have no affect. jhrg 10/19/12
235  (*value)->set_send_p(true);
236  (*value)->set_read_p(true);
237  return true;
238  }
239  else {
240  return false;
241  }
242  }
243  else {
244  throw InternalErr(__FILE__, __LINE__,
245  "Clause::value() was called in a context expecting a BaseType pointer return, but the Clause was boolean-valued instead.");
246  }
247 }
248 
249 } // namespace libdap
top level DAP object to house generic methods
Definition: AlarmHandler.h:35
A class for software fault reporting.
Definition: InternalErr.h:64
bool value(DDS &dds)
Evaluate a clause which returns a boolean value This method must only be evaluated for clauses with r...
Definition: Clause.cc:157
BaseType ** build_btp_args(rvalue_list *args, DDS &dds)
Definition: RValue.cc:88
The basic data type for the DODS DAP types.
Definition: BaseType.h:117
virtual bool ops(BaseType *b, int op)
Evaluate relational operators.
Definition: BaseType.cc:1248
bool OK()
Checks the "representation invariant" of a clause.
Definition: Clause.cc:107
bool value_clause()
Return true if the clause returns a value in a BaseType pointer.
Definition: Clause.cc:139
bool boolean_clause()
Return true if the clause returns a boolean value.
Definition: Clause.cc:130