libdap++ Updated for version 3.8.2
|
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