123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208 |
- #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;
- }
|