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

Generated on Wed Nov 28 16:23:15 2007 for libdap++ by  doxygen 1.4.7