mirror of
https://github.com/signalwire/freeswitch.git
synced 2025-03-23 23:57:37 +00:00
git-svn-id: http://svn.freeswitch.org/svn/freeswitch/trunk@8545 d0543943-73ff-0310-b7d9-9358b9ac24b2
170 lines
4.5 KiB
C++
170 lines
4.5 KiB
C++
#include <string>
|
|
#include <cstring>
|
|
|
|
#include "xmlrpc-c/girerr.hpp"
|
|
using girerr::error;
|
|
#include "env_wrap.hpp"
|
|
#include "xmlrpc-c/base.h"
|
|
#include "xmlrpc-c/base.hpp"
|
|
#include "xmlrpc-c/client.hpp"
|
|
#include <xmlrpc-c/client.hpp>
|
|
|
|
#include "xmlrpc-c/client_simple.hpp"
|
|
|
|
using namespace std;
|
|
using namespace xmlrpc_c;
|
|
|
|
namespace xmlrpc_c {
|
|
|
|
|
|
namespace {
|
|
|
|
void
|
|
throwIfError(env_wrap const& env) {
|
|
|
|
if (env.env_c.fault_occurred)
|
|
throw(error(env.env_c.fault_string));
|
|
}
|
|
|
|
|
|
class cValueWrapper {
|
|
/*----------------------------------------------------------------------------
|
|
Use an object of this class to set up to remove a reference to an
|
|
xmlrpc_value object (a C object with manual reference management)
|
|
at then end of a scope -- even if the scope ends with a throw.
|
|
-----------------------------------------------------------------------------*/
|
|
xmlrpc_value * valueP;
|
|
public:
|
|
cValueWrapper(xmlrpc_value * valueP) : valueP(valueP) {}
|
|
~cValueWrapper() { xmlrpc_DECREF(valueP); }
|
|
};
|
|
|
|
} // namespace
|
|
|
|
|
|
|
|
clientSimple::clientSimple() {
|
|
|
|
clientXmlTransportPtr const transportP(clientXmlTransport_http::create());
|
|
|
|
this->clientP = clientPtr(new client_xml(transportP));
|
|
}
|
|
|
|
|
|
|
|
void
|
|
clientSimple::call(string const serverUrl,
|
|
string const methodName,
|
|
value * const resultP) {
|
|
|
|
carriageParm_http0 carriageParm(serverUrl);
|
|
|
|
rpcPtr rpcPtr(methodName, paramList());
|
|
|
|
rpcPtr->call(this->clientP.get(), &carriageParm);
|
|
|
|
*resultP = rpcPtr->getResult();
|
|
}
|
|
|
|
|
|
namespace {
|
|
|
|
void
|
|
makeParamArray(string const format,
|
|
xmlrpc_value ** const paramArrayPP,
|
|
va_list args) {
|
|
|
|
env_wrap env;
|
|
|
|
/* The format is a sequence of parameter specifications, such as
|
|
"iiii" for 4 integer parameters. We add parentheses to make it
|
|
an array of those parameters: "(iiii)".
|
|
*/
|
|
string const arrayFormat("(" + string(format) + ")");
|
|
const char * tail;
|
|
|
|
xmlrpc_build_value_va(&env.env_c, arrayFormat.c_str(),
|
|
args, paramArrayPP, &tail);
|
|
|
|
if (env.env_c.fault_occurred)
|
|
throw(error(env.env_c.fault_string));
|
|
|
|
if (strlen(tail) != 0) {
|
|
/* xmlrpc_build_value_va() parses off a single value specification
|
|
from its format string, and 'tail' points to whatever is after
|
|
it. Our format string should have been a single array value,
|
|
meaning tail is end-of-string. If it's not, that means
|
|
something closed our array early.
|
|
*/
|
|
xmlrpc_DECREF(*paramArrayPP);
|
|
throw(error("format string is invalid. It apparently has a "
|
|
"stray right parenthesis"));
|
|
}
|
|
}
|
|
|
|
} // namespace
|
|
|
|
|
|
void
|
|
clientSimple::call(string const serverUrl,
|
|
string const methodName,
|
|
string const format,
|
|
value * const resultP,
|
|
...) {
|
|
|
|
carriageParm_http0 carriageParm(serverUrl);
|
|
|
|
env_wrap env;
|
|
xmlrpc_value * paramArrayP;
|
|
|
|
va_list args;
|
|
va_start(args, resultP);
|
|
makeParamArray(format, ¶mArrayP, args);
|
|
va_end(args);
|
|
|
|
if (env.env_c.fault_occurred)
|
|
throw(error(env.env_c.fault_string));
|
|
else {
|
|
cValueWrapper paramArrayWrapper(paramArrayP); // ensure destruction
|
|
unsigned int const paramCount(
|
|
xmlrpc_array_size(&env.env_c, paramArrayP));
|
|
|
|
if (env.env_c.fault_occurred)
|
|
throw(error(env.env_c.fault_string));
|
|
|
|
paramList paramList;
|
|
for (unsigned int i = 0; i < paramCount; ++i) {
|
|
xmlrpc_value * paramP;
|
|
xmlrpc_array_read_item(&env.env_c, paramArrayP, i, ¶mP);
|
|
if (env.env_c.fault_occurred)
|
|
throw(error(env.env_c.fault_string));
|
|
else {
|
|
cValueWrapper paramWrapper(paramP); // ensure destruction
|
|
paramList.add(value(paramP));
|
|
}
|
|
}
|
|
rpcPtr rpcPtr(methodName, paramList);
|
|
rpcPtr->call(this->clientP.get(), &carriageParm);
|
|
*resultP = rpcPtr->getResult();
|
|
}
|
|
}
|
|
|
|
|
|
|
|
void
|
|
clientSimple::call(string const serverUrl,
|
|
string const methodName,
|
|
paramList const& paramList,
|
|
value * const resultP) {
|
|
|
|
carriageParm_http0 carriageParm(serverUrl);
|
|
|
|
rpcPtr rpcPtr(methodName, paramList);
|
|
|
|
rpcPtr->call(this->clientP.get(), &carriageParm);
|
|
|
|
*resultP = rpcPtr->getResult();
|
|
}
|
|
|
|
} // namespace
|