|
Packit |
a4aae4 |
// ServerFunctionsList.cc
|
|
Packit |
a4aae4 |
|
|
Packit |
a4aae4 |
// This file is part of bes, A C++ back-end server implementation framework
|
|
Packit |
a4aae4 |
// for the OPeNDAP Data Access Protocol.
|
|
Packit |
a4aae4 |
|
|
Packit |
a4aae4 |
// Copyright (c) 2013 OPeNDAP, Inc.
|
|
Packit |
a4aae4 |
// Author: James Gallagher <jgallagher@opendap.org>
|
|
Packit |
a4aae4 |
//
|
|
Packit |
a4aae4 |
// This library is free software; you can redistribute it and/or
|
|
Packit |
a4aae4 |
// modify it under the terms of the GNU Lesser General Public
|
|
Packit |
a4aae4 |
// License as published by the Free Software Foundation; either
|
|
Packit |
a4aae4 |
// version 2.1 of the License, or (at your option) any later version.
|
|
Packit |
a4aae4 |
//
|
|
Packit |
a4aae4 |
// This library is distributed in the hope that it will be useful,
|
|
Packit |
a4aae4 |
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
Packit |
a4aae4 |
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
|
Packit |
a4aae4 |
// Lesser General Public License for more details.
|
|
Packit |
a4aae4 |
//
|
|
Packit |
a4aae4 |
// You should have received a copy of the GNU Lesser General Public
|
|
Packit |
a4aae4 |
// License along with this library; if not, write to the Free Software
|
|
Packit |
a4aae4 |
// Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
|
Packit |
a4aae4 |
//
|
|
Packit |
a4aae4 |
// You can contact OPeNDAP, Inc. at PO Box 112, Saunderstown, RI. 02874-0112.
|
|
Packit |
a4aae4 |
|
|
Packit |
a4aae4 |
#include "config.h"
|
|
Packit |
a4aae4 |
|
|
Packit |
a4aae4 |
#ifdef HAVE_STDLIB_H
|
|
Packit |
a4aae4 |
#include <stdlib.h>
|
|
Packit |
a4aae4 |
#endif
|
|
Packit |
a4aae4 |
|
|
Packit |
a4aae4 |
#include <pthread.h>
|
|
Packit |
a4aae4 |
|
|
Packit |
a4aae4 |
#include <iostream>
|
|
Packit |
a4aae4 |
#include <algorithm>
|
|
Packit |
a4aae4 |
|
|
Packit |
a4aae4 |
//#define DODS_DEBUG
|
|
Packit |
a4aae4 |
|
|
Packit |
a4aae4 |
#include <expr.h>
|
|
Packit |
a4aae4 |
#include "debug.h"
|
|
Packit |
a4aae4 |
|
|
Packit |
a4aae4 |
#include "ServerFunctionsList.h"
|
|
Packit |
a4aae4 |
|
|
Packit |
a4aae4 |
using namespace std;
|
|
Packit |
a4aae4 |
using namespace libdap;
|
|
Packit |
a4aae4 |
|
|
Packit |
a4aae4 |
namespace libdap {
|
|
Packit |
a4aae4 |
|
|
Packit |
a4aae4 |
static pthread_once_t ServerFunctionsList_instance_control = PTHREAD_ONCE_INIT;
|
|
Packit |
a4aae4 |
|
|
Packit |
a4aae4 |
ServerFunctionsList *ServerFunctionsList::d_instance = 0 ;
|
|
Packit |
a4aae4 |
|
|
Packit |
a4aae4 |
/**
|
|
Packit |
a4aae4 |
* private static that only gets called once in the life cycle of the process.
|
|
Packit |
a4aae4 |
*/
|
|
Packit |
a4aae4 |
void ServerFunctionsList::initialize_instance() {
|
|
Packit |
a4aae4 |
if (d_instance == 0) {
|
|
Packit |
a4aae4 |
DBG(cerr << "ServerFunctionsList::initialize_instance() - Creating singleton ServerFunctionList instance." << endl);
|
|
Packit |
a4aae4 |
d_instance = new ServerFunctionsList;
|
|
Packit |
a4aae4 |
#if HAVE_ATEXIT
|
|
Packit |
a4aae4 |
atexit(delete_instance);
|
|
Packit |
a4aae4 |
#endif
|
|
Packit |
a4aae4 |
}
|
|
Packit |
a4aae4 |
}
|
|
Packit |
a4aae4 |
|
|
Packit |
a4aae4 |
/**
|
|
Packit |
a4aae4 |
* Private static function can only be called by friends andf pThreads code.
|
|
Packit |
a4aae4 |
*/
|
|
Packit |
a4aae4 |
void ServerFunctionsList::delete_instance() {
|
|
Packit |
a4aae4 |
DBG(cerr << "ServerFunctionsList::delete_instance() - Deleting singleton ServerFunctionList instance." << endl);
|
|
Packit |
a4aae4 |
delete d_instance;
|
|
Packit |
a4aae4 |
d_instance = 0;
|
|
Packit |
a4aae4 |
}
|
|
Packit |
a4aae4 |
|
|
Packit |
a4aae4 |
/**
|
|
Packit |
a4aae4 |
* Private method insures that nobody can try to delete the singleton class.
|
|
Packit |
a4aae4 |
*/
|
|
Packit |
a4aae4 |
|
|
Packit |
a4aae4 |
ServerFunctionsList::~ServerFunctionsList() {
|
|
Packit |
a4aae4 |
SFLIter fit;
|
|
Packit |
a4aae4 |
for(fit=d_func_list.begin(); fit!=d_func_list.end() ; fit++){
|
|
Packit |
a4aae4 |
ServerFunction *func = fit->second;
|
|
Packit |
a4aae4 |
DBG(cerr << "ServerFunctionsList::~ServerFunctionsList() - Deleting ServerFunction " << func->getName() << " from ServerFunctionsList." << endl);
|
|
Packit |
a4aae4 |
delete func;
|
|
Packit |
a4aae4 |
}
|
|
Packit |
a4aae4 |
d_func_list.clear();
|
|
Packit |
a4aae4 |
}
|
|
Packit |
a4aae4 |
|
|
Packit |
a4aae4 |
ServerFunctionsList * ServerFunctionsList::TheList() {
|
|
Packit |
a4aae4 |
pthread_once(&ServerFunctionsList_instance_control, initialize_instance);
|
|
Packit |
a4aae4 |
DBG(cerr << "ServerFunctionsList::TheList() - Returning singleton ServerFunctionList instance." << endl);
|
|
Packit |
a4aae4 |
return d_instance;
|
|
Packit |
a4aae4 |
}
|
|
Packit |
a4aae4 |
|
|
Packit |
a4aae4 |
/**
|
|
Packit |
a4aae4 |
* Adds the passed ServerFunction pointer to the list of ServerFunctions using
|
|
Packit |
a4aae4 |
* the value of ServerFunction.getName() as the key in the list.
|
|
Packit |
a4aae4 |
*
|
|
Packit |
a4aae4 |
* @brief Adds the passed ServerFunction pointer to the list of ServerFunctions.
|
|
Packit |
a4aae4 |
* @param *func A pointer to the ServerFunction object to add to the ServerFunctionList.
|
|
Packit |
a4aae4 |
* The pointer is copied, not the object referenced; this class does not
|
|
Packit |
a4aae4 |
* delete the pointer.
|
|
Packit |
a4aae4 |
*/
|
|
Packit |
a4aae4 |
void ServerFunctionsList::add_function(ServerFunction *func )
|
|
Packit |
a4aae4 |
{
|
|
Packit |
a4aae4 |
DBG(cerr << "ServerFunctionsList::add_function() - Adding ServerFunction " << func->getName() << endl);
|
|
Packit |
a4aae4 |
d_func_list.insert(std::make_pair(func->getName(),func));
|
|
Packit |
a4aae4 |
}
|
|
Packit |
a4aae4 |
|
|
Packit |
a4aae4 |
/**
|
|
Packit |
a4aae4 |
* Returns the first boolean function in the list whose key value matches the passed string name.
|
|
Packit |
a4aae4 |
* When a match is found the function returns true and sets returned value parameter *f to
|
|
Packit |
a4aae4 |
* the boolean function held by the ServerFunction object extracted from the list.
|
|
Packit |
a4aae4 |
*
|
|
Packit |
a4aae4 |
* Method:
|
|
Packit |
a4aae4 |
* Looks through the list of ServerFunctions and compares each function's key value (which
|
|
Packit |
a4aae4 |
* would be the value of SurverFunction.getName()) with the value of the string parameter
|
|
Packit |
a4aae4 |
* 'name'. When they match then the returned value parameter is set to the value returned
|
|
Packit |
a4aae4 |
* by ServerFunction.get_btp_func(). If the ServerFunction _is not_ a instance of a boolean
|
|
Packit |
a4aae4 |
* function then the return value will be 0 (null) and the search for matching function will continue.
|
|
Packit |
a4aae4 |
* If the ServerFunction _is_ a boolean function then the returned value will be non-zero and
|
|
Packit |
a4aae4 |
* the search will return true (it found the thing) and the returned value parameter *f will have
|
|
Packit |
a4aae4 |
* it's value set to the boolean function.
|
|
Packit |
a4aae4 |
*
|
|
Packit |
a4aae4 |
* @brief Find a boolean function with a given name in the function list.
|
|
Packit |
a4aae4 |
* @param name A string containing the name of the function to find.
|
|
Packit |
a4aae4 |
* @param *f A returned value parameter through which a point to the desired function is returned.
|
|
Packit |
a4aae4 |
*
|
|
Packit |
a4aae4 |
*/
|
|
Packit |
a4aae4 |
bool ServerFunctionsList::find_function(const std::string &name, bool_func *f) const
|
|
Packit |
a4aae4 |
{
|
|
Packit |
a4aae4 |
if (d_func_list.empty())
|
|
Packit |
a4aae4 |
return false;
|
|
Packit |
a4aae4 |
|
|
Packit |
a4aae4 |
std::pair <SFLCIter, SFLCIter> ret;
|
|
Packit |
a4aae4 |
ret = d_func_list.equal_range(name);
|
|
Packit |
a4aae4 |
for (SFLCIter it = ret.first; it != ret.second; ++it) {
|
|
Packit |
a4aae4 |
if (name == it->first && (*f = it->second->get_bool_func())){
|
|
Packit |
a4aae4 |
DBG(cerr << "ServerFunctionsList::find_function() - Found boolean function " << it->second->getName() << endl);
|
|
Packit |
a4aae4 |
return true;
|
|
Packit |
a4aae4 |
}
|
|
Packit |
a4aae4 |
}
|
|
Packit |
a4aae4 |
|
|
Packit |
a4aae4 |
return false;
|
|
Packit |
a4aae4 |
}
|
|
Packit |
a4aae4 |
|
|
Packit |
a4aae4 |
/**
|
|
Packit |
a4aae4 |
* Returns the first BaseType function in the list whose key value matches the passed string name.
|
|
Packit |
a4aae4 |
* When a match is found the function returns true and sets returned value parameter *f to
|
|
Packit |
a4aae4 |
* the BaseType function held by the ServerFunction object extracted from the list.
|
|
Packit |
a4aae4 |
*
|
|
Packit |
a4aae4 |
* Method:
|
|
Packit |
a4aae4 |
* Looks through the list of ServerFunctions and compares each function's key value (which
|
|
Packit |
a4aae4 |
* would be the value of SurverFunction.getName()) with the value of the string parameter
|
|
Packit |
a4aae4 |
* 'name'. When they match then the returned value parameter is set to the value returned
|
|
Packit |
a4aae4 |
* by ServerFunction.get_btp_func(). If the ServerFunction _is not_ a instance of a BaseType
|
|
Packit |
a4aae4 |
* function then the return value will be 0 (null) and the search for matching function will continue.
|
|
Packit |
a4aae4 |
* If the ServerFunction _is_ a BaseType function then the returned value will be non-zero and
|
|
Packit |
a4aae4 |
* the search will return true (it found the thing) and the returned value parameter *f will have
|
|
Packit |
a4aae4 |
* it's value set to the BaseType function.
|
|
Packit |
a4aae4 |
*
|
|
Packit |
a4aae4 |
* @brief Find a BaseType function with a given name in the function list.
|
|
Packit |
a4aae4 |
* @param name A string containing the name of the function to find.
|
|
Packit |
a4aae4 |
* @param *f A returned value parameter through which a point to the desired function is returned.
|
|
Packit |
a4aae4 |
*
|
|
Packit |
a4aae4 |
*/
|
|
Packit |
a4aae4 |
bool ServerFunctionsList::find_function(const string &name, btp_func *f) const
|
|
Packit |
a4aae4 |
{
|
|
Packit |
a4aae4 |
if (d_func_list.empty())
|
|
Packit |
a4aae4 |
return false;
|
|
Packit |
a4aae4 |
DBG(cerr << "ServerFunctionsList::find_function() - Looking for ServerFunction '" << name << "'" << endl);
|
|
Packit |
a4aae4 |
|
|
Packit |
a4aae4 |
std::pair <SFLCIter, SFLCIter> ret;
|
|
Packit |
a4aae4 |
ret = d_func_list.equal_range(name);
|
|
Packit |
a4aae4 |
for (SFLCIter it = ret.first; it != ret.second; ++it) {
|
|
Packit |
a4aae4 |
if (name == it->first && (*f = it->second->get_btp_func())){
|
|
Packit |
a4aae4 |
DBG(cerr << "ServerFunctionsList::find_function() - Found basetype function " << it->second->getName() << endl);
|
|
Packit |
a4aae4 |
return true;
|
|
Packit |
a4aae4 |
}
|
|
Packit |
a4aae4 |
}
|
|
Packit |
a4aae4 |
|
|
Packit |
a4aae4 |
return false;
|
|
Packit |
a4aae4 |
}
|
|
Packit |
a4aae4 |
|
|
Packit |
a4aae4 |
/**
|
|
Packit |
a4aae4 |
* Returns the first projection function in the list whose key value matches the passed string name.
|
|
Packit |
a4aae4 |
* When a match is found the function returns true and sets returned value parameter *f to
|
|
Packit |
a4aae4 |
* the projection function held by the ServerFunction object extracted from the list.
|
|
Packit |
a4aae4 |
*
|
|
Packit |
a4aae4 |
* Method:
|
|
Packit |
a4aae4 |
* Looks through the list of ServerFunctions and looks at each function's key value (which
|
|
Packit |
a4aae4 |
* would be the value of SurverFunction.getName() for each function). When a function has the same
|
|
Packit |
a4aae4 |
* key name as the value of the string parameter 'name', then the returned value parameter is set
|
|
Packit |
a4aae4 |
* the value returned by ServerFunction.get_proj_func(). If the ServerFunction _is not_ a projection
|
|
Packit |
a4aae4 |
* function then the return value will be 0 (null) and the search for matching function will continue.
|
|
Packit |
a4aae4 |
* If the ServerFunction _is_ a projection then the returned value will be non-zero and the search will
|
|
Packit |
a4aae4 |
* return true (it found the thing) and the returned value parameter *f will have it's value set
|
|
Packit |
a4aae4 |
* to the projection function.
|
|
Packit |
a4aae4 |
*
|
|
Packit |
a4aae4 |
* @brief Find a projection function with a given name in the function list.
|
|
Packit |
a4aae4 |
* @param name A string containing the name of the function to find.
|
|
Packit |
a4aae4 |
* @param *f A returned value parameter through which a point to the desired function is returned.
|
|
Packit |
a4aae4 |
*
|
|
Packit |
a4aae4 |
*/
|
|
Packit |
a4aae4 |
bool ServerFunctionsList::find_function(const string &name, proj_func *f) const
|
|
Packit |
a4aae4 |
{
|
|
Packit |
a4aae4 |
if (d_func_list.empty())
|
|
Packit |
a4aae4 |
return false;
|
|
Packit |
a4aae4 |
|
|
Packit |
a4aae4 |
std::pair <SFLCIter, SFLCIter> ret;
|
|
Packit |
a4aae4 |
ret = d_func_list.equal_range(name);
|
|
Packit |
a4aae4 |
for (SFLCIter it = ret.first; it != ret.second; ++it) {
|
|
Packit |
a4aae4 |
if (name == it->first && (*f = it->second->get_proj_func())){
|
|
Packit |
a4aae4 |
DBG(cerr << "ServerFunctionsList::find_function() - Found projection function " << it->second->getName() << endl);
|
|
Packit |
a4aae4 |
return true;
|
|
Packit |
a4aae4 |
}
|
|
Packit |
a4aae4 |
}
|
|
Packit |
a4aae4 |
|
|
Packit |
a4aae4 |
return false;
|
|
Packit |
a4aae4 |
}
|
|
Packit |
a4aae4 |
|
|
Packit |
a4aae4 |
/**
|
|
Packit |
a4aae4 |
* Find a DAP4 function in the Server Functions List.
|
|
Packit |
a4aae4 |
*
|
|
Packit |
a4aae4 |
* @param name Look for this function name
|
|
Packit |
a4aae4 |
* @param f Value-result parameter. NULL if the function is not found
|
|
Packit |
a4aae4 |
* @return True if the function was found, otherwise false.
|
|
Packit |
a4aae4 |
*/
|
|
Packit |
a4aae4 |
bool ServerFunctionsList::find_function(const string &name, D4Function *f) const
|
|
Packit |
a4aae4 |
{
|
|
Packit |
a4aae4 |
if (d_func_list.empty())
|
|
Packit |
a4aae4 |
return false;
|
|
Packit |
a4aae4 |
|
|
Packit |
a4aae4 |
std::pair <SFLCIter, SFLCIter> ret;
|
|
Packit |
a4aae4 |
ret = d_func_list.equal_range(name);
|
|
Packit |
a4aae4 |
for (SFLCIter it = ret.first; it != ret.second; ++it) {
|
|
Packit |
a4aae4 |
if (name == it->first && (*f = it->second->get_d4_function())) {
|
|
Packit |
a4aae4 |
return true;
|
|
Packit |
a4aae4 |
}
|
|
Packit |
a4aae4 |
}
|
|
Packit |
a4aae4 |
|
|
Packit |
a4aae4 |
return false;
|
|
Packit |
a4aae4 |
}
|
|
Packit |
a4aae4 |
|
|
Packit |
a4aae4 |
/** @brief Returns an iterator pointing to the first key pair in the ServerFunctionList. */
|
|
Packit |
a4aae4 |
ServerFunctionsList::SFLIter ServerFunctionsList::begin()
|
|
Packit |
a4aae4 |
{
|
|
Packit |
a4aae4 |
return d_func_list.begin();
|
|
Packit |
a4aae4 |
}
|
|
Packit |
a4aae4 |
|
|
Packit |
a4aae4 |
/** @brief Returns an iterator pointing to the last key pair in the ServerFunctionList. */
|
|
Packit |
a4aae4 |
ServerFunctionsList::SFLIter ServerFunctionsList::end()
|
|
Packit |
a4aae4 |
{
|
|
Packit |
a4aae4 |
return d_func_list.end();
|
|
Packit |
a4aae4 |
}
|
|
Packit |
a4aae4 |
|
|
Packit |
a4aae4 |
/**
|
|
Packit |
a4aae4 |
*
|
|
Packit |
a4aae4 |
*
|
|
Packit |
a4aae4 |
* @brief Returns the ServerFunction pointed to by the passed iterator.
|
|
Packit |
a4aae4 |
*
|
|
Packit |
a4aae4 |
*/
|
|
Packit |
a4aae4 |
ServerFunction *ServerFunctionsList::getFunction(SFLIter it)
|
|
Packit |
a4aae4 |
{
|
|
Packit |
a4aae4 |
return (*it).second;
|
|
Packit |
a4aae4 |
}
|
|
Packit |
a4aae4 |
|
|
Packit |
a4aae4 |
void ServerFunctionsList::getFunctionNames(vector<string> *names){
|
|
Packit |
a4aae4 |
SFLIter fit;
|
|
Packit |
a4aae4 |
for(fit = d_func_list.begin(); fit != d_func_list.end(); fit++) {
|
|
Packit |
a4aae4 |
ServerFunction *func = fit->second;
|
|
Packit |
a4aae4 |
names->push_back(func->getName());
|
|
Packit |
a4aae4 |
}
|
|
Packit |
a4aae4 |
}
|
|
Packit |
a4aae4 |
|
|
Packit |
a4aae4 |
} // namespace libdap
|