libdap++  Updated for version 3.8.2
RValue.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-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 static char rcsid[] not_used =
00040     {"$Id: RValue.cc 24281 2011-03-09 00:22:31Z jimg $"
00041     };
00042 
00043 #include <cassert>
00044 #include <iostream>
00045 
00046 #include "BaseType.h"
00047 #include "expr.h"
00048 #include "RValue.h"
00049 #include "DDS.h"
00050 #include "dods-limits.h"
00051 #include "util.h"
00052 
00053 using namespace std;
00054 
00055 namespace libdap {
00056 
00057 rvalue_list *
00058 make_rvalue_list(rvalue *rv)
00059 {
00060     assert(rv);
00061 
00062     rvalue_list *rvals = new rvalue_list;
00063 
00064     return append_rvalue_list(rvals, rv);
00065 }
00066 
00067 // Given a rvalue_list pointer RVALS and a value pointer VAL, make a variable
00068 // to hold VAL and append that variable to the list RVALS.
00069 //
00070 // Returns: A pointer to the updated rvalue_list.
00071 
00072 rvalue_list *
00073 append_rvalue_list(rvalue_list *rvals, rvalue *rv)
00074 {
00075     rvals->push_back(rv);
00076 
00077     return rvals;
00078 }
00079 
00080 
00091 BaseType **
00092 build_btp_args(rvalue_list *args, DDS &dds)
00093 {
00094     int argc = 0;
00095 
00096     if (args)
00097         argc = args->size();
00098 
00099     // Sanitize allocation size
00100     if (!size_ok(sizeof(BaseType*), argc + 1))
00101         throw Error(malformed_expr, string("Malformed argument list (")
00102                 + long_to_string(argc) + string(")."));
00103 
00104     // Add space for a null terminator
00105     BaseType **argv = new BaseType*[argc + 1];
00106 
00107     int index = 0;
00108     if (argv && argc) {
00109         for (rvalue::Args_iter i = args->begin(); i != args->end() && index
00110                 < argc + 1; ++i)
00111             argv[index++] = (*i)->bvalue(dds);
00112     }
00113 
00114     if (index != argc) {
00115         delete[] argv;
00116         throw InternalErr(__FILE__, __LINE__, "index out of range.");
00117     }
00118 
00119     argv[index] = 0; // Add the null terminator.
00120 
00121     return argv;
00122 }
00123 
00124 rvalue::rvalue(BaseType *bt): d_value(bt), d_func(0), d_args(0)
00125 {}
00126 
00127 rvalue::rvalue(btp_func f, vector<rvalue *> *a) : d_value(0), d_func(f), d_args(a)
00128 {}
00129 
00130 rvalue::rvalue(): d_value(0), d_func(0), d_args(0)
00131 {}
00132 
00133 rvalue::~rvalue()
00134 {
00135     // Deleting the BaseType pointers in value and args is a bad idea since
00136     // those might be variables in the dataset. The DDS dtor will take care
00137     // of deleting them. The constants wrapped in BaseType objects should be
00138     // pushed on the list of CE-allocated temp objects which the CE frees.
00139 }
00140 
00141 string
00142 rvalue::value_name()
00143 {
00144     assert(d_value);
00145 
00146     return d_value->name();
00147 }
00148 
00156 BaseType *
00157 rvalue::bvalue(DDS &dds)
00158 {
00159     if (d_value) {        // i.e., if this RValue is a BaseType
00160         return d_value;
00161     }
00162     else if (d_func) {
00163         // If func is true, then args must be set. See the constructor.
00164         // 12/23/04 jhrg
00165         BaseType **argv = build_btp_args(d_args, dds);
00166         BaseType *ret_val;
00167         (*d_func)(d_args->size(), argv, dds, &ret_val);
00168         delete[] argv;
00169         return ret_val;
00170     }
00171     else {
00172         return 0;
00173     }
00174 }
00175 
00176 } // namespace libdap
00177