bes  Updated for version 3.20.6
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 <BESDebug.h>
33 
34 #include "grid_utils.h"
35 #include "gse_parser.h"
36 #include "GSEClause.h"
37 #include "GridGeoConstraint.h"
38 
39 using namespace libdap;
40 
41 int gse_parse(functions::gse_arg *arg);
42 void gse_restart(FILE * in);
43 
44 // Glue routines declared in gse.lex
45 void gse_delete_buffer(void *buffer);
46 void *gse_string(const char *yy_str);
47 
48 namespace functions {
49 
56 void get_grids(BaseType *bt, vector<Grid *> *grids)
57 {
58  switch (bt->type()) {
59 
60  case dods_grid_c: {
61  // Yay! It's a Grid!
62  grids->push_back(static_cast<Grid*>(bt));
63  break;
64  }
65  case dods_structure_c: {
66  // It's an Structure - but of what? Check each variable in the Structure.
67  Structure &s = static_cast<Structure&>(*bt);
68  for (Structure::Vars_iter i = s.var_begin(); i != s.var_begin(); i++) {
69  get_grids(*i, grids);
70  }
71  break;
72  }
73  // Grids cannot be members of Array or Sequence in DAP2. jhrg 6/10/13
74  case dods_array_c:
75  case dods_sequence_c:
76  default:
77  break;
78  }
79 }
80 
87 void get_grids(DDS &dds, vector<Grid *> *grids)
88 {
89  for (DDS::Vars_iter i = dds.var_begin(); i != dds.var_end(); i++) {
90  get_grids(*i, grids);
91  }
92 }
93 
103 bool is_geo_grid(Grid *grid)
104 {
105  try {
106  GridGeoConstraint gc(grid);
107  }
108  catch (Error *e) {
109  return false;
110  }
111 
112  return true;
113 }
114 
115 void parse_gse_expression(gse_arg *arg, BaseType *expr)
116 {
117  gse_restart(0); // Restart the scanner.
118  void *cls = gse_string(extract_string_argument(expr).c_str());
119  // gse_switch_to_buffer(cls); // Get set to scan the string.
120  bool status = gse_parse(arg) == 0;
121  gse_delete_buffer(cls);
122  if (!status)
123  throw Error(malformed_expr, "Error parsing grid selection.");
124 }
125 
126 static void apply_grid_selection_expr(Grid *grid, GSEClause *clause)
127 {
128  // Basic plan: For each map, look at each clause and set start and stop
129  // to be the intersection of the ranges in those clauses.
130  Grid::Map_iter map_i = grid->map_begin();
131  while (map_i != grid->map_end() && (*map_i)->name() != clause->get_map_name())
132  ++map_i;
133 
134  if (map_i == grid->map_end())
135  throw Error(malformed_expr,"The map vector '" + clause->get_map_name()
136  + "' is not in the grid '" + grid->name() + "'.");
137 
138  // Use pointer arith & the rule that map order must match array dim order
139  Array::Dim_iter grid_dim = (grid->get_array()->dim_begin() + (map_i - grid->map_begin()));
140 
141  Array *map = dynamic_cast < Array * >((*map_i));
142  if (!map)
143  throw InternalErr(__FILE__, __LINE__, "Expected an Array");
144  int start = max(map->dimension_start(map->dim_begin()), clause->get_start());
145  int stop = min(map->dimension_stop(map->dim_begin()), clause->get_stop());
146 
147  if (start > stop) {
148  ostringstream msg;
149  msg
150  << "The expressions passed to grid() do not result in an inclusive \n"
151  << "subset of '" << clause->get_map_name()
152  << "'. The map's values range " << "from "
153  << clause->get_map_min_value() << " to "
154  << clause->get_map_max_value() << ".";
155  throw Error(malformed_expr,msg.str());
156  }
157 
158  BESDEBUG("GeoGrid", "Setting constraint on " << map->name() << "[" << start << ":" << stop << "]" << endl);
159 
160  // Stride is always one.
161  map->add_constraint(map->dim_begin(), start, 1, stop);
162  grid->get_array()->add_constraint(grid_dim, start, 1, stop);
163 }
164 
165 void apply_grid_selection_expressions(Grid * grid, vector < GSEClause * >clauses)
166 {
167  vector < GSEClause * >::iterator clause_i = clauses.begin();
168  while (clause_i != clauses.end())
169  apply_grid_selection_expr(grid, *clause_i++);
170 
171  grid->set_read_p(false);
172 }
173 
174 } //namespace libdap
functions::gse_arg
Definition: gse_parser.h:47
libdap
Definition: BESDapFunctionResponseCache.h:35
Error