2006-12-21 03:57:49 +00:00
|
|
|
#include <iostream>
|
2008-05-23 20:56:24 +00:00
|
|
|
#include <sstream>
|
2006-12-21 03:57:49 +00:00
|
|
|
#include <stdexcept>
|
|
|
|
|
|
|
|
#include "xmlrpc-c/oldcppwrapper.hpp"
|
|
|
|
#include "DataType.hpp"
|
|
|
|
#include "XmlRpcFunction.hpp"
|
|
|
|
|
2008-05-23 20:56:24 +00:00
|
|
|
using namespace std;
|
2006-12-21 03:57:49 +00:00
|
|
|
|
|
|
|
|
2008-05-23 20:56:24 +00:00
|
|
|
XmlRpcFunction::XmlRpcFunction(string const& functionName,
|
|
|
|
string const& methodName,
|
|
|
|
string const& help,
|
|
|
|
XmlRpcValue const signatureList) :
|
|
|
|
mFunctionName(functionName),
|
|
|
|
mMethodName(methodName),
|
|
|
|
mHelp(help),
|
|
|
|
mSynopsis(signatureList) {}
|
2006-12-21 03:57:49 +00:00
|
|
|
|
|
|
|
|
|
|
|
|
2008-05-23 20:56:24 +00:00
|
|
|
XmlRpcFunction::XmlRpcFunction(XmlRpcFunction const& f) :
|
|
|
|
mFunctionName(f.mFunctionName),
|
|
|
|
mMethodName(f.mMethodName),
|
|
|
|
mHelp(f.mHelp),
|
|
|
|
mSynopsis(f.mSynopsis) {}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
XmlRpcFunction&
|
|
|
|
XmlRpcFunction::operator= (XmlRpcFunction const& f) {
|
|
|
|
|
|
|
|
if (this != &f) {
|
|
|
|
this->mFunctionName = f.mFunctionName;
|
|
|
|
this->mMethodName = f.mMethodName;
|
|
|
|
this->mHelp = f.mHelp;
|
|
|
|
this->mSynopsis = f.mSynopsis;
|
|
|
|
}
|
2006-12-21 03:57:49 +00:00
|
|
|
return *this;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
2008-05-23 20:56:24 +00:00
|
|
|
void
|
|
|
|
XmlRpcFunction::printDeclarations(ostream & out) const {
|
|
|
|
|
|
|
|
try {
|
|
|
|
// Print the method help as a comment
|
|
|
|
|
|
|
|
out << endl << " /* " << mHelp << " */" << endl;
|
|
|
|
|
|
|
|
size_t end;
|
|
|
|
|
|
|
|
try {
|
|
|
|
end = mSynopsis.arraySize();
|
|
|
|
} catch (XmlRpcFault const& fault) {
|
|
|
|
throw(logic_error("Failed to get size of signature array for "
|
|
|
|
"method " + this->mFunctionName + ". " +
|
|
|
|
fault.getFaultString()));
|
|
|
|
}
|
|
|
|
// Print the declarations for all the signatures of this
|
|
|
|
// XML-RPC method.
|
|
|
|
|
|
|
|
for (size_t i = 0; i < end; ++i)
|
|
|
|
printDeclaration(out, i);
|
|
|
|
|
|
|
|
} catch (exception const& e) {
|
|
|
|
throw(logic_error("Failed to generate declarations for method " +
|
|
|
|
this->mFunctionName + ". " + e.what()));
|
|
|
|
}
|
2006-12-21 03:57:49 +00:00
|
|
|
}
|
|
|
|
|
2008-05-23 20:56:24 +00:00
|
|
|
|
|
|
|
|
|
|
|
void
|
|
|
|
XmlRpcFunction::printDefinitions(ostream & out,
|
|
|
|
string const& className) const {
|
|
|
|
|
|
|
|
try {
|
|
|
|
size_t const end(mSynopsis.arraySize());
|
|
|
|
|
|
|
|
for (size_t i = 0; i < end; ++i) {
|
|
|
|
out << endl;
|
|
|
|
printDefinition(out, className, i);
|
|
|
|
}
|
|
|
|
} catch (XmlRpcFault const& fault) {
|
|
|
|
throw(logic_error("Failed to generate definitions for class " +
|
|
|
|
this->mFunctionName + ". " +
|
|
|
|
fault.getFaultString()));
|
2006-12-21 03:57:49 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2008-05-23 20:56:24 +00:00
|
|
|
|
|
|
|
|
|
|
|
void
|
|
|
|
XmlRpcFunction::printParameters(ostream & out,
|
|
|
|
size_t const synopsisIndex) const {
|
|
|
|
/*----------------------------------------------------------------------------
|
|
|
|
Print the parameter declarations.
|
|
|
|
-----------------------------------------------------------------------------*/
|
|
|
|
size_t const end(parameterCount(synopsisIndex));
|
|
|
|
|
|
|
|
bool first;
|
|
|
|
|
|
|
|
first = true;
|
|
|
|
|
|
|
|
for (size_t i = 0; i < end; ++i) {
|
|
|
|
if (!first)
|
|
|
|
out << ", ";
|
|
|
|
|
|
|
|
DataType const& ptype(parameterType(synopsisIndex, i));
|
|
|
|
string const basename(ptype.defaultParameterBaseName(i + 1));
|
|
|
|
out << ptype.parameterFragment(basename);
|
|
|
|
|
|
|
|
first = false;
|
2006-12-21 03:57:49 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2008-05-23 20:56:24 +00:00
|
|
|
|
|
|
|
|
|
|
|
void
|
|
|
|
XmlRpcFunction::printDeclaration(ostream & out,
|
|
|
|
size_t const synopsisIndex) const {
|
|
|
|
|
|
|
|
try {
|
|
|
|
DataType const& rtype(returnType(synopsisIndex));
|
|
|
|
|
|
|
|
out << " " << rtype.returnTypeFragment() << " "
|
|
|
|
<< mFunctionName << " (";
|
|
|
|
|
|
|
|
printParameters(out, synopsisIndex);
|
|
|
|
|
|
|
|
out << ");" << endl;
|
|
|
|
} catch (XmlRpcFault const& fault) {
|
|
|
|
ostringstream msg;
|
|
|
|
|
|
|
|
msg << "Failed to generate header for signature "
|
|
|
|
<< synopsisIndex
|
|
|
|
<< " . "
|
|
|
|
<< fault.getFaultString();
|
|
|
|
|
|
|
|
throw(logic_error(msg.str()));
|
|
|
|
}
|
2006-12-21 03:57:49 +00:00
|
|
|
}
|
|
|
|
|
2008-05-23 20:56:24 +00:00
|
|
|
|
|
|
|
|
|
|
|
void
|
|
|
|
XmlRpcFunction::printDefinition(ostream & out,
|
|
|
|
string const& className,
|
|
|
|
size_t const synopsisIndex) const {
|
|
|
|
|
|
|
|
DataType const& rtype(returnType(synopsisIndex));
|
|
|
|
|
2006-12-21 03:57:49 +00:00
|
|
|
out << rtype.returnTypeFragment() << " "
|
2008-05-23 20:56:24 +00:00
|
|
|
<< className << "::" << mFunctionName << " (";
|
|
|
|
|
|
|
|
printParameters(out, synopsisIndex);
|
|
|
|
|
2006-12-21 03:57:49 +00:00
|
|
|
out << ") {" << endl;
|
2008-05-23 20:56:24 +00:00
|
|
|
out << " XmlRpcValue params(XmlRpcValue::makeArray());" << endl;
|
2006-12-21 03:57:49 +00:00
|
|
|
|
|
|
|
/* Emit code to convert the parameters into an array of XML-RPC objects. */
|
2008-05-23 20:56:24 +00:00
|
|
|
size_t const end(parameterCount(synopsisIndex));
|
|
|
|
for (size_t i = 0; i < end; ++i) {
|
|
|
|
DataType const& ptype(parameterType(synopsisIndex, i));
|
|
|
|
string const basename(ptype.defaultParameterBaseName(i + 1));
|
|
|
|
out << " params.arrayAppendItem("
|
|
|
|
<< ptype.inputConversionFragment(basename) << ");" << endl;
|
2006-12-21 03:57:49 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
/* Emit the function call.*/
|
2008-05-23 20:56:24 +00:00
|
|
|
out << " XmlRpcValue result(this->mClient.call(\""
|
|
|
|
<< mMethodName << "\", params));" << endl;
|
2006-12-21 03:57:49 +00:00
|
|
|
|
|
|
|
/* Emit the return statement. */
|
|
|
|
out << " return " << rtype.outputConversionFragment("result")
|
2008-05-23 20:56:24 +00:00
|
|
|
<< ";" << endl;
|
2006-12-21 03:57:49 +00:00
|
|
|
out << "}" << endl;
|
|
|
|
}
|
|
|
|
|
2008-05-23 20:56:24 +00:00
|
|
|
|
|
|
|
|
|
|
|
const DataType&
|
|
|
|
XmlRpcFunction::returnType(size_t const synopsisIndex) const {
|
|
|
|
|
|
|
|
XmlRpcValue const funcSynop(mSynopsis.arrayGetItem(synopsisIndex));
|
|
|
|
|
|
|
|
return findDataType(funcSynop.arrayGetItem(0).getString());
|
2006-12-21 03:57:49 +00:00
|
|
|
}
|
|
|
|
|
2008-05-23 20:56:24 +00:00
|
|
|
|
|
|
|
|
|
|
|
size_t
|
|
|
|
XmlRpcFunction::parameterCount(size_t const synopsisIndex) const {
|
|
|
|
|
|
|
|
XmlRpcValue const funcSynop(mSynopsis.arrayGetItem(synopsisIndex));
|
|
|
|
size_t const size(funcSynop.arraySize());
|
|
|
|
|
2006-12-21 03:57:49 +00:00
|
|
|
if (size < 1)
|
2008-05-23 20:56:24 +00:00
|
|
|
throw domain_error("Synopsis contained no items");
|
2006-12-21 03:57:49 +00:00
|
|
|
return size - 1;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
2008-05-23 20:56:24 +00:00
|
|
|
DataType const&
|
|
|
|
XmlRpcFunction::parameterType(size_t const synopsisIndex,
|
|
|
|
size_t const parameterIndex) const {
|
|
|
|
|
|
|
|
XmlRpcValue const funcSynop(mSynopsis.arrayGetItem(synopsisIndex));
|
|
|
|
XmlRpcValue const param(funcSynop.arrayGetItem(parameterIndex + 1));
|
|
|
|
|
|
|
|
return findDataType(param.getString());
|
|
|
|
}
|