libdap  Updated for version 3.20.9
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 
49 using namespace std;
50 
51 namespace libdap {
52 
53 rvalue_list *
54 make_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 
68 rvalue_list *
69 append_rvalue_list(rvalue_list *rvals, rvalue *rv)
70 {
71  rvals->push_back(rv);
72 
73  return rvals;
74 }
75 
76 
87 BaseType **
88 build_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 
133 rvalue::rvalue(BaseType *bt): d_value(bt), d_func(0), d_args(0)
134 {}
135 
136 rvalue::rvalue(btp_func f, vector<rvalue *> *a) : d_value(0), d_func(f), d_args(a)
137 {}
138 
139 rvalue::rvalue(): d_value(0), d_func(0), d_args(0)
140 {}
141 
142 rvalue::~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 
158 string
159 rvalue::value_name()
160 {
161  assert(d_value);
162 
163  return d_value->name();
164 }
165 
173 BaseType *
174 rvalue::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:1150
BaseType ** build_btp_args(const rvalue_list *args, DDS &dds)
Definition: RValue.cc:88