39 {
"$Id: ce_functions.cc 23551 2010-09-13 21:00:46Z jimg $" 86 double w32strtod(
const char *,
char **);
102 inline bool double_eq(
double lhs,
double rhs,
double epsilon = 1.0e-5)
105 return (lhs - rhs) < ((lhs + rhs) / epsilon);
107 return (rhs - lhs) < ((lhs + rhs) / epsilon);
121 "The function requires a DAP string argument.");
125 "The CE Evaluator built an argument list where some constants held no values.");
127 string s =
dynamic_cast<Str&
>(*arg).
value();
129 DBG(cerr <<
"s: " << s << endl);
133 template<
class T>
static void set_array_using_double_helper(
Array * a,
134 double *src,
int src_len)
136 T *values =
new T[src_len];
137 for (
int i = 0; i < src_len; ++i)
138 values[i] = (T) src[i];
173 "The function requires a DAP numeric-type array argument.");
179 if (dest->
length() != src_len)
181 "The source and destination array sizes don't match (" 191 set_array_using_double_helper<dods_byte>(dest, src, src_len);
194 set_array_using_double_helper<dods_uint16>(dest, src, src_len);
197 set_array_using_double_helper<dods_int16>(dest, src, src_len);
200 set_array_using_double_helper<dods_uint32>(dest, src, src_len);
203 set_array_using_double_helper<dods_int32>(dest, src, src_len);
206 set_array_using_double_helper<dods_float32>(dest, src, src_len);
209 set_array_using_double_helper<dods_float64>(dest, src, src_len);
213 "The argument list built by the CE parser contained an unsupported numeric type.");
220 template<
class T>
static double *extract_double_array_helper(
Array * a)
224 T *b =
new T[length];
227 double *dest =
new double[length];
228 for (
int i = 0; i < length; ++i)
229 dest[i] = (
double) b[i];
245 "The function requires a DAP numeric-type array argument.");
249 string(
"The Array '") + a->
name() +
250 "'does not contain values.");
258 return extract_double_array_helper<dods_byte>(a);
260 return extract_double_array_helper<dods_uint16>(a);
262 return extract_double_array_helper<dods_int16>(a);
264 return extract_double_array_helper<dods_uint32>(a);
266 return extract_double_array_helper<dods_int32>(a);
268 return extract_double_array_helper<dods_float32>(a);
270 return extract_double_array_helper<dods_float64>(a);
273 "The argument list built by the CE parser contained an unsupported numeric type.");
290 "The function requires a DAP numeric-type argument.");
294 "The CE Evaluator built an argument list where some constants held no values.");
300 switch (arg->
type()) {
302 return (
double)(
dynamic_cast<Byte&
>(*arg).
value());
304 return (
double)(
dynamic_cast<UInt16&
>(*arg).
value());
306 return (
double)(
dynamic_cast<Int16&
>(*arg).
value());
308 return (
double)(
dynamic_cast<UInt32&
>(*arg).
value());
310 return (
double)(
dynamic_cast<Int32&
>(*arg).
value());
317 "The argument list built by the CE parser contained an unsupported numeric type.");
328 "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\ 330 <function name=\"geogrid\" version=\"1.2\"/>\ 331 <function name=\"grid\" version=\"1.0\"/>\ 332 <function name=\"linear_scale\" version=\"1.0b1\"/>\ 333 <function name=\"version\" version=\"1.0\"/>\ 338 Str *response =
new Str(
"version");
350 bool status =
gse_parse((
void *) arg) == 0;
356 static void apply_grid_selection_expr(
Grid * grid,
GSEClause * clause)
366 +
"' is not in the grid '" + grid->
name() +
"'.");
371 Array *map = dynamic_cast <
Array * >((*map_i));
373 throw InternalErr(__FILE__, __LINE__,
"Expected an Array");
380 <<
"The expressions passed to grid() do not result in an inclusive \n" 382 <<
"'. The map's values range " <<
"from " 388 DBG(cerr <<
"Setting constraint on " << map->
name()
389 <<
"[" << start <<
":" << stop <<
"]" << endl);
396 static void apply_grid_selection_expressions(
Grid * grid,
397 vector < GSEClause * >clauses)
399 vector < GSEClause * >::iterator clause_i = clauses.begin();
400 while (clause_i != clauses.end())
401 apply_grid_selection_expr(grid, *clause_i++);
445 DBG(cerr <<
"Entering function_grid..." << endl);
448 string(
"<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n") +
449 "<function name=\"grid\" version=\"1.0\" href=\"http://docs.opendap.org/index.php/Server_Side_Processing_Functions#grid\">\n" +
453 Str *response =
new Str(
"info");
459 Grid *original_grid = dynamic_cast <
Grid * >(argv[0]);
467 throw InternalErr(__FILE__, __LINE__,
"Expected a Grid.");
469 DBG(cerr <<
"grid: past initialization code" << endl);
479 (*i++)->set_send_p(
true);
482 DBG(cerr <<
"grid: past map read" << endl);
488 vector < GSEClause * > clauses;
490 for (
int i = 1; i < argc; ++i) {
491 parse_gse_expression(arg, argv[i]);
497 apply_grid_selection_expressions(l_grid, clauses);
499 DBG(cerr <<
"grid: past gse application" << endl);
548 string(
"<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n") +
549 "<function name=\"geogrid\" version=\"1.2\" href=\"http://docs.opendap.org/index.php/Server_Side_Processing_Functions#geogrid\">\n"+
553 Str *response =
new Str(
"version");
568 if (argc < 1 || !(l_grid = dynamic_cast < Grid * >(argv[0]->ptr_duplicate())))
573 throw Error(
malformed_expr,
"Wrong number of arguments to geogrid() (expected at least 5 args). See geogrid() for more information.");
575 bool grid_lat_lon_form;
578 if (!(l_lat = dynamic_cast < Array * >(argv[1])))
579 grid_lat_lon_form =
false;
580 else if (!(l_lon = dynamic_cast < Array * >(argv[2])))
581 throw Error(
malformed_expr,
"When using the Grid, Lat, Lon form of geogrid() both the lat and lon maps must be given (lon map missing)!");
583 grid_lat_lon_form =
true;
585 if (grid_lat_lon_form && argc < 7)
586 throw Error(
malformed_expr,
"Wrong number of arguments to geogrid() (expected at least 7 args). See geogrid() for more information.");
605 (*i++)->set_send_p(
true);
612 DBG(cerr <<
"geogrid: past map read" << endl);
616 int min_arg_count = (grid_lat_lon_form) ? 7 : 5;
617 if (argc > min_arg_count) {
620 vector < GSEClause * > clauses;
622 for (
int i = min_arg_count; i < argc; ++i) {
623 parse_gse_expression(arg, argv[i]);
629 apply_grid_selection_expressions(l_grid, clauses);
639 int box_index_offset = (grid_lat_lon_form) ? 3 : 1;
645 DBG(cerr <<
"geogrid: past bounding box set" << endl);
649 DBG(cerr <<
"geogrid: past apply constraint" << endl);
659 catch (exception & e) {
662 (
"A C++ exception was thrown from inside geogrid(): ")
672 static double string_to_double(
const char *val)
679 double v = w32strtod(val, &ptr);
681 double v = strtod(val, &ptr);
684 if ((v == 0.0 && (val == ptr || errno == HUGE_VAL || errno == ERANGE))
686 throw Error(
malformed_expr,
string(
"Could not convert the string '") + val +
"' to a double.");
689 double abs_val = fabs(v);
691 throw Error(
malformed_expr,
string(
"Could not convert the string '") + val +
"' to a double.");
705 static double get_attribute_double_value(
BaseType *var,
706 vector<string> &attributes)
711 string attribute_value =
"";
713 vector<string>::iterator i = attributes.begin();
714 while (attribute_value ==
"" && i != attributes.end()) {
718 attribute_value = attr.
get_attr(*i++);
723 if (attribute_value.empty()) {
725 return get_attribute_double_value(dynamic_cast<Grid&>(*var).get_array(), attributes);
727 throw Error(
malformed_expr,
string(
"No COARDS/CF '") + values.substr(0, values.length() - 2)
728 +
"' attribute was found for the variable '" 729 + var->
name() +
"'.");
732 return string_to_double(
remove_quotes(attribute_value).c_str());
735 static double get_attribute_double_value(
BaseType *var,
const string &attribute)
738 string attribute_value = attr.
get_attr(attribute);
742 if (attribute_value.empty()) {
744 return get_attribute_double_value(dynamic_cast<Grid&>(*var).get_array(), attribute);
747 +
"' attribute was found for the variable '" 748 + var->
name() +
"'.");
751 return string_to_double(
remove_quotes(attribute_value).c_str());
754 static double get_y_intercept(
BaseType *var)
756 vector<string> attributes;
757 attributes.push_back(
"add_offset");
758 attributes.push_back(
"add_off");
759 return get_attribute_double_value(var, attributes);
762 static double get_slope(
BaseType *var)
764 return get_attribute_double_value(var,
"scale_factor");
767 static double get_missing_value(
BaseType *var)
769 return get_attribute_double_value(var,
"missing_value");
788 string(
"<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n") +
789 "<function name=\"linear_scale\" version=\"1.0b1\" href=\"http://docs.opendap.org/index.php/Server_Side_Processing_Functions#linear_scale\">\n" +
793 Str *response =
new Str(
"info");
800 DBG(cerr <<
"argc = " << argc << endl);
801 if (!(argc == 1 || argc == 3 || argc == 4))
802 throw Error(
malformed_expr,
"Wrong number of arguments to linear_scale(). See linear_scale() for more information");
805 bool use_missing =
false;
806 double m, b, missing = 0.0;
812 }
else if (argc == 3) {
817 m = get_slope(argv[0]);
823 b = get_y_intercept(argv[0]);
833 missing = get_missing_value(argv[0]);
841 DBG(cerr <<
"m: " << m <<
", b: " << b << endl);
DBG(cerr <<
"use_missing: " << use_missing <<
", missing: " << missing << endl);
848 Array &source = *
dynamic_cast<Grid&
>(*argv[0]).get_array();
852 int length = source.
length();
855 DBG2(cerr <<
"data[" << i <<
"]: " << data[i] << endl);
856 if (!use_missing || !
double_eq(data[i], missing))
857 data[i] = data[i] * m + b;
858 DBG2(cerr <<
" >> data[" << i <<
"]: " << data[i] << endl);
866 source.
val2buf(static_cast<void*>(data),
false);
873 }
else if (argv[0]->is_vector_type()) {
874 Array &source =
dynamic_cast<Array&
>(*argv[0]);
884 int length = source.
length();
887 if (!use_missing || !
double_eq(data[i], missing))
888 data[i] = data[i] * m + b;
895 source.
val2buf(static_cast<void*>(data),
false);
901 }
else if (argv[0]->is_simple_type() && !(argv[0]->type() ==
dods_str_c 904 if (!use_missing || !
double_eq(data, missing))
907 dest =
new Float64(argv[0]->name());
909 dest->
val2buf(static_cast<void*>(&data));
912 throw Error(
malformed_expr,
"The linear_scale() function works only for numeric Grids, Arrays and scalars.");
940 string(
"<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n") +
941 "<function name=\"geoarray\" version=\"0.9b1\" href=\"http://docs.opendap.org/index.php/Server_Side_Processing_Functions#geoarray\">\n" +
945 Str *response =
new Str(
"version");
951 DBG(cerr <<
"argc = " << argc << endl);
952 if (!(argc == 5 || argc == 9 || argc == 11))
953 throw Error(
malformed_expr,
"Wrong number of arguments to geoarray(). See geoarray() for more information.");
1001 var_left, var_top, var_right, var_bottom,
1012 throw InternalErr(__FILE__, __LINE__,
"Wrong number of args to geoarray.");
1018 catch (exception & e) {
1021 (
"A C++ exception was thrown from inside geoarray(): ")
1026 throw InternalErr(__FILE__, __LINE__,
"Impossible condition in geoarray.");
virtual bool read()
Read data into a local buffer.
void gse_delete_buffer(void *buffer)
virtual void add_constraint(Dim_iter i, int start, int stride, int stop)
Adds a constraint to an Array dimension.
virtual bool read_p()
Has this variable been read?
string name() const
Returns the name of the class instance.
void gse_restart(FILE *in)
void add_var(BaseType *v, Part p=nil)
Add the BaseType pointer to this constructor type instance.
Contains the attributes for a dataset.
Holds an unsigned 16-bit integer.
virtual void set_read_p(bool state)
Indicates that the data is ready to send.
virtual BaseType * get_parent()
void * gse_string(const char *yy_str)
void register_functions(ConstraintEvaluator &ce)
string extract_string_argument(BaseType *arg)
virtual string get_attr(const string &name, unsigned int i=0)
virtual dods_byte value() const
void function_geoarray(int argc, BaseType *argv[], DDS &dds, BaseType **btpp)
void set_bounding_box(double top, double left, double bottom, double right)
virtual dods_float64 value() const
Holds a 32-bit floating point value.
string get_map_max_value() const
Get the maximum map vector value.
void function_linear_scale(int argc, BaseType *argv[], DDS &, BaseType **btpp)
int get_stop() const
Get the stopping index of the clause's map variable as constrained by this clause.
A class for software fault reporting.
virtual BaseType * var(const string &name="", bool exact_match=true, btp_stack *s=0)
Holds character string data.
Map_iter map_begin()
Returns an iterator referencing the first Map vector.
void set_array_using_double(Array *dest, double *src, int src_len)
double * extract_double_array(Array *a)
virtual BaseType * ptr_duplicate()
Holds a 16-bit signed integer value.
void function_grid(int argc, BaseType *argv[], DDS &, BaseType **btpp)
Type type() const
Returns the type of the class instance.
std::vector< dimension >::iterator Dim_iter
virtual void set_read_p(bool state)
Sets the value of the read_p property.
string get_map_min_value() const
Get the minimum map vector value.
virtual void value(dods_byte *b) const
Get a copy of the data held by this variable. Read data from this variable's internal storage and loa...
Holds the Grid data type.
void gse_switch_to_buffer(void *new_buffer)
virtual void apply_constraint_to_data()
virtual unsigned int val2buf(void *val, bool reuse=false)
Reads data into the Vector buffer.
virtual bool set_value(const string &value)
Array * get_array()
Returns the Grid Array. This method returns the array using an Array*, so no cast is required...
std::vector< BaseType * >::iterator Map_iter
double extract_double_value(BaseType *arg)
virtual unsigned int val2buf(void *val, bool reuse=false)=0
Loads class data.
virtual BaseType * ptr_duplicate()=0
virtual int dimension_stop(Dim_iter i, bool constrained=false)
Return the stop index of the constraint.
string long_to_string(long val, int base)
Evaluate a constraint expression.
virtual dods_int32 value() const
virtual void set_send_p(bool state)
Indicates that the data is ready to send.
virtual int dimension_start(Dim_iter i, bool constrained=false)
Return the start index of a dimension.
void function_version(int, BaseType *[], DDS &, BaseType **btpp)
int get_start() const
Get the starting index of the clause's map variable as constrained by this clause.
virtual AttrTable & get_attr_table()
string remove_quotes(const string &s)
void add_function(const string &name, bool_func f)
Add a boolean function to the list.
virtual dods_uint16 value() const
The basic data type for the DODS DAP types.
virtual Grid * get_constrained_grid() const
void function_geogrid(int argc, BaseType *argv[], DDS &, BaseType **btpp)
virtual string value() const
Holds a 64-bit (double precision) floating point value.
virtual int length() const
virtual dods_float32 value() const
virtual dods_uint32 value() const
virtual bool is_simple_type()
Returns true if the instance is a numeric, string or URL type variable.
virtual bool set_value(dods_byte *val, int sz)
set the value of a byte array
A class for error processing.
Holds a 32-bit unsigned integer.
virtual Array * get_constrained_array() const
A multidimensional array of identical data types.
bool double_eq(double lhs, double rhs, double epsilon=1.0e-5)
string get_map_name() const
Get the name of the map variable constrained by this clause.
Holds a 32-bit signed integer.
virtual void apply_constraint_to_data()
virtual dods_int16 value() const