Clause.cc

Go to the documentation of this file.
00001 
00002 // -*- mode: c++; c-basic-offset:4 -*-
00003 
00004 // This file is part of libdap, A C++ implementation of the OPeNDAP Data
00005 // Access Protocol.
00006 
00007 // Copyright (c) 2002,2003 OPeNDAP, Inc.
00008 // Author: James Gallagher <jgallagher@opendap.org>
00009 //
00010 // This library is free software; you can redistribute it and/or
00011 // modify it under the terms of the GNU Lesser General Public
00012 // License as published by the Free Software Foundation; either
00013 // version 2.1 of the License, or (at your option) any later version.
00014 //
00015 // This library is distributed in the hope that it will be useful,
00016 // but WITHOUT ANY WARRANTY; without even the implied warranty of
00017 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
00018 // Lesser General Public License for more details.
00019 //
00020 // You should have received a copy of the GNU Lesser General Public
00021 // License along with this library; if not, write to the Free Software
00022 // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
00023 //
00024 // You can contact OPeNDAP, Inc. at PO Box 112, Saunderstown, RI. 02874-0112.
00025 
00026 // (c) COPYRIGHT URI/MIT 1996,1998,1999
00027 // Please first read the full copyright statement in the file COPYRIGHT_URI.
00028 //
00029 // Authors:
00030 // jhrg,jimg James Gallagher <jgallagher@gso.uri.edu>
00031 
00032 // Implementation for the CE Clause class.
00033 
00034 
00035 #include "config.h"
00036 
00037 #include <assert.h>
00038 
00039 #include <algorithm>
00040 
00041 #include "expr.h"
00042 #include "DDS.h"
00043 #include "Clause.h"
00044 
00045 using std::cerr;
00046 using std::endl;
00047 
00048 Clause::Clause(const int oper, rvalue *a1, rvalue_list *rv)
00049         : _op(oper), _b_func(0), _bt_func(0), _arg1(a1), _args(rv)
00050 {
00051     assert(OK());
00052 }
00053 
00054 Clause::Clause(bool_func func, rvalue_list *rv)
00055         : _op(0), _b_func(func), _bt_func(0), _arg1(0), _args(rv)
00056 {
00057     assert(OK());
00058 
00059     if (_args)   // account for null arg list
00060         _argc = _args->size();
00061     else
00062         _argc = 0;
00063 }
00064 
00065 Clause::Clause(btp_func func, rvalue_list *rv)
00066         : _op(0), _b_func(0), _bt_func(func), _arg1(0), _args(rv)
00067 {
00068     assert(OK());
00069 
00070     if (_args)
00071         _argc = _args->size();
00072     else
00073         _argc = 0;
00074 }
00075 
00076 Clause::Clause() : _op(0), _b_func(0), _bt_func(0), _arg1(0), _args(0)
00077 {}
00078 
00079 static inline void
00080 delete_rvalue(rvalue *rv)
00081 {
00082     delete rv; rv = 0;
00083 }
00084 
00085 Clause::~Clause()
00086 {
00087     if (_arg1) {
00088         delete _arg1; _arg1 = 0;
00089     }
00090 
00091     if (_args) {
00092         // _args is a pointer to a vector<rvalue*> and we must must delete
00093         // each rvalue pointer here explicitly. 02/03/04 jhrg
00094         for_each(_args->begin(), _args->end(), delete_rvalue);
00095         delete _args; _args = 0;
00096     }
00097 }
00098 
00100 bool
00101 Clause::OK()
00102 {
00103     // Each clause object can contain one of: a relational clause, a boolean
00104     // function clause or a BaseType pointer function clause. It must have a
00105     // valid argument list.
00106     //
00107     // But, a valid arg list might contain zero arguments! 10/16/98 jhrg
00108     bool relational = (_op && !_b_func && !_bt_func);
00109     bool boolean = (!_op && _b_func && !_bt_func);
00110     bool basetype = (!_op && !_b_func && _bt_func);
00111 
00112     if (relational)
00113         return _arg1 && _args;
00114     else if (boolean || basetype)
00115         return true;  // Until we check arguments...10/16/98 jhrg
00116     else
00117         return false;
00118 }
00119 
00121 bool
00122 Clause::boolean_clause()
00123 {
00124     assert(OK());
00125 
00126     return _op || _b_func;
00127 }
00128 
00130 bool
00131 Clause::value_clause()
00132 {
00133     assert(OK());
00134 
00135     return (_bt_func != 0);
00136 }
00137 
00147 bool
00148 Clause::value(const string &dataset, DDS &dds)
00149 {
00150     assert(OK());
00151     assert(_op || _b_func);
00152 
00153     if (_op) {   // Is it a relational clause?
00154         // rvalue::bvalue(...) returns the rvalue encapsulated in a
00155         // BaseType *.
00156         BaseType *btp = _arg1->bvalue(dataset, dds);
00157         // The list of rvalues is an implicit logical OR, so assume
00158         // FALSE and return TRUE for the first TRUE subclause.
00159         bool result = false;
00160         for (rvalue_list_iter i = _args->begin();
00161              i != _args->end() && !result;
00162              i++) {
00163             result = result || btp->ops((*i)->bvalue(dataset, dds),
00164                                         _op, dataset);
00165         }
00166 
00167         return result;
00168     }
00169     else if (_b_func) {  // ...A bool function?
00170         BaseType **argv = build_btp_args(_args, dds, dataset);
00171 
00172         bool result = (*_b_func)(_argc, argv, dds);
00173         delete[] argv;  // Cache me!
00174         argv = 0;
00175 
00176         return result;
00177     }
00178     else {
00179         throw InternalErr(__FILE__, __LINE__,
00180                           "A selection expression must contain only boolean clauses.");
00181     }
00182 }
00183 
00196 bool
00197 Clause::value(const string &dataset, DDS &dds, BaseType **value)
00198 {
00199     assert(OK());
00200     assert(_bt_func);
00201 
00202     if (_bt_func) {
00203         // build_btp_args() is a function defined in RValue.cc. It no longer
00204         // reads the values as it builds the arguments, that is now left up
00205         // to the functions themselves. 9/25/06 jhrg
00206         BaseType **argv = build_btp_args(_args, dds, dataset);
00207 
00208         *value = (*_bt_func)(_argc, argv, dds, dataset);
00209         delete[] argv;  // Cache me!
00210         argv = 0;
00211 
00212         if (*value) {
00213             (*value)->set_send_p(true);
00214             (*value)->set_read_p(true);
00215             return true;
00216         }
00217         else {
00218             return false;
00219         }
00220     }
00221     else {
00222         throw InternalErr(__FILE__, __LINE__,
00223                           "Claue::value() was called in a context expecting a BaseType pointer return, but the Clause was boolean-valued instead.");
00224     }
00225 }

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