OPeNDAP Hyrax Back End Server (BES)  Updated for version 3.8.3
BindShapeFunction.cc
Go to the documentation of this file.
1 
2 // -*- mode: c++; c-basic-offset:4 -*-
3 
4 // This file is part of libdap, A C++ implementation of the OPeNDAP Data
5 // Access Protocol.
6 
7 // Copyright (c) 2013 OPeNDAP, Inc.
8 // Authors: James Gallagher <jgallagher@opendap.org>
9 //
10 // This library is free software; you can redistribute it and/or
11 // modify it under the terms of the GNU Lesser General Public
12 // License as published by the Free Software Foundation; either
13 // version 2.1 of the License, or (at your option) any later version.
14 //
15 // This library is distributed in the hope that it will be useful,
16 // but WITHOUT ANY WARRANTY; without even the implied warranty of
17 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
18 // Lesser General Public License for more details.
19 //
20 // You should have received a copy of the GNU Lesser General Public
21 // License along with this library; if not, write to the Free Software
22 // Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
23 //
24 // You can contact OPeNDAP, Inc. at PO Box 112, Saunderstown, RI. 02874-0112.
25 
26 #include "config.h"
27 
28 #include <cassert>
29 
30 #include <sstream>
31 #include <vector>
32 
33 #include <BaseType.h>
34 #include <Array.h>
35 #include <Str.h>
36 
37 #include <Error.h>
38 #include <DDS.h>
39 #include <DMR.h>
40 #include <D4RValue.h>
41 #include <D4Dimensions.h>
42 #include <debug.h>
43 #include <util.h>
44 
45 #include <BESDebug.h>
46 
47 #include "BindNameFunction.h"
48 
49 namespace libdap {
51 string("<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n") +
52 "<function name=\"make_array\" version=\"1.0\" href=\"http://docs.opendap.org/index.php/Server_Side_Processing_Functions#bind_shape\">\n" +
53 "</function>";
54 
55 
56 vector<int> parse_dims(const string &shape); // defined in MakeArrayFunction.cc
57 
58 
59 BaseType *bind_shape_worker(string shape, BaseType *btp){
60 
61  // string shape = extract_string_argument(argv[0]);
62  vector<int> dims = parse_dims(shape);
63 
64  Array *array = dynamic_cast<Array*>(btp);
65  if (!array)
66  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 
72  array->clear_all_dims();
73 
74  unsigned long number_of_elements = 1;
75  vector<int>::iterator i = dims.begin();
76  while (i != dims.end()) {
77  int dimSize = *i;
78  number_of_elements *= dimSize;
79  if(array->is_dap4()){
80  DBG(cerr << "bind_shape_worker() - Adding DAP4 dimension." << endl);
81 
82  // FIXME - I think this creates a memory leak because
83  // the D4Dimension will never be deleted by the
84  // current implementation of Array which only has a
85  // weak pointer to the D4Dimension.
86  //
87  // NB: The likely fix is to find the Group that holds
88  // this variable and add the new D4Dimension to its
89  // D4Dimensions object. That will enure it is
90  // deleted. jhrg 8/26/14
91  D4Dimension *this_dim = new D4Dimension("",dimSize);
92  array->append_dim(this_dim);
93  }
94  else
95  {
96  DBG(cerr << "bind_shape_worker() - Adding DAP2 dimension." << endl);
97  array->append_dim(dimSize);
98  }
99  i++;
100  }
101  DBG(cerr << "bind_shape_worker() - number_of_elements: " << long_to_string(number_of_elements) << endl);
102 
103  if (number_of_elements != vector_size)
104  throw Error(malformed_expr, "bind_shape(): The product of the new dimensions must match the size of the Array's internal storage vector.");
105 
106 
107  return array;
108 
109 
110 }
111 
126 void
127 function_bind_shape_dap2(int argc, BaseType * argv[], DDS &, BaseType **btpp)
128 {
129 
130  if (argc == 0) {
131  Str *response = new Str("info");
132  response->set_value(bind_shape_info);
133  *btpp = response;
134  return;
135  }
136 
137  // Check for two args or more. The first two must be strings.
138  if (argc != 2)
139  throw Error(malformed_expr, "bind_shape(shape,variable) requires two arguments.");
140 
141  string shape = extract_string_argument(argv[0]);
142 
143  BaseType *btp = argv[1];
144 
145  *btpp = bind_shape_worker(shape, btp);
146 
147  return;
148 }
149 
164 BaseType *function_bind_shape_dap4(D4RValueList *args, DMR &dmr){
165 
166 
167  // DAP4 function porting information: in place of 'argc' use 'args.size()'
168  if (args == 0 || args->size() == 0) {
169  Str *response = new Str("info");
170  response->set_value(bind_shape_info);
171  // DAP4 function porting: return a BaseType* instead of using the value-result parameter
172  return response;
173  }
174 
175 
176  // Check for 2 arguments
177  DBG(cerr << "args.size() = " << args.size() << endl);
178  if (args->size() != 2)
179  throw Error(malformed_expr,"bind_shape(shape,variable) requires two arguments.");
180 
181  string shape = extract_string_argument(args->get_rvalue(0)->value(dmr));
182 
183  BaseType *btp = args->get_rvalue(1)->value(dmr);
184 
185  return bind_shape_worker(shape, btp);
186 
187 }
188 
189 
190 } // namesspace libdap
BaseType * function_bind_shape_dap4(D4RValueList *args, DMR &dmr)
Bind a shape to a DAP4 Array that is a vector.
vector< int > parse_dims(const string &shape)
Parse the shape 'expression'.
BaseType * bind_shape_worker(string shape, BaseType *btp)
static class NCMLUtil overview
string bind_shape_info
void function_bind_shape_dap2(int argc, BaseType *argv[], DDS &, BaseType **btpp)
Bind a shape to a DAP2 Array that is a vector.