33#include <libdap/Type.h>
34#include <libdap/BaseType.h>
35#include <libdap/Str.h>
36#include <libdap/Array.h>
37#include <libdap/Structure.h>
38#include <libdap/Error.h>
39#include <libdap/DDS.h>
41#include <libdap/DMR.h>
42#include <libdap/D4Group.h>
43#include <libdap/D4RValue.h>
45#include <libdap/debug.h>
46#include <libdap/util.h>
48#include <libdap/BaseTypeFactory.h>
52#include "MakeArrayFunction.h"
53#include "functions_util.h"
59string mask_array_info =
60 string(
"<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n")
61 +
"<function name=\"mask_array\" version=\"1.0\" href=\"http://docs.opendap.org/index.php/Server_Side_Processing_Functions#mask_array\">\n"
77void mask_array_helper(Array *array,
double no_data_value,
const vector<dods_byte> &mask)
81 array->set_read_p(
true);
82 vector<T> data(array->length());
83 array->value(data.data());
85 assert(data.size() == mask.size());
88 vector<dods_byte>::const_iterator mi = mask.begin();
89 for (
typename vector<T>::iterator i = data.begin(), e = data.end(); i != e; ++i) {
90 if (!*mi++) *i = no_data_value;
94 array->set_value(data, data.size());
111void function_mask_dap2_array(
int argc, BaseType * argv[], DDS &, BaseType **btpp)
115 Str *response =
new Str(
"info");
116 response->set_value(mask_array_info);
121 BESDEBUG(
"functions",
"function_mask_dap2_array() - argc: " << argc << endl);
124 if (argc < 3)
throw Error(malformed_expr,
"In mask_array(Array1, ..., ArrayN, NoData, Mask) requires at least three arguments.");
127 double no_data_value = extract_double_value(argv[argc-2]);
130 check_number_type_array(argv[argc-1]);
131 Array *mask_var =
static_cast<Array*
>(argv[argc-1]);
132 if (mask_var->var()->type() != dods_byte_c)
133 throw Error(malformed_expr,
"In mask_array(): Expected the last argument (the mask) to be a byte array.");
136 mask_var->set_read_p(
true);
137 vector<dods_byte> mask(mask_var->length());
138 mask_var->value(mask.data());
141 for (
int i = 0; i < argc-2; ++i) {
142 check_number_type_array (argv[i]);
143 Array *array =
static_cast<Array*
>(argv[i]);
146 if ((vector<dods_byte>::size_type)array->length() != mask.size())
147 throw Error(malformed_expr,
"In make_array(): The array '" + array->name() +
"' and the mask do not match in size.");
149 switch (array->var()->type()) {
151 mask_array_helper<dods_byte>(array, no_data_value, mask);
154 mask_array_helper<dods_int16>(array, no_data_value, mask);
157 mask_array_helper<dods_uint16>(array, no_data_value, mask);
160 mask_array_helper<dods_int32>(array, no_data_value, mask);
163 mask_array_helper<dods_uint32>(array, no_data_value, mask);
166 mask_array_helper<dods_float32>(array, no_data_value, mask);
169 mask_array_helper<dods_float64>(array, no_data_value, mask);
172 throw InternalErr(__FILE__, __LINE__,
"In mask_array(): Type " + array->type_name() +
" not handled.");
179 dest = argv[0]->ptr_duplicate();
181 dest =
new Structure(
"masked_arays");
182 for (
int i = 0; i < argc-2; ++i) {
183 dest->add_var(argv[i]);
187 dest->set_send_p(
true);
188 dest->set_read_p(
true);
208BaseType *function_mask_dap4_array(D4RValueList *args, DMR &dmr)
211 if (args == 0 || args->size() == 0) {
212 Str *response =
new Str(
"info");
213 response->set_value(mask_array_info);
219 if (args->size() < 3)
throw Error(malformed_expr,
"In mask_array(Array1, ..., ArrayN, NoData, Mask) requires at least three arguments.");
222 double no_data_value = extract_double_value(args->get_rvalue(args->size()-2)->value(dmr));
225 BaseType *mask_btp = args->get_rvalue(args->size()-1)->value(dmr);
226 check_number_type_array (mask_btp);
227 Array *mask_var =
static_cast<Array*
>(mask_btp);
228 if (mask_var->var()->type() != dods_byte_c)
229 throw Error(malformed_expr,
"In mask_array(): Expected the last argument (the mask) to be a byte array.");
232 mask_var->set_read_p(
true);
233 vector<dods_byte> mask(mask_var->length());
234 mask_var->value(mask.data());
237 for (
unsigned int i = 0; i < args->size() - 2; ++i) {
238 BaseType *array_btp = args->get_rvalue(i)->value(dmr);
239 check_number_type_array (array_btp);
240 Array *array =
static_cast<Array*
>(array_btp);
243 if ((vector<dods_byte>::size_type) array->length() != mask.size())
244 throw Error(malformed_expr,
245 "In make_array(): The array '" + array->name() +
"' and the mask do not match in size.");
247 switch (array->var()->type()) {
249 mask_array_helper<dods_byte>(array, no_data_value, mask);
252 mask_array_helper<dods_int16>(array, no_data_value, mask);
255 mask_array_helper<dods_uint16>(array, no_data_value, mask);
258 mask_array_helper<dods_int32>(array, no_data_value, mask);
261 mask_array_helper<dods_uint32>(array, no_data_value, mask);
264 mask_array_helper<dods_float32>(array, no_data_value, mask);
267 mask_array_helper<dods_float64>(array, no_data_value, mask);
270 throw InternalErr(__FILE__, __LINE__,
"In mask_array(): Type " + array->type_name() +
" not handled.");
276 if (args->size() == 3)
277 dest = args->get_rvalue(0)->value(dmr)->ptr_duplicate();
279 dest =
new Structure(
"masked_arays");
280 for (
unsigned int i = 0; i < args->size() - 2; ++i) {
281 dest->add_var(args->get_rvalue(i)->value(dmr));
285 dest->set_send_p(
true);
286 dest->set_read_p(
true);