initial load of upstream version 1.06.32
[xmlrpc-c] / tools / xml-rpc-api2cpp / xml-rpc-api2cpp.cpp
diff --git a/tools/xml-rpc-api2cpp/xml-rpc-api2cpp.cpp b/tools/xml-rpc-api2cpp/xml-rpc-api2cpp.cpp
new file mode 100644 (file)
index 0000000..756d50d
--- /dev/null
@@ -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;
+}