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 <cassert>
00038 #include <algorithm>
00039 
00040 #include "expr.h"
00041 #include "DDS.h"
00042 #include "Clause.h"
00043 
00044 using std::cerr;
00045 using std::endl;
00046 
00047 namespace libdap {
00048 
00049 Clause::Clause(const int oper, rvalue *a1, rvalue_list *rv)
00050         : _op(oper), _b_func(0), _bt_func(0), _arg1(a1), _args(rv)
00051 {
00052     assert(OK());
00053 }
00054 
00055 Clause::Clause(bool_func func, rvalue_list *rv)
00056         : _op(0), _b_func(func), _bt_func(0), _arg1(0), _args(rv)
00057 {
00058     assert(OK());
00059 
00060     if (_args)   // account for null arg list
00061         _argc = _args->size();
00062     else
00063         _argc = 0;
00064 }
00065 
00066 Clause::Clause(btp_func func, rvalue_list *rv)
00067         : _op(0), _b_func(0), _bt_func(func), _arg1(0), _args(rv)
00068 {
00069     assert(OK());
00070 
00071     if (_args)
00072         _argc = _args->size();
00073     else
00074         _argc = 0;
00075 }
00076 
00077 Clause::Clause() : _op(0), _b_func(0), _bt_func(0), _arg1(0), _args(0)
00078 {}
00079 
00080 static inline void
00081 delete_rvalue(rvalue *rv)
00082 {
00083     delete rv; rv = 0;
00084 }
00085 
00086 Clause::~Clause()
00087 {
00088     if (_arg1) {
00089         delete _arg1; _arg1 = 0;
00090     }
00091 
00092     if (_args) {
00093         // _args is a pointer to a vector<rvalue*> and we must must delete
00094         // each rvalue pointer here explicitly. 02/03/04 jhrg
00095         for_each(_args->begin(), _args->end(), delete_rvalue);
00096         delete _args; _args = 0;
00097     }
00098 }
00099 
00101 bool
00102 Clause::OK()
00103 {
00104     // Each clause object can contain one of: a relational clause, a boolean
00105     // function clause or a BaseType pointer function clause. It must have a
00106     // valid argument list.
00107     //
00108     // But, a valid arg list might contain zero arguments! 10/16/98 jhrg
00109     bool relational = (_op && !_b_func && !_bt_func);
00110     bool boolean = (!_op && _b_func && !_bt_func);
00111     bool basetype = (!_op && !_b_func && _bt_func);
00112 
00113     if (relational)
00114         return _arg1 && _args;
00115     else if (boolean || basetype)
00116         return true;  // Until we check arguments...10/16/98 jhrg
00117     else
00118         return false;
00119 }
00120 
00122 bool
00123 Clause::boolean_clause()
00124 {
00125     assert(OK());
00126 
00127     return _op || _b_func;
00128 }
00129 
00131 bool
00132 Clause::value_clause()
00133 {
00134     assert(OK());
00135 
00136     return (_bt_func != 0);
00137 }
00138 
00148 bool
00149 Clause::value(const string &dataset, DDS &dds)
00150 {
00151     assert(OK());
00152     assert(_op || _b_func);
00153 
00154     if (_op) {   // Is it a relational clause?
00155         // rvalue::bvalue(...) returns the rvalue encapsulated in a
00156         // BaseType *.
00157         BaseType *btp = _arg1->bvalue(dataset, dds);
00158         // The list of rvalues is an implicit logical OR, so assume
00159         // FALSE and return TRUE for the first TRUE subclause.
00160         bool result = false;
00161         for (rvalue_list_iter i = _args->begin();
00162              i != _args->end() && !result;
00163              i++) {
00164             result = result || btp->ops((*i)->bvalue(dataset, dds),
00165                                         _op, dataset);
00166         }
00167 
00168         return result;
00169     }
00170     else if (_b_func) {  // ...A bool function?
00171         BaseType **argv = build_btp_args(_args, dds, dataset);
00172 
00173         bool result = (*_b_func)(_argc, argv, dds);
00174         delete[] argv;  // Cache me!
00175         argv = 0;
00176 
00177         return result;
00178     }
00179     else {
00180         throw InternalErr(__FILE__, __LINE__,
00181                           "A selection expression must contain only boolean clauses.");
00182     }
00183 }
00184 
00197 bool
00198 Clause::value(const string &dataset, DDS &dds, BaseType **value)
00199 {
00200     assert(OK());
00201     assert(_bt_func);
00202 
00203     if (_bt_func) {
00204         // build_btp_args() is a function defined in RValue.cc. It no longer
00205         // reads the values as it builds the arguments, that is now left up
00206         // to the functions themselves. 9/25/06 jhrg
00207         BaseType **argv = build_btp_args(_args, dds, dataset);
00208 
00209         *value = (*_bt_func)(_argc, argv, dds, dataset);
00210         delete[] argv;  // Cache me!
00211         argv = 0;
00212 
00213         if (*value) {
00214             (*value)->set_send_p(true);
00215             (*value)->set_read_p(true);
00216             return true;
00217         }
00218         else {
00219             return false;
00220         }
00221     }
00222     else {
00223         throw InternalErr(__FILE__, __LINE__,
00224                           "Claue::value() was called in a context expecting a BaseType pointer return, but the Clause was boolean-valued instead.");
00225     }
00226 }
00227 
00228 } // namespace libdap

Generated on Tue Jun 10 18:00:29 2008 for libdap++ by  doxygen 1.5.4