mirror of
https://github.com/signalwire/freeswitch.git
synced 2025-08-13 01:26:58 +00:00
add xmlrpc-c 1.03.14 to in tree libs
git-svn-id: http://svn.freeswitch.org/svn/freeswitch/trunk@3772 d0543943-73ff-0310-b7d9-9358b9ac24b2
This commit is contained in:
1
libs/xmlrpc-c/tools/xml-rpc-api2cpp/.cvsignore
Normal file
1
libs/xmlrpc-c/tools/xml-rpc-api2cpp/.cvsignore
Normal file
@@ -0,0 +1 @@
|
||||
xml-rpc-api2cpp
|
195
libs/xmlrpc-c/tools/xml-rpc-api2cpp/DataType.cpp
Normal file
195
libs/xmlrpc-c/tools/xml-rpc-api2cpp/DataType.cpp
Normal file
@@ -0,0 +1,195 @@
|
||||
#include <iostream>
|
||||
#include <sstream>
|
||||
#include <stdexcept>
|
||||
|
||||
#include "xmlrpc-c/oldcppwrapper.hpp"
|
||||
#include "DataType.hpp"
|
||||
|
||||
using namespace std;
|
||||
|
||||
|
||||
|
||||
//=========================================================================
|
||||
// abstract class DataType
|
||||
//=========================================================================
|
||||
// Instances of DataType know how generate code fragments for manipulating
|
||||
// a specific XML-RPC data type.
|
||||
|
||||
string DataType::defaultParameterBaseName (int position) const {
|
||||
ostringstream name_stream;
|
||||
name_stream << typeName() << position << ends;
|
||||
string name(name_stream.str());
|
||||
return name;
|
||||
}
|
||||
|
||||
|
||||
//=========================================================================
|
||||
// class RawDataType
|
||||
//=========================================================================
|
||||
// We want to manipulate some XML-RPC data types as XmlRpcValue objects.
|
||||
|
||||
class RawDataType : public DataType {
|
||||
public:
|
||||
RawDataType (const string& type_name) : DataType(type_name) {}
|
||||
|
||||
virtual string parameterFragment (const string& base_name) const;
|
||||
virtual string inputConversionFragment (const string& base_name) const;
|
||||
virtual string returnTypeFragment () const;
|
||||
virtual string outputConversionFragment (const string& var_name) const;
|
||||
};
|
||||
|
||||
string RawDataType::parameterFragment (const string& base_name) const {
|
||||
return "XmlRpcValue /*" + typeName() + "*/ " + base_name;
|
||||
}
|
||||
|
||||
string RawDataType::inputConversionFragment (const string& base_name) const {
|
||||
return base_name;
|
||||
}
|
||||
|
||||
string RawDataType::returnTypeFragment () const {
|
||||
return "XmlRpcValue /*" + typeName() + "*/";
|
||||
}
|
||||
|
||||
string RawDataType::outputConversionFragment (const string& var_name) const {
|
||||
return var_name;
|
||||
}
|
||||
|
||||
|
||||
//=========================================================================
|
||||
// class SimpleDataType
|
||||
//=========================================================================
|
||||
// Other types can be easily converted to and from a single native type.
|
||||
|
||||
class SimpleDataType : public DataType {
|
||||
string mNativeType;
|
||||
string mMakerFunc;
|
||||
string mGetterFunc;
|
||||
|
||||
public:
|
||||
SimpleDataType (const string& type_name,
|
||||
const string& native_type,
|
||||
const string& maker_func,
|
||||
const string& getter_func);
|
||||
|
||||
virtual string parameterFragment (const string& base_name) const;
|
||||
virtual string inputConversionFragment (const string& base_name) const;
|
||||
virtual string returnTypeFragment () const;
|
||||
virtual string outputConversionFragment (const string& var_name) const;
|
||||
};
|
||||
|
||||
SimpleDataType::SimpleDataType (const string& type_name,
|
||||
const string& native_type,
|
||||
const string& maker_func,
|
||||
const string& getter_func)
|
||||
: DataType(type_name),
|
||||
mNativeType(native_type),
|
||||
mMakerFunc(maker_func),
|
||||
mGetterFunc(getter_func)
|
||||
{
|
||||
}
|
||||
|
||||
string SimpleDataType::parameterFragment (const string& base_name) const {
|
||||
return mNativeType + " " + base_name;
|
||||
}
|
||||
|
||||
string SimpleDataType::inputConversionFragment (const string& base_name) const
|
||||
{
|
||||
return mMakerFunc + "(" + base_name + ")";
|
||||
}
|
||||
|
||||
string SimpleDataType::returnTypeFragment () const {
|
||||
return mNativeType;
|
||||
}
|
||||
|
||||
string SimpleDataType::outputConversionFragment (const string& var_name) const
|
||||
{
|
||||
return var_name + "." + mGetterFunc + "()";
|
||||
}
|
||||
|
||||
|
||||
//=========================================================================
|
||||
// class VoidDataType
|
||||
//=========================================================================
|
||||
// Some XML-RPC servers declare functions as void. Such functions have
|
||||
// an arbitrary return value which we should ignore.
|
||||
|
||||
class VoidDataType : public DataType {
|
||||
public:
|
||||
VoidDataType () : DataType("void") {}
|
||||
|
||||
virtual string parameterFragment (const string& base_name) const;
|
||||
virtual string inputConversionFragment (const string& base_name) const;
|
||||
virtual string returnTypeFragment () const;
|
||||
virtual string outputConversionFragment (const string& var_name) const;
|
||||
};
|
||||
|
||||
string VoidDataType::parameterFragment (const string&) const {
|
||||
throw domain_error("Can't handle functions with 'void' arguments'");
|
||||
|
||||
}
|
||||
|
||||
string VoidDataType::inputConversionFragment (const string&) const {
|
||||
throw domain_error("Can't handle functions with 'void' arguments'");
|
||||
}
|
||||
|
||||
string VoidDataType::returnTypeFragment () const {
|
||||
return "void";
|
||||
}
|
||||
|
||||
string VoidDataType::outputConversionFragment (const string&) const {
|
||||
return "/* Return value ignored. */";
|
||||
}
|
||||
|
||||
|
||||
//=========================================================================
|
||||
// function findDataType
|
||||
//=========================================================================
|
||||
// Given the name of an XML-RPC data type, try to find a corresponding
|
||||
// DataType object.
|
||||
|
||||
SimpleDataType intType ("int", "XmlRpcValue::int32",
|
||||
"XmlRpcValue::makeInt",
|
||||
"getInt");
|
||||
SimpleDataType boolType ("bool", "bool",
|
||||
"XmlRpcValue::makeBool",
|
||||
"getBool");
|
||||
SimpleDataType doubleType ("double", "double",
|
||||
"XmlRpcValue::makeDouble",
|
||||
"getDouble");
|
||||
SimpleDataType stringType ("string", "string",
|
||||
"XmlRpcValue::makeString",
|
||||
"getString");
|
||||
|
||||
RawDataType dateTimeType ("dateTime");
|
||||
RawDataType base64Type ("base64");
|
||||
RawDataType structType ("struct");
|
||||
RawDataType arrayType ("array");
|
||||
|
||||
VoidDataType voidType;
|
||||
|
||||
const DataType& findDataType (const string& name) {
|
||||
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
|
||||
throw domain_error("Unknown XML-RPC type " + name);
|
||||
|
||||
// This code should never be executed.
|
||||
XMLRPC_ASSERT(0);
|
||||
return intType;
|
||||
}
|
43
libs/xmlrpc-c/tools/xml-rpc-api2cpp/DataType.hpp
Normal file
43
libs/xmlrpc-c/tools/xml-rpc-api2cpp/DataType.hpp
Normal file
@@ -0,0 +1,43 @@
|
||||
#include <string>
|
||||
#include <cassert>
|
||||
|
||||
class DataType {
|
||||
std::string mTypeName;
|
||||
|
||||
DataType(DataType const&) { assert(false); }
|
||||
|
||||
DataType& operator= (DataType const&) {
|
||||
assert(false);
|
||||
return *this;
|
||||
}
|
||||
|
||||
public:
|
||||
DataType(const std::string& type_name) : mTypeName(type_name) {}
|
||||
|
||||
virtual ~DataType () {}
|
||||
|
||||
// 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(int 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 DataType& findDataType(const std::string& name);
|
49
libs/xmlrpc-c/tools/xml-rpc-api2cpp/Makefile
Normal file
49
libs/xmlrpc-c/tools/xml-rpc-api2cpp/Makefile
Normal file
@@ -0,0 +1,49 @@
|
||||
ifeq ($(SRCDIR)x,x)
|
||||
SRCDIR = $(CURDIR)/../..
|
||||
BUILDDIR= $(SRCDIR)
|
||||
endif
|
||||
|
||||
default: all
|
||||
|
||||
include $(BUILDDIR)/Makefile.config
|
||||
|
||||
include ../Makefile.common
|
||||
|
||||
INCLUDES = -I$(SRCDIR) -I$(SRCDIR)/include
|
||||
|
||||
CXXFLAGS = $(INCLUDES) $(CXXFLAGS_COMMON) $(CFLAGS_PERSONAL) $(CADD)
|
||||
|
||||
LDFLAGS = $(CLIENT_LDFLAGS) $(LADD)
|
||||
|
||||
all: xml-rpc-api2cpp
|
||||
|
||||
OBJECTS = \
|
||||
xml-rpc-api2cpp.o \
|
||||
DataType.o \
|
||||
XmlRpcFunction.o \
|
||||
XmlRpcClass.o \
|
||||
SystemProxy.o \
|
||||
|
||||
xml-rpc-api2cpp: \
|
||||
$(OBJECTS) \
|
||||
$(LIBXMLRPC_CPP) \
|
||||
$(LIBXMLRPC_CLIENT) \
|
||||
$(LIBXMLRPC_SERVER) \
|
||||
$(LIBXMLRPC) \
|
||||
$(LIBXML)
|
||||
$(LIBTOOL) --mode=link $(CXXLD) -o $@ $(LDFLAGS) $^
|
||||
|
||||
%.o:%.cpp
|
||||
$(LIBTOOL) --mode=compile $(CXX) -c $(CXXFLAGS) $<
|
||||
|
||||
include Makefile.depend
|
||||
|
||||
.PHONY: clean
|
||||
clean: clean-common
|
||||
rm -f xml-rpc-api2cpp
|
||||
|
||||
.PHONY: distclean
|
||||
distclean: clean distclean-common
|
||||
|
||||
.PHONY: dep
|
||||
dep: dep-common
|
0
libs/xmlrpc-c/tools/xml-rpc-api2cpp/Makefile.depend
Normal file
0
libs/xmlrpc-c/tools/xml-rpc-api2cpp/Makefile.depend
Normal file
6
libs/xmlrpc-c/tools/xml-rpc-api2cpp/README
Normal file
6
libs/xmlrpc-c/tools/xml-rpc-api2cpp/README
Normal file
@@ -0,0 +1,6 @@
|
||||
This program generates C++ wrapper classes for XML-RPC servers. It talks
|
||||
to xmlrpc-c and XML-RPC.NET servers without any problems, but tends to
|
||||
choke when talking to mod_php-based servers. It looks like there is some
|
||||
kind of pipelining problem.
|
||||
|
||||
This code is an ongoing project. Please send feedback!
|
39
libs/xmlrpc-c/tools/xml-rpc-api2cpp/SystemProxy.cpp
Normal file
39
libs/xmlrpc-c/tools/xml-rpc-api2cpp/SystemProxy.cpp
Normal file
@@ -0,0 +1,39 @@
|
||||
// SystemProxy.cc - xmlrpc-c C++ proxy class
|
||||
// Auto-generated by xml-rpc-api2cpp.
|
||||
// But for now, this file is maintained manually. When someone figures
|
||||
// out how stuff in this directory works, maybe we'll make it an automatically
|
||||
// generated file. -Bryan 2005.06.05.
|
||||
|
||||
#include <string>
|
||||
|
||||
#include "xmlrpc-c/oldcppwrapper.hpp"
|
||||
#include "SystemProxy.hpp"
|
||||
|
||||
using namespace std;
|
||||
|
||||
XmlRpcValue /*array*/ SystemProxy::listMethods () {
|
||||
XmlRpcValue params = XmlRpcValue::makeArray();
|
||||
XmlRpcValue result = this->mClient.call("system.listMethods", params);
|
||||
return result;
|
||||
}
|
||||
|
||||
XmlRpcValue /*array*/ SystemProxy::methodSignature (string string1) {
|
||||
XmlRpcValue params = XmlRpcValue::makeArray();
|
||||
params.arrayAppendItem(XmlRpcValue::makeString(string1));
|
||||
XmlRpcValue result = this->mClient.call("system.methodSignature", params);
|
||||
return result;
|
||||
}
|
||||
|
||||
string SystemProxy::methodHelp (string string1) {
|
||||
XmlRpcValue params = XmlRpcValue::makeArray();
|
||||
params.arrayAppendItem(XmlRpcValue::makeString(string1));
|
||||
XmlRpcValue result = this->mClient.call("system.methodHelp", params);
|
||||
return result.getString();
|
||||
}
|
||||
|
||||
XmlRpcValue /*array*/ SystemProxy::multicall (XmlRpcValue /*array*/ array1) {
|
||||
XmlRpcValue params = XmlRpcValue::makeArray();
|
||||
params.arrayAppendItem(array1);
|
||||
XmlRpcValue result = this->mClient.call("system.multicall", params);
|
||||
return result;
|
||||
}
|
48
libs/xmlrpc-c/tools/xml-rpc-api2cpp/SystemProxy.hpp
Normal file
48
libs/xmlrpc-c/tools/xml-rpc-api2cpp/SystemProxy.hpp
Normal file
@@ -0,0 +1,48 @@
|
||||
// SystemProxy.h - xmlrpc-c C++ proxy class
|
||||
// Auto-generated by xml-rpc-api2cpp.
|
||||
|
||||
#ifndef _SystemProxy_H_
|
||||
#define _SystemProxy_H_ 1
|
||||
|
||||
#include <string>
|
||||
|
||||
#include "xmlrpc-c/oldcppwrapper.hpp"
|
||||
|
||||
class SystemProxy {
|
||||
XmlRpcClient mClient;
|
||||
|
||||
public:
|
||||
SystemProxy (const XmlRpcClient& client)
|
||||
: mClient(client) {}
|
||||
SystemProxy (const std::string& server_url)
|
||||
: mClient(XmlRpcClient(server_url)) {}
|
||||
SystemProxy (const SystemProxy& o)
|
||||
: mClient(o.mClient) {}
|
||||
|
||||
SystemProxy& operator= (const SystemProxy& o) {
|
||||
if (this != &o) mClient = o.mClient;
|
||||
return *this;
|
||||
}
|
||||
|
||||
/* Return an array of all available XML-RPC methods on this server. */
|
||||
XmlRpcValue /*array*/ listMethods ();
|
||||
|
||||
/* Given the name of a method, return an array of legal
|
||||
signatures. Each signature is an array of strings. The first item of
|
||||
each signature is the return type, and any others items are
|
||||
parameter types. */
|
||||
XmlRpcValue /*array*/ methodSignature (std::string string1);
|
||||
|
||||
/* Given the name of a method, return a help string. */
|
||||
std::string methodHelp (std::string string1);
|
||||
|
||||
/* Process an array of calls, and return an array of results. Calls
|
||||
should be structs of the form {'methodName': string, 'params':
|
||||
array}. Each result will either be a single-item array containg the
|
||||
result value, or a struct of the form {'faultCode': int,
|
||||
'faultString': string}. This is useful when you need to make lots of
|
||||
small calls without lots of round trips. */
|
||||
XmlRpcValue /*array*/ multicall (XmlRpcValue /*array*/ array1);
|
||||
};
|
||||
|
||||
#endif /* _SystemProxy_H_ */
|
78
libs/xmlrpc-c/tools/xml-rpc-api2cpp/XmlRpcClass.cpp
Normal file
78
libs/xmlrpc-c/tools/xml-rpc-api2cpp/XmlRpcClass.cpp
Normal file
@@ -0,0 +1,78 @@
|
||||
#include <iostream>
|
||||
#include <stdexcept>
|
||||
#include <vector>
|
||||
|
||||
using namespace std;
|
||||
|
||||
#include "xmlrpc-c/oldcppwrapper.hpp"
|
||||
|
||||
#include "DataType.hpp"
|
||||
#include "XmlRpcFunction.hpp"
|
||||
#include "XmlRpcClass.hpp"
|
||||
|
||||
|
||||
//=========================================================================
|
||||
// XmlRpcClass
|
||||
//=========================================================================
|
||||
// This class stores information about a proxy class, and knows how to
|
||||
// generate code.
|
||||
|
||||
XmlRpcClass::XmlRpcClass (string class_name)
|
||||
: mClassName(class_name)
|
||||
{
|
||||
}
|
||||
|
||||
XmlRpcClass::XmlRpcClass (const XmlRpcClass& c)
|
||||
: mClassName(c.mClassName),
|
||||
mFunctions(c.mFunctions)
|
||||
{
|
||||
}
|
||||
|
||||
XmlRpcClass& XmlRpcClass::operator= (const XmlRpcClass& c)
|
||||
{
|
||||
if (this == &c)
|
||||
return *this;
|
||||
mClassName = c.mClassName;
|
||||
mFunctions = c.mFunctions;
|
||||
return *this;
|
||||
}
|
||||
|
||||
void XmlRpcClass::addFunction (const XmlRpcFunction& function)
|
||||
{
|
||||
mFunctions.push_back(function);
|
||||
}
|
||||
|
||||
void XmlRpcClass::printDeclaration (ostream&)
|
||||
{
|
||||
cout << "class " << mClassName << " {" << endl;
|
||||
cout << " XmlRpcClient mClient;" << endl;
|
||||
cout << endl;
|
||||
cout << "public:" << endl;
|
||||
cout << " " << mClassName << " (const XmlRpcClient& client)" << endl;
|
||||
cout << " : mClient(client) {}" << endl;
|
||||
cout << " " << mClassName << " (const string& server_url)" << endl;
|
||||
cout << " : mClient(XmlRpcClient(server_url)) {}" << endl;
|
||||
cout << " " << mClassName << " (const " << mClassName << "& o)" << endl;
|
||||
cout << " : mClient(o.mClient) {}" << endl;
|
||||
cout << endl;
|
||||
cout << " " << mClassName << "& operator= (const "
|
||||
<< mClassName << "& o) {" << endl;
|
||||
cout << " if (this != &o) mClient = o.mClient;" << endl;
|
||||
cout << " return *this;" << endl;
|
||||
cout << " }" << endl;
|
||||
|
||||
vector<XmlRpcFunction>::iterator f;
|
||||
for (f = mFunctions.begin(); f < mFunctions.end(); ++f) {
|
||||
f->printDeclarations(cout);
|
||||
}
|
||||
|
||||
cout << "};" << endl;
|
||||
}
|
||||
|
||||
void XmlRpcClass::printDefinition (ostream&)
|
||||
{
|
||||
vector<XmlRpcFunction>::iterator f;
|
||||
for (f = mFunctions.begin(); f < mFunctions.end(); ++f) {
|
||||
f->printDefinitions(cout, mClassName);
|
||||
}
|
||||
}
|
19
libs/xmlrpc-c/tools/xml-rpc-api2cpp/XmlRpcClass.hpp
Normal file
19
libs/xmlrpc-c/tools/xml-rpc-api2cpp/XmlRpcClass.hpp
Normal file
@@ -0,0 +1,19 @@
|
||||
#include <vector>
|
||||
|
||||
class XmlRpcClass {
|
||||
std::string mClassName;
|
||||
std::vector<XmlRpcFunction> mFunctions;
|
||||
|
||||
|
||||
public:
|
||||
XmlRpcClass (std::string class_name);
|
||||
XmlRpcClass (const XmlRpcClass&);
|
||||
XmlRpcClass& operator= (const XmlRpcClass&);
|
||||
|
||||
std::string className () const { return mClassName; }
|
||||
|
||||
void addFunction (const XmlRpcFunction& function);
|
||||
|
||||
void printDeclaration (ostream& out);
|
||||
void printDefinition (ostream& out);
|
||||
};
|
137
libs/xmlrpc-c/tools/xml-rpc-api2cpp/XmlRpcFunction.cpp
Normal file
137
libs/xmlrpc-c/tools/xml-rpc-api2cpp/XmlRpcFunction.cpp
Normal file
@@ -0,0 +1,137 @@
|
||||
#include <iostream>
|
||||
#include <stdexcept>
|
||||
|
||||
#include "xmlrpc-c/oldcppwrapper.hpp"
|
||||
#include "DataType.hpp"
|
||||
#include "XmlRpcFunction.hpp"
|
||||
|
||||
using std::domain_error;
|
||||
using std::endl;
|
||||
|
||||
|
||||
//=========================================================================
|
||||
// class XmlRpcFunction
|
||||
//=========================================================================
|
||||
// Contains everything we know about a given server function, and knows
|
||||
// how to print local bindings.
|
||||
|
||||
XmlRpcFunction::XmlRpcFunction(const string& function_name,
|
||||
const string& method_name,
|
||||
const string& help,
|
||||
XmlRpcValue synopsis)
|
||||
: mFunctionName(function_name), mMethodName(method_name),
|
||||
mHelp(help), mSynopsis(synopsis)
|
||||
{
|
||||
}
|
||||
|
||||
XmlRpcFunction::XmlRpcFunction (const XmlRpcFunction& f)
|
||||
: mFunctionName(f.mFunctionName), mMethodName(f.mMethodName),
|
||||
mHelp(f.mHelp), mSynopsis(f.mSynopsis)
|
||||
{
|
||||
}
|
||||
|
||||
XmlRpcFunction& XmlRpcFunction::operator= (const XmlRpcFunction& f) {
|
||||
if (this == &f)
|
||||
return *this;
|
||||
mFunctionName = f.mFunctionName;
|
||||
mMethodName = f.mMethodName;
|
||||
mHelp = f.mHelp;
|
||||
mSynopsis = f.mSynopsis;
|
||||
return *this;
|
||||
}
|
||||
|
||||
void XmlRpcFunction::printDeclarations (ostream& out) {
|
||||
|
||||
// XXX - Do a sloppy job of printing documentation.
|
||||
out << endl << " /* " << mHelp << " */" << endl;
|
||||
|
||||
// Print each declaration.
|
||||
size_t end = mSynopsis.arraySize();
|
||||
for (size_t i = 0; i < end; i++)
|
||||
printDeclaration(out, i);
|
||||
}
|
||||
|
||||
void XmlRpcFunction::printDefinitions (ostream& out, const string& className) {
|
||||
size_t end = mSynopsis.arraySize();
|
||||
for (size_t i = 0; i < end; i++) {
|
||||
out << endl;
|
||||
printDefinition(out, className, i);
|
||||
}
|
||||
}
|
||||
|
||||
// Print the parameter declarations.
|
||||
void XmlRpcFunction::printParameters (ostream& out, size_t synopsis_index) {
|
||||
size_t end = parameterCount(synopsis_index);
|
||||
bool first = true;
|
||||
for (size_t i = 0; i < end; i++) {
|
||||
if (first)
|
||||
first = false;
|
||||
else
|
||||
out << ", ";
|
||||
|
||||
const DataType& ptype (parameterType(synopsis_index, i));
|
||||
string basename = ptype.defaultParameterBaseName(i + 1);
|
||||
out << ptype.parameterFragment(basename);
|
||||
}
|
||||
}
|
||||
|
||||
void XmlRpcFunction::printDeclaration (ostream& out, size_t synopsis_index) {
|
||||
const DataType& rtype (returnType(synopsis_index));
|
||||
out << " " << rtype.returnTypeFragment() << " "
|
||||
<< mFunctionName << " (";
|
||||
printParameters(out, synopsis_index);
|
||||
out << ");" << endl;
|
||||
}
|
||||
|
||||
void XmlRpcFunction::printDefinition (ostream& out,
|
||||
const string& className,
|
||||
size_t synopsis_index)
|
||||
{
|
||||
const DataType& rtype (returnType(synopsis_index));
|
||||
out << rtype.returnTypeFragment() << " "
|
||||
<< className << "::" << mFunctionName << " (";
|
||||
printParameters(out, synopsis_index);
|
||||
out << ") {" << endl;
|
||||
out << " XmlRpcValue params = XmlRpcValue::makeArray();" << endl;
|
||||
|
||||
/* Emit code to convert the parameters into an array of XML-RPC objects. */
|
||||
size_t end = parameterCount(synopsis_index);
|
||||
for (size_t i = 0; i < end; i++) {
|
||||
const DataType& ptype (parameterType(synopsis_index, i));
|
||||
string basename = ptype.defaultParameterBaseName(i + 1);
|
||||
out << " params.arrayAppendItem("
|
||||
<< ptype.inputConversionFragment(basename) << ");" << endl;
|
||||
}
|
||||
|
||||
/* Emit the function call.*/
|
||||
out << " XmlRpcValue result = this->mClient.call(\""
|
||||
<< mMethodName << "\", params);" << endl;
|
||||
|
||||
/* Emit the return statement. */
|
||||
out << " return " << rtype.outputConversionFragment("result")
|
||||
<< ";" << endl;
|
||||
out << "}" << endl;
|
||||
}
|
||||
|
||||
const DataType& XmlRpcFunction::returnType (size_t synopsis_index) {
|
||||
XmlRpcValue func_synop = mSynopsis.arrayGetItem(synopsis_index);
|
||||
return findDataType(func_synop.arrayGetItem(0).getString());
|
||||
}
|
||||
|
||||
size_t XmlRpcFunction::parameterCount (size_t synopsis_index) {
|
||||
XmlRpcValue func_synop = mSynopsis.arrayGetItem(synopsis_index);
|
||||
size_t size = func_synop.arraySize();
|
||||
if (size < 1)
|
||||
throw domain_error("Synopsis contained no items");
|
||||
return size - 1;
|
||||
}
|
||||
|
||||
const DataType& XmlRpcFunction::parameterType (size_t synopsis_index,
|
||||
size_t parameter_index)
|
||||
{
|
||||
XmlRpcValue func_synop = mSynopsis.arrayGetItem(synopsis_index);
|
||||
XmlRpcValue param = func_synop.arrayGetItem(parameter_index + 1);
|
||||
return findDataType(param.getString());
|
||||
}
|
||||
|
||||
|
37
libs/xmlrpc-c/tools/xml-rpc-api2cpp/XmlRpcFunction.hpp
Normal file
37
libs/xmlrpc-c/tools/xml-rpc-api2cpp/XmlRpcFunction.hpp
Normal file
@@ -0,0 +1,37 @@
|
||||
|
||||
#include <string>
|
||||
#include <iostream>
|
||||
|
||||
using std::string;
|
||||
using std::ostream;
|
||||
|
||||
class XmlRpcFunction {
|
||||
string mFunctionName;
|
||||
string mMethodName;
|
||||
string mHelp;
|
||||
XmlRpcValue mSynopsis;
|
||||
|
||||
public:
|
||||
XmlRpcFunction(const string& function_name,
|
||||
const string& method_name,
|
||||
const string& help,
|
||||
XmlRpcValue synopsis);
|
||||
|
||||
XmlRpcFunction (const XmlRpcFunction&);
|
||||
XmlRpcFunction& operator= (const XmlRpcFunction&);
|
||||
|
||||
void printDeclarations (ostream& out);
|
||||
void printDefinitions (ostream& out, const string& className);
|
||||
|
||||
private:
|
||||
void printParameters (ostream& out, size_t synopsis_index);
|
||||
void printDeclaration (ostream& out, size_t synopsis_index);
|
||||
void printDefinition (ostream& out,
|
||||
const string& className,
|
||||
size_t synopsis_index);
|
||||
|
||||
const DataType& returnType (size_t synopsis_index);
|
||||
size_t parameterCount (size_t synopsis_index);
|
||||
const DataType& parameterType (size_t synopsis_index,
|
||||
size_t parameter_index);
|
||||
};
|
62
libs/xmlrpc-c/tools/xml-rpc-api2cpp/xml-rpc-api2cpp.1
Normal file
62
libs/xmlrpc-c/tools/xml-rpc-api2cpp/xml-rpc-api2cpp.1
Normal file
@@ -0,0 +1,62 @@
|
||||
.\" Hey, EMACS: -*- nroff -*-
|
||||
.\" First parameter, NAME, should be all caps
|
||||
.\" Second parameter, SECTION, should be 1-8, maybe w/ subsection
|
||||
.\" other parameters are allowed: see man(7), man(1)
|
||||
.TH XML-RPC-API2CPP 1 "June 27, 2001"
|
||||
.\" Please adjust this date whenever revising the manpage.
|
||||
.\"
|
||||
.\" Some roff macros, for reference:
|
||||
.\" .nh disable hyphenation
|
||||
.\" .hy enable hyphenation
|
||||
.\" .ad l left justify
|
||||
.\" .ad b justify to both left and right margins
|
||||
.\" .nf disable filling
|
||||
.\" .fi enable filling
|
||||
.\" .br insert line break
|
||||
.\" .sp <n> insert n+1 empty lines
|
||||
.\" for manpage-specific macros, see man(7)
|
||||
.SH NAME
|
||||
xml-rpc-api2cpp \- Make a C++ wrapper class for an XML-RPC API
|
||||
.SH SYNOPSIS
|
||||
.B xml-rpc-api2cpp
|
||||
\fIserver-url\fR \fIremote-method-prefix\fR \fIc++-class-name\fR
|
||||
.SH DESCRIPTION
|
||||
xml-rpc-api2cpp queries an XML-RPC server using the XML-RPC
|
||||
Instrospection API designed by Edd Dumbill. It then prints a C++
|
||||
wrapper class to standard output. This class can be used with
|
||||
xmlrpc-c's C++ API.
|
||||
.PP
|
||||
You can find a list of supported XML-RPC server libraries (and patches
|
||||
for many others) at \fBhttp://xmlrpc-c.sourceforge.net/hacks.php\fR.
|
||||
.SH OPTIONS
|
||||
.TP
|
||||
.I server-url
|
||||
The name of the server to query. Try
|
||||
\fBhttp://xmlrpc-c.sourceforge.net/cgi-bin/interop.cgi\fR.
|
||||
.TP
|
||||
.I remote-method-prefix
|
||||
The prefix of the methods to wrap. For example, to wrap all the
|
||||
system.* calls, you could specify "system".
|
||||
.TP
|
||||
.I c++-class-name
|
||||
The name of the C++ class to generate. Try "SystemProxy".
|
||||
.SH BUGS
|
||||
xml-rpc-api2cpp can't talk to certain PHP servers based on Edd
|
||||
Dumbill's PHP library, because the trailing bytes of the XML-RPC
|
||||
message get truncated in HTTP pipelining mode. It's not clear whether
|
||||
this is a PHP, Apache or w3c-libwww bug.
|
||||
.PP
|
||||
xml-rpc-api2cpp assumes that method descriptions are ASCII text, not
|
||||
HTML as specified in the standard. (In practice, both conventions are
|
||||
often seen.) It may also get unhappy if method descriptions contain
|
||||
"*/".
|
||||
.PP
|
||||
In general, error messages and diagnostics are still fairly poor.
|
||||
.SH SEE ALSO
|
||||
.BR xmlrpc-c (7),
|
||||
.BR xml-rpc-api2txt (1).
|
||||
.PP
|
||||
This program is part of xmlrpc-c.
|
||||
.SH AUTHOR
|
||||
This manual page was written by Eric Kidd <eric.kidd@pobox.com>.
|
||||
It may be distributed under the same terms as the rest of xmlrpc-c.
|
157
libs/xmlrpc-c/tools/xml-rpc-api2cpp/xml-rpc-api2cpp.cpp
Normal file
157
libs/xmlrpc-c/tools/xml-rpc-api2cpp/xml-rpc-api2cpp.cpp
Normal file
@@ -0,0 +1,157 @@
|
||||
#include <iostream>
|
||||
#include <stdexcept>
|
||||
|
||||
#include "xmlrpc-c/oldcppwrapper.hpp"
|
||||
|
||||
#include "DataType.hpp"
|
||||
#include "XmlRpcFunction.hpp"
|
||||
#include "XmlRpcClass.hpp"
|
||||
#include "SystemProxy.hpp"
|
||||
|
||||
using namespace std;
|
||||
|
||||
#define NAME "xml-rpc-api2cpp"
|
||||
#define VERSION "0.1"
|
||||
|
||||
|
||||
//=========================================================================
|
||||
// function get_class_info
|
||||
//=========================================================================
|
||||
// Connect to a remote server and extract the information we'll need to
|
||||
// build a proxy class.
|
||||
|
||||
XmlRpcClass get_class_info (string server_url,
|
||||
string class_prefix,
|
||||
string class_name)
|
||||
{
|
||||
// Create a place to store our data.
|
||||
XmlRpcClass info(class_name);
|
||||
|
||||
// Create a proxy class.
|
||||
SystemProxy system(server_url);
|
||||
|
||||
// Fetch the full list of methods, and process the ones we want.
|
||||
XmlRpcValue methods = system.listMethods();
|
||||
size_t end = methods.arraySize();
|
||||
for (size_t i = 0; i < end; i++) {
|
||||
|
||||
// Break the method name into two pieces.
|
||||
string method_prefix;
|
||||
string function_name;
|
||||
string method_name = methods.arrayGetItem(i).getString();
|
||||
size_t last_dot = method_name.rfind('.');
|
||||
if (last_dot == string::npos) {
|
||||
function_name = method_name;
|
||||
} else {
|
||||
method_prefix = string(method_name, 0, last_dot);
|
||||
function_name = string(method_name, last_dot + 1);
|
||||
}
|
||||
|
||||
// Decide whether we care about this function.
|
||||
if (method_prefix == class_prefix) {
|
||||
|
||||
// Fetch some information about the function.
|
||||
string help = system.methodHelp(method_name);
|
||||
XmlRpcValue signature = system.methodSignature(method_name);
|
||||
|
||||
// Add this function to our class information.
|
||||
XmlRpcFunction func(function_name, method_name, help, signature);
|
||||
info.addFunction(func);
|
||||
}
|
||||
}
|
||||
|
||||
return info;
|
||||
}
|
||||
|
||||
|
||||
//=========================================================================
|
||||
// function print_header
|
||||
//=========================================================================
|
||||
// Print a complete header for the specified class.
|
||||
|
||||
void print_header (ostream& out, XmlRpcClass& class_info) {
|
||||
string class_name = class_info.className();
|
||||
out << "// " << class_name << ".h - xmlrpc-c C++ proxy class" << endl;
|
||||
out << "// Auto-generated by xml-rpc-api2cpp." << endl;
|
||||
out << endl;
|
||||
|
||||
string header_symbol = "_" + class_name + "_H_";
|
||||
out << "#ifndef " << header_symbol << endl;
|
||||
out << "#define " << header_symbol << " 1" << endl;
|
||||
out << endl;
|
||||
out << "#include <XmlRpcCpp.h>" << endl;
|
||||
out << endl;
|
||||
|
||||
class_info.printDeclaration(cout);
|
||||
|
||||
out << endl;
|
||||
out << "#endif /* " << header_symbol << " */" << endl;
|
||||
}
|
||||
|
||||
|
||||
//=========================================================================
|
||||
// function print_cc_file
|
||||
//=========================================================================
|
||||
// Print a complete header for the specified class.
|
||||
|
||||
void print_cc_file (ostream& out, XmlRpcClass& class_info) {
|
||||
string class_name = class_info.className();
|
||||
out << "// " << class_name << ".cc - xmlrpc-c C++ proxy class" << endl;
|
||||
out << "// Auto-generated by xml-rpc-api2cpp." << endl;
|
||||
out << endl;
|
||||
|
||||
out << "#include <XmlRpcCpp.h>" << endl;
|
||||
out << "#include \"" << class_name << ".h\"" << endl;
|
||||
|
||||
class_info.printDefinition(cout);
|
||||
}
|
||||
|
||||
|
||||
//=========================================================================
|
||||
// function main
|
||||
//=========================================================================
|
||||
// For now, just a test harness.
|
||||
|
||||
int main (int argc, char **argv) {
|
||||
|
||||
/* Parse our command-line arguments. */
|
||||
if (argc != 4) {
|
||||
cerr << argv[0] << ": Usage:" << endl
|
||||
<< " xml-rpc-api2cpp <server_url> <method_prefix> <local_class>"
|
||||
<< endl << endl
|
||||
<< "Sample arguments:" << endl
|
||||
<< " server_url = http://localhost/RPC2" << endl
|
||||
<< " method_prefix = system" << endl
|
||||
<< " local_class = SystemProxy" << endl;
|
||||
exit(1);
|
||||
}
|
||||
string server_url = argv[1];
|
||||
string method_prefix = argv[2];
|
||||
string local_class = argv[3];
|
||||
|
||||
int status = 0;
|
||||
XmlRpcClient::Initialize(NAME, VERSION);
|
||||
|
||||
try {
|
||||
XmlRpcClass system = get_class_info(server_url,
|
||||
method_prefix,
|
||||
local_class);
|
||||
print_header(cout, system);
|
||||
cout << endl;
|
||||
print_cc_file(cout, system);
|
||||
} catch (XmlRpcFault& fault) {
|
||||
cerr << argv[0] << ": XML-RPC fault #" << fault.getFaultCode()
|
||||
<< ": " << fault.getFaultString() << endl;
|
||||
status = 1;
|
||||
} catch (logic_error& err) {
|
||||
cerr << argv[0] << ": " << err.what() << endl;
|
||||
status = 1;
|
||||
} catch (...) {
|
||||
cerr << argv[0] << ": Unknown exception" << endl;
|
||||
status = 1;
|
||||
}
|
||||
|
||||
XmlRpcClient::Terminate();
|
||||
|
||||
return status;
|
||||
}
|
Reference in New Issue
Block a user