2
0

XmlRpcFunction.cpp 5.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216
  1. #include <iostream>
  2. #include <sstream>
  3. #include <stdexcept>
  4. #include "xmlrpc-c/oldcppwrapper.hpp"
  5. #include "DataType.hpp"
  6. #include "XmlRpcFunction.hpp"
  7. using namespace std;
  8. XmlRpcFunction::XmlRpcFunction(string const& functionName,
  9. string const& methodName,
  10. string const& help,
  11. XmlRpcValue const signatureList) :
  12. mFunctionName(functionName),
  13. mMethodName(methodName),
  14. mHelp(help),
  15. mSynopsis(signatureList) {}
  16. XmlRpcFunction::XmlRpcFunction(XmlRpcFunction const& f) :
  17. mFunctionName(f.mFunctionName),
  18. mMethodName(f.mMethodName),
  19. mHelp(f.mHelp),
  20. mSynopsis(f.mSynopsis) {}
  21. XmlRpcFunction&
  22. XmlRpcFunction::operator= (XmlRpcFunction const& f) {
  23. if (this != &f) {
  24. this->mFunctionName = f.mFunctionName;
  25. this->mMethodName = f.mMethodName;
  26. this->mHelp = f.mHelp;
  27. this->mSynopsis = f.mSynopsis;
  28. }
  29. return *this;
  30. }
  31. void
  32. XmlRpcFunction::printDeclarations(ostream & out) const {
  33. try {
  34. // Print the method help as a comment
  35. out << endl << " /* " << mHelp << " */" << endl;
  36. size_t end;
  37. try {
  38. end = mSynopsis.arraySize();
  39. } catch (XmlRpcFault const& fault) {
  40. throw(logic_error("Failed to get size of signature array for "
  41. "method " + this->mFunctionName + ". " +
  42. fault.getFaultString()));
  43. }
  44. // Print the declarations for all the signatures of this
  45. // XML-RPC method.
  46. for (size_t i = 0; i < end; ++i)
  47. printDeclaration(out, i);
  48. } catch (exception const& e) {
  49. throw(logic_error("Failed to generate declarations for method " +
  50. this->mFunctionName + ". " + e.what()));
  51. }
  52. }
  53. void
  54. XmlRpcFunction::printDefinitions(ostream & out,
  55. string const& className) const {
  56. try {
  57. size_t const end(mSynopsis.arraySize());
  58. for (size_t i = 0; i < end; ++i) {
  59. out << endl;
  60. printDefinition(out, className, i);
  61. }
  62. } catch (XmlRpcFault const& fault) {
  63. throw(logic_error("Failed to generate definitions for class " +
  64. this->mFunctionName + ". " +
  65. fault.getFaultString()));
  66. }
  67. }
  68. void
  69. XmlRpcFunction::printParameters(ostream & out,
  70. size_t const synopsisIndex) const {
  71. /*----------------------------------------------------------------------------
  72. Print the parameter declarations.
  73. -----------------------------------------------------------------------------*/
  74. size_t const end(parameterCount(synopsisIndex));
  75. bool first;
  76. first = true;
  77. for (size_t i = 0; i < end; ++i) {
  78. if (!first)
  79. out << ", ";
  80. DataType const& ptype(parameterType(synopsisIndex, i));
  81. string const basename(ptype.defaultParameterBaseName(i + 1));
  82. out << ptype.parameterFragment(basename);
  83. first = false;
  84. }
  85. }
  86. void
  87. XmlRpcFunction::printDeclaration(ostream & out,
  88. size_t const synopsisIndex) const {
  89. try {
  90. DataType const& rtype(returnType(synopsisIndex));
  91. out << " " << rtype.returnTypeFragment() << " "
  92. << mFunctionName << " (";
  93. printParameters(out, synopsisIndex);
  94. out << ");" << endl;
  95. } catch (XmlRpcFault const& fault) {
  96. ostringstream msg;
  97. msg << "Failed to generate header for signature "
  98. << synopsisIndex
  99. << " . "
  100. << fault.getFaultString();
  101. throw(logic_error(msg.str()));
  102. }
  103. }
  104. void
  105. XmlRpcFunction::printDefinition(ostream & out,
  106. string const& className,
  107. size_t const synopsisIndex) const {
  108. DataType const& rtype(returnType(synopsisIndex));
  109. out << rtype.returnTypeFragment() << " "
  110. << className << "::" << mFunctionName << " (";
  111. printParameters(out, synopsisIndex);
  112. out << ") {" << endl;
  113. out << " XmlRpcValue params(XmlRpcValue::makeArray());" << endl;
  114. /* Emit code to convert the parameters into an array of XML-RPC objects. */
  115. size_t const end(parameterCount(synopsisIndex));
  116. for (size_t i = 0; i < end; ++i) {
  117. DataType const& ptype(parameterType(synopsisIndex, i));
  118. string const basename(ptype.defaultParameterBaseName(i + 1));
  119. out << " params.arrayAppendItem("
  120. << ptype.inputConversionFragment(basename) << ");" << endl;
  121. }
  122. /* Emit the function call.*/
  123. out << " XmlRpcValue result(this->mClient.call(\""
  124. << mMethodName << "\", params));" << endl;
  125. /* Emit the return statement. */
  126. out << " return " << rtype.outputConversionFragment("result")
  127. << ";" << endl;
  128. out << "}" << endl;
  129. }
  130. const DataType&
  131. XmlRpcFunction::returnType(size_t const synopsisIndex) const {
  132. XmlRpcValue const funcSynop(mSynopsis.arrayGetItem(synopsisIndex));
  133. return findDataType(funcSynop.arrayGetItem(0).getString());
  134. }
  135. size_t
  136. XmlRpcFunction::parameterCount(size_t const synopsisIndex) const {
  137. XmlRpcValue const funcSynop(mSynopsis.arrayGetItem(synopsisIndex));
  138. size_t const size(funcSynop.arraySize());
  139. if (size < 1)
  140. throw domain_error("Synopsis contained no items");
  141. return size - 1;
  142. }
  143. DataType const&
  144. XmlRpcFunction::parameterType(size_t const synopsisIndex,
  145. size_t const parameterIndex) const {
  146. XmlRpcValue const funcSynop(mSynopsis.arrayGetItem(synopsisIndex));
  147. XmlRpcValue const param(funcSynop.arrayGetItem(parameterIndex + 1));
  148. return findDataType(param.getString());
  149. }