bes Updated for version 3.21.1
The Backend Server (BES) is the lower two tiers of the Hyrax data server
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 <libdap/BaseType.h>
30#include <libdap/Structure.h>
31#include <libdap/Array.h>
32#include <libdap/Int32.h>
33#include <libdap/Str.h>
34
35#include <libdap/util.h>
36
37#include "roi_util.h"
38
39using namespace libdap;
40
41namespace functions {
42
58void 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
92unsigned 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
124void 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
155Structure *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
194unique_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