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), _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), _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), _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), _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 
00155 bool
00156 Clause::value(DDS &dds)
00157 {
00158     assert(OK());
00159     assert(_op || _b_func);
00160 
00161     if (_op) {   // Is it a relational clause?
00162         // rvalue::bvalue(...) returns the rvalue encapsulated in a
00163         // BaseType *.
00164         BaseType *btp = _arg1->bvalue(dds);
00165         // The list of rvalues is an implicit logical OR, so assume
00166         // FALSE and return TRUE for the first TRUE subclause.
00167         bool result = false;
00168         for (rvalue_list_iter i = _args->begin();
00169              i != _args->end() && !result;
00170              i++) {
00171             result = result || btp->ops((*i)->bvalue(dds), _op);
00172         }
00173 
00174         return result;
00175     }
00176     else if (_b_func) {  // ...A bool function?
00177         BaseType **argv = build_btp_args(_args, dds);
00178 
00179         bool result = false;
00180         (*_b_func)(_argc, argv, dds, &result);
00181         delete[] argv;  // Cache me!
00182         argv = 0;
00183 
00184         return result;
00185     }
00186     else {
00187         throw InternalErr(__FILE__, __LINE__,
00188                           "A selection expression must contain only boolean clauses.");
00189     }
00190 }
00191 
00203 bool
00204 Clause::value(DDS &dds, BaseType **value)
00205 {
00206     assert(OK());
00207     assert(_bt_func);
00208 
00209     if (_bt_func) {
00210         // build_btp_args() is a function defined in RValue.cc. It no longer
00211         // reads the values as it builds the arguments, that is now left up
00212         // to the functions themselves. 9/25/06 jhrg
00213         BaseType **argv = build_btp_args(_args, dds);
00214 
00215         (*_bt_func)(_argc, argv, dds, value);
00216 
00217         delete[] argv;  // Cache me!
00218         argv = 0;
00219 
00220         if (*value) {
00221             (*value)->set_send_p(true);
00222             (*value)->set_read_p(true);
00223             return true;
00224         }
00225         else {
00226             return false;
00227         }
00228     }
00229     else {
00230         throw InternalErr(__FILE__, __LINE__,
00231                           "Clause::value() was called in a context expecting a BaseType pointer return, but the Clause was boolean-valued instead.");
00232     }
00233 }
00234 
00235 } // namespace libdap