1 /***************************************************************************
2 GenClientMethod.cpp - generate class with client methods
3 -------------------
4 begin : Sun May 28 2007
5 copyright : (C) 2002-2007 by Ewald Arnold
6 email : ulxmlrpcpp@ewald-arnold.de
7
8 $Id: GenClientMethod.cpp 1016 2007-07-22 15:03:44Z ewald-arnold $
9
10 ***************************************************************************/
11
12 /**************************************************************************
13 *
14 * This program is free software; you can redistribute it and/or modify
15 * it under the terms of the GNU Lesser General Public License as
16 * published by the Free Software Foundation; either version 2 of the License,
17 * or (at your option) any later version.
18 *
19 * This program is distributed in the hope that it will be useful,
20 * but WITHOUT ANY WARRANTY; without even the implied warranty of
21 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
22 * GNU General Public License for more details.
23 *
24 * You should have received a copy of the GNU Lesser General Public License
25 * along with this program; if not, write to the Free Software
26 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
27 *
28 ***************************************************************************/
29
30 #include "GenClientMethod.h"
31
32 #include <fstream>
33 #include <iostream>
34
35 #include <sys/stat.h>
36
37
GenerateClientMethods(const UlxrIdlClass & in_class)38 GenerateClientMethods::GenerateClientMethods(const UlxrIdlClass &in_class)
39 : theClass(in_class)
40 {
41 theClass.resolveOverloaded();
42 }
43
44
generate_H(const std::string & destdir,const std::string & name)45 void GenerateClientMethods::generate_H(const std::string &destdir, const std::string &name)
46 {
47 const std::string h_name = destdir + theClass.getBaseName() + "_ulxr_client.h";
48 std::ofstream h_file(h_name.c_str());
49 std::cout << "Header file will be created: " << h_name << std::endl;
50
51 generateHeaderHead(h_file, name + "UlxrClient");
52 generateHeaderClassHead(h_file, name);
53 generateHeaderMethods(h_file);
54 generateHeaderVariables(h_file);
55 generateHeaderTail(h_file, name + "UlxrClient");
56 }
57
58
generate_CPP(const std::string & destdir,const std::string & name)59 void GenerateClientMethods::generate_CPP(const std::string &destdir, const std::string &name)
60 {
61 const std::string h_name = theClass.getBaseName() + "_ulxr_client.h";
62 const std::string cpp_name = destdir + theClass.getBaseName() + "_ulxr_client.cpp";
63 std::ofstream cpp_file(cpp_name.c_str());
64 std::cout << "Source file will be created: " << cpp_name << std::endl;
65
66 generateSourceHead(cpp_file, h_name);
67 generateSourceCtors(cpp_file, name);
68 generateSourceMethods(cpp_file);
69 }
70
71
generate_CPP_USER(const std::string & destdir,const std::string & name)72 void GenerateClientMethods::generate_CPP_USER(const std::string &destdir, const std::string &name)
73 {
74 const std::string h_name = theClass.getBaseName() + "_ulxr_client.h";
75 std::string cpp_name = destdir + theClass.getBaseName() + "_ulxr_client_user.cpp";
76
77 struct stat statbuf;
78 if (stat(cpp_name.c_str(), &statbuf) >= 0)
79 {
80 std::cout << "User file already exists: " << cpp_name << std::endl;
81 cpp_name += ".new";
82 std::cout << "New template will be created: " << cpp_name << std::endl;
83 }
84
85 std::ofstream cpp_file(cpp_name.c_str());
86 std::cout << "User file will be created: " << cpp_name << std::endl;
87
88 generateUserSourceHead(cpp_file, h_name);
89
90 cpp_file << "#include <ulxmlrpcpp/ulxr_response.h>\n";
91 cpp_file << "#include <ulxmlrpcpp/ulxr_requester.h>\n";
92 cpp_file << "#include <ulxmlrpcpp/ulxr_except.h>\n\n";
93
94 cpp_file << "#include \"" << name + "_ulxr_names.h" << "\"\n\n";
95
96 cpp_file << name << "Client::" << name << "Client\n"
97 << " (ulxr::Requester &in_requester, const ulxr::CppString &realm,\n"
98 " const ulxr::CppString &user, const ulxr::CppString &pass)\n"
99 " : requester(in_requester)\n"
100 " , rpc_realm(realm)\n"
101 " , rpc_user(user)\n"
102 " , rpc_pass(pass)\n";
103
104 for (unsigned i = 0; i < theClass.numMethods(); ++i)
105 {
106 cpp_file << " , ";
107
108 Method method = theClass.getMethod(i);
109 method.extractNamespace();
110
111 cpp_file << "callTo_" << method.getOverloadName()
112 << "(ULXR_CALLTO_" << method.getOverloadName(true, "", "_")
113 << ") // mapped to: " << method.getCppString(0, true, "");
114
115 if (method.getName() != method.getOverloadName())
116 cpp_file << " (there are overloaded methods)";
117
118 cpp_file << "\n";
119 }
120
121 cpp_file << "{\n"
122 "}\n\n\n";
123
124 cpp_file << "ulxr::MethodResponse\n "
125 << name << "Client::" << "sendCall(const ulxr::MethodCall &calldata) const\n"
126 << "{\n"
127 << " ulxr::MethodResponse resp = requester.call(calldata, rpc_realm, rpc_user, rpc_pass);\n"
128 << "\n"
129 << " if (!resp.isOK())\n"
130 << " {\n"
131 << " ulxr::Struct st = resp.getResult();\n"
132 << " int ec = ulxr::Integer(st.getMember(ULXR_PCHAR(\"faultCode\"))).getInteger();\n"
133 << " ulxr::CppString es = ulxr::RpcString(st.getMember(ULXR_PCHAR(\"faultString\"))).getString();\n"
134 << " throw ulxr::RuntimeException(ec, es);\n"
135 << " }\n"
136 << "\n"
137 << " return resp;\n"
138 << "}\n\n\n";
139
140 cpp_file<< name << "Client::~" << name << "Client()\n"
141 << "{\n"
142 << "}\n\n\n";
143 }
144
145
generate(const std::string & destdir,const std::string & name)146 void GenerateClientMethods::generate(const std::string &destdir, const std::string &name)
147 {
148 generate_NameDefines(destdir, theClass.getBaseName() , theClass.getAllMethods());
149 generate_H(destdir, name);
150 generate_CPP(destdir, name);
151 generate_CPP_USER(destdir, name);
152 }
153
154
generateHeaderMethods(std::ostream & h_file)155 void GenerateClientMethods::generateHeaderMethods(std::ostream & h_file)
156 {
157 for (unsigned i = 0; i < theClass.numMethods(); ++i)
158 {
159 Method method = theClass.getMethod(i);
160 method.extractNamespace();
161
162 h_file << " // mapped to " << method.getOverloadName();
163 if (method.getName() != method.getOverloadName())
164 h_file << " (there are overloaded methods)";
165
166 h_file << "\n " << method.getCppString(0, false, "") << "\n\n";
167 }
168
169 h_file << " virtual ~" << theClass.getBaseName() << "Client();\n\n";
170
171 h_file << " virtual ulxr::MethodResponse sendCall(const ulxr::MethodCall &calldata) const;\n\n";
172 }
173
174
generateSourceCtors(std::ostream & cpp_file,const std::string & name)175 void GenerateClientMethods::generateSourceCtors(std::ostream & cpp_file,
176 const std::string &name)
177 {
178 cpp_file << "#include <ulxmlrpcpp/ulxr_requester.h>\n\n";
179
180 // cpp_file << "#include \"" << theClass.getSource() << "\"\n\n\n";
181 }
182
183
generateSourceMethods(std::ostream & cpp_file)184 void GenerateClientMethods::generateSourceMethods(std::ostream & cpp_file)
185 {
186 for (unsigned i = 0; i < theClass.numMethods(); ++i)
187 {
188 Method method = theClass.getMethod(i);
189 method.extractNamespace();
190
191 cpp_file << "// mapped to " << method.getOverloadName(true);
192 if (method.getName() != method.getOverloadName())
193 cpp_file << " (there are overloaded methods)";
194
195 cpp_file << "\n"
196 << method.getCppString(0, true, "Client") << "\n"
197 << "{\n";
198
199 cpp_file << " callTo_" << method.getOverloadName() << ".clear();\n";
200
201 for (unsigned iarg = 0; iarg < method.numArgs(); ++iarg)
202 {
203 std::string adap = method.getArg(iarg).getType().getInversTypeAdapter();
204 std::string adap2;
205 if (adap.length() != 0)
206 {
207 adap += "(";
208 adap2 = ")";
209 }
210
211 cpp_file << " callTo_" << method.getOverloadName() << ".addParam("
212 << method.getArg(iarg).getType().getRpcName() << "(" << adap
213 << method.getArg(iarg).getType().getTypeDereference() << method.getArg(iarg).getName()
214 << adap2
215 << "));\n";
216
217 }
218
219 bool have_retval = false;
220 if (method.getType().getName() != "void" || method.getType().getLeft() != "" || method.getType().getRight() != "")
221 have_retval = true;
222
223 if (have_retval)
224 cpp_file << " ulxr::MethodResponse resp = sendCall(callTo_" << method.getOverloadName() << ");\n";
225 else
226 cpp_file << " sendCall(callTo_" << method.getOverloadName() << ");\n";
227
228 if (have_retval)
229 {
230 std::string adap = method.getType().getTypeAdapter();
231 std::string adap2;
232 if (adap.length() != 0)
233 {
234 adap += "(";
235 adap2 = ")";
236 }
237
238 const bool reftype = method.getType().isReference();
239 const bool ptrtype = method.getType().isPointer();
240 if (reftype || ptrtype)
241 cpp_file << " ulxr_refFor_"
242 << method.getOverloadName() << " = ";
243 else
244 cpp_file << " return ";
245
246 cpp_file << "(" << method.getType().getProxyType() << ") "
247 << adap + method.getType().getRpcName() << "(resp.getResult())." << method.getType().getRpcAccessor()
248 << "()" << adap2 << ";\n";
249
250 if (reftype)
251 cpp_file << " return ulxr_refFor_"
252 << method.getOverloadName() << ";\n";
253
254 else if (ptrtype)
255 {
256 std::string acc = "&";
257 std::string acc2 = method.getType().getTypeAccessor();
258 if (acc2.length() != 0)
259 acc = "";
260
261 cpp_file << " return "
262 << "(" << method.getType().getCppString() << ") "
263 << acc << "ulxr_refFor_"
264 << method.getOverloadName() << acc2 << ";\n";
265 }
266 }
267
268 cpp_file << "}\n\n\n";
269 }
270 }
271
272
generateHeaderClassHead(std::ostream & h_file,const std::string & name)273 void GenerateClientMethods::generateHeaderClassHead(std::ostream & h_file,
274 const std::string &name)
275 {
276 h_file<< "#include <ulxmlrpcpp/ulxr_call.h>\n\n"
277 << "namespace ulxr\n"
278 << "{\n"
279 << " class Requester;\n"
280 << " class MethodResponse;\n"
281 << " class MethodCall;\n"
282 << "}\n\n"
283 << "class " << name << "Client\n"
284 << "{\n"
285 << " public:\n\n"
286 << " " << name << "Client\n"
287 << " (ulxr::Requester &requester, const ulxr::CppString &realm = ULXR_PCHAR(\"/RPC2\"),\n"
288 << " const ulxr::CppString &user = ULXR_PCHAR(\"\"), const ulxr::CppString &pass = ULXR_PCHAR(\"\"));\n\n";
289 }
290
291
generateHeaderVariables(std::ostream & h_file)292 void GenerateClientMethods::generateHeaderVariables(std::ostream & h_file)
293 {
294 h_file << " private:\n\n";
295
296 h_file<< " ulxr::Requester &requester;\n";
297 h_file<< " ulxr::CppString rpc_realm;\n";
298 h_file<< " ulxr::CppString rpc_user;\n";
299 h_file<< " ulxr::CppString rpc_pass;\n\n";
300
301 for (unsigned i = 0; i < theClass.numMethods(); ++i)
302 {
303 Method method = theClass.getMethod(i);
304 method.extractNamespace();
305
306 const bool reftype = method.getType().isReference();
307 const bool ptrtype = method.getType().isPointer();
308 if (reftype || ptrtype)
309 h_file << " mutable " << method.getType().getProxyType() << " ulxr_refFor_" << method.getOverloadName() << ";\n";
310 }
311
312 for (unsigned i = 0; i < theClass.numMethods(); ++i)
313 {
314 if (i == 0)
315 h_file << "\n";
316
317 Method method = theClass.getMethod(i);
318 method.extractNamespace();
319
320 h_file << " mutable ulxr::MethodCall callTo_" << method.getOverloadName()
321 << "; // mapped to: " << method.getCppString(0, true, "")
322 << "\n";
323 }
324 }
325
326
327