#include #include #include #include "xmlrpcType.hpp" #include "xmlrpcMethod.hpp" using namespace std; xmlrpcMethod::xmlrpcMethod(string const& functionName, string const& methodName, string const& help, xmlrpc_c::value_array const& signatureList) : mFunctionName(functionName), mMethodName(methodName), mHelp(help), mSynopsis(signatureList) {} xmlrpcMethod::xmlrpcMethod(xmlrpcMethod const& f) : mFunctionName(f.mFunctionName), mMethodName(f.mMethodName), mHelp(f.mHelp), mSynopsis(f.mSynopsis) {} xmlrpcMethod& xmlrpcMethod::operator= (xmlrpcMethod const& f) { if (this != &f) { this->mFunctionName = f.mFunctionName; this->mMethodName = f.mMethodName; this->mHelp = f.mHelp; this->mSynopsis = f.mSynopsis; } return *this; } size_t xmlrpcMethod::parameterCount(size_t const synopsisIndex) const { xmlrpc_c::value_array const funcSynop( mSynopsis.vectorValueValue()[synopsisIndex]); size_t const size(funcSynop.size()); if (size < 1) throw domain_error("Synopsis contains no items"); return size - 1; } xmlrpcType const& xmlrpcMethod::parameterType(size_t const synopsisIndex, size_t const parameterIndex) const { xmlrpc_c::value_array const funcSynop( mSynopsis.vectorValueValue()[synopsisIndex]); xmlrpc_c::value_string const param( funcSynop.vectorValueValue()[parameterIndex + 1]); return findXmlrpcType(static_cast(param)); } const xmlrpcType& xmlrpcMethod::returnType(size_t const synopsisIndex) const { xmlrpc_c::value_array const funcSynop( mSynopsis.vectorValueValue()[synopsisIndex]); xmlrpc_c::value_string datatype(funcSynop.vectorValueValue()[0]); return findXmlrpcType(static_cast(datatype)); } void xmlrpcMethod::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 << ", "; xmlrpcType const& ptype(parameterType(synopsisIndex, i)); string const localName(ptype.defaultParameterBaseName(i + 1)); out << ptype.parameterFragment(localName); first = false; } } void xmlrpcMethod::printDeclaration(ostream & out, size_t const synopsisIndex) const { try { xmlrpcType const& rtype(returnType(synopsisIndex)); out << " " << rtype.returnTypeFragment() << " " << mFunctionName << " ("; printParameters(out, synopsisIndex); out << ");" << endl; } catch (xmlrpc_c::fault const& f) { ostringstream msg; msg << "Failed to generate header for signature " << synopsisIndex << " . " << f.getDescription(); throw(logic_error(msg.str())); } } void xmlrpcMethod::printDeclarations(ostream & out) const { try { // Print the method help as a comment out << endl << " /* " << mHelp << " */" << endl; size_t end; try { end = mSynopsis.size(); } catch (xmlrpc_c::fault const& f) { throw(logic_error("Failed to get size of signature array for " "method " + this->mFunctionName + ". " + f.getDescription())); } // 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())); } } void xmlrpcMethod::printDefinition(ostream & out, string const& className, size_t const synopsisIndex) const { xmlrpcType const& rtype(returnType(synopsisIndex)); out << rtype.returnTypeFragment() << " " << className << "::" << mFunctionName << " ("; printParameters(out, synopsisIndex); out << ") {" << endl; size_t const end(parameterCount(synopsisIndex)); if (end > 0){ // Emit code to generate the parameter list object out << " xmlrpc_c::paramList params;" << endl; for (size_t i = 0; i < end; ++i) { xmlrpcType const& ptype(parameterType(synopsisIndex, i)); string const basename(ptype.defaultParameterBaseName(i + 1)); out << " params.add(" << ptype.inputConversionFragment(basename) << ");" << endl; } } // Emit result holder declaration. out << " xmlrpc_c::value result;" << endl; // Emit the call to the XML-RPC call method out << " this->client.call(" << "this->serverUrl, " << "\"" << mMethodName << "\", "; if (end > 0) out << "params, "; out << "&result);" << endl; // Emit the return statement. out << " return " << rtype.outputConversionFragment("result") << ";" << endl; out << "}" << endl; } void xmlrpcMethod::printDefinitions(ostream & out, string const& className) const { try { size_t const end(mSynopsis.size()); for (size_t i = 0; i < end; ++i) { out << endl; printDefinition(out, className, i); } } catch (xmlrpc_c::fault const& f) { throw(logic_error("Failed to generate definitions for class " + this->mFunctionName + ". " + f.getDescription())); } }