1 /* An XML-RPC client program written in C, as an example of using
2 compound XML-RPC values.
3
4 For a simple client program that just deals with integer values,
5 see xmlrpc_sample_add_client.c. This example focuses just on the
6 compound XML-RPC values and not the client functions.
7
8 This client invokes the example.divide XML-RPC method that the example
9 server program compound_value_server.c provides. That method takes a
10 list of pairs of numbers and returns the list of their quotients.
11
12 Compound XML-RPC values are arrays and structures. We call them compound
13 because they are made up of other XML-RPC values (e.g. an array of XML-RPC
14 integers).
15
16 The arguments to the example.divide method are specified as follows:
17
18 There are two arguments:
19
20 Argument 0: Integer. Version number of this argument protocol. Must
21 be 1.
22
23 Argument 1: Array. One element for each pair of numbers you want the
24 server to divide. Each element is structure, with these
25 members:
26
27 KEY: "dividend"
28 VALUE: floating point number. The dividend.
29
30 KEY: "divisor"
31 VALUE: floating point number. The divisor.
32
33 The result of the method is an array. It has one member for each pair of
34 numbers in the arguments (So it is the same size as Argument 1). That
35 member is a floating point number. It is the quotient of the numbers
36 in the corresponding element of Argument 1.
37
38 The client sends the RPC to the server running on the local system
39 ("localhost"), HTTP Port 8080.
40 */
41
42 #include <stdlib.h>
43 #include <stdio.h>
44
45 #include <xmlrpc-c/base.h>
46 #include <xmlrpc-c/client.h>
47
48 #include "config.h" /* information about this build environment */
49
50 #define NAME "Xmlrpc-c Test Client"
51 #define VERSION "1.0"
52
53 static void
dieIfFaultOccurred(xmlrpc_env * const envP)54 dieIfFaultOccurred (xmlrpc_env * const envP) {
55 if (envP->fault_occurred) {
56 fprintf(stderr, "ERROR: %s (%d)\n",
57 envP->fault_string, envP->fault_code);
58 exit(1);
59 }
60 }
61
62
63
64 struct ratio {
65 double dividend;
66 double divisor;
67 };
68
69
70
71 int
main(int const argc,const char ** const argv)72 main(int const argc,
73 const char ** const argv) {
74
75 const char * const serverUrl = "http://localhost:8080/RPC2";
76 const char * const methodName = "example.divide";
77 unsigned int const argVersion = 1;
78 struct ratio const data[] = {{1,2},{12,3},{10,3},{89,3000}};
79 xmlrpc_env env;
80 xmlrpc_value * resultP;
81 unsigned int i;
82 xmlrpc_value * ratioArrayP;
83 unsigned int quotientCt;
84
85 if (argc-1 > 0) {
86 fprintf(stderr, "This program has no arguments\n");
87 exit(1);
88 }
89
90 xmlrpc_env_init(&env);
91
92 xmlrpc_client_init2(&env, XMLRPC_CLIENT_NO_FLAGS, NAME, VERSION, NULL, 0);
93 dieIfFaultOccurred(&env);
94
95 /* Build the 2nd method argument: the array of ratios */
96
97 ratioArrayP = xmlrpc_array_new(&env);
98 dieIfFaultOccurred(&env);
99
100 for (i = 0; i < 4; ++i) {
101 xmlrpc_value * dividendP;
102 xmlrpc_value * divisorP;
103 xmlrpc_value * ratioP;
104
105 dividendP = xmlrpc_double_new(&env, data[i].dividend);
106 dieIfFaultOccurred(&env);
107 divisorP = xmlrpc_double_new(&env, data[i].divisor);
108 dieIfFaultOccurred(&env);
109
110 ratioP = xmlrpc_struct_new(&env);
111 dieIfFaultOccurred(&env);
112
113 xmlrpc_struct_set_value(&env, ratioP, "DIVIDEND", dividendP);
114 dieIfFaultOccurred(&env);
115 xmlrpc_struct_set_value(&env, ratioP, "DIVISOR", divisorP);
116 dieIfFaultOccurred(&env);
117
118 xmlrpc_array_append_item(&env, ratioArrayP, ratioP);
119 dieIfFaultOccurred(&env);
120
121 xmlrpc_DECREF(ratioP);
122 xmlrpc_DECREF(divisorP);
123 xmlrpc_DECREF(dividendP);
124 }
125
126 /* Make the call */
127
128 resultP = xmlrpc_client_call(&env, serverUrl, methodName, "(iA)",
129 (xmlrpc_int32) argVersion, ratioArrayP);
130 dieIfFaultOccurred(&env);
131
132 /* Print out the quotients returned */
133
134 quotientCt = xmlrpc_array_size(&env, resultP);
135 dieIfFaultOccurred(&env);
136
137 for (i = 0; i < quotientCt; ++i) {
138 xmlrpc_value * quotientP;
139 xmlrpc_double quotient;
140
141 xmlrpc_array_read_item(&env, resultP, i, "ientP);
142 dieIfFaultOccurred(&env);
143
144 xmlrpc_read_double(&env, quotientP, "ient);
145 dieIfFaultOccurred(&env);
146
147 printf("Server says quotient %u is %f\n", i, quotient);
148
149 xmlrpc_DECREF(quotientP);
150 }
151
152 xmlrpc_DECREF(resultP);
153
154 xmlrpc_env_clean(&env);
155
156 xmlrpc_client_cleanup();
157
158 return 0;
159 }
160
161