138 lines
4.2 KiB
C++
138 lines
4.2 KiB
C++
|
#include <iostream>
|
||
|
#include <stdexcept>
|
||
|
|
||
|
#include "xmlrpc-c/oldcppwrapper.hpp"
|
||
|
#include "DataType.hpp"
|
||
|
#include "XmlRpcFunction.hpp"
|
||
|
|
||
|
using std::domain_error;
|
||
|
using std::endl;
|
||
|
|
||
|
|
||
|
//=========================================================================
|
||
|
// class XmlRpcFunction
|
||
|
//=========================================================================
|
||
|
// Contains everything we know about a given server function, and knows
|
||
|
// how to print local bindings.
|
||
|
|
||
|
XmlRpcFunction::XmlRpcFunction(const string& function_name,
|
||
|
const string& method_name,
|
||
|
const string& help,
|
||
|
XmlRpcValue synopsis)
|
||
|
: mFunctionName(function_name), mMethodName(method_name),
|
||
|
mHelp(help), mSynopsis(synopsis)
|
||
|
{
|
||
|
}
|
||
|
|
||
|
XmlRpcFunction::XmlRpcFunction (const XmlRpcFunction& f)
|
||
|
: mFunctionName(f.mFunctionName), mMethodName(f.mMethodName),
|
||
|
mHelp(f.mHelp), mSynopsis(f.mSynopsis)
|
||
|
{
|
||
|
}
|
||
|
|
||
|
XmlRpcFunction& XmlRpcFunction::operator= (const XmlRpcFunction& f) {
|
||
|
if (this == &f)
|
||
|
return *this;
|
||
|
mFunctionName = f.mFunctionName;
|
||
|
mMethodName = f.mMethodName;
|
||
|
mHelp = f.mHelp;
|
||
|
mSynopsis = f.mSynopsis;
|
||
|
return *this;
|
||
|
}
|
||
|
|
||
|
void XmlRpcFunction::printDeclarations (ostream& out) {
|
||
|
|
||
|
// XXX - Do a sloppy job of printing documentation.
|
||
|
out << endl << " /* " << mHelp << " */" << endl;
|
||
|
|
||
|
// Print each declaration.
|
||
|
size_t end = mSynopsis.arraySize();
|
||
|
for (size_t i = 0; i < end; i++)
|
||
|
printDeclaration(out, i);
|
||
|
}
|
||
|
|
||
|
void XmlRpcFunction::printDefinitions (ostream& out, const string& className) {
|
||
|
size_t end = mSynopsis.arraySize();
|
||
|
for (size_t i = 0; i < end; i++) {
|
||
|
out << endl;
|
||
|
printDefinition(out, className, i);
|
||
|
}
|
||
|
}
|
||
|
|
||
|
// Print the parameter declarations.
|
||
|
void XmlRpcFunction::printParameters (ostream& out, size_t synopsis_index) {
|
||
|
size_t end = parameterCount(synopsis_index);
|
||
|
bool first = true;
|
||
|
for (size_t i = 0; i < end; i++) {
|
||
|
if (first)
|
||
|
first = false;
|
||
|
else
|
||
|
out << ", ";
|
||
|
|
||
|
const DataType& ptype (parameterType(synopsis_index, i));
|
||
|
string basename = ptype.defaultParameterBaseName(i + 1);
|
||
|
out << ptype.parameterFragment(basename);
|
||
|
}
|
||
|
}
|
||
|
|
||
|
void XmlRpcFunction::printDeclaration (ostream& out, size_t synopsis_index) {
|
||
|
const DataType& rtype (returnType(synopsis_index));
|
||
|
out << " " << rtype.returnTypeFragment() << " "
|
||
|
<< mFunctionName << " (";
|
||
|
printParameters(out, synopsis_index);
|
||
|
out << ");" << endl;
|
||
|
}
|
||
|
|
||
|
void XmlRpcFunction::printDefinition (ostream& out,
|
||
|
const string& className,
|
||
|
size_t synopsis_index)
|
||
|
{
|
||
|
const DataType& rtype (returnType(synopsis_index));
|
||
|
out << rtype.returnTypeFragment() << " "
|
||
|
<< className << "::" << mFunctionName << " (";
|
||
|
printParameters(out, synopsis_index);
|
||
|
out << ") {" << endl;
|
||
|
out << " XmlRpcValue params = XmlRpcValue::makeArray();" << endl;
|
||
|
|
||
|
/* Emit code to convert the parameters into an array of XML-RPC objects. */
|
||
|
size_t end = parameterCount(synopsis_index);
|
||
|
for (size_t i = 0; i < end; i++) {
|
||
|
const DataType& ptype (parameterType(synopsis_index, i));
|
||
|
string basename = ptype.defaultParameterBaseName(i + 1);
|
||
|
out << " params.arrayAppendItem("
|
||
|
<< ptype.inputConversionFragment(basename) << ");" << endl;
|
||
|
}
|
||
|
|
||
|
/* Emit the function call.*/
|
||
|
out << " XmlRpcValue result = this->mClient.call(\""
|
||
|
<< mMethodName << "\", params);" << endl;
|
||
|
|
||
|
/* Emit the return statement. */
|
||
|
out << " return " << rtype.outputConversionFragment("result")
|
||
|
<< ";" << endl;
|
||
|
out << "}" << endl;
|
||
|
}
|
||
|
|
||
|
const DataType& XmlRpcFunction::returnType (size_t synopsis_index) {
|
||
|
XmlRpcValue func_synop = mSynopsis.arrayGetItem(synopsis_index);
|
||
|
return findDataType(func_synop.arrayGetItem(0).getString());
|
||
|
}
|
||
|
|
||
|
size_t XmlRpcFunction::parameterCount (size_t synopsis_index) {
|
||
|
XmlRpcValue func_synop = mSynopsis.arrayGetItem(synopsis_index);
|
||
|
size_t size = func_synop.arraySize();
|
||
|
if (size < 1)
|
||
|
throw domain_error("Synopsis contained no items");
|
||
|
return size - 1;
|
||
|
}
|
||
|
|
||
|
const DataType& XmlRpcFunction::parameterType (size_t synopsis_index,
|
||
|
size_t parameter_index)
|
||
|
{
|
||
|
XmlRpcValue func_synop = mSynopsis.arrayGetItem(synopsis_index);
|
||
|
XmlRpcValue param = func_synop.arrayGetItem(parameter_index + 1);
|
||
|
return findDataType(param.getString());
|
||
|
}
|
||
|
|
||
|
|