File: xml-rpc-api2cpp.cpp

package info (click to toggle)
xmlrpc-c 1.06.27-1.1
  • links: PTS
  • area: main
  • in suites: squeeze
  • size: 4,308 kB
  • ctags: 5,111
  • sloc: ansic: 39,324; sh: 8,284; cpp: 6,051; makefile: 1,339; perl: 494; xml: 134
file content (157 lines) | stat: -rw-r--r-- 4,706 bytes parent folder | download | duplicates (2)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
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;
}