libdap++ Updated for version 3.8.2
|
00001 // -*- mode: c++; c-basic-offset:4 -*- 00002 00003 // This file is part of libdap, A C++ implementation of the OPeNDAP Data 00004 // Access Protocol. 00005 00006 // Copyright (c) 2002,2003 OPeNDAP, Inc. 00007 // Author: James Gallagher <jgallagher@opendap.org> 00008 // 00009 // This library is free software; you can redistribute it and/or 00010 // modify it under the terms of the GNU Lesser General Public 00011 // License as published by the Free Software Foundation; either 00012 // version 2.1 of the License, or (at your option) any later version. 00013 // 00014 // This library is distributed in the hope that it will be useful, 00015 // but WITHOUT ANY WARRANTY; without even the implied warranty of 00016 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 00017 // Lesser General Public License for more details. 00018 // 00019 // You should have received a copy of the GNU Lesser General Public 00020 // License along with this library; if not, write to the Free Software 00021 // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 00022 // 00023 // You can contact OPeNDAP, Inc. at PO Box 112, Saunderstown, RI. 02874-0112. 00024 00025 #include "config.h" 00026 00027 static char rcsid[] not_used = 00028 {"$Id: ConstraintEvaluator.cc 19914 2008-11-25 17:26:22Z jimg $" 00029 }; 00030 00031 #include "ConstraintEvaluator.h" 00032 00033 #include "ce_functions.h" 00034 #include "parser.h" 00035 #include "ce_parser.h" 00036 #include "debug.h" 00037 00038 struct yy_buffer_state; 00039 yy_buffer_state *ce_expr_scan_string(const char *str); 00040 int ce_exprparse(void *arg); 00041 00042 // Glue routines declared in expr.lex 00043 void ce_expr_switch_to_buffer(void *new_buffer); 00044 void ce_expr_delete_buffer(void * buffer); 00045 void *ce_expr_string(const char *yy_str); 00046 00047 namespace libdap { 00048 00049 ConstraintEvaluator::ConstraintEvaluator() 00050 { 00051 register_functions(*this); 00052 } 00053 00054 ConstraintEvaluator::~ConstraintEvaluator() 00055 { 00056 // delete all the constants created by the parser for CE evaluation 00057 for (Constants_iter j = constants.begin(); j != constants.end(); j++) { 00058 BaseType *btp = *j ; 00059 delete btp ; btp = 0; 00060 } 00061 00062 for (Clause_iter k = expr.begin(); k != expr.end(); k++) { 00063 Clause *cp = *k ; 00064 delete cp ; cp = 0; 00065 } 00066 } 00067 00069 ConstraintEvaluator::Clause_iter 00070 ConstraintEvaluator::clause_begin() 00071 { 00072 return expr.begin() ; 00073 } 00074 00077 ConstraintEvaluator::Clause_iter 00078 ConstraintEvaluator::clause_end() 00079 { 00080 return expr.end() ; 00081 } 00082 00085 bool 00086 ConstraintEvaluator::clause_value(Clause_iter &iter, DDS &dds/*, const string &***/) 00087 { 00088 if (expr.empty()) 00089 throw InternalErr(__FILE__, __LINE__, 00090 "There are no CE clauses for *this* DDS object."); 00091 00092 return (*iter)->value(dds); 00093 } 00094 00107 void 00108 ConstraintEvaluator::append_clause(int op, rvalue *arg1, rvalue_list *arg2) 00109 { 00110 Clause *clause = new Clause(op, arg1, arg2); 00111 00112 expr.push_back(clause); 00113 } 00114 00124 void 00125 ConstraintEvaluator::append_clause(bool_func func, rvalue_list *args) 00126 { 00127 Clause *clause = new Clause(func, args); 00128 00129 expr.push_back(clause); 00130 } 00131 00141 void 00142 ConstraintEvaluator::append_clause(btp_func func, rvalue_list *args) 00143 { 00144 Clause *clause = new Clause(func, args); 00145 00146 expr.push_back(clause); 00147 } 00148 00156 void 00157 ConstraintEvaluator::append_constant(BaseType *btp) 00158 { 00159 constants.push_back(btp); 00160 } 00161 00162 class func_name_is 00163 { 00164 private: 00165 const string d_name; 00166 00167 public: 00168 func_name_is(const string &name): d_name(name) 00169 {} 00170 bool operator()(const ConstraintEvaluator::function f) 00171 { 00172 return f.name == d_name; 00173 } 00174 }; 00175 00195 #if 1 00196 00197 void 00198 ConstraintEvaluator::add_function(const string &name, bool_func f) 00199 { 00200 functions.remove_if(func_name_is(name)); 00201 function func(name, f); 00202 functions.push_back(func); 00203 } 00204 #endif 00205 00206 void 00207 ConstraintEvaluator::add_function(const string &name, btp_func f) 00208 { 00209 functions.remove_if(func_name_is(name)); 00210 function func(name, f); 00211 functions.push_back(func); 00212 } 00213 00215 void 00216 ConstraintEvaluator::add_function(const string &name, proj_func f) 00217 { 00218 functions.remove_if(func_name_is(name)); 00219 function func(name, f); 00220 functions.push_back(func); 00221 } 00222 #if 1 00223 00224 bool 00225 ConstraintEvaluator::find_function(const string &name, bool_func *f) const 00226 { 00227 if (functions.empty()) 00228 return false; 00229 00230 for (Functions_citer i = functions.begin(); i != functions.end(); i++) { 00231 if (name == (*i).name && (*f = (*i).b_func)) { 00232 return true; 00233 } 00234 } 00235 00236 return false; 00237 } 00238 #endif 00239 00240 bool 00241 ConstraintEvaluator::find_function(const string &name, btp_func *f) const 00242 { 00243 if (functions.empty()) 00244 return false; 00245 00246 for (Functions_citer i = functions.begin(); i != functions.end(); i++) { 00247 if (name == (*i).name && (*f = (*i).bt_func)) { 00248 return true; 00249 } 00250 } 00251 00252 return false; 00253 } 00254 00256 bool 00257 ConstraintEvaluator::find_function(const string &name, proj_func *f) const 00258 { 00259 if (functions.empty()) 00260 return false; 00261 00262 for (Functions_citer i = functions.begin(); i != functions.end(); i++) 00263 if (name == (*i).name && (*f = (*i).p_func)) { 00264 return true; 00265 } 00266 00267 return false; 00268 } 00270 00273 bool 00274 ConstraintEvaluator::functional_expression() 00275 { 00276 if (expr.empty()) 00277 return false; 00278 00279 Clause *cp = expr[0] ; 00280 return cp->value_clause(); 00281 } 00282 00284 BaseType * 00285 ConstraintEvaluator::eval_function(DDS &dds, const string &) 00286 { 00287 if (expr.size() != 1) 00288 throw InternalErr(__FILE__, __LINE__, 00289 "The length of the list of CE clauses is not 1."); 00290 00291 Clause *cp = expr[0] ; 00292 BaseType *result; 00293 if (cp->value(dds, &result)) 00294 return result; 00295 else 00296 return NULL; 00297 } 00298 00300 bool 00301 ConstraintEvaluator::boolean_expression() 00302 { 00303 if (expr.empty()) 00304 return false; 00305 00306 bool boolean = true; 00307 for (Clause_iter i = expr.begin(); i != expr.end(); i++) { 00308 boolean = boolean && (*i)->boolean_clause(); 00309 } 00310 00311 return boolean; 00312 } 00313 00314 00322 bool 00323 ConstraintEvaluator::eval_selection(DDS &dds, const string &) 00324 { 00325 if (expr.empty()) { 00326 DBG(cerr << "No selection recorded" << endl); 00327 return true; 00328 } 00329 00330 DBG(cerr << "Eval selection" << endl); 00331 00332 // A CE is made up of zero or more clauses, each of which has a boolean 00333 // value. The value of the CE is the logical AND of the clause 00334 // values. See ConstraintEvaluator::clause::value(...) for information on logical ORs in 00335 // CEs. 00336 bool result = true; 00337 for (Clause_iter i = expr.begin(); i != expr.end() && result; i++) { 00338 // A selection expression *must* contain only boolean clauses! 00339 if (!((*i)->boolean_clause())) 00340 throw InternalErr(__FILE__, __LINE__, 00341 "A selection expression must contain only boolean clauses."); 00342 result = result && (*i)->value(dds); 00343 } 00344 00345 return result; 00346 } 00347 00358 void 00359 ConstraintEvaluator::parse_constraint(const string &constraint, DDS &dds) 00360 { 00361 void *buffer = ce_expr_string(constraint.c_str()); 00362 ce_expr_switch_to_buffer(buffer); 00363 00364 ce_parser_arg arg(this, &dds); 00365 00366 // For all errors, exprparse will throw Error. 00367 ce_exprparse((void *)&arg); 00368 00369 ce_expr_delete_buffer(buffer); 00370 } 00371 00372 } // namespace libdap