libdap  Updated for version 3.20.6
libdap4 is an implementation of OPeNDAP's DAP protocol.
D4RValue.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) 2014 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 #include "config.h"
27 
28 #include <iostream>
29 
30 #include "BaseType.h"
31 #include "Array.h"
32 #include "Byte.h"
33 #include "Int8.h"
34 #include "UInt16.h"
35 #include "Int16.h"
36 #include "UInt32.h"
37 #include "Int32.h"
38 #include "UInt64.h"
39 #include "Int64.h"
40 #include "Float32.h"
41 #include "Float64.h"
42 #include "Str.h"
43 
44 #include "D4RValue.h"
45 #include "InternalErr.h"
46 
47 #include "dods-datatypes.h"
48 #include "dods-limits.h"
49 #include "parser-util.h"
50 #include "util.h"
51 
52 using namespace std;
53 
54 namespace libdap {
55 
56 void
57 D4RValueList::m_duplicate(const D4RValueList &src)
58 {
59  for (std::vector<D4RValue *>::const_iterator i = src.d_rvalues.begin(), e = src.d_rvalues.end(); i != e; ++i) {
60  D4RValue *rv = *i;
61  d_rvalues.push_back(new D4RValue(*rv));
62  }
63 }
64 
65 D4RValueList::~D4RValueList()
66 {
67  for (std::vector<D4RValue *>::iterator i = d_rvalues.begin(), e = d_rvalues.end(); i != e; ++i)
68  delete *i;
69 }
70 
71 void
72 D4RValue::m_duplicate(const D4RValue &src)
73 {
74  d_value_kind = src.d_value_kind;
75 
76  d_variable = src.d_variable; // weak pointers
77 
78  d_func = src.d_func;
79  d_args = (src.d_args != 0) ? new D4RValueList(*src.d_args) : 0; // deep copy these
80 
81  d_constant = (src.d_constant != 0) ? src.d_constant->ptr_duplicate() : 0;
82 }
83 
84 template<typename T, class DAP_TYPE>
85 static BaseType *
86 build_constant_array(vector<T> &values, DAP_TYPE &dt)
87 {
88  Array *array = new Array("", &dt);
89  array->append_dim(values.size());
90 
91  // TODO Make set_value_nocopy() methods so that values' pointers can be copied
92  // instead of allocating memory twice. jhrg 7/5/13
93 
94  array->set_value(values, values.size());
95 
96  array->set_read_p(true);
97 
98  static unsigned long counter = 1;
99  array->set_name(string("g") + long_to_string(counter++));
100 
101  return array;
102 }
103 
104 D4RValue::D4RValue(unsigned long long ull) : d_variable(0), d_func(0), d_args(0), d_constant(0), d_value_kind(constant)
105 {
106  UInt64 *ui = new UInt64("constant");
107  ui->set_value(ull);
108  d_constant = ui;
109 }
110 
111 D4RValue::D4RValue(long long ll) : d_variable(0), d_func(0), d_args(0), d_constant(0), d_value_kind(constant)
112 {
113  Int64 *i = new Int64("constant");
114  i->set_value(ll);
115  d_constant = i;
116 }
117 
118 D4RValue::D4RValue(double r) : d_variable(0), d_func(0), d_args(0), d_constant(0), d_value_kind(constant)
119 {
120  Float64 *f = new Float64("constant");
121  f->set_value(r);
122  d_constant = f;
123 }
124 
125 D4RValue::D4RValue(std::string cpps) : d_variable(0), d_func(0), d_args(0), d_constant(0), d_value_kind(constant)
126 {
127  Str *s = new Str("constant");
128  s->set_value(remove_quotes(cpps));
129  d_constant = s;
130 }
131 
132 D4RValue::D4RValue(std::vector<dods_byte> &byte_args)
133  : d_variable(0), d_func(0), d_args(0), d_constant(0), d_value_kind(constant)
134 {
135  Byte b("");
136  d_constant = build_constant_array(byte_args, b);
137 }
138 
139 D4RValue::D4RValue(std::vector<dods_int8> &byte_int8)
140  : d_variable(0), d_func(0), d_args(0), d_constant(0), d_value_kind(constant)
141 {
142  Int8 b("");
143  d_constant = build_constant_array(byte_int8, b);
144 }
145 
146 D4RValue::D4RValue(std::vector<dods_uint16> &byte_uint16)
147  : d_variable(0), d_func(0), d_args(0), d_constant(0), d_value_kind(constant)
148 {
149  UInt16 b("");
150  d_constant = build_constant_array(byte_uint16, b);
151 }
152 
153 D4RValue::D4RValue(std::vector<dods_int16> &byte_int16)
154  : d_variable(0), d_func(0), d_args(0), d_constant(0), d_value_kind(constant)
155 {
156  Int16 b("");
157  d_constant = build_constant_array(byte_int16, b);
158 }
159 
160 D4RValue::D4RValue(std::vector<dods_uint32> &byte_uint32)
161  : d_variable(0), d_func(0), d_args(0), d_constant(0), d_value_kind(constant)
162 {
163  UInt32 b("");
164  d_constant = build_constant_array(byte_uint32, b);
165 }
166 
167 D4RValue::D4RValue(std::vector<dods_int32> &byte_int32)
168  : d_variable(0), d_func(0), d_args(0), d_constant(0), d_value_kind(constant)
169 {
170  Int32 b("");
171  d_constant = build_constant_array(byte_int32, b);
172 }
173 
174 D4RValue::D4RValue(std::vector<dods_uint64> &byte_uint64)
175  : d_variable(0), d_func(0), d_args(0), d_constant(0), d_value_kind(constant)
176 {
177  UInt64 b("");
178  d_constant = build_constant_array(byte_uint64, b);
179 }
180 
181 D4RValue::D4RValue(std::vector<dods_int64> &byte_int64)
182  : d_variable(0), d_func(0), d_args(0), d_constant(0), d_value_kind(constant)
183 {
184  Int64 b("");
185  d_constant = build_constant_array(byte_int64, b);
186 }
187 
188 D4RValue::D4RValue(std::vector<dods_float32> &byte_float32)
189  : d_variable(0), d_func(0), d_args(0), d_constant(0), d_value_kind(constant)
190 {
191  Float32 b("");
192  d_constant = build_constant_array(byte_float32, b);
193 }
194 
195 D4RValue::D4RValue(std::vector<dods_float64> &byte_float64)
196  : d_variable(0), d_func(0), d_args(0), d_constant(0), d_value_kind(constant)
197 {
198  Float64 b("");
199  d_constant = build_constant_array(byte_float64, b);
200 }
201 
202 D4RValue::~D4RValue() {
203  // d_variable and d_func are weak pointers; don't delete.
204  delete d_args;
205  delete d_constant;
206 }
207 
218 D4RValue *D4RValueFactory(std::string cpps)
219 {
220  char *ptr;
221 
222  // First check if the string is a uint64, ..., then convert it.
223  // Since the check_* function use the strtoull() functions, no
224  // need to test for errors when building the actual values.
225  if (check_uint64(cpps.c_str())) {
226  return new D4RValue(strtoull(cpps.c_str(), &ptr, 0));
227  }
228  else if (check_int64(cpps.c_str())) {
229  return new D4RValue(strtoll(cpps.c_str(), &ptr, 0));
230  }
231  else if (check_float64(cpps.c_str())) {
232 #ifdef WIN32
233  return new D4RValue(w32strtod(cpps.c_str(), &ptr));
234 #else
235  return new D4RValue(strtod(cpps.c_str(), &ptr));
236 #endif
237  }
238  else {
239  return new D4RValue(cpps);
240  }
241 }
242 
269 BaseType *
271 {
272  switch (d_value_kind) {
273  case basetype:
274  d_variable->read();
275  d_variable->set_read_p(true);
276  return d_variable;
277 
278  case function:
279  return (*d_func)(d_args, dmr);
280 
281  case constant:
282  return d_constant;
283 
284  default:
285  throw InternalErr(__FILE__, __LINE__, "Unknown rvalue type.");
286  }
287 }
288 
299 BaseType *
301 {
302  switch (d_value_kind) {
303  case basetype:
304  d_variable->read();
305  d_variable->set_read_p(true);
306  return d_variable;
307 
308  case function:
309  throw Error(malformed_expr, "An expression that included a function call was used in a place where that won't work.");
310 
311  case constant:
312  return d_constant;
313 
314  default:
315  throw InternalErr(__FILE__, __LINE__, "Unknown rvalue type.");
316  }
317 }
318 
319 } // namespace libdap
320 
virtual bool read()
Read data into a local buffer.
Definition: BaseType.cc:899
STL namespace.
top level DAP object to house generic methods
Definition: AISConnect.cc:30
A class for software fault reporting.
Definition: InternalErr.h:64
D4RValue * D4RValueFactory(std::string cpps)
Build an appropriate RValue.
Definition: D4RValue.cc:218
string remove_quotes(const string &s)
Definition: util.cc:585
The basic data type for the DODS DAP types.
Definition: BaseType.h:117
virtual BaseType * value()
Get the value for a RValue object.
Definition: D4RValue.cc:300
A class for error processing.
Definition: Error.h:92