ConstraintEvaluator.cc

Go to the documentation of this file.
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 16612 2007-06-04 22:08:57Z 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 using namespace libdap;
00039 
00040 struct yy_buffer_state;
00041 yy_buffer_state *ce_expr_scan_string(const char *str);
00042 int ce_exprparse(void *arg);
00043 
00044 // Glue routines declared in expr.lex
00045 void ce_expr_switch_to_buffer(void *new_buffer);
00046 void ce_expr_delete_buffer(void * buffer);
00047 void *ce_expr_string(const char *yy_str);
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,
00087                                   const string &dataset)
00088 {
00089     if (expr.empty())
00090         throw InternalErr(__FILE__, __LINE__,
00091                           "There are no CE clauses for *this* DDS object.");
00092 
00093     return (*iter)->value(dataset, dds);
00094 }
00095 
00108 void
00109 ConstraintEvaluator::append_clause(int op, rvalue *arg1, rvalue_list *arg2)
00110 {
00111     Clause *clause = new Clause(op, arg1, arg2);
00112 
00113     expr.push_back(clause);
00114 }
00115 
00125 void
00126 ConstraintEvaluator::append_clause(bool_func func, rvalue_list *args)
00127 {
00128     Clause *clause = new Clause(func, args);
00129 
00130     expr.push_back(clause);
00131 }
00132 
00142 void
00143 ConstraintEvaluator::append_clause(btp_func func, rvalue_list *args)
00144 {
00145     Clause *clause = new Clause(func, args);
00146 
00147     expr.push_back(clause);
00148 }
00149 
00157 void
00158 ConstraintEvaluator::append_constant(BaseType *btp)
00159 {
00160     constants.push_back(btp);
00161 }
00162 
00163 class func_name_is
00164 {
00165 private:
00166     const string d_name;
00167 
00168 public:
00169     func_name_is(const string &name): d_name(name)
00170     {}
00171     bool operator()(const ConstraintEvaluator::function f)
00172     {
00173         return f.name == d_name;
00174     }
00175 };
00176 
00196 
00198 void
00199 ConstraintEvaluator::add_function(const string &name, bool_func f)
00200 {
00201     functions.remove_if(func_name_is(name));
00202     function func(name, f);
00203     functions.push_back(func);
00204 }
00205 
00207 void
00208 ConstraintEvaluator::add_function(const string &name, btp_func f)
00209 {
00210     functions.remove_if(func_name_is(name));
00211     function func(name, f);
00212     functions.push_back(func);
00213 }
00214 
00216 void
00217 ConstraintEvaluator::add_function(const string &name, proj_func f)
00218 {
00219     functions.remove_if(func_name_is(name));
00220     function func(name, f);
00221     functions.push_back(func);
00222 }
00223 
00225 bool
00226 ConstraintEvaluator::find_function(const string &name, bool_func *f) const
00227 {
00228     if (functions.empty())
00229         return false;
00230 
00231     for (Functions_citer i = functions.begin(); i != functions.end(); i++) {
00232         if (name == (*i).name && (*f = (*i).b_func)) {
00233             return true;
00234         }
00235     }
00236 
00237     return false;
00238 }
00239 
00241 bool
00242 ConstraintEvaluator::find_function(const string &name, btp_func *f) const
00243 {
00244     if (functions.empty())
00245         return false;
00246 
00247     for (Functions_citer i = functions.begin(); i != functions.end(); i++) {
00248         if (name == (*i).name && (*f = (*i).bt_func)) {
00249             return true;
00250         }
00251     }
00252 
00253     return false;
00254 }
00255 
00257 bool
00258 ConstraintEvaluator::find_function(const string &name, proj_func *f) const
00259 {
00260     if (functions.empty())
00261         return false;
00262 
00263     for (Functions_citer i = functions.begin(); i != functions.end(); i++)
00264         if (name == (*i).name && (*f = (*i).p_func)) {
00265             return true;
00266         }
00267 
00268     return false;
00269 }
00271 
00274 bool
00275 ConstraintEvaluator::functional_expression()
00276 {
00277     if (expr.empty())
00278         return false;
00279 
00280     Clause *cp = expr[0] ;
00281     return cp->value_clause();
00282 }
00283 
00285 BaseType *
00286 ConstraintEvaluator::eval_function(DDS &dds, const string &dataset)
00287 {
00288     if (expr.size() != 1)
00289         throw InternalErr(__FILE__, __LINE__,
00290                           "The length of the list of CE clauses is not 1.");
00291 
00292     Clause *cp = expr[0] ;
00293     BaseType *result;
00294     if (cp->value(dataset, dds, &result))
00295         return result;
00296     else
00297         return NULL;
00298 }
00299 
00301 bool
00302 ConstraintEvaluator::boolean_expression()
00303 {
00304     if (expr.empty())
00305         return false;
00306 
00307     bool boolean = true;
00308     for (Clause_iter i = expr.begin(); i != expr.end(); i++) {
00309         boolean = boolean && (*i)->boolean_clause();
00310     }
00311 
00312     return boolean;
00313 }
00314 
00315 
00323 bool
00324 ConstraintEvaluator::eval_selection(DDS &dds, const string &dataset)
00325 {
00326     if (expr.empty()) {
00327         DBG(cerr << "No selection recorded" << endl);
00328         return true;
00329     }
00330 
00331     DBG(cerr << "Eval selection" << endl);
00332 
00333     // A CE is made up of zero or more clauses, each of which has a boolean
00334     // value. The value of the CE is the logical AND of the clause
00335     // values. See ConstraintEvaluator::clause::value(...) for information on logical ORs in
00336     // CEs.
00337     bool result = true;
00338     for (Clause_iter i = expr.begin(); i != expr.end() && result; i++) {
00339         // A selection expression *must* contain only boolean clauses!
00340         if (!((*i)->boolean_clause()))
00341             throw InternalErr(__FILE__, __LINE__,
00342                               "A selection expression must contain only boolean clauses.");
00343         result = result && (*i)->value(dataset, dds);
00344     }
00345 
00346     return result;
00347 }
00348 
00359 void
00360 ConstraintEvaluator::parse_constraint(const string &constraint, DDS &dds)
00361 {
00362     void *buffer = ce_expr_string(constraint.c_str());
00363     ce_expr_switch_to_buffer(buffer);
00364 
00365     ce_parser_arg arg(this, &dds);
00366 
00367     // For all errors, exprparse will throw Error.
00368     ce_exprparse((void *)&arg);
00369 
00370     ce_expr_delete_buffer(buffer);
00371 }

Generated on Wed Jun 27 12:56:38 2007 for libdap++ by  doxygen 1.4.7