libdap  Updated for version 3.17.0
RValue.cc
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., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
00023 //
00024 // You can contact OPeNDAP, Inc. at PO Box 112, Saunderstown, RI. 02874-0112.
00025 
00026 // (c) COPYRIGHT URI/MIT 1996-1999
00027 // Please read the full copyright statement in the file COPYRIGHT_URI.
00028 //
00029 // Authors:
00030 //      jhrg,jimg       James Gallagher <jgallagher@gso.uri.edu>
00031 
00032 // This file contains mfuncs defined for struct rvalue (see expr.h) that
00033 // *cannot* be included in that struct's declaration because their
00034 // definitions must follow *both* rvalue's and func_rvalue's declarations.
00035 // jhrg 3/4/96
00036 
00037 #include "config.h"
00038 
00039 #include <cassert>
00040 #include <iostream>
00041 
00042 #include "BaseType.h"
00043 #include "expr.h"
00044 #include "RValue.h"
00045 #include "DDS.h"
00046 #include "dods-limits.h"
00047 #include "util.h"
00048 
00049 using namespace std;
00050 
00051 namespace libdap {
00052 
00053 rvalue_list *
00054 make_rvalue_list(rvalue *rv)
00055 {
00056     assert(rv);
00057 
00058     rvalue_list *rvals = new rvalue_list;
00059 
00060     return append_rvalue_list(rvals, rv);
00061 }
00062 
00063 // Given a rvalue_list pointer RVALS and a value pointer VAL, make a variable
00064 // to hold VAL and append that variable to the list RVALS.
00065 //
00066 // Returns: A pointer to the updated rvalue_list.
00067 
00068 rvalue_list *
00069 append_rvalue_list(rvalue_list *rvals, rvalue *rv)
00070 {
00071     rvals->push_back(rv);
00072 
00073     return rvals;
00074 }
00075 
00076 
00087 BaseType **
00088 build_btp_args(rvalue_list *args, DDS &dds)
00089 {
00090     int argc = 0;
00091 
00092     if (args)
00093         argc = args->size();
00094 
00095     // Sanitize allocation size
00096     if (!size_ok(sizeof(BaseType*), argc + 1))
00097         throw Error(malformed_expr, string("Malformed argument list (")
00098                 + long_to_string(argc) + string(")."));
00099 
00100     // Add space for a null terminator
00101     BaseType **argv = new BaseType*[argc + 1];
00102 
00103     int index = 0;
00104     if (argv && argc) {
00105         for (rvalue::Args_iter i = args->begin(); i != args->end() && index
00106                 < argc + 1; ++i)
00107             argv[index++] = (*i)->bvalue(dds);
00108 
00109         argv[index] = 0; // Add the null terminator.
00110     }
00111 
00112     if (index != argc) {
00113         delete[] argv;
00114         throw InternalErr(__FILE__, __LINE__, "index out of range.");
00115     }
00116 #if 0
00117     argv[index] = 0; // Add the null terminator.
00118 #endif
00119     return argv;
00120 }
00121 
00122 rvalue::rvalue(BaseType *bt): d_value(bt), d_func(0), d_args(0)
00123 {}
00124 
00125 rvalue::rvalue(btp_func f, vector<rvalue *> *a) : d_value(0), d_func(f), d_args(a)
00126 {}
00127 
00128 rvalue::rvalue(): d_value(0), d_func(0), d_args(0)
00129 {}
00130 
00131 rvalue::~rvalue()
00132 {
00133     // Deleting the BaseType pointers in value and args is a bad idea since
00134     // those might be variables in the dataset. The DDS dtor will take care
00135     // of deleting them. The constants wrapped in BaseType objects should be
00136     // pushed on the list of CE-allocated temp objects which the CE frees.
00137 
00138         // ADB: the d_args vector still needs to be deleted
00139         if (d_args != 0) {
00140                 for (std::vector<rvalue *>::iterator iter = d_args->begin(); iter != d_args->end(); ++iter) {
00141                         delete *iter;
00142                 }
00143                 delete d_args;
00144         }
00145 }
00146 
00147 string
00148 rvalue::value_name()
00149 {
00150     assert(d_value);
00151 
00152     return d_value->name();
00153 }
00154 
00162 BaseType *
00163 rvalue::bvalue(DDS &dds)
00164 {
00165     if (d_value) {        // i.e., if this RValue is a BaseType
00166         return d_value;
00167     }
00168     else if (d_func) {
00169         // If func is true, then args must be set. See the constructor.
00170         // 12/23/04 jhrg
00171         BaseType **argv = build_btp_args(d_args, dds);
00172         BaseType *ret_val;
00173         (*d_func)(d_args->size(), argv, dds, &ret_val);
00174         delete[] argv;
00175         return ret_val;
00176     }
00177     else {
00178         return 0;
00179     }
00180 }
00181 
00182 } // namespace libdap
00183