1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137
|
#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());
}
|