bes  Updated for version 3.20.6
roi_util.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) 2015 OPeNDAP, Inc.
7 // Author: James Gallagher <jgallagher@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 <memory>
28 
29 #include <BaseType.h>
30 #include <Structure.h>
31 #include <Array.h>
32 #include <Int32.h>
33 #include <Str.h>
34 
35 #include <util.h>
36 
37 #include "roi_util.h"
38 
39 using namespace libdap;
40 
41 namespace functions {
42 
58 void roi_bbox_valid_slice(BaseType *btp)
59 {
60  // we know it's a Structure * and it has one element because the test above passed
61  if (btp->type() != dods_structure_c)
62  throw Error("In function roi(): Expected an Array of Structures for the slice information.");
63 
64  Structure *slice = static_cast<Structure*>(btp);
65 
66  Constructor::Vars_iter i = slice->var_begin();
67  if (i == slice->var_end() || (*i)->name() != "start" || (*i)->type() != dods_int32_c)
68  throw Error("In function roi(): Could not find valid 'start' field in slice information");
69 
70  ++i;
71  if (i == slice->var_end() || (*i)->name() != "stop" || (*i)->type() != dods_int32_c)
72  throw Error("In function roi(): Could not find valid 'stop' field in slice information");
73 
74  ++i;
75  if (i == slice->var_end() || (*i)->name() != "name" || (*i)->type() != dods_str_c)
76  throw Error("In function roi(): Could not find valid 'name' field in slice information");
77 }
78 
92 unsigned int roi_valid_bbox(BaseType *btp)
93 {
94  if (!btp)
95  throw InternalErr(__FILE__, __LINE__, "Function called with null slice array.");
96 
97  if (btp->type() != dods_array_c)
98  throw Error("Function expected last argument to be a Bounding Box (i.e., an Array of Structures) (1).");
99 
100  Array *slices = static_cast<Array*>(btp);
101  if (slices->dimensions() != 1)
102  throw Error("Function expected last argument to be a Bounding Box (i.e., an Array of Structures) (2).");
103 
104  int rank = slices->dimension_size(slices->dim_begin());
105  for (int i = 0; i < rank; ++i) {
106  roi_bbox_valid_slice(slices->var(i));
107  }
108 
109  return rank;
110 }
111 
124 void roi_bbox_get_slice_data(Array *slices, unsigned int i, int &start, int &stop, string &name)
125 {
126  BaseType *btp = slices->var(i);
127 
128  Structure *slice = static_cast<Structure*>(btp);
129  Constructor::Vars_iter vi = slice->var_begin();
130 
131  start = static_cast<Int32*>(*vi++)->value();
132  stop = static_cast<Int32*>(*vi++)->value();
133  name = static_cast<Str*>(*vi++)->value();
134 }
135 
155 Structure *roi_bbox_build_slice(unsigned int start_value, unsigned int stop_value, const string &dim_name)
156 {
157  Structure *slice = new Structure("slice"); // This name is superfluous
158 
159  Int32 *start = new Int32("start");
160  start->set_value(start_value);
161  slice->add_var_nocopy(start);
162 
163  Int32 *stop = new Int32("stop");
164  stop->set_value(stop_value);
165  slice->add_var_nocopy(stop);
166 
167  Str *name = new Str("name");
168  name->set_value(dim_name);
169  slice->add_var_nocopy(name);
170 
171  slice->set_read_p(true); // Sets all children too, as does set_send_p()
172  slice->set_send_p(true);
173 
174  return slice;
175 }
176 
194 unique_ptr<Array> roi_bbox_build_empty_bbox(unsigned int num_dim, const string &bbox_name)
195 {
196  // Build the Structure and load it with the needed fields. The
197  // Array instances will have the same fields, but each instance
198  // will also be loaded with values.
199  Structure *proto = new Structure(bbox_name);
200  proto->add_var_nocopy(new Int32("start"));
201  proto->add_var_nocopy(new Int32("stop"));
202  proto->add_var_nocopy(new Str("name"));
203  // Using auto_ptr and not unique_ptr because of OS/X 10.7. jhrg 2/24/15
204  // using unique_ptr because auto_ptr deprecated. sbl 1.2.20
205  unique_ptr<Array> response(new Array(bbox_name, proto));
206 
207  response->append_dim(num_dim, bbox_name);
208 
209  return response;
210 }
211 
212 } //namespace functions
libdap
Definition: BESDapFunctionResponseCache.h:35
Error