#include <stdbool.h>
#include "EXTERN.h"
#include "perl.h"
#include "XSUB.h"
#include <xmlrpc-c/base.h>
#include <xmlrpc-c/util.h>
#include <xmlrpc-c/client.h>
static void
returnCreateData(xmlrpc_env const env,
xmlrpc_client * const clientP,
SV * const execObjR,
SV * const errorRetR) {
if (SvROK(errorRetR)) {
SV * const errorRet = SvRV(errorRetR);
if (env.fault_occurred)
sv_setpv(errorRet, env.fault_string);
else
sv_setsv(errorRet, &PL_sv_undef);
}
if (!env.fault_occurred) {
SV * const execObj = SvRV(execObjR);
sv_setuv(execObj, (unsigned long)clientP);
}
}
static void
returnCallData(xmlrpc_env const env,
xmlrpc_value * const resultP,
SV * const resultR,
SV * const errorRetR) {
if (SvROK(errorRetR)) {
SV * const errorRet = SvRV(errorRetR);
if (env.fault_occurred)
sv_setpv(errorRet, env.fault_string);
else
sv_setsv(errorRet, &PL_sv_undef);
}
if (!env.fault_occurred) {
SV * const result = SvRV(resultR);
sv_setuv(result, (unsigned long)resultP);
}
}
static void
returnCallXmlData(xmlrpc_env const env,
xmlrpc_mem_block * const xmlP,
SV * const xmlR,
SV * const errorRetR) {
if (SvROK(errorRetR)) {
SV * const errorRet = SvRV(errorRetR);
if (env.fault_occurred)
sv_setpv(errorRet, env.fault_string);
else
sv_setsv(errorRet, &PL_sv_undef);
}
if (!env.fault_occurred) {
SV * const xml = SvRV(xmlR);
xmlrpc_env env;
xmlrpc_env_init(&env);
XMLRPC_TYPED_MEM_BLOCK_APPEND(char, &env, xmlP, "\0", 1);
sv_setpv(xml, XMLRPC_TYPED_MEM_BLOCK_CONTENTS(char, xmlP));
xmlrpc_env_clean(&env);
}
}
MODULE = RPC::Xmlrpc_c::Client PACKAGE = RPC::Xmlrpc_c::Client
PROTOTYPES: ENABLE
void
_client_setup_global_const(errorRetR)
SV * errorRetR;
CODE:
{
if (!SvROK(errorRetR))
XSRETURN_EMPTY;
else {
SV * const errorRet = SvRV(errorRetR);
xmlrpc_env env;
xmlrpc_env_init(&env);
xmlrpc_client_setup_global_const(&env);
if (env.fault_occurred)
sv_setpv(errorRet, env.fault_string);
else
sv_setsv(errorRet, &PL_sv_undef);
xmlrpc_env_clean(&env);
}
}
void
_clientCreate(_transportOps, _transport, execObjR, errorRetR)
unsigned long _transportOps;
unsigned long _transport;
SV * execObjR;
SV * errorRetR;
CODE:
{
xmlrpc_client * clientP;
xmlrpc_env env;
xmlrpc_env_init(&env);
if (!SvROK(execObjR))
xmlrpc_faultf(&env,
"executable object argument is not a reference");
if (!env.fault_occurred) {
struct xmlrpc_client_transport_ops * const transportOpsP =
(struct xmlrpc_client_transport_ops *) _transportOps;
struct xmlrpc_client_transport * const transportP =
(struct xmlrpc_client_transport *) _transport;
struct xmlrpc_clientparms clientParms;
clientParms.transport = NULL;
clientParms.transportparmsP = NULL;
clientParms.transportparm_size = 0;
clientParms.transportOpsP = transportOpsP;
clientParms.transportP = transportP;
xmlrpc_client_create(&env, 0, "", "",
&clientParms, XMLRPC_CPSIZE(transportP),
&clientP);
}
returnCreateData(env, clientP, execObjR, errorRetR);
xmlrpc_env_clean(&env);
}
void
_clientDestroy(_client)
unsigned long _client;
CODE:
{
xmlrpc_client * const clientP = (xmlrpc_client *)_client;
xmlrpc_client_destroy(clientP);
}
void
_clientCall(_client, serverUrl, methodName, _paramArray, resultR, errorRetR)
unsigned long _client;
const char * serverUrl;
const char * methodName;
unsigned long _paramArray;
SV * resultR;
SV * errorRetR;
CODE:
{
xmlrpc_client * const clientP = (xmlrpc_client *)_client;
xmlrpc_value * const paramArrayP = (xmlrpc_value *)_paramArray;
xmlrpc_value * resultP;
xmlrpc_server_info * serverInfoP;
xmlrpc_env env;
XMLRPC_ASSERT_ARRAY_OK(paramArrayP);
xmlrpc_env_init(&env);
serverInfoP = xmlrpc_server_info_new(&env, serverUrl);
if (!env.fault_occurred) {
xmlrpc_client_call2(&env, clientP, serverInfoP, methodName,
paramArrayP, &resultP);
xmlrpc_server_info_free(serverInfoP);
}
returnCallData(env, resultP, resultR, errorRetR);
xmlrpc_env_clean(&env);
}
void
_callXml(methodName, _paramArray, xmlR, errorRetR)
const char * methodName;
unsigned long _paramArray;
SV * xmlR;
SV * errorRetR;
CODE:
{
xmlrpc_value * const paramArrayP = (xmlrpc_value *)_paramArray;
xmlrpc_env env;
xmlrpc_mem_block * outputP;
XMLRPC_ASSERT_ARRAY_OK(paramArrayP);
xmlrpc_env_init(&env);
outputP = XMLRPC_MEMBLOCK_NEW(char, &env, 0);
xmlrpc_serialize_call(&env, outputP, methodName, paramArrayP);
returnCallXmlData(env, outputP, xmlR, errorRetR);
XMLRPC_MEMBLOCK_FREE(char, outputP);
xmlrpc_env_clean(&env);
}