123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212 |
- #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"
- /*----------------------------------------------------------------------------
- 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 << 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);
- }
- this->serverUrl = string(argv[1]);
- this->methodPrefix = string(argv[2]);
- this->localClass = string(argv[3]);
- }
- static XmlRpcClass
- 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.
- -----------------------------------------------------------------------------*/
- XmlRpcClass info(className);
- SystemProxy system(serverUrl);
- XmlRpcValue const methods(system.listMethods());
- size_t const end = methods.arraySize();
-
- for (size_t i = 0; i < end; ++i) {
- // Break the method name into two pieces.
- string const methodName(methods.arrayGetItem(i).getString());
- 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(methodName));
- XmlRpcValue const signatureList(
- system.methodSignature(methodName));
- if (signatureList.getType() != XMLRPC_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.
- XmlRpcFunction const method(functionName,
- methodName,
- help,
- signatureList);
- info.addFunction(method);
- }
- }
- }
- return info;
- }
- static void
- printHeader(ostream & out,
- XmlRpcClass const& classInfo) {
- /*----------------------------------------------------------------------------
- Print a complete header for the specified class.
- -----------------------------------------------------------------------------*/
- string const className(classInfo.className());
- try {
- out << "// " << className << ".h - xmlrpc-c C++ proxy class" << endl;
- out << "// Auto-generated by xml-rpc-api2cpp." << endl;
- out << endl;
- string const headerSymbol("_" + className + "_H_");
- out << "#ifndef " << headerSymbol << endl;
- out << "#define " << headerSymbol << " 1" << endl;
- out << endl;
- out << "#include <xmlrpc-c/oldcppwrapper.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,
- XmlRpcClass const& classInfo) {
- /*----------------------------------------------------------------------------
- Print a complete definition for the specified class.
- -----------------------------------------------------------------------------*/
- string const className(classInfo.className());
- try {
- out << "// " << className << ".cc - xmlrpc-c C++ proxy class" << endl;
- out << "// Auto-generated by xml-rpc-api2cpp." << endl;
- out << endl;
-
- out << "#include <xmlrpc-c/oldcppwrapper.hpp>" << endl;
- out << "#include \"" << className << ".h\"" << endl;
-
- classInfo.printDefinition(cout);
- } catch (XmlRpcFault const& fault) {
- throw(logic_error("Failed to generate definition for class " +
- className + ". " + fault.getFaultString()));
- }
- }
- int
- main(int const argc,
- const char ** const argv) {
- string const progName(argv[0]);
- cmdlineInfo const cmdline(argc, argv);
- int retval;
- XmlRpcClient::Initialize(NAME, VERSION);
- try {
- XmlRpcClass system = getClassInfo(cmdline.serverUrl,
- cmdline.methodPrefix,
- cmdline.localClass);
- printHeader(cout, system);
- cout << endl;
- printCppFile(cout, system);
- retval = 0;
- } catch (XmlRpcFault& fault) {
- cerr << progName << ": XML-RPC fault #" << fault.getFaultCode()
- << ": " << fault.getFaultString() << endl;
- retval = 1;
- } catch (logic_error& err) {
- cerr << progName << ": " << err.what() << endl;
- retval = 1;
- } catch (...) {
- cerr << progName << ": Unknown exception" << endl;
- retval = 1;
- }
- XmlRpcClient::Terminate();
- return retval;
- }
|