3 #include "xmlrpc-c/girerr.hpp"
6 #include "xmlrpc-c/base.h"
7 #include "xmlrpc-c/string_int.h"
8 #include "xmlrpc-c/base.hpp"
9 #include "env_wrap.hpp"
11 #include "xmlrpc-c/xml.hpp"
14 using namespace xmlrpc_c;
20 /*----------------------------------------------------------------------------
21 Use an object of this class to set up to remove a reference to an
22 xmlrpc_value object (a C object with manual reference management)
23 at then end of a scope -- even if the scope ends with a throw.
24 -----------------------------------------------------------------------------*/
26 xmlrpc_value * valueP;
27 cValueWrapper(xmlrpc_value * valueP) : valueP(valueP) {}
28 ~cValueWrapper() { xmlrpc_DECREF(valueP); }
32 cArrayFromParamList(paramList const& paramList) {
36 xmlrpc_value * paramArrayP;
38 paramArrayP = xmlrpc_array_new(&env.env_c);
39 if (!env.env_c.fault_occurred) {
40 for (unsigned int i = 0;
41 i < paramList.size() && !env.env_c.fault_occurred;
43 cValueWrapper const param(paramList[i].cValue());
45 xmlrpc_array_append_item(&env.env_c, paramArrayP, param.valueP);
48 if (env.env_c.fault_occurred) {
49 xmlrpc_DECREF(paramArrayP);
50 throw(error(env.env_c.fault_string));
63 generateCall(string const& methodName,
64 paramList const& paramList,
65 string * const callXmlP) {
66 /*----------------------------------------------------------------------------
67 Generate the XML for an XML-RPC call, given a method name and parameter
69 -----------------------------------------------------------------------------*/
70 class memblockWrapper {
71 xmlrpc_mem_block * const memblockP;
73 memblockWrapper(xmlrpc_mem_block * const memblockP) :
74 memblockP(memblockP) {}
77 XMLRPC_MEMBLOCK_FREE(char, memblockP);
81 xmlrpc_mem_block * callXmlMP;
84 callXmlMP = XMLRPC_MEMBLOCK_NEW(char, &env.env_c, 0);
85 if (!env.env_c.fault_occurred) {
86 memblockWrapper callXmlHolder(callXmlMP);
87 // Makes callXmlMP get freed at end of scope
89 xmlrpc_value * const paramArrayP(cArrayFromParamList(paramList));
91 xmlrpc_serialize_call(&env.env_c, callXmlMP, methodName.c_str(),
94 *callXmlP = string(XMLRPC_MEMBLOCK_CONTENTS(char, callXmlMP),
95 XMLRPC_MEMBLOCK_SIZE(char, callXmlMP));
97 xmlrpc_DECREF(paramArrayP);
99 if (env.env_c.fault_occurred)
100 throw(error(env.env_c.fault_string));
106 parseResponse(string const& responseXml,
107 rpcOutcome * const outcomeP) {
108 /*----------------------------------------------------------------------------
109 Parse the XML for an XML-RPC response into an XML-RPC result value.
110 -----------------------------------------------------------------------------*/
113 xmlrpc_value * c_resultP;
115 const char * faultString;
117 xmlrpc_parse_response2(&env.env_c, responseXml.c_str(), responseXml.size(),
118 &c_resultP, &faultCode, &faultString);
120 if (env.env_c.fault_occurred)
121 throwf("Unable to find XML-RPC response in what server sent back. %s",
122 env.env_c.fault_string);
126 rpcOutcome(fault(faultString,
127 static_cast<fault::code_t>(faultCode)));
128 xmlrpc_strfree(faultString);
130 XMLRPC_ASSERT_VALUE_OK(c_resultP);
131 *outcomeP = rpcOutcome(value(c_resultP));
132 xmlrpc_DECREF(c_resultP);
140 parseSuccessfulResponse(string const& responseXml,
141 value * const resultP) {
142 /*----------------------------------------------------------------------------
143 Same as parseResponse(), but expects the response to indicate success;
144 throws an error if it doesn't.
145 -----------------------------------------------------------------------------*/
148 parseResponse(responseXml, &outcome);
150 if (!outcome.succeeded())
151 throwf("RPC response indicates it failed. %s",
152 outcome.getFault().getDescription().c_str());
154 *resultP = outcome.getResult();
160 trace(string const& label,
163 xmlrpc_traceXml(label.c_str(), xml.c_str(), xml.size());