Revert "Use a variable on the stack to not have a temporary in the call"
[ACE_TAO.git] / TAO / TAO_IDL / be / be_visitor_component / context_svts.cpp
blobbc19dd0ce0dbe19ff027315b686953417d6b4b46
2 //=============================================================================
3 /**
4 * @file context_svts.cpp
6 * Visitor generating code for a context class in the
7 * servant source.
9 * @author Jeff Parsons
11 //=============================================================================
13 #include "component.h"
15 be_visitor_context_svts::be_visitor_context_svts (be_visitor_context *ctx)
16 : be_visitor_component_scope (ctx)
20 be_visitor_context_svts::~be_visitor_context_svts ()
24 int
25 be_visitor_context_svts::visit_component (be_component *node)
27 // This visitor is spawned by be_visitor_component_svh,
28 // which already does a check for imported node, so none
29 // is needed here.
31 node_ = node;
33 AST_Decl *scope = ScopeAsDecl (node->defined_in ());
34 ACE_CString sname_str (scope->full_name ());
35 const char *lname = node_->local_name ();
36 const char *global = (sname_str == "" ? "" : "::");
38 os_ << be_nl
39 << "template <typename CONTAINER_TYPE, typename BASE>" << be_nl
40 << lname <<"_Context_T<CONTAINER_TYPE, BASE>::"
41 << lname << "_Context_T ("
42 << be_idt << be_idt_nl
43 << "::Components::CCMHome_ptr h," << be_nl
44 << "typename CONTAINER_TYPE::_ptr_type c," << be_nl
45 << "PortableServer::Servant sv," << be_uidt_nl
46 << "const char *id)" << be_uidt_nl
47 << ": ::CIAO::Context_Impl_Base_T <CONTAINER_TYPE> (h, c, id),"
48 << be_idt_nl;
50 // Spec: no multiple inheritance allowed for components.
51 AST_Component * base = node->base_component ();
52 if (base)
54 const char *lbase_name =
55 base->original_local_name ()->get_string ();
57 os_ << global << "CIAO_" << base->flat_name ()
58 << "_Impl::" << lbase_name << "_Context_T<CONTAINER_TYPE, BASE>";
60 else
62 os_ << "BASE";
64 os_ << " (h, c, sv, id)";
66 os_ << be_uidt_nl
67 << "{" << be_nl
68 << "}";
70 os_ << be_nl_2
71 << "template <typename CONTAINER_TYPE, typename BASE>" << be_nl
72 << lname << "_Context_T<CONTAINER_TYPE, BASE>::~"
73 << lname << "_Context_T ()" << be_nl
74 << "{" << be_nl
75 << "}";
77 if (this->visit_scope (node) == -1)
79 ACE_ERROR_RETURN ((LM_ERROR,
80 ACE_TEXT ("be_visitor_context_svts")
81 ACE_TEXT ("::visit_component - ")
82 ACE_TEXT ("visit_component_scope() ")
83 ACE_TEXT ("failed\n")),
84 -1);
87 return 0;
90 int
91 be_visitor_context_svts::visit_connector (be_connector *node)
93 return this->visit_component (node);
96 int
97 be_visitor_context_svts::visit_uses (be_uses *node)
99 ACE_CString prefix (this->ctx_->port_prefix ());
100 prefix += node->local_name ()->get_string ();
101 const char *port_name = prefix.c_str ();
103 AST_Type *obj = node->uses_type ();
104 bool const is_multiple = node->is_multiple ();
106 if (is_multiple)
108 this->gen_uses_multiplex (obj, port_name);
110 else
112 this->gen_uses_simplex (obj, port_name);
115 return 0;
119 be_visitor_context_svts::visit_publishes (be_publishes *node)
121 AST_Type *obj = node->publishes_type ();
122 const char *port_name =
123 node->local_name ()->get_string ();
124 const char *fname = obj->full_name ();
125 const char *lname = obj->local_name ()->get_string ();
126 ACE_CString sname_str (
127 ScopeAsDecl (obj->defined_in ())->full_name ());
129 os_ << be_nl_2
130 << "template <typename CONTAINER_TYPE, typename BASE>" << be_nl
131 << "void" << be_nl
132 << node_->local_name () << "_Context_T<CONTAINER_TYPE, BASE>::push_"
133 << port_name << " (" << be_idt_nl
134 << "::" << fname << " * ev)" << be_uidt_nl
135 << "{" << be_idt_nl;
137 os_ << "ACE_GUARD (TAO_SYNCH_MUTEX," << be_nl
138 << " mon," << be_nl
139 << " this->" << port_name
140 << "_lock_);" << be_nl_2;
142 os_ << "for (" << tao_cg->upcase (port_name)
143 << "_TABLE::const_iterator iter =" << be_nl
144 << " this->ciao_publishes_" << port_name
145 << "_.begin ();" << be_nl
146 << " iter != this->ciao_publishes_" << port_name
147 << "_.end ();" << be_nl
148 << " ++iter)" << be_idt_nl
149 << "{" << be_idt_nl
150 << "iter->second->push_" << lname << " (ev);"
151 << be_uidt_nl
152 << "}" << be_uidt << be_uidt_nl
153 << "}";
155 os_ << be_nl_2
156 << "template <typename CONTAINER_TYPE, typename BASE>" << be_nl
157 << "::Components::Cookie *" << be_nl
158 << node_->local_name () << "_Context_T<CONTAINER_TYPE, BASE>::subscribe_"
159 << port_name << " (" << be_idt_nl
160 << "::" << fname << "Consumer_ptr c)" << be_uidt_nl
161 << "{" << be_idt_nl
162 << "if (::CORBA::is_nil (c))" << be_idt_nl
163 << "{" << be_idt_nl
164 << "throw ::Components::InvalidConnection ();" << be_uidt_nl
165 << "}" << be_uidt_nl << be_nl;
167 os_ << "ptrdiff_t const ptr = reinterpret_cast<ptrdiff_t> (c);"
168 << be_nl_2;
170 os_ << "{" << be_idt_nl
171 << "ACE_GUARD_RETURN (TAO_SYNCH_MUTEX," << be_nl
172 << " mon," << be_nl
173 << " this->" << port_name
174 << "_lock_," << be_nl
175 << " 0);";
177 os_ << be_nl_2
178 << "::" << fname << "Consumer_var ciao_var = " << be_idt_nl
179 << "::" << fname << "Consumer::_duplicate (c);" << be_uidt << be_nl_2
180 << "std::pair<" << tao_cg->upcase (port_name) <<"_TABLE::iterator, bool> ret =" << be_idt_nl
181 << "this->ciao_publishes_" << port_name
182 << "_.insert (" << be_idt_nl << tao_cg->upcase (port_name)
183 << "_TABLE::value_type (ptr, ciao_var.in ()));"
184 << be_uidt << be_uidt_nl
185 << "if (!ret.second)" << be_idt_nl
186 << "{" << be_idt_nl
187 << "throw ::Components::AlreadyConnected ();" << be_uidt_nl
188 << "}" << be_uidt_nl
189 << "ciao_var._retn ();" << be_uidt_nl
190 << "}";
192 os_ << be_nl
193 << be_nl
194 << "::Components::Cookie * retv {};" << be_nl
195 << "ACE_NEW_THROW_EX (retv," << be_nl
196 << " ::CIAO::Cookie_Impl (ptr),"
197 << be_nl
198 << " ::CORBA::NO_MEMORY ());"
199 << be_nl_2
200 << "return retv;" << be_uidt_nl
201 << "}";
203 os_ << be_nl_2
204 << "template <typename CONTAINER_TYPE, typename BASE>" << be_nl
205 << "::" << fname << "Consumer_ptr" << be_nl
206 << node_->local_name () << "_Context_T<CONTAINER_TYPE, BASE>::unsubscribe_"
207 << port_name << " (" << be_idt_nl
208 << "::Components::Cookie * ck)" << be_uidt_nl
209 << "{" << be_idt_nl
210 << "ptrdiff_t key = 0UL;" << be_nl_2
211 << "if (ck == 0 || ! ::CIAO::Cookie_Impl::extract (ck, key))"
212 << be_idt_nl
213 << "{" << be_idt_nl
214 << "throw ::Components::InvalidConnection ();" << be_uidt_nl
215 << "}" << be_uidt_nl << be_nl;
217 os_ << "{" << be_idt_nl
218 << "ACE_GUARD_RETURN (TAO_SYNCH_MUTEX," << be_nl
219 << " mon," << be_nl
220 << " this->" << port_name
221 << "_lock_," << be_nl
222 << " ::" << fname
223 << "Consumer::_nil ());" << be_nl_2;
225 os_ << tao_cg->upcase (port_name) << "_TABLE::iterator iter ="
226 << be_idt_nl
227 << "this->ciao_publishes_" << port_name << "_.find (key);"
228 << be_uidt_nl << be_nl
229 << "if (iter != this->ciao_publishes_" << port_name
230 << "_.end ())" << be_idt_nl
231 << "{" << be_idt_nl
232 << "::" << fname
233 << "Consumer_var retv = iter->second;" << be_nl
234 << tao_cg->upcase (port_name)
235 << "_TABLE::size_type n =" << be_idt_nl
236 << "this->ciao_publishes_" << port_name
237 << "_.erase (key);" << be_uidt_nl << be_nl
238 << "if (n == 1UL)" << be_idt_nl
239 << "{" << be_idt_nl
240 << "return retv._retn ();" << be_uidt_nl
241 << "}" << be_uidt << be_uidt_nl
242 << "}" << be_uidt_nl;
244 os_ << be_uidt_nl
245 << "}";
247 os_ << be_nl_2
248 << "throw ::Components::InvalidConnection ();" << be_uidt_nl
249 << "}";
251 return 0;
255 be_visitor_context_svts::visit_emits (be_emits *node)
257 AST_Type *obj = node->emits_type ();
258 const char *port_name =
259 node->local_name ()->get_string ();
261 const char *fname = obj->full_name ();
262 const char *lname = obj->local_name ()->get_string ();
264 os_ << be_nl_2
265 << "template <typename CONTAINER_TYPE, typename BASE>" << be_nl
266 << "void" << be_nl
267 << node_->local_name () << "_Context_T<CONTAINER_TYPE, BASE>::push_" << port_name
268 << " (" << be_idt_nl
269 << "::" << fname << " * ev)" << be_uidt_nl
270 << "{" << be_idt_nl
271 << "if (! ::CORBA::is_nil (this->ciao_emits_"
272 << port_name << "_consumer_.in ()))" << be_idt_nl
273 << "{" << be_idt_nl
274 << "this->ciao_emits_" << port_name << "_consumer_->push_"
275 << lname << " (ev);" << be_uidt_nl
276 << "}" << be_uidt << be_uidt_nl
277 << "}";
279 os_ << be_nl_2
280 << "template <typename CONTAINER_TYPE, typename BASE>" << be_nl
281 << "void" << be_nl
282 << node_->local_name () << "_Context_T<CONTAINER_TYPE, BASE>::connect_" << port_name
283 << " (" << be_idt_nl
284 << "::" << fname << "Consumer_ptr c)" << be_uidt_nl
285 << "{" << be_idt_nl
286 << "if (::CORBA::is_nil (c))" << be_idt_nl
287 << "{" << be_idt_nl
288 << "throw ::Components::InvalidConnection ();" << be_uidt_nl
289 << "}" << be_uidt_nl << be_nl
290 << "if (! ::CORBA::is_nil (this->ciao_emits_"
291 << port_name << "_consumer_.in ()))" << be_idt_nl
292 << "{" << be_idt_nl
293 << "throw ::Components::AlreadyConnected ();" << be_uidt_nl
294 << "}" << be_uidt_nl << be_nl
295 << "this->ciao_emits_" << port_name
296 << "_consumer_ =" << be_idt_nl
297 << "::" << fname << "Consumer::_duplicate (c);"
298 << be_uidt << be_uidt_nl
299 << "}";
301 os_ << be_nl_2
302 << "template <typename CONTAINER_TYPE, typename BASE>" << be_nl
303 << "::" << fname << "Consumer_ptr" << be_nl
304 << node_->local_name () << "_Context_T<CONTAINER_TYPE, BASE>::disconnect_"
305 << port_name << " ()" << be_nl
306 << "{" << be_idt_nl
307 << "::" << fname << "Consumer_var ciao_emits_" << port_name << " =" << be_idt_nl
308 << "this->ciao_emits_" << port_name << "_consumer_._retn ();" << be_uidt_nl << be_nl
309 << "if (::CORBA::is_nil (ciao_emits_"
310 << port_name << ".in ()))" << be_idt_nl
311 << "{" << be_idt_nl
312 << "throw ::Components::NoConnection ();" << be_uidt_nl
313 << "}" << be_uidt_nl << be_nl
314 << "return ciao_emits_" << port_name
315 << "._retn ();" << be_uidt_nl
316 << "}";
318 return 0;
321 void
322 be_visitor_context_svts::gen_uses_simplex (AST_Type *obj,
323 const char *port_name)
325 const char *fname = obj->full_name ();
327 os_ << be_nl_2
328 << "template <typename CONTAINER_TYPE, typename BASE>" << be_nl
329 << "::" << fname << "_ptr" << be_nl
330 << node_->local_name () << "_Context_T<CONTAINER_TYPE, BASE>::get_connection_"
331 << port_name << " ()" << be_nl
332 << "{" << be_idt_nl
333 << "return ::" << fname << "::_duplicate (" << be_idt_nl
334 << "this->ciao_uses_" << port_name << "_.in ());"
335 << be_uidt << be_uidt_nl
336 << "}";
338 os_ << be_nl_2
339 << "template <typename CONTAINER_TYPE, typename BASE>" << be_nl
340 << "void" << be_nl
341 << node_->local_name () << "_Context_T<CONTAINER_TYPE, BASE>::connect_"
342 << port_name << " (" << be_idt_nl
343 << "::" << fname << "_ptr c)" << be_uidt_nl
344 << "{" << be_idt_nl
345 << "if (::CORBA::is_nil (c))" << be_idt_nl
346 << "{" << be_idt_nl
347 << "throw ::Components::InvalidConnection ();" << be_uidt_nl
348 << "}" << be_uidt_nl << be_nl
349 << "if (! ::CORBA::is_nil (this->ciao_uses_"
350 << port_name << "_.in ()))" << be_idt_nl
351 << "{" << be_idt_nl
352 << "throw ::Components::AlreadyConnected ();" << be_uidt_nl
353 << "}" << be_uidt_nl << be_nl
354 << "this->ciao_uses_" << port_name << "_ =" << be_idt_nl
355 << "::" << fname << "::_duplicate (c);"
356 << be_uidt << be_uidt_nl
357 << "}";
359 os_ << be_nl_2
360 << "template <typename CONTAINER_TYPE, typename BASE>" << be_nl
361 << "::" << fname << "_ptr" << be_nl
362 << node_->local_name () << "_Context_T<CONTAINER_TYPE, BASE>::disconnect_"
363 << port_name << " ()" << be_nl
364 << "{" << be_idt_nl
365 << "::" << fname << "_var ciao_uses_" << port_name << " =" << be_idt_nl
366 << "this->ciao_uses_" << port_name << "_._retn ();" << be_uidt_nl << be_nl
367 << "if (::CORBA::is_nil (ciao_uses_"
368 << port_name << ".in ()))" << be_idt_nl
369 << "{" << be_idt_nl
370 << "throw ::Components::NoConnection ();" << be_uidt_nl
371 << "}" << be_uidt_nl << be_nl
372 << "return ciao_uses_" << port_name
373 << "._retn ();" << be_uidt_nl
374 << "}";
377 void
378 be_visitor_context_svts::gen_uses_multiplex (
379 AST_Type *obj,
380 const char *port_name)
382 const char *fname = obj->full_name ();
384 os_ << be_nl_2
385 << "template <typename CONTAINER_TYPE, typename BASE>" << be_nl
386 << "::" << node_->full_name () << "::" << port_name
387 << "Connections *" << be_nl
388 << node_->local_name () << "_Context_T<CONTAINER_TYPE, BASE>::get_connections_"
389 << port_name << " ()" << be_nl
390 << "{" << be_idt_nl;
392 os_ << "ACE_GUARD_RETURN (TAO_SYNCH_MUTEX," << be_nl
393 << " mon," << be_nl
394 << " this->" << port_name
395 << "_lock_," << be_nl
396 << " 0);" << be_nl_2;
398 os_ << "::" << node_->full_name () << "::" << port_name
399 << "Connections * tmp_retv {};" << be_nl
400 << "ACE_NEW_THROW_EX (tmp_retv," << be_nl
401 << " ::" << node_->full_name ()
402 << "::" << port_name << "Connections (" << be_nl
403 << " this->ciao_uses_"
404 << port_name << "_.size ())," << be_nl
405 << " ::CORBA::NO_MEMORY ());"
406 << be_nl_2
407 << "::" << node_->full_name () << "::" << port_name
408 << "Connections_var retv = tmp_retv;" << be_nl
409 << "retv->length (this->ciao_uses_" << port_name
410 << "_.size ());" << be_nl
411 << "::CORBA::ULong i = 0UL;" << be_nl_2
412 << "for (" << tao_cg->upcase (port_name)
413 << "_TABLE::const_iterator iter =" << be_nl
414 << " this->ciao_uses_" << port_name << "_.begin ();"
415 << be_nl
416 << " iter != this->ciao_uses_"
417 << port_name << "_.end ();" << be_nl
418 << " ++iter, ++i)" << be_idt_nl
419 << "{" << be_idt_nl
420 << "retv[i].objref = iter->second;" << be_nl_2
421 << "ACE_NEW_THROW_EX (retv[i].ck.inout ()," << be_nl
422 << " ::CIAO::Cookie_Impl (iter->first),"
423 << be_nl
424 << " ::CORBA::NO_MEMORY ());" << be_uidt_nl
425 << "}" << be_uidt_nl << be_nl
426 << "return retv._retn (); " << be_uidt_nl
427 << "}";
429 os_ << be_nl_2
430 << "template <typename CONTAINER_TYPE, typename BASE>" << be_nl
431 << "::Components::Cookie *" << be_nl
432 << node_->local_name () << "_Context_T<CONTAINER_TYPE, BASE>::connect_"
433 << port_name << " (" << be_idt_nl
434 << "::" << fname << "_ptr c)" << be_uidt_nl
435 << "{" << be_idt_nl
436 << "if (::CORBA::is_nil (c))" << be_idt_nl
437 << "{" << be_idt_nl
438 << "throw ::Components::InvalidConnection ();" << be_uidt_nl
439 << "}" << be_uidt_nl << be_nl;
441 os_ << "ptrdiff_t const ptr = reinterpret_cast<ptrdiff_t> (c);";
443 os_ << be_nl_2
444 << "{" << be_idt_nl
445 << "ACE_GUARD_RETURN (TAO_SYNCH_MUTEX," << be_nl
446 << " mon," << be_nl
447 << " this->" << port_name
448 << "_lock_," << be_nl
449 << " 0);";
451 os_ << be_nl_2
452 << "::" << fname << "_var ciao_var = " << be_idt_nl
453 << "::" << fname << "::_duplicate (c);" << be_uidt << be_nl_2
454 << "std::pair<" << tao_cg->upcase (port_name) <<"_TABLE::iterator, bool> ret =" << be_idt_nl
455 << "this->ciao_uses_" << port_name
456 << "_.insert (" << be_idt_nl << tao_cg->upcase (port_name)
457 << "_TABLE::value_type (ptr, ciao_var.in ()));"
458 << be_uidt << be_uidt_nl
459 << "if (!ret.second)" << be_idt_nl
460 << "{" << be_idt_nl
461 << "throw ::Components::AlreadyConnected ();" << be_uidt_nl
462 << "}" << be_uidt_nl
463 << "ciao_var._retn ();" << be_uidt_nl
464 << "}";
466 os_ << be_nl_2
467 << "::Components::Cookie * ck {};" << be_nl
468 << "ACE_NEW_THROW_EX (ck," << be_nl
469 << " ::CIAO::Cookie_Impl (ptr),"
470 << be_nl
471 << " ::CORBA::NO_MEMORY ());"
472 << be_nl_2
473 << "return ck;" << be_uidt_nl
474 << "}";
476 os_ << be_nl_2
477 << "template <typename CONTAINER_TYPE, typename BASE>" << be_nl
478 << "::" << fname << "_ptr" << be_nl
479 << node_->local_name () << "_Context_T<CONTAINER_TYPE, BASE>::disconnect_"
480 << port_name << " (" << be_idt_nl
481 << "::Components::Cookie * ck)" << be_uidt_nl
482 << "{" << be_idt_nl
483 << "::" << fname << "_var retv;" << be_nl
484 << "ptrdiff_t key = 0UL;" << be_nl
485 << tao_cg->upcase (port_name)
486 << "_TABLE::size_type n = 0UL;" << be_nl_2
487 << "if (ck == 0 || ! ::CIAO::Cookie_Impl::extract (ck, key))"
488 << be_idt_nl
489 << "{" << be_idt_nl
490 << "throw ::Components::InvalidConnection ();" << be_uidt_nl
491 << "}" << be_uidt;
493 os_ << be_nl_2
494 << "{" << be_idt_nl
495 << "ACE_GUARD_RETURN (TAO_SYNCH_MUTEX," << be_nl
496 << " mon," << be_nl
497 << " this->" << port_name
498 << "_lock_," << be_nl
499 << " ::" << fname
500 << "::_nil ());";
502 os_ << be_nl_2
503 << tao_cg->upcase (port_name)
504 << "_TABLE::iterator iter =" << be_idt_nl
505 << "this->ciao_uses_" << port_name
506 << "_.find (key);" << be_uidt_nl << be_nl
507 << "if (iter != this->ciao_uses_" << port_name
508 << "_.end ())" << be_idt_nl
509 << "{" << be_idt_nl
510 << "retv = iter->second;" << be_nl
511 << "n = this->ciao_uses_" << port_name
512 << "_.erase (key);" << be_uidt_nl
513 << "}" << be_uidt << be_uidt_nl
514 << "}";
516 os_ << be_nl_2
517 << "if (n != 1UL)" << be_idt_nl
518 << "{" << be_idt_nl
519 << "throw ::Components::InvalidConnection ();" << be_uidt_nl
520 << "}" << be_uidt_nl << be_nl
521 << "return retv._retn ();" << be_uidt_nl
522 << "}";