Merge pull request #2303 from jwillemsen/jwi-803
[ACE_TAO.git] / TAO / TAO_IDL / be / be_visitor_valuebox / valuebox_cs.cpp
blob96f252b024c4e6e0ff650bba79a073b6f0f8bd45
2 //=============================================================================
3 /**
4 * @file valuebox_cs.cpp
6 * Visitor generating code for valueboxes in the client stub file
8 * @author Gary Maxey
9 */
10 //=============================================================================
12 #include "valuebox.h"
14 be_visitor_valuebox_cs::be_visitor_valuebox_cs (be_visitor_context *ctx)
15 : be_visitor_valuebox (ctx)
19 be_visitor_valuebox_cs::~be_visitor_valuebox_cs ()
23 int
24 be_visitor_valuebox_cs::visit_valuebox (be_valuebox *node)
26 // Nothing to do if we are imported or code is already generated.
27 if (node->cli_stub_gen () || node->imported ())
29 return 0;
32 if (be_global->tc_support ())
34 be_visitor_context ctx (*this->ctx_);
35 TAO::be_visitor_alias_typecode visitor (&ctx);
37 if (node->accept (&visitor) == -1)
39 ACE_ERROR_RETURN ((LM_ERROR,
40 "(%N:%l) be_visitor_valuebox_cs::"
41 "visit_valuebox - "
42 "TypeCode definition failed\n"),
43 -1);
47 TAO_OutStream *os = this->ctx_->stream ();
49 this->ctx_->node (node); // save the node
51 TAO_INSERT_COMMENT (os);
53 if (node->is_defined ())
55 *os << be_nl_2
56 << "void" << be_nl
57 << "TAO::Value_Traits<" << node->name () << ">::add_ref ("
58 << node->name () << " * p)"
59 << be_nl
60 << "{" << be_idt_nl
61 << "::CORBA::add_ref (p);" << be_uidt_nl
62 << "}";
64 *os << be_nl_2
65 << "void" << be_nl
66 << "TAO::Value_Traits<" << node->name () << ">::remove_ref ("
67 << node->name () << " * p)" << be_nl
68 << "{" << be_idt_nl
69 << "::CORBA::remove_ref (p);" << be_uidt_nl
70 << "}";
72 *os << be_nl_2
73 << "void" << be_nl
74 << "TAO::Value_Traits<" << node->name () << ">::release ("
75 << node->name () << " * p)" << be_nl
76 << "{" << be_idt_nl
77 << "::CORBA::remove_ref (p);" << be_uidt_nl
78 << "}";
81 // The _downcast method.
82 *os << be_nl_2
83 << node->name () << " *" << be_nl
84 << node->name () << "::_downcast (::CORBA::ValueBase *v)" << be_nl
85 << "{" << be_idt_nl
86 << "return dynamic_cast<::" << node->name () << " *> (v);"
87 << be_uidt_nl << "}" << be_nl_2;
89 // _copy_value method
90 *os << "::CORBA::ValueBase *" << be_nl
91 << node->name () << "::_copy_value ()" << be_nl
92 << "{" << be_idt_nl
93 << "::CORBA::ValueBase *result = 0;" << be_nl
94 << "ACE_NEW_RETURN (" << be_idt_nl
95 << "result," << be_nl
96 << node->local_name () << " (*this)," << be_nl
97 << "0);" << be_nl << be_uidt_nl
98 << "return result;" << be_uidt_nl
99 << "}" << be_nl_2;
101 // The _tao_obv_repository_id method.
102 *os << "const char *" << be_nl
103 << node->name () << "::_tao_obv_repository_id () const"
104 << be_nl << "{" << be_idt_nl
105 << "return this->_tao_obv_static_repository_id ();" << be_uidt_nl
106 << "}" << be_nl_2;
108 *os << "void" << be_nl
109 << node->name ()
110 << "::_tao_obv_truncatable_repo_ids (Repository_Id_List& ids) const"
111 << be_nl
112 << "{" << be_idt_nl
113 << "ids.push_back (this->_tao_obv_static_repository_id ());"
114 << be_uidt_nl
115 << "}" << be_nl_2;
117 // _tao_match_formal_type method. Generated because ValueBase interface
118 // requires it. Since value boxes do not support inheritence, this can
119 // simply return true.
120 *os << "::CORBA::Boolean" << be_nl
121 << node->name ()
122 << "::_tao_match_formal_type (ptrdiff_t) const" << be_nl
123 << "{" << be_idt_nl
124 << "return true;" << be_uidt_nl
125 << "}" << be_nl_2;
128 if (be_global->any_support ())
130 *os << "void" << be_nl
131 << node->name ()
132 << "::_tao_any_destructor (void *_tao_void_pointer)" << be_nl
133 << "{" << be_idt_nl
134 << node->local_name () << " *_tao_tmp_pointer =" << be_idt_nl
135 << "static_cast<" << be_idt
136 << node->local_name () << " *> ("
137 << "_tao_void_pointer);" << be_uidt << be_uidt_nl
138 << "::CORBA::remove_ref (_tao_tmp_pointer);" << be_uidt_nl
139 << "}" << be_nl_2;
142 // Switch streams to the *A.cpp file if we are using this option.
143 if (be_global->gen_anyop_files ())
145 os = tao_cg->anyop_source ();
148 if (be_global->tc_support ())
150 *os << "// TAO extension - the virtual _type method." << be_nl;
151 *os << "::CORBA::TypeCode_ptr " << node->name ()
152 << "::_tao_type () const" << be_nl;
153 *os << "{" << be_idt_nl;
154 *os << "return ::" << node->tc_name () << ";" << be_uidt_nl;
155 *os << "}" << be_nl_2;
158 // Make sure we are generating to *C.cpp regardless of the above.
159 os = tao_cg->client_stubs ();
161 AST_Type * at = node->boxed_type()->unaliased_type();
162 be_type *bt = dynamic_cast<be_type*> (at);
164 if (!bt)
166 ACE_ERROR_RETURN ((LM_ERROR,
167 "(%N:%l) be_visitor_valuebox_cs::"
168 "visit_valuebox - "
169 "Bad type\n"),
170 -1);
173 bool is_array = false;
174 const char * unmarshal_arg;
175 be_predefined_type *bpt = dynamic_cast<be_predefined_type*> (bt);
177 if (bpt != nullptr)
179 switch (bpt->pt())
181 case AST_PredefinedType::PT_boolean:
182 unmarshal_arg =
183 "::ACE_InputCDR::to_boolean (vb_object->_pd_value)";
184 break;
186 case AST_PredefinedType::PT_char:
187 unmarshal_arg =
188 "::ACE_InputCDR::to_char (vb_object->_pd_value)";
189 break;
191 case AST_PredefinedType::PT_wchar:
192 unmarshal_arg =
193 "::ACE_InputCDR::to_wchar (vb_object->_pd_value)";
194 break;
196 case AST_PredefinedType::PT_octet:
197 unmarshal_arg =
198 "::ACE_InputCDR::to_octet (vb_object->_pd_value)";
199 break;
201 case AST_PredefinedType::PT_uint8:
202 unmarshal_arg =
203 "::ACE_InputCDR::to_uint8 (vb_object->_pd_value)";
204 break;
206 case AST_PredefinedType::PT_int8:
207 unmarshal_arg =
208 "::ACE_InputCDR::to_int8 (vb_object->_pd_value)";
209 break;
211 case AST_PredefinedType::PT_any:
212 // We need to help the ">>" operator for "any" because
213 // a conversion operator is not available.
214 unmarshal_arg = "vb_object->_pd_value.inout ()";
215 break;
217 default:
218 unmarshal_arg = "vb_object->_pd_value";
221 else if (dynamic_cast<be_array*> (bt) != nullptr)
223 is_array = true;
224 unmarshal_arg = "temp";
226 else
228 unmarshal_arg = "vb_object->_pd_value";
231 // The _tao_unmarshal method.
232 *os << "::CORBA::Boolean" << be_nl
233 << node->name () << "::_tao_unmarshal (" << be_idt << be_idt_nl
234 << "TAO_InputCDR &strm," << be_nl
235 << node->local_name () << " *&vb_object" << be_uidt_nl
236 << ")" << be_uidt_nl
237 << "{" << be_idt_nl
238 << "::CORBA::Boolean is_null_object = false;" << be_nl
239 << "::CORBA::Boolean is_indirected = false;" << be_nl
240 << "TAO_InputCDR indrected_strm ((size_t) 0);" << be_nl
241 << "if (::CORBA::ValueBase::_tao_validate_box_type (" << be_idt
242 << be_idt << be_idt_nl
243 << "strm, indrected_strm," << be_nl
244 << node->local_name () << "::_tao_obv_static_repository_id (),"
245 << be_nl
246 << "is_null_object, is_indirected"
247 << be_uidt_nl
248 << ") == false)" << be_uidt_nl
249 << "{" << be_idt_nl
250 << "return false;" << be_uidt_nl
251 << "}" << be_uidt_nl << be_nl
252 << "vb_object = 0;" << be_nl
253 << "if (is_null_object)" << be_idt_nl
254 << "{" << be_idt_nl
255 << "return true;" << be_uidt_nl
256 << "}" << be_uidt_nl << be_nl
257 << "if (is_indirected)" << be_idt_nl
258 << "{" << be_idt_nl
259 << "return " << node->name () << "::_tao_unmarshal (" << be_idt
260 << be_idt << be_idt_nl
261 << " indrected_strm, vb_object);"
262 << be_uidt << be_uidt << be_uidt << be_uidt_nl
263 << "}" << be_uidt_nl << be_nl
264 << "ACE_NEW_RETURN (" << be_idt_nl
265 << "vb_object," << be_nl
266 << node->local_name () << "," << be_nl
267 << "false);" << be_uidt_nl << be_nl;
269 if (is_array)
271 *os << at->full_name()
272 << "_forany temp (vb_object->_boxed_inout ());" << be_nl;
275 *os << "return (strm >> ";
277 be_string *str = dynamic_cast<be_string*> (bt);
278 if (str != nullptr &&
279 str->max_size ()->ev ()->u.ulval != 0)
281 if (str->width () == (long) sizeof (char))
283 *os << "::ACE_InputCDR::to_string "
284 << "(vb_object->_pd_value, "
285 << str->max_size ()->ev ()->u.ulval << ")";
287 else
289 *os << "::ACE_InputCDR::to_wstring "
290 << "(vb_object->_pd_value, "
291 << str->max_size ()->ev ()->u.ulval << ")";
294 else
296 *os << unmarshal_arg;
299 *os << ");" << be_uidt_nl
300 << "}" << be_nl_2;
302 // _tao_unmarshal_v method. Generated because ValueBase interface
303 // requires it. But there is nothing for it to do in the valuebox
304 // case.
305 *os << "::CORBA::Boolean" << be_nl
306 << node->name ()
307 << "::_tao_unmarshal_v (TAO_InputCDR &)" << be_nl
308 << "{" << be_idt_nl
309 << "return true;" << be_uidt_nl
310 << "}" << be_nl_2;
312 // Emit the type specific elements. The visit_* methods in this
313 // module do that work.
314 if (bt->accept (this) == -1)
316 ACE_ERROR_RETURN ((LM_ERROR,
317 " (%N:%l) be_visitor_valuebox_cs::visit_valuebox - "
318 "type-specific valuebox code generation failed\n"),
319 -1);
322 // Indicate that code is already generated for this node.
323 node->cli_stub_gen (true);
325 return 0;
329 be_visitor_valuebox_cs::visit_array (be_array * node)
331 TAO_OutStream & os = *this->ctx_->stream ();
333 // Retrieve the node being visited by this be_visitor_valuebox_cs.
334 be_decl * const vb_node = this->ctx_->node ();
336 TAO_INSERT_COMMENT (&os);
338 this->emit_destructor ();
340 // _tao_marshal_v method
341 os << "::CORBA::Boolean" << be_nl
342 << vb_node->name ()
343 << "::_tao_marshal_v (TAO_OutputCDR & strm) const" << be_nl
344 << "{" << be_idt_nl
345 << node->name () << "_forany temp (this->_pd_value.ptr ());"
346 << be_nl
347 << "return (strm << temp);" << be_uidt_nl
348 << "}" << be_nl_2;
350 return 0;
354 be_visitor_valuebox_cs::visit_enum (be_enum *)
356 TAO_OutStream & os = *this->ctx_->stream ();
358 // Retrieve the node being visited by this be_visitor_valuebox_cs.
359 be_decl * const vb_node = this->ctx_->node ();
361 TAO_INSERT_COMMENT (&os);
363 this->emit_destructor ();
365 static char const marshal_arg[] = "this->_pd_value";
367 // _tao_marshal_v method
368 os << "::CORBA::Boolean" << be_nl
369 << vb_node->name ()
370 << "::_tao_marshal_v (TAO_OutputCDR & strm) const" << be_nl
371 << "{" << be_idt_nl
372 << "return (strm << " << marshal_arg << ");" << be_uidt_nl
373 << "}" << be_nl_2;
375 return 0;
380 be_visitor_valuebox_cs::visit_interface (be_interface *)
382 return this->emit_for_predef_enum ("this->_pd_value");
386 be_visitor_valuebox_cs::visit_predefined_type (be_predefined_type * node)
388 char const * marshal_arg;
390 switch (node->pt ())
392 case AST_PredefinedType::PT_boolean:
393 marshal_arg =
394 "::ACE_OutputCDR::from_boolean (this->_pd_value)";
395 break;
397 case AST_PredefinedType::PT_char:
398 marshal_arg =
399 "::ACE_OutputCDR::from_char (this->_pd_value)";
400 break;
402 case AST_PredefinedType::PT_wchar:
403 marshal_arg =
404 "::ACE_OutputCDR::from_wchar (this->_pd_value)";
405 break;
407 case AST_PredefinedType::PT_octet:
408 marshal_arg =
409 "::ACE_OutputCDR::from_octet (this->_pd_value)";
410 break;
412 case AST_PredefinedType::PT_uint8:
413 marshal_arg =
414 "::ACE_OutputCDR::from_uint8 (this->_pd_value)";
415 break;
417 case AST_PredefinedType::PT_int8:
418 marshal_arg =
419 "::ACE_OutputCDR::from_int8 (this->_pd_value)";
420 break;
422 case AST_PredefinedType::PT_any:
423 marshal_arg = "this->_pd_value.in ()";
424 break;
426 default:
427 marshal_arg = "this->_pd_value";
428 break;
431 return this->emit_for_predef_enum (marshal_arg);
435 be_visitor_valuebox_cs::visit_sequence (be_sequence *node)
437 TAO_OutStream *os = this->ctx_->stream ();
439 // Retrieve the node being visited by this be_visitor_valuebox_cs.
440 be_decl * vb_node = this->ctx_->node ();
442 if (node->anonymous ())
443 { // Our sequence is anonymous so we must generate a declaration
444 // for it.
445 be_visitor_context ctx (*this->ctx_);
446 ctx.node (node);
448 // First generate the sequence definition
449 be_visitor_sequence_cs visitor (&ctx);
451 if (node->accept (&visitor) == -1)
453 ACE_ERROR_RETURN ((LM_ERROR,
454 "(%N:%l) be_visitor_valuebox_cs::"
455 "visit_sequence - "
456 "codegen failed\n"),
457 -1);
461 // Retrieve the base type since we will need to do some code
462 // generation for it.
463 be_type *bt = dynamic_cast<be_type*> (node->base_type ());
465 if (bt == nullptr)
467 ACE_ERROR_RETURN ((LM_ERROR,
468 "(%N:%l) be_visitor_valuebox_cs::"
469 "visit_sequence - "
470 "Bad element type\n"),
471 -1);
473 be_visitor_context ctx (*this->ctx_);
474 ctx.state (TAO_CodeGen::TAO_SEQUENCE_BUFFER_TYPE_CH);
475 be_visitor_sequence_buffer_type bt_visitor (&ctx);
477 TAO_INSERT_COMMENT (os);
479 if (node->unbounded ())
481 // Public constructor with one argument of type ULong
482 *os << vb_node->name () << "::" << vb_node->local_name ()
483 << " (::CORBA::ULong max)" << be_nl
484 << "{" << be_idt_nl
485 << node->full_name () << "* p;" << be_nl
486 << "ACE_NEW (" << be_idt_nl
487 << "p," << be_nl
488 << node->full_name () << " (max));" << be_uidt_nl
489 << "this->_pd_value = p;" << be_uidt_nl
490 << "}" << be_nl_2;
493 // Public constructor for sequence with supplied buffer
494 *os << vb_node->name () << "::" << vb_node->local_name ()
495 << " (" << be_idt;
497 if (node->unbounded ())
499 *os << be_nl << "::CORBA::ULong max,";
502 *os << be_nl << "::CORBA::ULong length," << be_nl;
505 if (bt->accept (&bt_visitor) == -1)
507 ACE_ERROR_RETURN ((LM_ERROR,
508 "(%N:%l) be_visitor_valuebox_cs::"
509 "visit_valuebox - "
510 "base type visit failed\n"),
511 -1);
514 *os << " * buf," << be_nl
515 << "::CORBA::Boolean release)" << be_uidt_nl
516 << "{" << be_idt_nl
517 << node->full_name () << "* p;" << be_nl
518 << "ACE_NEW (" << be_idt_nl
519 << "p," << be_nl
520 << node->full_name () << " (";
522 if (node->unbounded ())
524 *os << "max, ";
527 *os << "length, buf, release));" << be_uidt_nl
528 << "this->_pd_value = p;" << be_uidt_nl
529 << "}" << be_nl_2;
531 // end: Public constructor for sequence with supplied buffer
533 this->emit_destructor ();
535 // Accessor: non const
536 if (bt->accept (&bt_visitor) == -1)
538 ACE_ERROR_RETURN ((LM_ERROR,
539 "(%N:%l) be_visitor_valuebox_cs::"
540 "visit_valuebox - "
541 "base type visit failed\n"),
542 -1);
545 *os << " &" << be_nl
546 << vb_node->name () << "::operator[] (::CORBA::ULong index)"
547 << be_nl
548 << "{" << be_idt_nl
549 << "return (";
551 if (bt->accept (&bt_visitor) == -1)
553 ACE_ERROR_RETURN ((LM_ERROR,
554 "(%N:%l) be_visitor_valuebox_cs::"
555 "visit_valuebox - "
556 "base type visit failed\n"),
557 -1);
560 *os << "&) this->_pd_value->operator[] (index);" << be_uidt_nl
561 << "}" << be_nl_2;
563 // Accessor: const
564 *os << "const ";
566 if (bt->accept (&bt_visitor) == -1)
568 ACE_ERROR_RETURN ((LM_ERROR,
569 "(%N:%l) be_visitor_valuebox_cs::"
570 "visit_sequence - "
571 "base type visit failed\n"),
572 -1);
575 *os << " &" << be_nl;
576 *os << vb_node->name ()
577 << "::operator[] (::CORBA::ULong index) const" << be_nl
578 << "{" << be_idt_nl;
580 switch (bt->node_type())
582 case AST_Decl::NT_wstring:
583 *os << "TAO_SeqElem_WString_Manager mgr = this->_pd_value->operator[] "
584 "(index);" << be_nl
585 << "return mgr._retn ();" << be_uidt_nl;
586 break;
588 case AST_Decl::NT_string:
589 *os << "TAO_SeqElem_String_Manager mgr = this->_pd_value->operator[] "
590 "(index);" << be_nl
591 << "return mgr._retn ();" << be_uidt_nl;
592 break;
594 default:
595 *os << "return (";
597 if (bt->accept (&bt_visitor) == -1)
599 ACE_ERROR_RETURN ((LM_ERROR,
600 "(%N:%l) be_visitor_valuebox_cs::"
601 "visit_sequence - "
602 "base type visit failed\n"),
603 -1);
606 *os << "&) this->_pd_value->operator[] (index);" << be_uidt_nl;
609 *os << "}" << be_nl_2;
611 // _tao_marshal_v method
612 *os << "::CORBA::Boolean" << be_nl
613 << vb_node->name ()
614 << "::_tao_marshal_v (TAO_OutputCDR & strm) const" << be_nl
615 << "{" << be_idt_nl
616 << "return (strm << this->_pd_value.in ());" << be_uidt_nl
617 << "}" << be_nl_2;
619 return 0;
623 be_visitor_valuebox_cs::visit_string (be_string *str)
625 TAO_OutStream & os = *this->ctx_->stream ();
627 // Retrieve the node being visited by this be_visitor_valuebox_cs.
628 be_decl * const vb_node = this->ctx_->node ();
630 TAO_INSERT_COMMENT (&os);
632 this->emit_destructor ();
634 // _tao_marshal_v method
635 os << "::CORBA::Boolean" << be_nl
636 << vb_node->name ()
637 << "::_tao_marshal_v (TAO_OutputCDR & strm) const" << be_nl
638 << "{" << be_idt_nl
639 << "return (strm << ";
641 if (str->max_size ()->ev ()->u.ulval != 0)
643 if (str->width () == (long) sizeof (char))
645 os << "::ACE_OutputCDR::from_string "
646 << "(this->_pd_value, "
647 << str->max_size ()->ev ()->u.ulval << ")";
649 else
651 os << "::ACE_OutputCDR::from_wstring "
652 << "(this->_pd_value, "
653 << str->max_size ()->ev ()->u.ulval << ")";
656 else
658 os << "this->_pd_value";
661 os << ");" << be_uidt_nl
662 << "}" << be_nl_2;
664 return 0;
668 be_visitor_valuebox_cs::visit_structure (be_structure *)
670 TAO_OutStream & os = *this->ctx_->stream ();
672 // Retrieve the node being visited by this be_visitor_valuebox_cs.
673 be_decl * const vb_node = this->ctx_->node ();
675 TAO_INSERT_COMMENT (&os);
677 this->emit_destructor ();
679 // _tao_marshal_v method
680 os << "::CORBA::Boolean" << be_nl
681 << vb_node->name ()
682 << "::_tao_marshal_v (TAO_OutputCDR & strm) const" << be_nl
683 << "{" << be_idt_nl
684 << "return (strm << this->_pd_value.in ());" << be_uidt_nl
685 << "}" << be_nl_2;
687 return 0;
691 be_visitor_valuebox_cs::visit_typedef (be_typedef *node)
693 // Make a decision based on the primitive base type.
694 be_type *bt = node->primitive_base_type ();
696 if (!bt || (bt->accept (this) == -1))
698 ACE_ERROR_RETURN ((LM_ERROR,
699 "(%N:%l) be_visitor_valuebox_cs::"
700 "visit_typedef - "
701 "Bad primitive type\n"),
702 -1);
705 return 0;
709 be_visitor_valuebox_cs::visit_union (be_union *)
711 TAO_OutStream & os = *this->ctx_->stream ();
713 // Retrieve the node being visited by this be_visitor_valuebox_cs.
714 be_decl * const vb_node = this->ctx_->node ();
716 TAO_INSERT_COMMENT (&os);
718 this->emit_destructor ();
720 // _tao_marshal_v method
721 os << "::CORBA::Boolean" << be_nl
722 << vb_node->name ()
723 << "::_tao_marshal_v (TAO_OutputCDR & strm) const" << be_nl
724 << "{" << be_idt_nl
725 << "return (strm << this->_pd_value.in ());" << be_uidt_nl
726 << "}" << be_nl_2;
728 return 0;
731 void
732 be_visitor_valuebox_cs::emit_destructor ()
734 TAO_OutStream & os = *this->ctx_->stream ();
736 // Retrieve the node being visited by this be_visitor_valuebox_cs.
737 be_decl * const vb_node = this->ctx_->node ();
739 // Protected destructor
740 os << vb_node->name () << "::~" << vb_node->local_name () << " ()"
741 << be_nl << "{" << be_nl << "}" << be_nl_2;
745 be_visitor_valuebox_cs::emit_for_predef_enum (char const * marshal_arg)
747 TAO_OutStream & os = *this->ctx_->stream ();
749 // Retrieve the node being visited by this be_visitor_valuebox_cs.
750 be_decl * const vb_node = this->ctx_->node ();
752 TAO_INSERT_COMMENT (&os);
754 this->emit_destructor ();
756 // _tao_marshal_v method
757 os << "::CORBA::Boolean" << be_nl
758 << vb_node->name ()
759 << "::_tao_marshal_v (TAO_OutputCDR & strm) const" << be_nl
760 << "{" << be_idt_nl
761 << "return (strm << " << marshal_arg << ");" << be_uidt_nl
762 << "}" << be_nl_2;
764 return 0;