// FileClient.cpp : A simple xmlrpc client. Usage: FileClient serverHost serverPort xmlfile | |
// Reads an xmlrpc request from the specified xmlfile and calls the method on the server. | |
// | |
// Link against xmlrpc lib and whatever socket libs your system needs (ws2_32.lib on windows) | |
#include "XmlRpc.h" | |
#include <iostream> | |
#include <fstream> | |
#include <stdlib.h> | |
using namespace XmlRpc; | |
std::string parseRequest(std::string const& xml, XmlRpcValue& params); | |
int main(int argc, char* argv[]) | |
{ | |
if (argc != 4) { | |
std::cerr << "Usage: FileClient serverHost serverPort requestXmlFile\n"; | |
return -1; | |
} | |
int port = atoi(argv[2]); | |
XmlRpc::setVerbosity(5); | |
XmlRpcClient c(argv[1], port); | |
// | |
std::ifstream infile(argv[3]); | |
if (infile.fail()) { | |
std::cerr << "Could not open file '" << argv[3] << "'.\n"; | |
return -1; | |
} | |
// Suck in the file. This is a one-liner in good compilers (which vc++ 6 is not)... | |
infile.seekg(0L, std::ios::end); | |
long nb = infile.tellg(); | |
infile.clear(); | |
infile.seekg(0L); | |
char* b = new char[nb+1]; | |
infile.read(b, nb); | |
b[nb] = 0; | |
std::cout << "Read file.\n"; | |
// Find the methodName and parse the params | |
std::string s(b); | |
XmlRpcValue params; | |
std::string name = parseRequest(s, params); | |
if (name.empty()) { | |
std::cerr << "Could not parse file\n"; | |
return -1; | |
} | |
for (;;) { | |
XmlRpcValue result; | |
std::cout << "Calling " << name << std::endl; | |
if (c.execute(name.c_str(), params, result)) | |
std::cout << result << "\n\n"; | |
else | |
std::cout << "Error calling '" << name << "'\n\n"; | |
std::cout << "Again? [y]: "; | |
std::string ans; | |
std::cin >> ans; | |
if (ans != "" && ans != "y") break; | |
} | |
return 0; | |
} | |
// | |
std::string | |
parseRequest(std::string const& xml, XmlRpcValue& params) | |
{ | |
const char METHODNAME_TAG[] = "<methodName>"; | |
const char PARAMS_TAG[] = "<params>"; | |
const char PARAMS_ETAG[] = "</params>"; | |
const char PARAM_TAG[] = "<param>"; | |
const char PARAM_ETAG[] = "</param>"; | |
int offset = 0; // Number of chars parsed from the request | |
std::string methodName = XmlRpcUtil::parseTag(METHODNAME_TAG, xml, &offset); | |
XmlRpcUtil::log(3, "XmlRpcServerConnection::parseRequest: parsed methodName %s.", methodName.c_str()); | |
if (! methodName.empty() && XmlRpcUtil::findTag(PARAMS_TAG, xml, &offset)) | |
{ | |
int nArgs = 0; | |
while (XmlRpcUtil::nextTagIs(PARAM_TAG, xml, &offset)) { | |
std::cout << "Parsing arg " << nArgs+1 << std::endl; | |
XmlRpcValue arg(xml, &offset); | |
if ( ! arg.valid()) { | |
std::cerr << "Invalid argument\n"; | |
return std::string(); | |
} | |
std::cout << "Adding arg " << nArgs+1 << " to params array." << std::endl; | |
params[nArgs++] = arg; | |
(void) XmlRpcUtil::nextTagIs(PARAM_ETAG, xml, &offset); | |
} | |
XmlRpcUtil::log(3, "XmlRpcServerConnection::parseRequest: parsed %d params.", nArgs); | |
(void) XmlRpcUtil::nextTagIs(PARAMS_ETAG, xml, &offset); | |
} | |
return methodName; | |
} |