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 23555 2010-09-14 16:43:59Z 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 00196 void 00197 ConstraintEvaluator::add_function(const string &name, bool_func f) 00198 { 00199 functions.remove_if(func_name_is(name)); 00200 function func(name, f); 00201 functions.push_back(func); 00202 } 00203 00205 void 00206 ConstraintEvaluator::add_function(const string &name, btp_func f) 00207 { 00208 functions.remove_if(func_name_is(name)); 00209 function func(name, f); 00210 functions.push_back(func); 00211 } 00212 00214 void 00215 ConstraintEvaluator::add_function(const string &name, proj_func f) 00216 { 00217 functions.remove_if(func_name_is(name)); 00218 function func(name, f); 00219 functions.push_back(func); 00220 } 00221 00223 bool 00224 ConstraintEvaluator::find_function(const string &name, bool_func *f) const 00225 { 00226 if (functions.empty()) 00227 return false; 00228 00229 for (Functions_citer i = functions.begin(); i != functions.end(); i++) { 00230 if (name == (*i).name && (*f = (*i).b_func)) { 00231 return true; 00232 } 00233 } 00234 00235 return false; 00236 } 00237 00239 bool 00240 ConstraintEvaluator::find_function(const string &name, btp_func *f) const 00241 { 00242 if (functions.empty()) 00243 return false; 00244 00245 for (Functions_citer i = functions.begin(); i != functions.end(); i++) { 00246 if (name == (*i).name && (*f = (*i).bt_func)) { 00247 return true; 00248 } 00249 } 00250 00251 return false; 00252 } 00253 00255 bool 00256 ConstraintEvaluator::find_function(const string &name, proj_func *f) const 00257 { 00258 if (functions.empty()) 00259 return false; 00260 00261 for (Functions_citer i = functions.begin(); i != functions.end(); i++) 00262 if (name == (*i).name && (*f = (*i).p_func)) { 00263 return true; 00264 } 00265 00266 return false; 00267 } 00269 00276 bool 00277 ConstraintEvaluator::functional_expression() 00278 { 00279 if (expr.empty()) 00280 return false; 00281 00282 Clause *cp = expr[0] ; 00283 return cp->value_clause(); 00284 } 00285 00287 BaseType * 00288 ConstraintEvaluator::eval_function(DDS &dds, const string &) 00289 { 00290 if (expr.size() != 1) 00291 throw InternalErr(__FILE__, __LINE__, 00292 "The length of the list of CE clauses is not 1."); 00293 00294 Clause *cp = expr[0] ; 00295 BaseType *result; 00296 if (cp->value(dds, &result)) 00297 return result; 00298 else 00299 return NULL; 00300 } 00301 00311 bool ConstraintEvaluator::function_clauses() 00312 { 00313 if (expr.empty()) 00314 return false; 00315 00316 for (unsigned int i = 0; i < expr.size(); ++i) { 00317 Clause *cp = expr[i]; 00318 if (!cp->value_clause()) 00319 return false; 00320 } 00321 00322 return true; 00323 } 00324 00340 DDS * 00341 ConstraintEvaluator::eval_function_clauses(DDS &dds) 00342 { 00343 if (expr.empty()) 00344 throw InternalErr(__FILE__, __LINE__, "The constraint expression is empty."); 00345 00346 DDS *fdds = new DDS(dds.get_factory(), "function_result_" + dds.get_dataset_name()); 00347 for (unsigned int i = 0; i < expr.size(); ++i) { 00348 Clause *cp = expr[i]; 00349 BaseType *result; 00350 if (cp->value(dds, &result)) { 00351 result->set_send_p(true); 00352 fdds->add_var(result); 00353 } 00354 else 00355 throw Error("A function was called but failed to return a value."); 00356 } 00357 00358 return fdds; 00359 } 00360 00366 DataDDS * 00367 ConstraintEvaluator::eval_function_clauses(DataDDS &dds) 00368 { 00369 if (expr.empty()) 00370 throw InternalErr(__FILE__, __LINE__, "The constraint expression is empty."); 00371 00372 DataDDS *fdds = new DataDDS(dds.get_factory(), 00373 "function_result_" + dds.get_dataset_name(), 00374 dds.get_version(), dds.get_protocol()); 00375 00376 for (unsigned int i = 0; i < expr.size(); ++i) { 00377 Clause *cp = expr[i]; 00378 BaseType *result; 00379 if (cp->value(dds, &result)) { 00380 result->set_send_p(true); 00381 fdds->add_var(result); 00382 } 00383 else 00384 throw Error("A function was called but failed to return a value."); 00385 } 00386 00387 return fdds; 00388 } 00389 00391 bool 00392 ConstraintEvaluator::boolean_expression() 00393 { 00394 if (expr.empty()) 00395 return false; 00396 00397 bool boolean = true; 00398 for (Clause_iter i = expr.begin(); i != expr.end(); i++) { 00399 boolean = boolean && (*i)->boolean_clause(); 00400 } 00401 00402 return boolean; 00403 } 00404 00405 00413 bool 00414 ConstraintEvaluator::eval_selection(DDS &dds, const string &) 00415 { 00416 if (expr.empty()) { 00417 DBG(cerr << "No selection recorded" << endl); 00418 return true; 00419 } 00420 00421 DBG(cerr << "Eval selection" << endl); 00422 00423 // A CE is made up of zero or more clauses, each of which has a boolean 00424 // value. The value of the CE is the logical AND of the clause 00425 // values. See ConstraintEvaluator::clause::value(...) for information on logical ORs in 00426 // CEs. 00427 bool result = true; 00428 for (Clause_iter i = expr.begin(); i != expr.end() && result; i++) { 00429 // A selection expression *must* contain only boolean clauses! 00430 if (!((*i)->boolean_clause())) 00431 throw InternalErr(__FILE__, __LINE__, 00432 "A selection expression must contain only boolean clauses."); 00433 result = result && (*i)->value(dds); 00434 } 00435 00436 return result; 00437 } 00438 00449 void 00450 ConstraintEvaluator::parse_constraint(const string &constraint, DDS &dds) 00451 { 00452 void *buffer = ce_expr_string(constraint.c_str()); 00453 ce_expr_switch_to_buffer(buffer); 00454 00455 ce_parser_arg arg(this, &dds); 00456 00457 // For all errors, exprparse will throw Error. 00458 ce_exprparse((void *)&arg); 00459 00460 ce_expr_delete_buffer(buffer); 00461 } 00462 00463 } // namespace libdap