initial load of upstream version 1.06.32
[xmlrpc-c] / tools / xml-rpc-api2cpp / XmlRpcFunction.cpp
1 #include <iostream>
2 #include <stdexcept>
3
4 #include "xmlrpc-c/oldcppwrapper.hpp"
5 #include "DataType.hpp"
6 #include "XmlRpcFunction.hpp"
7
8 using std::domain_error;
9 using std::endl;
10
11
12 //=========================================================================
13 //  class XmlRpcFunction
14 //=========================================================================
15 //  Contains everything we know about a given server function, and knows
16 //  how to print local bindings.
17
18 XmlRpcFunction::XmlRpcFunction(const string& function_name,
19                                const string& method_name,
20                                const string& help,
21                                XmlRpcValue synopsis)
22     : mFunctionName(function_name), mMethodName(method_name),
23       mHelp(help), mSynopsis(synopsis)
24 {
25 }
26
27 XmlRpcFunction::XmlRpcFunction (const XmlRpcFunction& f)
28     : mFunctionName(f.mFunctionName), mMethodName(f.mMethodName),
29       mHelp(f.mHelp), mSynopsis(f.mSynopsis)
30 {
31 }
32
33 XmlRpcFunction& XmlRpcFunction::operator= (const XmlRpcFunction& f) {
34     if (this == &f)
35         return *this;
36     mFunctionName = f.mFunctionName;
37     mMethodName = f.mMethodName;
38     mHelp = f.mHelp;
39     mSynopsis = f.mSynopsis;
40     return *this;
41 }
42
43 void XmlRpcFunction::printDeclarations (ostream& out) {
44
45     // XXX - Do a sloppy job of printing documentation.
46     out << endl << "    /* " << mHelp << " */" << endl;
47
48     // Print each declaration.
49     size_t end = mSynopsis.arraySize();
50     for (size_t i = 0; i < end; i++)
51         printDeclaration(out, i);
52 }
53
54 void XmlRpcFunction::printDefinitions (ostream& out, const string& className) {
55     size_t end = mSynopsis.arraySize();
56     for (size_t i = 0; i < end; i++) {
57         out << endl;
58         printDefinition(out, className, i);
59     }
60 }
61
62 // Print the parameter declarations.
63 void XmlRpcFunction::printParameters (ostream& out, size_t synopsis_index) {
64     size_t end = parameterCount(synopsis_index);
65     bool first = true;
66     for (size_t i = 0; i < end; i++) {
67         if (first)
68             first = false;
69         else
70             out << ", ";
71
72         const DataType& ptype (parameterType(synopsis_index, i));
73         string basename = ptype.defaultParameterBaseName(i + 1);
74         out << ptype.parameterFragment(basename);
75     }
76 }
77
78 void XmlRpcFunction::printDeclaration (ostream& out, size_t synopsis_index) {
79     const DataType& rtype (returnType(synopsis_index));
80     out << "    " << rtype.returnTypeFragment() << " "
81         << mFunctionName << " (";
82     printParameters(out, synopsis_index);
83     out << ");" << endl;
84 }
85
86 void XmlRpcFunction::printDefinition (ostream& out,
87                                       const string& className,
88                                       size_t synopsis_index)
89 {
90     const DataType& rtype (returnType(synopsis_index));
91     out << rtype.returnTypeFragment() << " "
92         << className << "::" << mFunctionName << " (";
93     printParameters(out, synopsis_index);
94     out << ") {" << endl;    
95     out << "    XmlRpcValue params = XmlRpcValue::makeArray();" << endl;
96
97     /* Emit code to convert the parameters into an array of XML-RPC objects. */
98     size_t end = parameterCount(synopsis_index);
99     for (size_t i = 0; i < end; i++) {
100         const DataType& ptype (parameterType(synopsis_index, i));
101         string basename = ptype.defaultParameterBaseName(i + 1);
102         out << "    params.arrayAppendItem("
103             << ptype.inputConversionFragment(basename) << ");" << endl;
104     }
105
106     /* Emit the function call.*/
107     out << "    XmlRpcValue result = this->mClient.call(\""
108         << mMethodName << "\", params);" << endl;    
109
110     /* Emit the return statement. */
111     out << "    return " << rtype.outputConversionFragment("result")
112         << ";" << endl;
113     out << "}" << endl;
114 }
115
116 const DataType& XmlRpcFunction::returnType (size_t synopsis_index) {
117     XmlRpcValue func_synop = mSynopsis.arrayGetItem(synopsis_index);
118     return findDataType(func_synop.arrayGetItem(0).getString());
119 }
120
121 size_t XmlRpcFunction::parameterCount (size_t synopsis_index) {
122     XmlRpcValue func_synop = mSynopsis.arrayGetItem(synopsis_index);
123     size_t size = func_synop.arraySize();
124     if (size < 1)
125         throw domain_error("Synopsis contained no items");
126     return size - 1;
127 }
128
129 const DataType& XmlRpcFunction::parameterType (size_t synopsis_index,
130                                                size_t parameter_index)
131 {
132     XmlRpcValue func_synop = mSynopsis.arrayGetItem(synopsis_index);
133     XmlRpcValue param = func_synop.arrayGetItem(parameter_index + 1);
134     return findDataType(param.getString());
135 }
136
137