bes  Updated for version 3.20.6
BindShapeFunction.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) 2013 OPeNDAP, Inc.
7 // Authors: 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 <cassert>
28 
29 #include <sstream>
30 #include <vector>
31 
32 #include <BaseType.h>
33 #include <Array.h>
34 #include <Str.h>
35 
36 #include <Error.h>
37 #include <DDS.h>
38 #include <DMR.h>
39 #include <D4RValue.h>
40 #include <D4Dimensions.h>
41 #include <debug.h>
42 #include <util.h>
43 
44 #include <BESDebug.h>
45 
46 #include "BindNameFunction.h"
47 
48 using namespace std;
49 using namespace libdap;
50 
51 namespace functions {
52 
53 string bind_shape_info =
54  string("<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n")
55  + "<function name=\"make_array\" version=\"1.0\" href=\"http://docs.opendap.org/index.php/Server_Side_Processing_Functions#bind_shape\">\n"
56  + "</function>";
57 
58 vector<int> parse_dims(const string &shape); // defined in MakeArrayFunction.cc
59 
60 BaseType *bind_shape_worker(string shape, BaseType *btp)
61 {
62  // string shape = extract_string_argument(argv[0]);
63  vector<int> dims = parse_dims(shape);
64 
65  Array *array = dynamic_cast<Array*>(btp);
66  if (!array) throw Error(malformed_expr, "bind_shape() requires an Array as its second argument.");
67 
68  unsigned long vector_size = array->length();
69  DBG(cerr << "bind_shape_worker() - vector_size: " << long_to_string(vector_size) << endl);
70 
71  array->clear_all_dims();
72 
73  unsigned long number_of_elements = 1;
74  vector<int>::iterator i = dims.begin();
75  while (i != dims.end()) {
76  int dimSize = *i;
77  number_of_elements *= dimSize;
78  if (array->is_dap4()) {
79  DBG(cerr << "bind_shape_worker() - Adding DAP4 dimension." << endl);
80 
81  // FIXME - I think this creates a memory leak because
82  // the D4Dimension will never be deleted by the
83  // current implementation of Array which only has a
84  // weak pointer to the D4Dimension.
85  //
86  // NB: The likely fix is to find the Group that holds
87  // this variable and add the new D4Dimension to its
88  // D4Dimensions object. That will enure it is
89  // deleted. jhrg 8/26/14
90  D4Dimension *this_dim = new D4Dimension("", dimSize);
91  array->append_dim(this_dim);
92  }
93  else {
94  DBG(cerr << "bind_shape_worker() - Adding DAP2 dimension." << endl);
95  array->append_dim(dimSize);
96  }
97  i++;
98  } DBG(cerr << "bind_shape_worker() - number_of_elements: " << long_to_string(number_of_elements) << endl);
99 
100  if (number_of_elements != vector_size)
101  throw Error(malformed_expr,
102  "bind_shape(): The product of the new dimensions must match the size of the Array's internal storage vector.");
103 
104  return array;
105 }
106 
121 void function_bind_shape_dap2(int argc, BaseType * argv[], DDS &, BaseType **btpp)
122 {
123  if (argc == 0) {
124  Str *response = new Str("info");
125  response->set_value(bind_shape_info);
126  *btpp = response;
127  return;
128  }
129 
130  // Check for two args or more. The first two must be strings.
131  if (argc != 2) throw Error(malformed_expr, "bind_shape(shape,variable) requires two arguments.");
132 
133  string shape = extract_string_argument(argv[0]);
134 
135  BaseType *btp = argv[1];
136 
137  *btpp = bind_shape_worker(shape, btp);
138 
139  return;
140 }
141 
156 BaseType *function_bind_shape_dap4(D4RValueList *args, DMR &dmr)
157 {
158  // DAP4 function porting information: in place of 'argc' use 'args.size()'
159  if (args == 0 || args->size() == 0) {
160  Str *response = new Str("info");
161  response->set_value(bind_shape_info);
162  // DAP4 function porting: return a BaseType* instead of using the value-result parameter
163  return response;
164  }
165 
166  // Check for 2 arguments
167  DBG(cerr << "args.size() = " << args.size() << endl);
168  if (args->size() != 2) throw Error(malformed_expr, "bind_shape(shape,variable) requires two arguments.");
169 
170  string shape = extract_string_argument(args->get_rvalue(0)->value(dmr));
171 
172  BaseType *btp = args->get_rvalue(1)->value(dmr);
173 
174  return bind_shape_worker(shape, btp);
175 }
176 
177 } // namesspace functions
libdap
Definition: BESDapFunctionResponseCache.h:35
Error