2 //=============================================================================
4 * @file valuebox_cs.cpp
6 * Visitor generating code for valueboxes in the client stub file
10 //=============================================================================
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 ()
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 ())
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::"
42 "TypeCode definition failed\n"),
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 ())
57 << "TAO::Value_Traits<" << node
->name () << ">::add_ref ("
58 << node
->name () << " * p)"
61 << "::CORBA::add_ref (p);" << be_uidt_nl
66 << "TAO::Value_Traits<" << node
->name () << ">::remove_ref ("
67 << node
->name () << " * p)" << be_nl
69 << "::CORBA::remove_ref (p);" << be_uidt_nl
74 << "TAO::Value_Traits<" << node
->name () << ">::release ("
75 << node
->name () << " * p)" << be_nl
77 << "::CORBA::remove_ref (p);" << be_uidt_nl
81 // The _downcast method.
83 << node
->name () << " *" << be_nl
84 << node
->name () << "::_downcast (::CORBA::ValueBase *v)" << be_nl
86 << "return dynamic_cast<::" << node
->name () << " *> (v);"
87 << be_uidt_nl
<< "}" << be_nl_2
;
90 *os
<< "::CORBA::ValueBase *" << be_nl
91 << node
->name () << "::_copy_value ()" << be_nl
93 << "::CORBA::ValueBase *result = 0;" << be_nl
94 << "ACE_NEW_RETURN (" << be_idt_nl
96 << node
->local_name () << " (*this)," << be_nl
97 << "0);" << be_nl
<< be_uidt_nl
98 << "return result;" << be_uidt_nl
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
108 *os
<< "void" << be_nl
110 << "::_tao_obv_truncatable_repo_ids (Repository_Id_List& ids) const"
113 << "ids.push_back (this->_tao_obv_static_repository_id ());"
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
122 << "::_tao_match_formal_type (ptrdiff_t) const" << be_nl
124 << "return true;" << be_uidt_nl
128 if (be_global
->any_support ())
130 *os
<< "void" << be_nl
132 << "::_tao_any_destructor (void *_tao_void_pointer)" << be_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
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
);
166 ACE_ERROR_RETURN ((LM_ERROR
,
167 "(%N:%l) be_visitor_valuebox_cs::"
173 bool is_array
= false;
174 const char * unmarshal_arg
;
175 be_predefined_type
*bpt
= dynamic_cast<be_predefined_type
*> (bt
);
181 case AST_PredefinedType::PT_boolean
:
183 "::ACE_InputCDR::to_boolean (vb_object->_pd_value)";
186 case AST_PredefinedType::PT_char
:
188 "::ACE_InputCDR::to_char (vb_object->_pd_value)";
191 case AST_PredefinedType::PT_wchar
:
193 "::ACE_InputCDR::to_wchar (vb_object->_pd_value)";
196 case AST_PredefinedType::PT_octet
:
198 "::ACE_InputCDR::to_octet (vb_object->_pd_value)";
201 case AST_PredefinedType::PT_uint8
:
203 "::ACE_InputCDR::to_uint8 (vb_object->_pd_value)";
206 case AST_PredefinedType::PT_int8
:
208 "::ACE_InputCDR::to_int8 (vb_object->_pd_value)";
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 ()";
218 unmarshal_arg
= "vb_object->_pd_value";
221 else if (dynamic_cast<be_array
*> (bt
) != nullptr)
224 unmarshal_arg
= "temp";
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
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 (),"
246 << "is_null_object, is_indirected"
248 << ") == false)" << be_uidt_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
255 << "return true;" << be_uidt_nl
256 << "}" << be_uidt_nl
<< be_nl
257 << "if (is_indirected)" << 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
;
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
<< ")";
289 *os
<< "::ACE_InputCDR::to_wstring "
290 << "(vb_object->_pd_value, "
291 << str
->max_size ()->ev ()->u
.ulval
<< ")";
296 *os
<< unmarshal_arg
;
299 *os
<< ");" << be_uidt_nl
302 // _tao_unmarshal_v method. Generated because ValueBase interface
303 // requires it. But there is nothing for it to do in the valuebox
305 *os
<< "::CORBA::Boolean" << be_nl
307 << "::_tao_unmarshal_v (TAO_InputCDR &)" << be_nl
309 << "return true;" << be_uidt_nl
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"),
322 // Indicate that code is already generated for this node.
323 node
->cli_stub_gen (true);
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
343 << "::_tao_marshal_v (TAO_OutputCDR & strm) const" << be_nl
345 << node
->name () << "_forany temp (this->_pd_value.ptr ());"
347 << "return (strm << temp);" << be_uidt_nl
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
370 << "::_tao_marshal_v (TAO_OutputCDR & strm) const" << be_nl
372 << "return (strm << " << marshal_arg
<< ");" << be_uidt_nl
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
;
392 case AST_PredefinedType::PT_boolean
:
394 "::ACE_OutputCDR::from_boolean (this->_pd_value)";
397 case AST_PredefinedType::PT_char
:
399 "::ACE_OutputCDR::from_char (this->_pd_value)";
402 case AST_PredefinedType::PT_wchar
:
404 "::ACE_OutputCDR::from_wchar (this->_pd_value)";
407 case AST_PredefinedType::PT_octet
:
409 "::ACE_OutputCDR::from_octet (this->_pd_value)";
412 case AST_PredefinedType::PT_uint8
:
414 "::ACE_OutputCDR::from_uint8 (this->_pd_value)";
417 case AST_PredefinedType::PT_int8
:
419 "::ACE_OutputCDR::from_int8 (this->_pd_value)";
422 case AST_PredefinedType::PT_any
:
423 marshal_arg
= "this->_pd_value.in ()";
427 marshal_arg
= "this->_pd_value";
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
445 be_visitor_context
ctx (*this->ctx_
);
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::"
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 ());
467 ACE_ERROR_RETURN ((LM_ERROR
,
468 "(%N:%l) be_visitor_valuebox_cs::"
470 "Bad element type\n"),
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
485 << node
->full_name () << "* p;" << be_nl
486 << "ACE_NEW (" << be_idt_nl
488 << node
->full_name () << " (max));" << be_uidt_nl
489 << "this->_pd_value = p;" << be_uidt_nl
493 // Public constructor for sequence with supplied buffer
494 *os
<< vb_node
->name () << "::" << vb_node
->local_name ()
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::"
510 "base type visit failed\n"),
514 *os
<< " * buf," << be_nl
515 << "::CORBA::Boolean release)" << be_uidt_nl
517 << node
->full_name () << "* p;" << be_nl
518 << "ACE_NEW (" << be_idt_nl
520 << node
->full_name () << " (";
522 if (node
->unbounded ())
527 *os
<< "length, buf, release));" << be_uidt_nl
528 << "this->_pd_value = p;" << be_uidt_nl
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::"
541 "base type visit failed\n"),
546 << vb_node
->name () << "::operator[] (::CORBA::ULong index)"
551 if (bt
->accept (&bt_visitor
) == -1)
553 ACE_ERROR_RETURN ((LM_ERROR
,
554 "(%N:%l) be_visitor_valuebox_cs::"
556 "base type visit failed\n"),
560 *os
<< "&) this->_pd_value->operator[] (index);" << be_uidt_nl
566 if (bt
->accept (&bt_visitor
) == -1)
568 ACE_ERROR_RETURN ((LM_ERROR
,
569 "(%N:%l) be_visitor_valuebox_cs::"
571 "base type visit failed\n"),
575 *os
<< " &" << be_nl
;
576 *os
<< vb_node
->name ()
577 << "::operator[] (::CORBA::ULong index) const" << be_nl
580 switch (bt
->node_type())
582 case AST_Decl::NT_wstring
:
583 *os
<< "TAO_SeqElem_WString_Manager mgr = this->_pd_value->operator[] "
585 << "return mgr._retn ();" << be_uidt_nl
;
588 case AST_Decl::NT_string
:
589 *os
<< "TAO_SeqElem_String_Manager mgr = this->_pd_value->operator[] "
591 << "return mgr._retn ();" << be_uidt_nl
;
597 if (bt
->accept (&bt_visitor
) == -1)
599 ACE_ERROR_RETURN ((LM_ERROR
,
600 "(%N:%l) be_visitor_valuebox_cs::"
602 "base type visit failed\n"),
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
614 << "::_tao_marshal_v (TAO_OutputCDR & strm) const" << be_nl
616 << "return (strm << this->_pd_value.in ());" << be_uidt_nl
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
637 << "::_tao_marshal_v (TAO_OutputCDR & strm) const" << be_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
<< ")";
651 os
<< "::ACE_OutputCDR::from_wstring "
652 << "(this->_pd_value, "
653 << str
->max_size ()->ev ()->u
.ulval
<< ")";
658 os
<< "this->_pd_value";
661 os
<< ");" << be_uidt_nl
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
682 << "::_tao_marshal_v (TAO_OutputCDR & strm) const" << be_nl
684 << "return (strm << this->_pd_value.in ());" << be_uidt_nl
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::"
701 "Bad primitive type\n"),
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
723 << "::_tao_marshal_v (TAO_OutputCDR & strm) const" << be_nl
725 << "return (strm << this->_pd_value.in ());" << be_uidt_nl
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
759 << "::_tao_marshal_v (TAO_OutputCDR & strm) const" << be_nl
761 << "return (strm << " << marshal_arg
<< ");" << be_uidt_nl