xmlrpcMethod.cpp 6.1 KB

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