OPeNDAP Hyrax Back End Server (BES)  Updated for version 3.8.3
BindNameFunction.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 <Str.h>
35 
36 #include <Error.h>
37 #include <DDS.h>
38 
39 #include <debug.h>
40 #include <util.h>
41 
42 #include <BESDebug.h>
43 
44 #include "BindNameFunction.h"
45 
46 namespace libdap {
47 
61 void
62 function_bind_name(int argc, BaseType * argv[], DDS &dds, BaseType **btpp)
63 {
64  string info =
65  string("<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n") +
66  "<function name=\"make_array\" version=\"1.0\" href=\"http://docs.opendap.org/index.php/Server_Side_Processing_Functions#bind_name\">\n" +
67  "</function>";
68 
69  if (argc == 0) {
70  Str *response = new Str("info");
71  response->set_value(info);
72  *btpp = response;
73  return;
74  }
75 
76  // Check for two args or more. The first two must be strings.
77  if (argc != 2)
78  throw Error(malformed_expr, "bind_name(name,variable) requires two arguments.");
79 
80  // Don't allow renaming that will introduce namespace collisions.
81  //
82  // Check the DDS to see if a variable with name given as argv[0] already exists. If
83  // so, return an error. This is complicated somewhat because the CE Evaluator will
84  // have already looked and, if the string passed into the function matches a variable,
85  // replaced that string with a BaseType* to the (already existing) variable. If not,
86  // the CE Evaluator will make a DAP String variable with a value that is the string
87  // passed into the function. So, either way argv[0] is a BaseType*. However, if it's
88  // a variable in the dataset, its name() will be found by DDS::var().
89  if (dds.var(argv[0]->name()))
90  throw Error(malformed_expr, "The name '" + argv[0]->name() + "' is already in use.");
91 
92  string name = extract_string_argument(argv[0]);
93 
94  // If the variable is the return value of a function, just pass it back. If it is
95  // a variable in the dataset (i.e., present in the DDS), copy it because DDS deletes
96  // all its variables and the function processing code also deletes all it's variables.
97  // NB: Could use reference counting pointers to eliminate this copy... jhrg 6/24/13
98  if (dds.var(argv[1]->name())) {
99  *btpp = argv[1]->ptr_duplicate();
100  if (!(*btpp)->read_p()) {
101  (*btpp)->read();
102  (*btpp)->set_read_p(true);
103  }
104  (*btpp)->set_send_p(true);
105  (*btpp)->set_name(name);
106  }
107  else {
108  argv[1]->set_name(name);
109 
110  *btpp = argv[1];
111  }
112 
113  return;
114 }
115 
116 } // namesspace libdap
void function_bind_name(int argc, BaseType *argv[], DDS &dds, BaseType **btpp)
Bind a new name to a variable.