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 
00146 #if 0
00147 static bool
00148 boolean_value(BaseType *btp)
00149 {
00150     switch (btp->type()) {
00151         case dods_byte_c:
00152             return !dynamic_cast<Byte&>(*btp).value();
00153         case dods_int16_c:
00154             return !dynamic_cast<Int16&>(*btp).value();
00155         case dods_uint16_c:
00156             return !dynamic_cast<UInt16&>(*btp).value();
00157         case dods_int32_c:
00158             return !dynamic_cast<Int32&>(*btp).value();
00159         case dods_uint32_c:
00160             return !dynamic_cast<UInt32&>(*btp).value();
00161         case dods_float32_c:
00162         case dods_float64_c:
00163         case dods_str_c:
00164         case dods_url_c:
00165         case dods_array_c:
00166         case dods_structure_c:
00167         case dods_sequence_c:
00168         case dods_grid_c:
00169         default:
00170             throw Error(malformed_expr, "A Function returning something other than an integer was used in a boolean context.");
00171     }
00172 }
00173 #endif
00174 
00184 bool
00185 Clause::value(DDS &dds)
00186 {
00187     assert(OK());
00188     assert(_op || _b_func);
00189 
00190     if (_op) {   // Is it a relational clause?
00191         // rvalue::bvalue(...) returns the rvalue encapsulated in a
00192         // BaseType *.
00193         BaseType *btp = _arg1->bvalue(dds);
00194         // The list of rvalues is an implicit logical OR, so assume
00195         // FALSE and return TRUE for the first TRUE subclause.
00196         bool result = false;
00197         for (rvalue_list_iter i = _args->begin();
00198              i != _args->end() && !result;
00199              i++) {
00200             result = result || btp->ops((*i)->bvalue(dds), _op);
00201         }
00202 
00203         return result;
00204     }
00205     else if (_b_func) {  // ...A bool function?
00206         BaseType **argv = build_btp_args(_args, dds);
00207 
00208         bool result = false;
00209         (*_b_func)(_argc, argv, dds, &result);
00210         delete[] argv;  // Cache me!
00211         argv = 0;
00212 
00213         return result;
00214     }
00215     else {
00216         throw InternalErr(__FILE__, __LINE__,
00217                           "A selection expression must contain only boolean clauses.");
00218     }
00219 }
00220 
00233 bool
00234 Clause::value(DDS &dds, BaseType **value)
00235 {
00236     assert(OK());
00237     assert(_bt_func);
00238 
00239     if (_bt_func) {
00240         // build_btp_args() is a function defined in RValue.cc. It no longer
00241         // reads the values as it builds the arguments, that is now left up
00242         // to the functions themselves. 9/25/06 jhrg
00243         BaseType **argv = build_btp_args(_args, dds);
00244 
00245 #if 0
00246         *value = (*_bt_func)(_argc, argv, dds);
00247 #endif
00248         (*_bt_func)(_argc, argv, dds, value);
00249         delete[] argv;  // Cache me!
00250         argv = 0;
00251 
00252         if (*value) {
00253             (*value)->set_send_p(true);
00254             (*value)->set_read_p(true);
00255             return true;
00256         }
00257         else {
00258             return false;
00259         }
00260     }
00261     else {
00262         throw InternalErr(__FILE__, __LINE__,
00263                           "Claue::value() was called in a context expecting a BaseType pointer return, but the Clause was boolean-valued instead.");
00264     }
00265 }
00266 
00267 } // namespace libdap

Generated on Wed Apr 15 19:20:23 2009 for libdap++ by  doxygen 1.4.7