#include #include #include #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(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 " << endl; out << "#include " << 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; }