|
|
#include <iostream> |
|
|
#include <stdexcept> |
|
|
#include <cstdlib> |
|
|
|
|
|
#include "xmlrpcType.hpp" |
|
|
#include "xmlrpcMethod.hpp" |
|
|
#include "proxyClass.hpp" |
|
|
#include "systemProxy.hpp" |
|
|
|
|
|
using namespace std; |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
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) { |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
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) { |
|
|
|
|
|
|
|
|
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) { |
|
|
|
|
|
|
|
|
string const help(system.methodHelp(serverUrl, methodName)); |
|
|
xmlrpc_c::value const signatureList( |
|
|
system.methodSignature(serverUrl, methodName)); |
|
|
|
|
|
if (signatureList.type() != xmlrpc_c::value::TYPE_ARRAY) { |
|
|
|
|
|
|
|
|
cerr << "Skipping method " << methodName << " " |
|
|
<< "because server does not report any signatures " |
|
|
<< "for it (via system.methodSignature method)" |
|
|
<< endl; |
|
|
} else { |
|
|
|
|
|
xmlrpcMethod const method( |
|
|
functionName, |
|
|
methodName, |
|
|
help, |
|
|
xmlrpc_c::value_array(signatureList)); |
|
|
theClass.addFunction(method); |
|
|
} |
|
|
} |
|
|
} |
|
|
return theClass; |
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
static void |
|
|
printHeader(ostream & out, |
|
|
proxyClass const& classInfo) { |
|
|
|
|
|
|
|
|
|
|
|
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) { |
|
|
|
|
|
|
|
|
|
|
|
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; |
|
|
} |
|
|
|