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