libdap  Updated for version 3.20.6
libdap4 is an implementation of OPeNDAP's DAP protocol.
grid_utils.cc
1 // -*- mode: c++; c-basic-offset:4 -*-
2 
3 // This file is part of libdap, A C++ implementation of the OPeNDAP Data
4 // Access Protocol.
5 
6 // Copyright (c) 2002,2003 OPeNDAP, Inc.
7 // Author: Nathan Potter <npotter@opendap.org>
8 //
9 // This library is free software; you can redistribute it and/or
10 // modify it under the terms of the GNU Lesser General Public
11 // License as published by the Free Software Foundation; either
12 // version 2.1 of the License, or (at your option) any later version.
13 //
14 // This library is distributed in the hope that it will be useful,
15 // but WITHOUT ANY WARRANTY; without even the implied warranty of
16 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
17 // Lesser General Public License for more details.
18 //
19 // You should have received a copy of the GNU Lesser General Public
20 // License along with this library; if not, write to the Free Software
21 // Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
22 //
23 // You can contact OPeNDAP, Inc. at PO Box 112, Saunderstown, RI. 02874-0112.
24 
25 #include "config.h"
26 
27 #include <BaseType.h>
28 #include <Structure.h>
29 #include <Grid.h>
30 #include <util.h>
31 
32 #include <debug.h>
33 
34 #include "grid_utils.h"
35 #include "gse_parser.h"
36 #include "GSEClause.h"
37 
38 #if 0
39 #include "GridGeoConstraint.h"
40 #endif
41 
42 using namespace libdap;
43 
44 int gse_parse(functions::gse_arg *arg);
45 void gse_restart(FILE * in);
46 
47 // Glue routines declared in gse.lex
48 void gse_delete_buffer(void *buffer);
49 void *gse_string(const char *yy_str);
50 
51 namespace functions {
52 
59 void get_grids(BaseType *bt, vector<Grid *> *grids)
60 {
61  switch (bt->type()) {
62 
63  case dods_grid_c: {
64  // Yay! It's a Grid!
65  grids->push_back(static_cast<Grid*>(bt));
66  break;
67  }
68  case dods_structure_c: {
69  // It's an Structure - but of what? Check each variable in the Structure.
70  Structure &s = static_cast<Structure&>(*bt);
71  for (Structure::Vars_iter i = s.var_begin(); i != s.var_begin(); i++) {
72  get_grids(*i, grids);
73  }
74  break;
75  }
76  // Grids cannot be members of Array or Sequence in DAP2. jhrg 6/10/13
77  case dods_array_c:
78  case dods_sequence_c:
79  default:
80  break;
81  }
82 }
83 
90 void get_grids(DDS &dds, vector<Grid *> *grids)
91 {
92  for (DDS::Vars_iter i = dds.var_begin(); i != dds.var_end(); i++) {
93  get_grids(*i, grids);
94  }
95 }
96 
97 #if 0
98 
99 // Hacked this out of the code to get prototype value-based subsetting
100 // into the code. We might add it back later (or maybe there is a better
101 // place? jhrg 4/18/19
102 
112 bool is_geo_grid(Grid *grid)
113 {
114  try {
115  GridGeoConstraint gc(grid);
116  }
117  catch (Error *e) {
118  return false;
119  }
120 
121  return true;
122 }
123 #endif
124 
125 void parse_gse_expression(gse_arg *arg, BaseType *expr)
126 {
127  gse_restart(0); // Restart the scanner.
128  void *cls = gse_string(extract_string_argument(expr).c_str());
129  // gse_switch_to_buffer(cls); // Get set to scan the string.
130  bool status = gse_parse(arg) == 0;
131  gse_delete_buffer(cls);
132  if (!status)
133  throw Error(malformed_expr, "Error parsing grid selection.");
134 }
135 
136 static void apply_grid_selection_expr(Grid *grid, GSEClause *clause)
137 {
138  // Basic plan: For each map, look at each clause and set start and stop
139  // to be the intersection of the ranges in those clauses.
140  Grid::Map_iter map_i = grid->map_begin();
141  while (map_i != grid->map_end() && (*map_i)->name() != clause->get_map_name())
142  ++map_i;
143 
144  if (map_i == grid->map_end())
145  throw Error(malformed_expr,"The map vector '" + clause->get_map_name()
146  + "' is not in the grid '" + grid->name() + "'.");
147 
148  // Use pointer arith & the rule that map order must match array dim order
149  Array::Dim_iter grid_dim = (grid->get_array()->dim_begin() + (map_i - grid->map_begin()));
150 
151  Array *map = dynamic_cast < Array * >((*map_i));
152  if (!map)
153  throw InternalErr(__FILE__, __LINE__, "Expected an Array");
154  int start = max(map->dimension_start(map->dim_begin()), clause->get_start());
155  int stop = min(map->dimension_stop(map->dim_begin()), clause->get_stop());
156 
157  if (start > stop) {
158  ostringstream msg;
159  msg
160  << "The expressions passed to grid() do not result in an inclusive \n"
161  << "subset of '" << clause->get_map_name()
162  << "'. The map's values range " << "from "
163  << clause->get_map_min_value() << " to "
164  << clause->get_map_max_value() << ".";
165  throw Error(malformed_expr,msg.str());
166  }
167 
168  DBG(cerr << "Setting constraint on " << map->name() << "[" << start << ":" << stop << "]" << endl);
169 
170  // Stride is always one.
171  map->add_constraint(map->dim_begin(), start, 1, stop);
172  grid->get_array()->add_constraint(grid_dim, start, 1, stop);
173 }
174 
175 void apply_grid_selection_expressions(Grid * grid, vector < GSEClause * >clauses)
176 {
177  vector < GSEClause * >::iterator clause_i = clauses.begin();
178  while (clause_i != clauses.end())
179  apply_grid_selection_expr(grid, *clause_i++);
180 
181  grid->set_read_p(false);
182 }
183 
184 } //namespace libdap
virtual void add_constraint(Dim_iter i, int start, int stride, int stop)
Adds a constraint to an Array dimension.
Definition: Array.cc:647
virtual string name() const
Returns the name of the class instance.
Definition: BaseType.cc:320
Vars_iter var_begin()
Return an iterator to the first variable.
Definition: DDS.cc:799
string extract_string_argument(BaseType *arg)
Definition: util.cc:119
Map_iter map_end()
Definition: Grid.cc:537
Holds a structure (aggregate) type.
Definition: Structure.h:83
top level DAP object to house generic methods
Definition: AISConnect.cc:30
A class for software fault reporting.
Definition: InternalErr.h:64
Map_iter map_begin()
Returns an iterator referencing the first Map vector.
Definition: Grid.cc:525
virtual Type type() const
Returns the type of the class instance.
Definition: BaseType.cc:365
std::vector< dimension >::iterator Dim_iter
Definition: Array.h:206
Holds the Grid data type.
Definition: Grid.h:122
Array * get_array()
Returns the Grid Array. This method returns the array using an Array*, so no cast is required...
Definition: Grid.cc:518
virtual int dimension_stop(Dim_iter i, bool constrained=false)
Return the stop index of the constraint.
Definition: Array.cc:788
Vars_iter var_end()
Return an iterator.
Definition: DDS.cc:811
virtual int dimension_start(Dim_iter i, bool constrained=false)
Return the start index of a dimension.
Definition: Array.cc:765
The basic data type for the DODS DAP types.
Definition: BaseType.h:117
Dim_iter dim_begin()
Definition: Array.cc:690
Vars_iter var_begin()
Definition: Constructor.cc:356
A class for error processing.
Definition: Error.h:92
A multidimensional array of identical data types.
Definition: Array.h:112
virtual void set_read_p(bool state)
Sets the value of the read_p property.
Definition: Constructor.cc:218