initial load of upstream version 1.06.32
[xmlrpc-c] / tools / xml-rpc-api2cpp / xml-rpc-api2cpp.cpp
1 #include <iostream>
2 #include <stdexcept>
3
4 #include "xmlrpc-c/oldcppwrapper.hpp"
5
6 #include "DataType.hpp"
7 #include "XmlRpcFunction.hpp"
8 #include "XmlRpcClass.hpp"
9 #include "SystemProxy.hpp"
10
11 using namespace std;
12
13 #define NAME           "xml-rpc-api2cpp"
14 #define VERSION        "0.1"
15
16
17 //=========================================================================
18 //  function get_class_info
19 //=========================================================================
20 //  Connect to a remote server and extract the information we'll need to
21 //  build a proxy class.
22
23 XmlRpcClass get_class_info (string server_url,
24                             string class_prefix,
25                             string class_name)
26 {
27     // Create a place to store our data.
28     XmlRpcClass info(class_name);
29
30     // Create a proxy class.
31     SystemProxy system(server_url);
32
33     // Fetch the full list of methods, and process the ones we want.
34     XmlRpcValue methods = system.listMethods();
35     size_t end = methods.arraySize();
36     for (size_t i = 0; i < end; i++) {
37
38         // Break the method name into two pieces.
39         string method_prefix;
40         string function_name;
41         string method_name = methods.arrayGetItem(i).getString();
42         size_t last_dot = method_name.rfind('.');
43         if (last_dot == string::npos) {
44             function_name = method_name;
45         } else {
46             method_prefix = string(method_name, 0, last_dot);
47             function_name = string(method_name, last_dot + 1);
48         }
49
50         // Decide whether we care about this function.
51         if (method_prefix == class_prefix) {
52
53             // Fetch some information about the function.
54             string help = system.methodHelp(method_name);
55             XmlRpcValue signature = system.methodSignature(method_name);
56
57             // Add this function to our class information.
58             XmlRpcFunction func(function_name, method_name, help, signature);
59             info.addFunction(func);
60         }
61     }
62
63     return info;
64 }
65
66
67 //=========================================================================
68 //  function print_header
69 //=========================================================================
70 //  Print a complete header for the specified class.
71
72 void print_header (ostream& out, XmlRpcClass& class_info) {
73     string class_name = class_info.className();
74     out << "// " << class_name << ".h - xmlrpc-c C++ proxy class" << endl;
75     out << "// Auto-generated by xml-rpc-api2cpp." << endl;
76     out << endl;
77
78     string header_symbol = "_" + class_name + "_H_";
79     out << "#ifndef " << header_symbol << endl;
80     out << "#define " << header_symbol << " 1" << endl;
81     out << endl;
82     out << "#include <XmlRpcCpp.h>" << endl;
83     out << endl;
84
85     class_info.printDeclaration(cout);
86
87     out << endl;
88     out << "#endif /* " << header_symbol << " */" << endl;
89 }
90
91
92 //=========================================================================
93 //  function print_cc_file
94 //=========================================================================
95 //  Print a complete header for the specified class.
96
97 void print_cc_file (ostream& out, XmlRpcClass& class_info) {
98     string class_name = class_info.className();
99     out << "// " << class_name << ".cc - xmlrpc-c C++ proxy class" << endl;
100     out << "// Auto-generated by xml-rpc-api2cpp." << endl;
101     out << endl;
102
103     out << "#include <XmlRpcCpp.h>" << endl;
104     out << "#include \"" << class_name << ".h\"" << endl;
105
106     class_info.printDefinition(cout);
107 }
108
109
110 //=========================================================================
111 //  function main
112 //=========================================================================
113 //  For now, just a test harness.
114
115 int main (int argc, char **argv) {
116
117     /* Parse our command-line arguments. */
118     if (argc != 4) {
119         cerr << argv[0] << ": Usage:" << endl
120              << "  xml-rpc-api2cpp <server_url> <method_prefix> <local_class>"
121              << endl << endl
122              << "Sample arguments:" << endl
123              << "  server_url = http://localhost/RPC2" << endl
124              << "  method_prefix = system" << endl
125              << "  local_class = SystemProxy" << endl;
126         exit(1);
127     }
128     string server_url = argv[1];
129     string method_prefix = argv[2];
130     string local_class = argv[3];
131
132     int status = 0;
133     XmlRpcClient::Initialize(NAME, VERSION);
134
135     try {
136         XmlRpcClass system = get_class_info(server_url,
137                                             method_prefix,
138                                             local_class);
139         print_header(cout, system);
140         cout << endl;
141         print_cc_file(cout, system);
142     } catch (XmlRpcFault& fault) {
143         cerr << argv[0] << ": XML-RPC fault #" << fault.getFaultCode()
144              << ": " << fault.getFaultString() << endl;
145         status = 1;
146     } catch (logic_error& err) {
147         cerr << argv[0] << ": " << err.what() << endl;
148         status = 1;
149     } catch (...) {
150         cerr << argv[0] << ": Unknown exception" << endl;
151         status = 1;
152     }
153
154     XmlRpcClient::Terminate();
155
156     return status;
157 }