mirror of
https://github.com/signalwire/freeswitch.git
synced 2025-08-13 09:36:46 +00:00
merged new xmlrpc-c revision 1472 from https://xmlrpc-c.svn.sourceforge.net/svnroot/xmlrpc-c/trunk
git-svn-id: http://svn.freeswitch.org/svn/freeswitch/trunk@8545 d0543943-73ff-0310-b7d9-9358b9ac24b2
This commit is contained in:
63
libs/xmlrpc-c/tools/xmlrpc_cpp_proxy/Makefile
Normal file
63
libs/xmlrpc-c/tools/xmlrpc_cpp_proxy/Makefile
Normal file
@@ -0,0 +1,63 @@
|
||||
ifeq ($(SRCDIR),)
|
||||
updir = $(shell echo $(dir $(1)) | sed 's/.$$//')
|
||||
TOOLSDIR := $(call updir,$(CURDIR))
|
||||
SRCDIR := $(call updir,$(TOOLSDIR))
|
||||
BLDDIR := $(SRCDIR)
|
||||
endif
|
||||
SUBDIR := tools/xmlrpc_cpp_proxy
|
||||
|
||||
default: all
|
||||
|
||||
include $(BLDDIR)/config.mk
|
||||
|
||||
PROGRAMS_TO_INSTALL = xmlrpc_cpp_proxy
|
||||
|
||||
include $(SRCDIR)/tools/common.mk
|
||||
|
||||
INCLUDES = -I$(BLDDIR) -I$(BLDDIR)/include -I$(SRCDIR)/include
|
||||
|
||||
CXXFLAGS = $(INCLUDES) $(CXXFLAGS_COMMON) $(CFLAGS_PERSONAL) $(CADD)
|
||||
|
||||
LDFLAGS = $(LADD)
|
||||
|
||||
all: xmlrpc_cpp_proxy
|
||||
|
||||
OBJECTS = \
|
||||
xmlrpc_cpp_proxy.o \
|
||||
xmlrpcMethod.o \
|
||||
xmlrpcType.o \
|
||||
proxyClass.o \
|
||||
systemProxy.o \
|
||||
|
||||
LIBS = \
|
||||
$(LIBXMLRPC_CLIENTPP) \
|
||||
$(LIBXMLRPCPP) \
|
||||
$(LIBXMLRPC_CLIENT) \
|
||||
$(LIBXMLRPC) \
|
||||
$(LIBXMLRPC_XML) \
|
||||
$(LIBXMLRPC_UTIL) \
|
||||
|
||||
LDLIBS = $(CLIENTPP_LDLIBS) $(CLIENT_LDLIBS)
|
||||
|
||||
xmlrpc_cpp_proxy: $(OBJECTS) $(LIBS)
|
||||
$(CXXLD) -o $@ $(LDFLAGS) $(OBJECTS) $(LDLIBS) $(LADD)
|
||||
|
||||
%.o:%.cpp $(BLDDIR)/include/xmlrpc-c/config.h
|
||||
$(CXX) -c $(CXXFLAGS) $<
|
||||
|
||||
# This common.mk dependency makes sure the symlinks get built before
|
||||
# this make file is used for anything.
|
||||
|
||||
$(SRCDIR)/tools/common.mk: srcdir blddir
|
||||
|
||||
include Makefile.depend
|
||||
|
||||
.PHONY: clean
|
||||
clean: clean-common
|
||||
rm -f xmlrpc_cpp_proxy
|
||||
|
||||
.PHONY: distclean
|
||||
distclean: clean distclean-common
|
||||
|
||||
.PHONY: dep
|
||||
dep: dep-common
|
85
libs/xmlrpc-c/tools/xmlrpc_cpp_proxy/proxyClass.cpp
Normal file
85
libs/xmlrpc-c/tools/xmlrpc_cpp_proxy/proxyClass.cpp
Normal file
@@ -0,0 +1,85 @@
|
||||
#include <iostream>
|
||||
#include <stdexcept>
|
||||
#include <vector>
|
||||
|
||||
using namespace std;
|
||||
|
||||
#include "xmlrpc-c/client_simple.hpp"
|
||||
|
||||
#include "xmlrpcType.hpp"
|
||||
#include "xmlrpcMethod.hpp"
|
||||
|
||||
#include "proxyClass.hpp"
|
||||
|
||||
|
||||
proxyClass::proxyClass(string const& className) :
|
||||
_className(className) {}
|
||||
|
||||
|
||||
|
||||
proxyClass::proxyClass(proxyClass const& c) :
|
||||
_className(c._className),
|
||||
functions(c.functions) {}
|
||||
|
||||
|
||||
|
||||
string
|
||||
proxyClass::className() const {
|
||||
|
||||
return this->_className;
|
||||
}
|
||||
|
||||
|
||||
|
||||
void
|
||||
proxyClass::addFunction(xmlrpcMethod const& function) {
|
||||
|
||||
functions.push_back(function);
|
||||
}
|
||||
|
||||
|
||||
|
||||
void
|
||||
proxyClass::printDeclaration(ostream & out) const {
|
||||
|
||||
out << "class " << this->_className << " {" << endl;
|
||||
out << endl;
|
||||
out << "public:" << endl;
|
||||
|
||||
// emit the constructor prototype:
|
||||
out << " " << this->_className << "(std::string const& serverUrl) "
|
||||
<< endl
|
||||
<< " : serverUrl(serverUrl) {}"
|
||||
<< endl;
|
||||
|
||||
// emit the XML-RPC method method prototypes:
|
||||
vector<xmlrpcMethod>::const_iterator f;
|
||||
for (f = this->functions.begin(); f < this->functions.end(); ++f) {
|
||||
f->printDeclarations(out);
|
||||
}
|
||||
|
||||
// emit the private data:
|
||||
|
||||
out << "private:" << endl;
|
||||
|
||||
out << " xmlrpc_c::clientSimple client;" << endl;
|
||||
|
||||
out << " std::string const serverUrl;" << endl;
|
||||
out << " // The URL for the server for which we are proxy" << endl;
|
||||
|
||||
// emit the class closing:
|
||||
out << "};" << endl;
|
||||
}
|
||||
|
||||
|
||||
|
||||
void
|
||||
proxyClass::printDefinition(ostream & out) const {
|
||||
|
||||
vector<xmlrpcMethod>::const_iterator f;
|
||||
|
||||
for (f = this->functions.begin(); f < this->functions.end(); ++f) {
|
||||
f->printDefinitions(out, this->_className);
|
||||
}
|
||||
}
|
||||
|
32
libs/xmlrpc-c/tools/xmlrpc_cpp_proxy/proxyClass.hpp
Normal file
32
libs/xmlrpc-c/tools/xmlrpc_cpp_proxy/proxyClass.hpp
Normal file
@@ -0,0 +1,32 @@
|
||||
#include <vector>
|
||||
#include <string>
|
||||
|
||||
#include "xmlrpcMethod.hpp"
|
||||
|
||||
class proxyClass {
|
||||
// An object of this class contains information about a proxy
|
||||
// class, and knows how to generate code.
|
||||
|
||||
public:
|
||||
proxyClass(std::string const& className);
|
||||
|
||||
proxyClass(proxyClass const&);
|
||||
|
||||
std::string
|
||||
className() const;
|
||||
|
||||
void
|
||||
addFunction(xmlrpcMethod const& function);
|
||||
|
||||
void
|
||||
printDeclaration(std::ostream& out) const;
|
||||
|
||||
void
|
||||
printDefinition(std::ostream& out) const;
|
||||
|
||||
private:
|
||||
|
||||
std::string const _className;
|
||||
|
||||
std::vector<xmlrpcMethod> functions;
|
||||
};
|
57
libs/xmlrpc-c/tools/xmlrpc_cpp_proxy/systemProxy.cpp
Normal file
57
libs/xmlrpc-c/tools/xmlrpc_cpp_proxy/systemProxy.cpp
Normal file
@@ -0,0 +1,57 @@
|
||||
/*=============================================================================
|
||||
systemProxy
|
||||
===============================================================================
|
||||
|
||||
This is a proxy class for the introspection system methods of the server.
|
||||
|
||||
Note that you can use 'xmlrpc_cpp_proxy' itself to generate this
|
||||
file, but we hand-edit it to make it easier to read.
|
||||
|
||||
=============================================================================*/
|
||||
|
||||
#include "systemProxy.hpp"
|
||||
|
||||
using namespace std;
|
||||
|
||||
xmlrpc_c::value // array
|
||||
systemProxy::listMethods(string const& serverUrl) {
|
||||
|
||||
xmlrpc_c::paramList params;
|
||||
xmlrpc_c::value result;
|
||||
|
||||
this->call(serverUrl, "system.listMethods", &result);
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
|
||||
|
||||
xmlrpc_c::value // array
|
||||
systemProxy::methodSignature(string const& serverUrl,
|
||||
string const& methodName) {
|
||||
|
||||
xmlrpc_c::paramList params;
|
||||
params.add(xmlrpc_c::value_string(methodName));
|
||||
|
||||
xmlrpc_c::value result;
|
||||
|
||||
this->call(serverUrl, "system.methodSignature", params, &result);
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
|
||||
|
||||
string
|
||||
systemProxy::methodHelp(string const& serverUrl,
|
||||
string const& methodName) {
|
||||
|
||||
xmlrpc_c::paramList params;
|
||||
params.add(xmlrpc_c::value_string(methodName));
|
||||
|
||||
xmlrpc_c::value result;
|
||||
|
||||
this->call(serverUrl, "system.methodHelp", params, &result);
|
||||
|
||||
return xmlrpc_c::value_string(result);
|
||||
}
|
25
libs/xmlrpc-c/tools/xmlrpc_cpp_proxy/systemProxy.hpp
Normal file
25
libs/xmlrpc-c/tools/xmlrpc_cpp_proxy/systemProxy.hpp
Normal file
@@ -0,0 +1,25 @@
|
||||
#ifndef SYSTEMPROXY_HPP_INCLUDED
|
||||
#define SYSTEMPROXY_HPP_INCLUDED
|
||||
|
||||
#include <xmlrpc-c/base.hpp>
|
||||
#include <xmlrpc-c/client_simple.hpp>
|
||||
|
||||
class systemProxy : public xmlrpc_c::clientSimple {
|
||||
|
||||
public:
|
||||
systemProxy() {}
|
||||
|
||||
xmlrpc_c::value /*array*/
|
||||
listMethods(std::string const& serverUrl);
|
||||
|
||||
xmlrpc_c::value /*array*/
|
||||
methodSignature(std::string const& serverUrl,
|
||||
std::string const& methodName);
|
||||
|
||||
std::string
|
||||
methodHelp(std::string const& serverUrl,
|
||||
std::string const& methodName);
|
||||
};
|
||||
|
||||
#endif
|
||||
|
240
libs/xmlrpc-c/tools/xmlrpc_cpp_proxy/xmlrpcMethod.cpp
Normal file
240
libs/xmlrpc-c/tools/xmlrpc_cpp_proxy/xmlrpcMethod.cpp
Normal file
@@ -0,0 +1,240 @@
|
||||
#include <iostream>
|
||||
#include <sstream>
|
||||
#include <stdexcept>
|
||||
|
||||
#include "xmlrpcType.hpp"
|
||||
|
||||
#include "xmlrpcMethod.hpp"
|
||||
|
||||
using namespace std;
|
||||
|
||||
|
||||
xmlrpcMethod::xmlrpcMethod(string const& functionName,
|
||||
string const& methodName,
|
||||
string const& help,
|
||||
xmlrpc_c::value_array const& signatureList) :
|
||||
mFunctionName(functionName),
|
||||
mMethodName(methodName),
|
||||
mHelp(help),
|
||||
mSynopsis(signatureList) {}
|
||||
|
||||
|
||||
|
||||
xmlrpcMethod::xmlrpcMethod(xmlrpcMethod const& f) :
|
||||
mFunctionName(f.mFunctionName),
|
||||
mMethodName(f.mMethodName),
|
||||
mHelp(f.mHelp),
|
||||
mSynopsis(f.mSynopsis) {}
|
||||
|
||||
|
||||
|
||||
xmlrpcMethod&
|
||||
xmlrpcMethod::operator= (xmlrpcMethod const& f) {
|
||||
|
||||
if (this != &f) {
|
||||
this->mFunctionName = f.mFunctionName;
|
||||
this->mMethodName = f.mMethodName;
|
||||
this->mHelp = f.mHelp;
|
||||
this->mSynopsis = f.mSynopsis;
|
||||
}
|
||||
return *this;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
size_t
|
||||
xmlrpcMethod::parameterCount(size_t const synopsisIndex) const {
|
||||
|
||||
xmlrpc_c::value_array const funcSynop(
|
||||
mSynopsis.vectorValueValue()[synopsisIndex]);
|
||||
size_t const size(funcSynop.size());
|
||||
|
||||
if (size < 1)
|
||||
throw domain_error("Synopsis contains no items");
|
||||
|
||||
return size - 1;
|
||||
}
|
||||
|
||||
|
||||
|
||||
xmlrpcType const&
|
||||
xmlrpcMethod::parameterType(size_t const synopsisIndex,
|
||||
size_t const parameterIndex) const {
|
||||
|
||||
xmlrpc_c::value_array const funcSynop(
|
||||
mSynopsis.vectorValueValue()[synopsisIndex]);
|
||||
xmlrpc_c::value_string const param(
|
||||
funcSynop.vectorValueValue()[parameterIndex + 1]);
|
||||
|
||||
return findXmlrpcType(static_cast<string>(param));
|
||||
}
|
||||
|
||||
|
||||
|
||||
const xmlrpcType&
|
||||
xmlrpcMethod::returnType(size_t const synopsisIndex) const {
|
||||
|
||||
xmlrpc_c::value_array const funcSynop(
|
||||
mSynopsis.vectorValueValue()[synopsisIndex]);
|
||||
|
||||
xmlrpc_c::value_string datatype(funcSynop.vectorValueValue()[0]);
|
||||
return findXmlrpcType(static_cast<string>(datatype));
|
||||
}
|
||||
|
||||
|
||||
|
||||
void
|
||||
xmlrpcMethod::printParameters(ostream & out,
|
||||
size_t const synopsisIndex) const {
|
||||
/*----------------------------------------------------------------------------
|
||||
Print the parameter declarations.
|
||||
-----------------------------------------------------------------------------*/
|
||||
size_t const end(parameterCount(synopsisIndex));
|
||||
|
||||
bool first;
|
||||
|
||||
first = true;
|
||||
|
||||
for (size_t i = 0; i < end; ++i) {
|
||||
if (!first)
|
||||
out << ", ";
|
||||
|
||||
xmlrpcType const& ptype(parameterType(synopsisIndex, i));
|
||||
|
||||
string const localName(ptype.defaultParameterBaseName(i + 1));
|
||||
out << ptype.parameterFragment(localName);
|
||||
|
||||
first = false;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
void
|
||||
xmlrpcMethod::printDeclaration(ostream & out,
|
||||
size_t const synopsisIndex) const {
|
||||
|
||||
try {
|
||||
xmlrpcType const& rtype(returnType(synopsisIndex));
|
||||
|
||||
out << " " << rtype.returnTypeFragment() << " "
|
||||
<< mFunctionName << " (";
|
||||
|
||||
printParameters(out, synopsisIndex);
|
||||
|
||||
out << ");" << endl;
|
||||
} catch (xmlrpc_c::fault const& f) {
|
||||
ostringstream msg;
|
||||
|
||||
msg << "Failed to generate header for signature "
|
||||
<< synopsisIndex
|
||||
<< " . "
|
||||
<< f.getDescription();
|
||||
|
||||
throw(logic_error(msg.str()));
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
void
|
||||
xmlrpcMethod::printDeclarations(ostream & out) const {
|
||||
|
||||
try {
|
||||
// Print the method help as a comment
|
||||
|
||||
out << endl << " /* " << mHelp << " */" << endl;
|
||||
|
||||
size_t end;
|
||||
|
||||
try {
|
||||
end = mSynopsis.size();
|
||||
} catch (xmlrpc_c::fault const& f) {
|
||||
throw(logic_error("Failed to get size of signature array for "
|
||||
"method " + this->mFunctionName + ". " +
|
||||
f.getDescription()));
|
||||
}
|
||||
// Print the declarations for all the signatures of this
|
||||
// XML-RPC method.
|
||||
|
||||
for (size_t i = 0; i < end; ++i)
|
||||
printDeclaration(out, i);
|
||||
|
||||
} catch (exception const& e) {
|
||||
throw(logic_error("Failed to generate declarations for method " +
|
||||
this->mFunctionName + ". " + e.what()));
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
void
|
||||
xmlrpcMethod::printDefinition(ostream & out,
|
||||
string const& className,
|
||||
size_t const synopsisIndex) const {
|
||||
|
||||
xmlrpcType const& rtype(returnType(synopsisIndex));
|
||||
|
||||
out << rtype.returnTypeFragment() << " "
|
||||
<< className << "::" << mFunctionName << " (";
|
||||
|
||||
printParameters(out, synopsisIndex);
|
||||
|
||||
out << ") {" << endl;
|
||||
|
||||
size_t const end(parameterCount(synopsisIndex));
|
||||
if (end > 0){
|
||||
// Emit code to generate the parameter list object
|
||||
out << " xmlrpc_c::paramList params;" << endl;
|
||||
for (size_t i = 0; i < end; ++i) {
|
||||
xmlrpcType const& ptype(parameterType(synopsisIndex, i));
|
||||
string const basename(ptype.defaultParameterBaseName(i + 1));
|
||||
out << " params.add("
|
||||
<< ptype.inputConversionFragment(basename) << ");" << endl;
|
||||
}
|
||||
}
|
||||
|
||||
// Emit result holder declaration.
|
||||
out << " xmlrpc_c::value result;" << endl;
|
||||
|
||||
// Emit the call to the XML-RPC call method
|
||||
out << " this->client.call("
|
||||
<< "this->serverUrl, "
|
||||
<< "\"" << mMethodName << "\", ";
|
||||
|
||||
if (end > 0)
|
||||
out << "params, ";
|
||||
|
||||
out << "&result);" << endl;
|
||||
|
||||
// Emit the return statement.
|
||||
out << " return " << rtype.outputConversionFragment("result")
|
||||
<< ";" << endl;
|
||||
out << "}" << endl;
|
||||
}
|
||||
|
||||
|
||||
|
||||
void
|
||||
xmlrpcMethod::printDefinitions(ostream & out,
|
||||
string const& className) const {
|
||||
|
||||
try {
|
||||
size_t const end(mSynopsis.size());
|
||||
|
||||
for (size_t i = 0; i < end; ++i) {
|
||||
out << endl;
|
||||
printDefinition(out, className, i);
|
||||
}
|
||||
} catch (xmlrpc_c::fault const& f) {
|
||||
throw(logic_error("Failed to generate definitions for class " +
|
||||
this->mFunctionName + ". " +
|
||||
f.getDescription()));
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
59
libs/xmlrpc-c/tools/xmlrpc_cpp_proxy/xmlrpcMethod.hpp
Normal file
59
libs/xmlrpc-c/tools/xmlrpc_cpp_proxy/xmlrpcMethod.hpp
Normal file
@@ -0,0 +1,59 @@
|
||||
#ifndef XMLRPCMETHOD_HPP
|
||||
#define XMLRPCMETHOD_HPP
|
||||
|
||||
#include <string>
|
||||
#include <iostream>
|
||||
#include <xmlrpc-c/base.hpp>
|
||||
|
||||
class xmlrpcMethod {
|
||||
// An object of this class contains everything we know about a
|
||||
// given XML-RPC method, and knows how to print local bindings.
|
||||
|
||||
std::string mFunctionName;
|
||||
std::string mMethodName;
|
||||
std::string mHelp;
|
||||
xmlrpc_c::value_array mSynopsis;
|
||||
|
||||
public:
|
||||
xmlrpcMethod(std::string const& function_name,
|
||||
std::string const& method_name,
|
||||
std::string const& help,
|
||||
xmlrpc_c::value_array const& signatureList);
|
||||
|
||||
xmlrpcMethod(xmlrpcMethod const& f);
|
||||
|
||||
xmlrpcMethod& operator= (xmlrpcMethod const& f);
|
||||
|
||||
void
|
||||
printDeclarations(std::ostream& out) const;
|
||||
|
||||
void
|
||||
printDefinitions(std::ostream & out,
|
||||
std::string const& className) const;
|
||||
|
||||
private:
|
||||
void
|
||||
printParameters(std::ostream & out,
|
||||
size_t const synopsis_index) const;
|
||||
|
||||
void
|
||||
printDeclaration(std::ostream & out,
|
||||
size_t const synopsis_index) const;
|
||||
|
||||
void
|
||||
printDefinition(std::ostream & out,
|
||||
std::string const& className,
|
||||
size_t const synopsis_index) const;
|
||||
|
||||
const xmlrpcType&
|
||||
returnType(size_t const synopsis_index) const;
|
||||
|
||||
size_t
|
||||
parameterCount(size_t const synopsis_index) const;
|
||||
|
||||
const xmlrpcType&
|
||||
parameterType(size_t const synopsis_index,
|
||||
size_t const parameter_index) const;
|
||||
};
|
||||
|
||||
#endif
|
270
libs/xmlrpc-c/tools/xmlrpc_cpp_proxy/xmlrpcType.cpp
Normal file
270
libs/xmlrpc-c/tools/xmlrpc_cpp_proxy/xmlrpcType.cpp
Normal file
@@ -0,0 +1,270 @@
|
||||
#include <iostream>
|
||||
#include <sstream>
|
||||
#include <stdexcept>
|
||||
#include <map>
|
||||
#include <vector>
|
||||
|
||||
#include <xmlrpc-c/base.hpp>
|
||||
|
||||
#include "xmlrpcType.hpp"
|
||||
|
||||
using namespace std;
|
||||
|
||||
|
||||
|
||||
//=========================================================================
|
||||
// abstract class xmlrpcType
|
||||
//=========================================================================
|
||||
// Instances of xmlrpcType know how generate code fragments for manipulating
|
||||
// a specific XML-RPC data type.
|
||||
|
||||
string
|
||||
xmlrpcType::defaultParameterBaseName(unsigned int const position) const {
|
||||
|
||||
ostringstream nameStream;
|
||||
|
||||
nameStream << typeName() << position;
|
||||
|
||||
return nameStream.str();
|
||||
}
|
||||
|
||||
|
||||
|
||||
class rawXmlrpcType : public xmlrpcType {
|
||||
public:
|
||||
rawXmlrpcType(string const& typeName) : xmlrpcType(typeName) {}
|
||||
|
||||
virtual string
|
||||
parameterFragment(string const& baseName) const;
|
||||
|
||||
virtual string
|
||||
inputConversionFragment(string const& baseName) const;
|
||||
|
||||
virtual string
|
||||
returnTypeFragment() const;
|
||||
|
||||
virtual string
|
||||
outputConversionFragment(string const& varName) const;
|
||||
};
|
||||
|
||||
|
||||
|
||||
string
|
||||
rawXmlrpcType::parameterFragment(string const& baseName) const {
|
||||
return "xmlrpc_c::value /*" + typeName() + "*/ " + baseName;
|
||||
}
|
||||
|
||||
|
||||
|
||||
string
|
||||
rawXmlrpcType::inputConversionFragment(string const& baseName) const {
|
||||
|
||||
return baseName;
|
||||
}
|
||||
|
||||
|
||||
|
||||
string
|
||||
rawXmlrpcType::returnTypeFragment() const {
|
||||
return "xmlrpc_c::value /*" + typeName() + "*/";
|
||||
}
|
||||
|
||||
|
||||
|
||||
string
|
||||
rawXmlrpcType::outputConversionFragment(string const& varName) const {
|
||||
|
||||
return varName;
|
||||
}
|
||||
|
||||
|
||||
|
||||
class simpleXmlrpcType : public xmlrpcType {
|
||||
|
||||
string mNativeType;
|
||||
string mMakerFunc;
|
||||
string mGetterFunc;
|
||||
|
||||
public:
|
||||
simpleXmlrpcType(string const& typeName,
|
||||
string const& nativeType,
|
||||
string const& makerFunc,
|
||||
string const& getterFunc);
|
||||
|
||||
virtual string
|
||||
parameterFragment(string const& baseName) const;
|
||||
|
||||
virtual string
|
||||
inputConversionFragment(string const& baseName) const;
|
||||
|
||||
virtual string
|
||||
returnTypeFragment() const;
|
||||
|
||||
virtual string
|
||||
outputConversionFragment(string const& varName) const;
|
||||
};
|
||||
|
||||
|
||||
|
||||
simpleXmlrpcType::simpleXmlrpcType(string const& typeName,
|
||||
string const& nativeType,
|
||||
string const& makerFunc,
|
||||
string const& getterFunc)
|
||||
: xmlrpcType(typeName),
|
||||
mNativeType(nativeType),
|
||||
mMakerFunc(makerFunc),
|
||||
mGetterFunc(getterFunc) {
|
||||
}
|
||||
|
||||
|
||||
|
||||
string
|
||||
simpleXmlrpcType::parameterFragment(string const& baseName) const {
|
||||
|
||||
return mNativeType + " const " + baseName;
|
||||
}
|
||||
|
||||
|
||||
|
||||
string
|
||||
simpleXmlrpcType::inputConversionFragment(string const& baseName) const {
|
||||
|
||||
return mMakerFunc + "(" + baseName + ")";
|
||||
}
|
||||
|
||||
|
||||
|
||||
string
|
||||
simpleXmlrpcType::returnTypeFragment() const {
|
||||
|
||||
return mNativeType;
|
||||
}
|
||||
|
||||
|
||||
|
||||
string
|
||||
simpleXmlrpcType::outputConversionFragment(string const& varName) const {
|
||||
return mMakerFunc + "(" + varName + ")";
|
||||
}
|
||||
|
||||
|
||||
|
||||
class voidXmlrpcType : public xmlrpcType {
|
||||
public:
|
||||
voidXmlrpcType() : xmlrpcType("void") {}
|
||||
|
||||
virtual string
|
||||
parameterFragment(string const& baseName) const;
|
||||
|
||||
virtual string
|
||||
inputConversionFragment(string const& baseName) const;
|
||||
|
||||
virtual string
|
||||
returnTypeFragment() const;
|
||||
|
||||
virtual string
|
||||
outputConversionFragment(string const& varName) const;
|
||||
};
|
||||
|
||||
|
||||
|
||||
string
|
||||
voidXmlrpcType::parameterFragment(string const&) const {
|
||||
|
||||
throw domain_error("Can't handle functions with 'void' arguments'");
|
||||
}
|
||||
|
||||
|
||||
|
||||
string
|
||||
voidXmlrpcType::inputConversionFragment(string const&) const {
|
||||
|
||||
throw domain_error("Can't handle functions with 'void' arguments'");
|
||||
}
|
||||
|
||||
|
||||
|
||||
string
|
||||
voidXmlrpcType::returnTypeFragment () const {
|
||||
|
||||
return "void";
|
||||
}
|
||||
|
||||
|
||||
|
||||
string
|
||||
voidXmlrpcType::outputConversionFragment(string const&) const {
|
||||
return "/* Return value ignored. */";
|
||||
}
|
||||
|
||||
|
||||
|
||||
static simpleXmlrpcType const intType ("int", "int",
|
||||
"xmlrpc_c::value_int",
|
||||
"getInt");
|
||||
static simpleXmlrpcType const boolType ("bool", "bool",
|
||||
"xmlrpc_c::value_boolean",
|
||||
"getBool");
|
||||
static simpleXmlrpcType const doubleType ("double", "double",
|
||||
"xmlrpc_c::value_double",
|
||||
"getDouble");
|
||||
static simpleXmlrpcType const stringType ("string", "std::string",
|
||||
"xmlrpc_c::value_string",
|
||||
"getString");
|
||||
|
||||
static rawXmlrpcType const dateTimeType ("dateTime");
|
||||
static rawXmlrpcType const base64Type ("base64");
|
||||
static rawXmlrpcType const structType ("struct");
|
||||
static rawXmlrpcType const arrayType ("array");
|
||||
|
||||
static voidXmlrpcType const voidType;
|
||||
|
||||
|
||||
|
||||
const xmlrpcType&
|
||||
findXmlrpcType(string const& name) {
|
||||
/*----------------------------------------------------------------------------
|
||||
Given the name of an XML-RPC data type, try to find a corresponding
|
||||
xmlrpcType object.
|
||||
-----------------------------------------------------------------------------*/
|
||||
if (name == "int" || name == "i4")
|
||||
return intType;
|
||||
else if (name == "boolean")
|
||||
return boolType;
|
||||
else if (name == "double")
|
||||
return doubleType;
|
||||
else if (name == "string")
|
||||
return stringType;
|
||||
else if (name == "dateTime.iso8601")
|
||||
return dateTimeType;
|
||||
else if (name == "base64")
|
||||
return base64Type;
|
||||
else if (name == "struct")
|
||||
return structType;
|
||||
else if (name == "array")
|
||||
return arrayType;
|
||||
else if (name == "void")
|
||||
return voidType;
|
||||
else if (name == "INT")
|
||||
return intType;
|
||||
else if (name == "BOOLEAN")
|
||||
return boolType;
|
||||
else if (name == "DOUBLE")
|
||||
return doubleType;
|
||||
else if (name == "STRING")
|
||||
return stringType;
|
||||
else if (name == "DATETIME.ISO8601")
|
||||
return dateTimeType;
|
||||
else if (name == "BASE64")
|
||||
return base64Type;
|
||||
else if (name == "STRUCT")
|
||||
return structType;
|
||||
else if (name == "ARRAY")
|
||||
return arrayType;
|
||||
else if (name == "VOID")
|
||||
return voidType;
|
||||
else if (name == "NIL")
|
||||
return voidType;
|
||||
else
|
||||
throw domain_error("Unknown XML-RPC type name '" + name + "'");
|
||||
}
|
43
libs/xmlrpc-c/tools/xmlrpc_cpp_proxy/xmlrpcType.hpp
Normal file
43
libs/xmlrpc-c/tools/xmlrpc_cpp_proxy/xmlrpcType.hpp
Normal file
@@ -0,0 +1,43 @@
|
||||
#include <string>
|
||||
#include <cassert>
|
||||
|
||||
class xmlrpcType {
|
||||
std::string mTypeName;
|
||||
|
||||
xmlrpcType(xmlrpcType const&) { assert(false); }
|
||||
|
||||
xmlrpcType& operator= (xmlrpcType const&) {
|
||||
assert(false);
|
||||
return *this;
|
||||
}
|
||||
|
||||
public:
|
||||
xmlrpcType(const std::string& type_name) : mTypeName(type_name) {}
|
||||
|
||||
virtual ~xmlrpcType () {}
|
||||
|
||||
// Return the name for this XML-RPC type.
|
||||
virtual std::string
|
||||
typeName() const { return mTypeName; }
|
||||
|
||||
// Given a parameter position, calculate a unique base name for all
|
||||
// parameter-related variables.
|
||||
virtual std::string
|
||||
defaultParameterBaseName(unsigned int const position) const;
|
||||
|
||||
// Virtual functions for processing parameters.
|
||||
virtual std::string
|
||||
parameterFragment(std::string const& base_name) const = 0;
|
||||
|
||||
virtual std::string
|
||||
inputConversionFragment(std::string const& base_name) const = 0;
|
||||
|
||||
// Virtual functions for processing return values.
|
||||
virtual std::string
|
||||
returnTypeFragment () const = 0;
|
||||
|
||||
virtual std::string
|
||||
outputConversionFragment(std::string const& var_name) const = 0;
|
||||
};
|
||||
|
||||
const xmlrpcType& findXmlrpcType(const std::string& name);
|
208
libs/xmlrpc-c/tools/xmlrpc_cpp_proxy/xmlrpc_cpp_proxy.cpp
Normal file
208
libs/xmlrpc-c/tools/xmlrpc_cpp_proxy/xmlrpc_cpp_proxy.cpp
Normal file
@@ -0,0 +1,208 @@
|
||||
#include <iostream>
|
||||
#include <stdexcept>
|
||||
#include <cstdlib>
|
||||
|
||||
#include "xmlrpcType.hpp"
|
||||
#include "xmlrpcMethod.hpp"
|
||||
#include "proxyClass.hpp"
|
||||
#include "systemProxy.hpp"
|
||||
|
||||
using namespace std;
|
||||
|
||||
|
||||
/*----------------------------------------------------------------------------
|
||||
Command line
|
||||
-----------------------------------------------------------------------------*/
|
||||
|
||||
class cmdlineInfo {
|
||||
public:
|
||||
string serverUrl;
|
||||
string methodPrefix;
|
||||
string localClass;
|
||||
|
||||
cmdlineInfo(int const argc,
|
||||
const char ** const argv);
|
||||
|
||||
private:
|
||||
cmdlineInfo();
|
||||
};
|
||||
|
||||
|
||||
|
||||
cmdlineInfo::cmdlineInfo(int const argc,
|
||||
const char ** const argv) {
|
||||
|
||||
if (argc-1 != 3) {
|
||||
cerr << "There are 3 arguments: server URL, "
|
||||
<< "prefix for the methods to include (null to include all), "
|
||||
<< "and name to give the generated proxy class. "
|
||||
<< "You specified " << argc-1 << " arguments."
|
||||
<< endl
|
||||
<< "Example: "
|
||||
<< "xmlrpc_cpp_proxy http://localhost/RPC2 system systemProxy"
|
||||
<< endl;
|
||||
exit(1);
|
||||
}
|
||||
this->serverUrl = string(argv[1]);
|
||||
this->methodPrefix = string(argv[2]);
|
||||
this->localClass = string(argv[3]);
|
||||
}
|
||||
|
||||
|
||||
|
||||
static proxyClass
|
||||
getClassInfo(string const& serverUrl,
|
||||
string const& classPrefix,
|
||||
string const& className) {
|
||||
/*----------------------------------------------------------------------------
|
||||
Connect to a remote server and extract the information we'll need to
|
||||
build a proxy class.
|
||||
-----------------------------------------------------------------------------*/
|
||||
proxyClass theClass(className);
|
||||
|
||||
systemProxy system;
|
||||
|
||||
xmlrpc_c::value_array methods(system.listMethods(serverUrl));
|
||||
|
||||
unsigned int arraySize = methods.size();
|
||||
|
||||
for (size_t i = 0; i < arraySize; ++i) {
|
||||
|
||||
// Break the method name into two pieces.
|
||||
xmlrpc_c::value_string val = (methods.vectorValueValue())[i];
|
||||
string const methodName(static_cast<string>(val));
|
||||
size_t const lastDot(methodName.rfind('.'));
|
||||
|
||||
string methodPrefix;
|
||||
string functionName;
|
||||
|
||||
if (lastDot == string::npos) {
|
||||
methodPrefix = "";
|
||||
functionName = methodName;
|
||||
} else {
|
||||
methodPrefix = string(methodName, 0, lastDot);
|
||||
functionName = string(methodName, lastDot + 1);
|
||||
}
|
||||
|
||||
if (methodPrefix == classPrefix) {
|
||||
// It's a method User cares about
|
||||
|
||||
string const help(system.methodHelp(serverUrl, methodName));
|
||||
xmlrpc_c::value const signatureList(
|
||||
system.methodSignature(serverUrl, methodName));
|
||||
|
||||
if (signatureList.type() != xmlrpc_c::value::TYPE_ARRAY) {
|
||||
// It must be the string "undef", meaning the server
|
||||
// won't tell us any signatures.
|
||||
cerr << "Skipping method " << methodName << " "
|
||||
<< "because server does not report any signatures "
|
||||
<< "for it (via system.methodSignature method)"
|
||||
<< endl;
|
||||
} else {
|
||||
// Add this function to our class information.
|
||||
xmlrpcMethod const method(
|
||||
functionName,
|
||||
methodName,
|
||||
help,
|
||||
xmlrpc_c::value_array(signatureList));
|
||||
theClass.addFunction(method);
|
||||
}
|
||||
}
|
||||
}
|
||||
return theClass;
|
||||
}
|
||||
|
||||
|
||||
|
||||
static void
|
||||
printHeader(ostream & out,
|
||||
proxyClass const& classInfo) {
|
||||
/*----------------------------------------------------------------------------
|
||||
Print a complete header for the specified class.
|
||||
-----------------------------------------------------------------------------*/
|
||||
string const className(classInfo.className());
|
||||
|
||||
try {
|
||||
out << "// Interface definition for " << className << " class, "
|
||||
<< "an XML-RPC FOR C/C++ proxy class" << endl;
|
||||
out << "// Generated by 'xmlrpc_cpp_proxy'" << endl;
|
||||
out << endl;
|
||||
|
||||
string const headerSymbol("_" + className + "_H_");
|
||||
|
||||
out << "#ifndef " << headerSymbol << endl;
|
||||
out << "#define " << headerSymbol << " 1" << endl;
|
||||
out << endl;
|
||||
out << "#include <string>" << endl;
|
||||
out << "#include <xmlrpc-c/client_simple.hpp>" << endl;
|
||||
out << endl;
|
||||
|
||||
classInfo.printDeclaration(cout);
|
||||
|
||||
out << endl;
|
||||
out << "#endif /* " << headerSymbol << " */" << endl;
|
||||
} catch (exception const& e) {
|
||||
throw(logic_error("Failed to generate header for class " +
|
||||
className + ". " + e.what()));
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
static void
|
||||
printCppFile(ostream & out,
|
||||
proxyClass const& classInfo) {
|
||||
/*----------------------------------------------------------------------------
|
||||
Print a complete definition for the specified class.
|
||||
-----------------------------------------------------------------------------*/
|
||||
string const className(classInfo.className());
|
||||
|
||||
try {
|
||||
out << "// " << className << " - "
|
||||
<< "an XML-RPC FOR C/C++ proxy class" << endl;
|
||||
out << "// Generated by 'xmlrpc_cpp_proxy'" << endl;
|
||||
out << endl;
|
||||
|
||||
out << "#include \"" << className << ".h\"" << endl;
|
||||
|
||||
classInfo.printDefinition(cout);
|
||||
} catch (xmlrpc_c::fault const& f) {
|
||||
throw(logic_error("Failed to generate definition for class " +
|
||||
className + ". " + f.getDescription()));
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
int
|
||||
main(int const argc,
|
||||
const char ** const argv) {
|
||||
|
||||
string const myName(argv[0]);
|
||||
|
||||
cmdlineInfo const cmdline(argc, argv);
|
||||
|
||||
int retval;
|
||||
|
||||
try {
|
||||
proxyClass system(getClassInfo(cmdline.serverUrl,
|
||||
cmdline.methodPrefix,
|
||||
cmdline.localClass));
|
||||
printHeader(cout, system);
|
||||
cout << endl;
|
||||
printCppFile(cout, system);
|
||||
retval = 0;
|
||||
} catch (xmlrpc_c::fault& f) {
|
||||
cerr << myName << ": XML-RPC fault #" << f.getCode()
|
||||
<< ": " << f.getDescription() << endl;
|
||||
retval = 1;
|
||||
} catch (exception const& e) {
|
||||
cerr << myName << ": " << e.what() << endl;
|
||||
retval = 1;
|
||||
} catch (...) {
|
||||
cerr << myName << ": Unknown exception" << endl;
|
||||
retval = 1;
|
||||
}
|
||||
|
||||
return retval;
|
||||
}
|
Reference in New Issue
Block a user