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