33#include <libdap/Type.h>
34#include <libdap/BaseType.h>
35#include <libdap/Byte.h>
36#include <libdap/Int16.h>
37#include <libdap/UInt16.h>
38#include <libdap/Int32.h>
39#include <libdap/UInt32.h>
40#include <libdap/Float32.h>
41#include <libdap/Float64.h>
42#include <libdap/Str.h>
43#include <libdap/Url.h>
44#include <libdap/Array.h>
45#include <libdap/Error.h>
46#include <libdap/DDS.h>
48#include <libdap/DMR.h>
49#include <libdap/D4Group.h>
50#include <libdap/D4RValue.h>
52#include <libdap/debug.h>
53#include <libdap/util.h>
55#include <libdap/BaseTypeFactory.h>
59#include "MakeArrayFunction.h"
60#include "functions_util.h"
66string make_array_info =
67 string(
"<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n")
68 +
"<function name=\"make_array\" version=\"1.0\" href=\"http://docs.opendap.org/index.php/Server_Side_Processing_Functions#make_array\">\n"
71bool isValidTypeMatch(
Type requestedType,
Type argType)
73 bool typematch_status =
false;
74 switch (requestedType) {
85 typematch_status =
true;
95 case dods_float64_c: {
98 case dods_float64_c: {
99 typematch_status =
true;
114 typematch_status =
true;
124 throw InternalErr(__FILE__, __LINE__,
"Unknown type error");
127 return typematch_status;
130template<
class DAP_Primitive,
class DAP_BaseType>
131static void read_values(
int argc, BaseType *argv[], Array *dest)
133 vector<DAP_Primitive> values;
134 values.reserve(argc - 2);
136 string requestedTypeName = extract_string_argument(argv[0]);
137 Type requestedType = libdap::get_type(requestedTypeName.c_str());
138 BESDEBUG(
"functions",
"make_dap2_array() - Requested array type: " << requestedTypeName<< endl);
141 for (
int i = 2; i < argc; ++i) {
142 BESDEBUG(
"functions",
"make_dap2_array() - Adding value of type " << argv[i]->type_name() << endl);
143 if (!isValidTypeMatch(requestedType, argv[i]->type())) {
144 throw Error(malformed_expr,
145 "make_array(): Expected values to be of type " + requestedTypeName +
" but argument "
146 + long_to_string(i) +
" evaluated into a type " + argv[i]->type_name() +
" instead.");
148 BESDEBUG(
"functions",
"make_dap2_array() - Adding value: " <<
static_cast<DAP_BaseType*
>(argv[i])->value() << endl);
149 values.push_back(
static_cast<DAP_BaseType*
>(argv[i])->value());
152 BESDEBUG(
"functions",
"make_dap2_array() - values size: " << values.size() << endl);
155 dest->set_value(values, values.size());
158template<
class DAP_Primitive,
class DAP_BaseType>
159static void read_values(D4RValueList *args, DMR &dmr, Array *dest)
161 vector<DAP_Primitive> values;
162 values.reserve(args->size() - 2);
164 string requestedTypeName = extract_string_argument(args->get_rvalue(0)->value(dmr));
165 Type requestedType = libdap::get_type(requestedTypeName.c_str());
166 BESDEBUG(
"functions",
"make_dap2_array() - Requested array type: " << requestedTypeName<< endl);
169 for (
unsigned int i = 2; i < args->size(); ++i) {
171 BESDEBUG(
"functions",
"Adding value of type " << args->get_rvalue(i)->value(dmr)->type_name() << endl);
172 if (!isValidTypeMatch(requestedType, args->get_rvalue(i)->value(dmr)->type())) {
173 throw Error(malformed_expr,
174 "make_array(): Expected values to be of type " + requestedTypeName +
" but argument "
175 + long_to_string(i) +
" evaluated into a type "
176 + args->get_rvalue(i)->value(dmr)->type_name() +
" instead.");
179 BESDEBUG(
"functions",
180 "Adding value: " <<
static_cast<DAP_BaseType*
>(args->get_rvalue(i)->value(dmr))->value() <<endl);
181 values.push_back(
static_cast<DAP_BaseType*
>(args->get_rvalue(i)->value(dmr))->value());
184 BESDEBUG(
"functions",
"values size: " << values.size() << endl);
187 dest->set_value(values, values.size());
202void function_make_dap2_array(
int argc, BaseType * argv[], DDS &dds, BaseType **btpp)
205 Str *response =
new Str(
"info");
206 response->set_value(make_array_info);
211 BESDEBUG(
"functions",
"function_make_dap2_array() - argc: " << long_to_string(argc) << endl);
214 if (argc < 2)
throw Error(malformed_expr,
"make_array(type,shape,[value0,...]) requires at least two arguments.");
216 string requested_type_name = extract_string_argument(argv[0]);
217 string shape = extract_string_argument(argv[1]);
219 BESDEBUG(
"functions",
"function_make_dap2_array() - type: " << requested_type_name << endl);
220 BESDEBUG(
"functions",
"function_make_dap2_array() - shape: " << shape << endl);
223 Type requested_type = libdap::get_type(requested_type_name.c_str());
224 if (!is_simple_type(requested_type))
225 throw Error(malformed_expr,
226 "make_array() can only build arrays of simple types (integers, floats and strings).");
231 vector<int> dims = parse_dims(shape);
233 static unsigned long counter = 1;
236 name =
"g" + long_to_string(counter++);
237 }
while (dds.var(name));
239 Array *dest =
new Array(name, 0);
241 dest->add_var_nocopy(btf.NewVariable(requested_type));
243 unsigned long number_of_elements = 1;
244 vector<int>::iterator i = dims.begin();
245 while (i != dims.end()) {
246 number_of_elements *= *i;
247 dest->append_dim(*i++);
252 if (number_of_elements + 2 != (
unsigned long) argc)
253 throw Error(malformed_expr,
254 "make_array(): Expected " + long_to_string(number_of_elements) +
" parameters but found "
255 + long_to_string(argc - 2) +
" instead.");
257 switch (requested_type) {
261 read_values<dods_byte, Int32>(argc, argv, dest);
265 read_values<dods_int16, Int32>(argc, argv, dest);
269 read_values<dods_uint16, Int32>(argc, argv, dest);
273 read_values<dods_int32, Int32>(argc, argv, dest);
278 read_values<dods_uint32, Int32>(argc, argv, dest);
282 read_values<dods_float32, Float64>(argc, argv, dest);
286 read_values<dods_float64, Float64>(argc, argv, dest);
290 read_values<string, Str>(argc, argv, dest);
294 read_values<string, Url>(argc, argv, dest);
298 throw InternalErr(__FILE__, __LINE__,
"Unknown type error");
301 dest->set_send_p(
true);
302 dest->set_read_p(
true);
309BaseType *function_make_dap4_array(D4RValueList *args, DMR &dmr)
312 if (args == 0 || args->size() == 0) {
313 Str *response =
new Str(
"info");
314 response->set_value(make_array_info);
320 DBG(cerr <<
"args.size() = " << args.size() << endl);
321 if (args->size() < 2)
322 throw Error(malformed_expr,
"Wrong number of arguments to make_array(). See make_array() for more information");
324 string requested_type_name = extract_string_argument(args->get_rvalue(0)->value(dmr));
325 string shape = extract_string_argument(args->get_rvalue(1)->value(dmr));
327 BESDEBUG(
"functions",
"type: " << requested_type_name << endl);
328 BESDEBUG(
"functions",
"shape: " << shape << endl);
331 Type requested_type = libdap::get_type(requested_type_name.c_str());
332 if (!is_simple_type(requested_type))
333 throw Error(malformed_expr,
334 "make_array() can only build arrays of simple types (integers, floats and strings).");
339 vector<int> dims = parse_dims(shape);
341 static unsigned long counter = 1;
344 name =
"g" + long_to_string(counter++);
345 }
while (dmr.root()->var(name));
347 Array *dest =
new Array(name, 0);
349 dest->add_var_nocopy(btf.NewVariable(requested_type));
351 unsigned long number_of_elements = 1;
352 vector<int>::iterator i = dims.begin();
353 while (i != dims.end()) {
354 number_of_elements *= *i;
355 dest->append_dim(*i++);
360 if (number_of_elements + 2 != args->size())
361 throw Error(malformed_expr,
362 "make_array(): Expected " + long_to_string(number_of_elements) +
" parameters but found "
363 + long_to_string(args->size() - 2) +
" instead.");
365 switch (requested_type) {
369 read_values<dods_byte, Int32>(args, dmr, dest);
373 read_values<dods_int16, Int32>(args, dmr, dest);
377 read_values<dods_uint16, Int32>(args, dmr, dest);
381 read_values<dods_int32, Int32>(args, dmr, dest);
386 read_values<dods_uint32, Int32>(args, dmr, dest);
390 read_values<dods_float32, Float64>(args, dmr, dest);
394 read_values<dods_float64, Float64>(args, dmr, dest);
398 read_values<string, Str>(args, dmr, dest);
402 read_values<string, Url>(args, dmr, dest);
406 throw InternalErr(__FILE__, __LINE__,
"Unknown type error");
408 dest->set_send_p(
true);
409 dest->set_read_p(
true);