4 #include "xmlrpc-c/girerr.hpp"
6 #include "env_wrap.hpp"
7 #include "xmlrpc-c/base.h"
8 #include "xmlrpc-c/base.hpp"
9 #include "xmlrpc-c/client.hpp"
10 #include <xmlrpc-c/client.hpp>
12 #include "xmlrpc-c/client_simple.hpp"
15 using namespace xmlrpc_c;
23 throwIfError(env_wrap const& env) {
25 if (env.env_c.fault_occurred)
26 throw(error(env.env_c.fault_string));
31 /*----------------------------------------------------------------------------
32 Use an object of this class to set up to remove a reference to an
33 xmlrpc_value object (a C object with manual reference management)
34 at then end of a scope -- even if the scope ends with a throw.
35 -----------------------------------------------------------------------------*/
36 xmlrpc_value * valueP;
38 cValueWrapper(xmlrpc_value * valueP) : valueP(valueP) {}
39 ~cValueWrapper() { xmlrpc_DECREF(valueP); }
46 clientSimple::clientSimple() {
48 clientXmlTransportPtr const transportP(clientXmlTransport_http::create());
50 this->clientP = clientPtr(new client_xml(transportP));
56 clientSimple::call(string const serverUrl,
57 string const methodName,
58 value * const resultP) {
60 carriageParm_http0 carriageParm(serverUrl);
62 rpcPtr rpcPtr(methodName, paramList());
64 rpcPtr->call(this->clientP.get(), &carriageParm);
66 *resultP = rpcPtr->getResult();
73 makeParamArray(string const format,
74 xmlrpc_value ** const paramArrayPP,
79 /* The format is a sequence of parameter specifications, such as
80 "iiii" for 4 integer parameters. We add parentheses to make it
81 an array of those parameters: "(iiii)".
83 string const arrayFormat("(" + string(format) + ")");
86 xmlrpc_build_value_va(&env.env_c, arrayFormat.c_str(),
87 args, paramArrayPP, &tail);
89 if (env.env_c.fault_occurred)
90 throw(error(env.env_c.fault_string));
92 if (strlen(tail) != 0) {
93 /* xmlrpc_build_value_va() parses off a single value specification
94 from its format string, and 'tail' points to whatever is after
95 it. Our format string should have been a single array value,
96 meaning tail is end-of-string. If it's not, that means
97 something closed our array early.
99 xmlrpc_DECREF(*paramArrayPP);
100 throw(error("format string is invalid. It apparently has a "
101 "stray right parenthesis"));
109 clientSimple::call(string const serverUrl,
110 string const methodName,
112 value * const resultP,
115 carriageParm_http0 carriageParm(serverUrl);
118 xmlrpc_value * paramArrayP;
121 va_start(args, resultP);
122 makeParamArray(format, ¶mArrayP, args);
125 if (env.env_c.fault_occurred)
126 throw(error(env.env_c.fault_string));
128 cValueWrapper paramArrayWrapper(paramArrayP); // ensure destruction
129 unsigned int const paramCount(
130 xmlrpc_array_size(&env.env_c, paramArrayP));
132 if (env.env_c.fault_occurred)
133 throw(error(env.env_c.fault_string));
136 for (unsigned int i = 0; i < paramCount; ++i) {
137 xmlrpc_value * paramP;
138 xmlrpc_array_read_item(&env.env_c, paramArrayP, i, ¶mP);
139 if (env.env_c.fault_occurred)
140 throw(error(env.env_c.fault_string));
142 cValueWrapper paramWrapper(paramP); // ensure destruction
143 paramList.add(value(paramP));
146 rpcPtr rpcPtr(methodName, paramList);
147 rpcPtr->call(this->clientP.get(), &carriageParm);
148 *resultP = rpcPtr->getResult();
155 clientSimple::call(string const serverUrl,
156 string const methodName,
157 paramList const& paramList,
158 value * const resultP) {
160 carriageParm_http0 carriageParm(serverUrl);
162 rpcPtr rpcPtr(methodName, paramList);
164 rpcPtr->call(this->clientP.get(), &carriageParm);
166 *resultP = rpcPtr->getResult();