libdap++  Updated for version 3.8.2
ConstraintEvaluator.cc
Go to the documentation of this file.
1 // -*- mode: c++; c-basic-offset:4 -*-
2 
3 // This file is part of libdap, A C++ implementation of the OPeNDAP Data
4 // Access Protocol.
5 
6 // Copyright (c) 2002,2003 OPeNDAP, Inc.
7 // Author: James Gallagher <jgallagher@opendap.org>
8 //
9 // This library is free software; you can redistribute it and/or
10 // modify it under the terms of the GNU Lesser General Public
11 // License as published by the Free Software Foundation; either
12 // version 2.1 of the License, or (at your option) any later version.
13 //
14 // This library is distributed in the hope that it will be useful,
15 // but WITHOUT ANY WARRANTY; without even the implied warranty of
16 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
17 // Lesser General Public License for more details.
18 //
19 // You should have received a copy of the GNU Lesser General Public
20 // License along with this library; if not, write to the Free Software
21 // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
22 //
23 // You can contact OPeNDAP, Inc. at PO Box 112, Saunderstown, RI. 02874-0112.
24 
25 #include "config.h"
26 
27 static char rcsid[] not_used =
28  {"$Id: ConstraintEvaluator.cc 23555 2010-09-14 16:43:59Z jimg $"
29  };
30 
31 #include "ConstraintEvaluator.h"
32 
33 #include "ce_functions.h"
34 #include "parser.h"
35 #include "ce_parser.h"
36 #include "debug.h"
37 
38 struct yy_buffer_state;
39 yy_buffer_state *ce_expr_scan_string(const char *str);
40 int ce_exprparse(void *arg);
41 
42 // Glue routines declared in expr.lex
43 void ce_expr_switch_to_buffer(void *new_buffer);
44 void ce_expr_delete_buffer(void * buffer);
45 void *ce_expr_string(const char *yy_str);
46 
47 namespace libdap {
48 
50 {
51  register_functions(*this);
52 }
53 
55 {
56  // delete all the constants created by the parser for CE evaluation
57  for (Constants_iter j = constants.begin(); j != constants.end(); j++) {
58  BaseType *btp = *j ;
59  delete btp ; btp = 0;
60  }
61 
62  for (Clause_iter k = expr.begin(); k != expr.end(); k++) {
63  Clause *cp = *k ;
64  delete cp ; cp = 0;
65  }
66 }
67 
71 {
72  return expr.begin() ;
73 }
74 
79 {
80  return expr.end() ;
81 }
82 
85 bool
86 ConstraintEvaluator::clause_value(Clause_iter &iter, DDS &dds/*, const string &***/)
87 {
88  if (expr.empty())
89  throw InternalErr(__FILE__, __LINE__,
90  "There are no CE clauses for *this* DDS object.");
91 
92  return (*iter)->value(dds);
93 }
94 
107 void
109 {
110  Clause *clause = new Clause(op, arg1, arg2);
111 
112  expr.push_back(clause);
113 }
114 
124 void
126 {
127  Clause *clause = new Clause(func, args);
128 
129  expr.push_back(clause);
130 }
131 
141 void
143 {
144  Clause *clause = new Clause(func, args);
145 
146  expr.push_back(clause);
147 }
148 
156 void
158 {
159  constants.push_back(btp);
160 }
161 
162 class func_name_is
163 {
164 private:
165  const string d_name;
166 
167 public:
168  func_name_is(const string &name): d_name(name)
169  {}
170  bool operator()(const ConstraintEvaluator::function f)
171  {
172  return f.name == d_name;
173  }
174 };
175 
196 void
197 ConstraintEvaluator::add_function(const string &name, bool_func f)
198 {
199  functions.remove_if(func_name_is(name));
200  function func(name, f);
201  functions.push_back(func);
202 }
203 
205 void
206 ConstraintEvaluator::add_function(const string &name, btp_func f)
207 {
208  functions.remove_if(func_name_is(name));
209  function func(name, f);
210  functions.push_back(func);
211 }
212 
214 void
215 ConstraintEvaluator::add_function(const string &name, proj_func f)
216 {
217  functions.remove_if(func_name_is(name));
218  function func(name, f);
219  functions.push_back(func);
220 }
221 
223 bool
224 ConstraintEvaluator::find_function(const string &name, bool_func *f) const
225 {
226  if (functions.empty())
227  return false;
228 
229  for (Functions_citer i = functions.begin(); i != functions.end(); i++) {
230  if (name == (*i).name && (*f = (*i).b_func)) {
231  return true;
232  }
233  }
234 
235  return false;
236 }
237 
239 bool
240 ConstraintEvaluator::find_function(const string &name, btp_func *f) const
241 {
242  if (functions.empty())
243  return false;
244 
245  for (Functions_citer i = functions.begin(); i != functions.end(); i++) {
246  if (name == (*i).name && (*f = (*i).bt_func)) {
247  return true;
248  }
249  }
250 
251  return false;
252 }
253 
255 bool
256 ConstraintEvaluator::find_function(const string &name, proj_func *f) const
257 {
258  if (functions.empty())
259  return false;
260 
261  for (Functions_citer i = functions.begin(); i != functions.end(); i++)
262  if (name == (*i).name && (*f = (*i).p_func)) {
263  return true;
264  }
265 
266  return false;
267 }
269 
276 bool
278 {
279  if (expr.empty())
280  return false;
281 
282  Clause *cp = expr[0] ;
283  return cp->value_clause();
284 }
285 
287 BaseType *
289 {
290  if (expr.size() != 1)
291  throw InternalErr(__FILE__, __LINE__,
292  "The length of the list of CE clauses is not 1.");
293 
294  Clause *cp = expr[0] ;
295  BaseType *result;
296  if (cp->value(dds, &result))
297  return result;
298  else
299  return NULL;
300 }
301 
312 {
313  if (expr.empty())
314  return false;
315 
316  for (unsigned int i = 0; i < expr.size(); ++i) {
317  Clause *cp = expr[i];
318  if (!cp->value_clause())
319  return false;
320  }
321 
322  return true;
323 }
324 
340 DDS *
342 {
343  if (expr.empty())
344  throw InternalErr(__FILE__, __LINE__, "The constraint expression is empty.");
345 
346  DDS *fdds = new DDS(dds.get_factory(), "function_result_" + dds.get_dataset_name());
347  for (unsigned int i = 0; i < expr.size(); ++i) {
348  Clause *cp = expr[i];
349  BaseType *result;
350  if (cp->value(dds, &result)) {
351  result->set_send_p(true);
352  fdds->add_var(result);
353  }
354  else
355  throw Error("A function was called but failed to return a value.");
356  }
357 
358  return fdds;
359 }
360 
366 DataDDS *
368 {
369  if (expr.empty())
370  throw InternalErr(__FILE__, __LINE__, "The constraint expression is empty.");
371 
372  DataDDS *fdds = new DataDDS(dds.get_factory(),
373  "function_result_" + dds.get_dataset_name(),
374  dds.get_version(), dds.get_protocol());
375 
376  for (unsigned int i = 0; i < expr.size(); ++i) {
377  Clause *cp = expr[i];
378  BaseType *result;
379  if (cp->value(dds, &result)) {
380  result->set_send_p(true);
381  fdds->add_var(result);
382  }
383  else
384  throw Error("A function was called but failed to return a value.");
385  }
386 
387  return fdds;
388 }
389 
391 bool
393 {
394  if (expr.empty())
395  return false;
396 
397  bool boolean = true;
398  for (Clause_iter i = expr.begin(); i != expr.end(); i++) {
399  boolean = boolean && (*i)->boolean_clause();
400  }
401 
402  return boolean;
403 }
404 
405 
413 bool
415 {
416  if (expr.empty()) {
417  DBG(cerr << "No selection recorded" << endl);
418  return true;
419  }
420 
421  DBG(cerr << "Eval selection" << endl);
422 
423  // A CE is made up of zero or more clauses, each of which has a boolean
424  // value. The value of the CE is the logical AND of the clause
425  // values. See ConstraintEvaluator::clause::value(...) for information on logical ORs in
426  // CEs.
427  bool result = true;
428  for (Clause_iter i = expr.begin(); i != expr.end() && result; i++) {
429  // A selection expression *must* contain only boolean clauses!
430  if (!((*i)->boolean_clause()))
431  throw InternalErr(__FILE__, __LINE__,
432  "A selection expression must contain only boolean clauses.");
433  result = result && (*i)->value(dds);
434  }
435 
436  return result;
437 }
438 
449 void
450 ConstraintEvaluator::parse_constraint(const string &constraint, DDS &dds)
451 {
452  void *buffer = ce_expr_string(constraint.c_str());
453  ce_expr_switch_to_buffer(buffer);
454 
455  ce_parser_arg arg(this, &dds);
456 
457  // For all errors, exprparse will throw Error.
458  ce_exprparse((void *)&arg);
459 
460  ce_expr_delete_buffer(buffer);
461 }
462 
463 } // namespace libdap
void ce_expr_delete_buffer(void *buffer)
yy_buffer_state * ce_expr_scan_string(const char *str)
std::vector< rvalue * > rvalue_list
Definition: RValue.h:67
string get_protocol() const
Definition: DataDDS.h:129
#define not_used
Definition: config.h:521
bool boolean_expression()
Does the current constraint expression return a boolean value?
std::list< function >::const_iterator Functions_citer
BaseType * eval_function(DDS &dds, const string &dataset)
Evaluate a function-valued constraint expression.
void parse_constraint(const string &constraint, DDS &dds)
Parse the constraint expression given the current DDS.
void register_functions(ConstraintEvaluator &ce)
bool find_function(const string &name, bool_func *f) const
Find a Boolean function with a given name in the function list.
string get_dataset_name() const
Definition: DDS.cc:444
void * ce_expr_string(const char *yy_str)
A class for software fault reporting.
Definition: InternalErr.h:64
bool eval_selection(DDS &dds, const string &dataset)
Evaluate a boolean-valued constraint expression. This is main method for the evaluator ans is called ...
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
#define DBG(x)
Definition: debug.h:58
virtual void set_send_p(bool state)
Definition: BaseType.cc:517
DDS * eval_function_clauses(DDS &dds)
Evaluate a function-valued constraint expression that contains several function calls.
void ce_expr_switch_to_buffer(void *new_buffer)
std::vector< BaseType * >::iterator Constants_iter
bool functional_expression()
Does the current constraint expression return a BaseType pointer? This method does not evaluate the c...
void add_function(const string &name, bool_func f)
Add a boolean function to the list.
string get_version() const
Get the server version string, unparsed.
Definition: DataDDS.h:109
int ce_exprparse(void *arg)
The basic data type for the DODS DAP types.
Definition: BaseType.h:190
void append_constant(BaseType *btp)
bool clause_value(Clause_iter &i, DDS &dds)
Holds a fragment of a constraint expression.
Definition: Clause.h:90
bool function_clauses()
Does the current constraint expression return a DDS pointer?
A class for error processing.
Definition: Error.h:90
BaseTypeFactory * get_factory() const
Definition: DDS.h:230
bool value_clause()
Return true if the clause returns a value in a BaseType pointer.
Definition: Clause.cc:139
std::vector< Clause * >::iterator Clause_iter
Holds a DAP2 DDS.
Definition: DataDDS.h:77
void append_clause(int op, rvalue *arg1, rvalue_list *arg2)
Add a clause to a constraint expression.
void add_var(BaseType *bt)
Adds a copy of the variable to the DDS. Using the ptr_duplicate() method, perform a deep copy on the ...
Definition: DDS.cc:572