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