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), _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