libdap Updated for version 3.20.11
libdap4 is an implementation of OPeNDAP's DAP protocol.
RValue.cc
1
2// -*- mode: c++; c-basic-offset:4 -*-
3
4// This file is part of libdap, A C++ implementation of the OPeNDAP Data
5// Access Protocol.
6
7// Copyright (c) 2002,2003 OPeNDAP, Inc.
8// Author: James Gallagher <jgallagher@opendap.org>
9//
10// This library is free software; you can redistribute it and/or
11// modify it under the terms of the GNU Lesser General Public
12// License as published by the Free Software Foundation; either
13// version 2.1 of the License, or (at your option) any later version.
14//
15// This library is distributed in the hope that it will be useful,
16// but WITHOUT ANY WARRANTY; without even the implied warranty of
17// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
18// Lesser General Public License for more details.
19//
20// You should have received a copy of the GNU Lesser General Public
21// License along with this library; if not, write to the Free Software
22// Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
23//
24// You can contact OPeNDAP, Inc. at PO Box 112, Saunderstown, RI. 02874-0112.
25
26// (c) COPYRIGHT URI/MIT 1996-1999
27// Please read the full copyright statement in the file COPYRIGHT_URI.
28//
29// Authors:
30// jhrg,jimg James Gallagher <jgallagher@gso.uri.edu>
31
32// This file contains mfuncs defined for struct rvalue (see expr.h) that
33// *cannot* be included in that struct's declaration because their
34// definitions must follow *both* rvalue's and func_rvalue's declarations.
35// jhrg 3/4/96
36
37#include "config.h"
38
39#include <cassert>
40#include <iostream>
41
42#include "BaseType.h"
43#include "expr.h"
44#include "RValue.h"
45#include "DDS.h"
46#include "dods-limits.h"
47#include "util.h"
48
49using namespace std;
50
51namespace libdap {
52
53rvalue_list *
54make_rvalue_list(rvalue *rv)
55{
56 assert(rv);
57
58 rvalue_list *rvals = new rvalue_list;
59
60 return append_rvalue_list(rvals, rv);
61}
62
63// Given a rvalue_list pointer RVALS and a value pointer VAL, make a variable
64// to hold VAL and append that variable to the list RVALS.
65//
66// Returns: A pointer to the updated rvalue_list.
67
68rvalue_list *
69append_rvalue_list(rvalue_list *rvals, rvalue *rv)
70{
71 rvals->push_back(rv);
72
73 return rvals;
74}
75
76
87BaseType **
88build_btp_args(const rvalue_list *args, DDS &dds)
89{
90 int argc = 0;
91
92 if (args)
93 argc = args->size();
94
95 // Sanitize allocation size
96 if (!size_ok(sizeof(BaseType*), argc + 1))
97 throw Error(malformed_expr, string("Malformed argument list (")
98 + long_to_string(argc) + string(")."));
99
100 // Add space for a null terminator
101 BaseType **argv = new BaseType*[argc + 1];
102 argv[argc] = nullptr;
103
104 if (argc) {
105 int i = 0;
106 for (auto btp: *args) {
107 argv[i++] = btp->bvalue(dds);
108 }
109
110 assert(i == argc);
111 }
112
113 return argv;
114}
115
116#if 0
117 int index = 0;
118 if (argv && argc) {
119 for (rvalue::Args_iter i = args->begin(); i != args->end() && index < argc + 1; ++i)
120 argv[index++] = (*i)->bvalue(dds);
121
122 argv[index] = 0; // Add the null terminator.
123 }
124
125 if (index != argc) {
126 delete[] argv;
127 throw InternalErr(__FILE__, __LINE__, "index out of range.");
128 }
129
130 return argv;
131#endif
132
133rvalue::rvalue(BaseType *bt): d_value(bt), d_func(0), d_args(0)
134{}
135
136rvalue::rvalue(btp_func f, vector<rvalue *> *a) : d_value(0), d_func(f), d_args(a)
137{}
138
139rvalue::rvalue(): d_value(0), d_func(0), d_args(0)
140{}
141
142rvalue::~rvalue()
143{
144 // Deleting the BaseType pointers in value and args is a bad idea since
145 // those might be variables in the dataset. The DDS dtor will take care
146 // of deleting them. The constants wrapped in BaseType objects should be
147 // pushed on the list of CE-allocated temp objects which the CE frees.
148
149 // ADB: the d_args vector still needs to be deleted
150 if (d_args != 0) {
151 for (std::vector<rvalue *>::iterator iter = d_args->begin(); iter != d_args->end(); ++iter) {
152 delete *iter;
153 }
154 delete d_args;
155 }
156}
157
158string
159rvalue::value_name()
160{
161 assert(d_value);
162
163 return d_value->name();
164}
165
173BaseType *
174rvalue::bvalue(DDS &dds)
175{
176 if (d_value) { // i.e., if this RValue is a BaseType
177 return d_value;
178 }
179 else if (d_func) {
180 // If func is true, then args must be set. See the constructor.
181 // 12/23/04 jhrg
182 BaseType **argv = build_btp_args(d_args, dds);
183 BaseType *ret_val;
184 (*d_func)(d_args->size(), argv, dds, &ret_val);
185 delete[] argv;
186 return ret_val;
187 }
188 else {
189 return 0;
190 }
191}
192
193} // namespace libdap
194
The basic data type for the DODS DAP types.
Definition: BaseType.h:118
A class for error processing.
Definition: Error.h:94
top level DAP object to house generic methods
Definition: AlarmHandler.h:36
bool size_ok(unsigned int sz, unsigned int nelem)
sanitize the size of an array. Test for integer overflow when dynamically allocating an array.
Definition: util.cc:1152
BaseType ** build_btp_args(const rvalue_list *args, DDS &dds)
Definition: RValue.cc:88