libdap
Updated for version 3.17.0
|
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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA 00022 // 00023 // You can contact OPeNDAP, Inc. at PO Box 112, Saunderstown, RI. 02874-0112. 00024 00025 #include "config.h" 00026 00027 //#define DODS_DEBUG 00028 00029 #include "ServerFunctionsList.h" 00030 #include "ConstraintEvaluator.h" 00031 #include "Clause.h" 00032 #include "DataDDS.h" 00033 00034 #include "ce_parser.h" 00035 #include "debug.h" 00036 #include "parser.h" 00037 #include "expr.h" 00038 00039 struct yy_buffer_state; 00040 00041 int ce_exprparse(libdap::ce_parser_arg *arg); 00042 00043 // Glue routines declared in expr.lex 00044 void ce_expr_switch_to_buffer(void *new_buffer); 00045 void ce_expr_delete_buffer(void * buffer); 00046 void *ce_expr_string(const char *yy_str); 00047 00048 extern int ce_exprdebug; 00049 00050 namespace libdap { 00051 00052 ConstraintEvaluator::ConstraintEvaluator() 00053 { 00054 // Functions are now held in BES modules. jhrg 1/30/13 00055 00056 // modules load functions to this list; this class searches the list 00057 // instead of having it's own copy. This is very similar to the BES' 00058 // various List classes, but this one is part of libdap and not the 00059 // BES. The List class is a singleton, so each function module can 00060 // register it's functions to the list object. 00061 d_functions_list = ServerFunctionsList::TheList(); 00062 } 00063 00064 ConstraintEvaluator::~ConstraintEvaluator() 00065 { 00066 // delete all the constants created by the parser for CE evaluation 00067 for (Constants_iter j = constants.begin(); j != constants.end(); j++) { 00068 BaseType *btp = *j; 00069 delete btp; 00070 btp = 0; 00071 } 00072 00073 for (Clause_iter k = expr.begin(); k != expr.end(); k++) { 00074 Clause *cp = *k; 00075 delete cp; 00076 cp = 0; 00077 } 00078 } 00079 00081 ConstraintEvaluator::Clause_iter ConstraintEvaluator::clause_begin() 00082 { 00083 return expr.begin(); 00084 } 00085 00088 ConstraintEvaluator::Clause_iter ConstraintEvaluator::clause_end() 00089 { 00090 return expr.end(); 00091 } 00092 00095 bool ConstraintEvaluator::clause_value(Clause_iter &iter, DDS &dds/*, const string &***/) 00096 { 00097 if (expr.empty()) 00098 throw InternalErr(__FILE__, __LINE__, "There are no CE clauses for *this* DDS object."); 00099 00100 return (*iter)->value(dds); 00101 } 00102 00115 void ConstraintEvaluator::append_clause(int op, rvalue *arg1, rvalue_list *arg2) 00116 { 00117 Clause *clause = new Clause(op, arg1, arg2); 00118 00119 expr.push_back(clause); 00120 } 00121 00131 void ConstraintEvaluator::append_clause(bool_func func, rvalue_list *args) 00132 { 00133 Clause *clause = new Clause(func, args); 00134 00135 expr.push_back(clause); 00136 } 00137 00147 void ConstraintEvaluator::append_clause(btp_func func, rvalue_list *args) 00148 { 00149 Clause *clause = new Clause(func, args); 00150 00151 expr.push_back(clause); 00152 } 00153 00161 void ConstraintEvaluator::append_constant(BaseType *btp) 00162 { 00163 constants.push_back(btp); 00164 } 00165 00167 bool ConstraintEvaluator::find_function(const string &name, bool_func *f) const 00168 { 00169 return d_functions_list->find_function(name, f); 00170 } 00171 00173 bool ConstraintEvaluator::find_function(const string &name, btp_func *f) const 00174 { 00175 return d_functions_list->find_function(name, f); 00176 } 00177 00179 bool ConstraintEvaluator::find_function(const string &name, proj_func *f) const 00180 { 00181 return d_functions_list->find_function(name, f); 00182 } 00184 00193 bool ConstraintEvaluator::functional_expression() 00194 { 00195 if (expr.empty()) 00196 return false; 00197 00198 Clause *cp = expr[0]; 00199 return cp->value_clause(); 00200 } 00201 00205 BaseType * 00206 ConstraintEvaluator::eval_function(DDS &dds, const string &) 00207 { 00208 if (expr.size() != 1) 00209 throw InternalErr(__FILE__, __LINE__, "The length of the list of CE clauses is not 1."); 00210 00211 Clause *cp = expr[0]; 00212 BaseType *result; 00213 if (cp->value(dds, &result)) 00214 return result; 00215 else 00216 return NULL; 00217 } 00218 00228 bool ConstraintEvaluator::function_clauses() 00229 { 00230 if (expr.empty()) 00231 return false; 00232 00233 for (unsigned int i = 0; i < expr.size(); ++i) { 00234 Clause *cp = expr[i]; 00235 if (!cp->value_clause()) 00236 return false; 00237 } 00238 00239 return true; 00240 } 00241 00257 DDS * 00258 ConstraintEvaluator::eval_function_clauses(DDS &dds) 00259 { 00260 if (expr.empty()) 00261 throw InternalErr(__FILE__, __LINE__, "The constraint expression is empty."); 00262 00263 DDS *fdds = new DDS(dds.get_factory(), "function_result_" + dds.get_dataset_name()); 00264 for (unsigned int i = 0; i < expr.size(); ++i) { 00265 Clause *cp = expr[i]; 00266 BaseType *result; 00267 if (cp->value(dds, &result)) { 00268 // This is correct: The function must allocate the memory for the result 00269 // variable. 11/30/12 jhrg 00270 fdds->add_var_nocopy(result); 00271 } 00272 else { 00273 delete fdds; 00274 throw Error(internal_error, "A function was called but failed to return a value."); 00275 } 00276 } 00277 00278 return fdds; 00279 } 00280 00286 DataDDS * 00287 ConstraintEvaluator::eval_function_clauses(DataDDS &dds) 00288 { 00289 if (expr.empty()) 00290 throw InternalErr(__FILE__, __LINE__, "The constraint expression is empty."); 00291 00292 DataDDS *fdds = new DataDDS(dds.get_factory(), "function_result_" + dds.get_dataset_name(), dds.get_version(), 00293 dds.get_protocol()); 00294 00295 for (unsigned int i = 0; i < expr.size(); ++i) { 00296 Clause *cp = expr[i]; 00297 BaseType *result; 00298 if (cp->value(dds, &result)) { 00299 fdds->add_var_nocopy(result); 00300 } 00301 else { 00302 delete fdds; 00303 throw Error(internal_error, "A function was called but failed to return a value."); 00304 } 00305 } 00306 00307 return fdds; 00308 } 00309 00311 bool ConstraintEvaluator::boolean_expression() 00312 { 00313 if (expr.empty()) 00314 return false; 00315 00316 bool boolean = true; 00317 for (Clause_iter i = expr.begin(); i != expr.end(); i++) { 00318 boolean = boolean && (*i)->boolean_clause(); 00319 } 00320 00321 return boolean; 00322 } 00323 00331 bool ConstraintEvaluator::eval_selection(DDS &dds, const string &) 00332 { 00333 if (expr.empty()) { 00334 DBG(cerr << "No selection recorded" << endl); 00335 return true; 00336 } 00337 00338 DBG(cerr << "Eval selection" << endl); 00339 00340 // A CE is made up of zero or more clauses, each of which has a boolean 00341 // value. The value of the CE is the logical AND of the clause 00342 // values. See ConstraintEvaluator::clause::value(...) for information on logical ORs in 00343 // CEs. 00344 bool result = true; 00345 for (Clause_iter i = expr.begin(); i != expr.end() && result; i++) { 00346 // A selection expression *must* contain only boolean clauses! 00347 if (!((*i)->boolean_clause())) 00348 throw InternalErr(__FILE__, __LINE__, "A selection expression must contain only boolean clauses."); 00349 result = result && (*i)->value(dds); 00350 } 00351 00352 return result; 00353 } 00354 00365 void ConstraintEvaluator::parse_constraint(const string &constraint, DDS &dds) 00366 { 00367 void *buffer = ce_expr_string(constraint.c_str()); 00368 00369 // Toggle this to debug the parser. A last resort... 00370 ce_exprdebug = false; 00371 00372 ce_expr_switch_to_buffer(buffer); 00373 00374 ce_parser_arg arg(this, &dds); 00375 00376 // For all errors, exprparse will throw Error. 00377 try { 00378 ce_exprparse(&arg); 00379 ce_expr_delete_buffer(buffer); 00380 } 00381 catch (...) { 00382 // Make sure to remove the buffer when there's an error 00383 ce_expr_delete_buffer(buffer); 00384 throw; 00385 } 00386 } 00387 00388 } // namespace libdap