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 (void)
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 << be_idt
<< be_idt_nl
59 << node
->name () << " * p" << be_uidt_nl
62 << "::CORBA::add_ref (p);" << be_uidt_nl
67 << "TAO::Value_Traits<" << node
->name () << ">::remove_ref ("
68 << be_idt
<< be_idt_nl
69 << node
->name () << " * p" << be_uidt_nl
72 << "::CORBA::remove_ref (p);" << be_uidt_nl
77 << "TAO::Value_Traits<" << node
->name () << ">::release ("
78 << be_idt
<< be_idt_nl
79 << node
->name () << " * p" << be_uidt_nl
82 << "::CORBA::remove_ref (p);" << be_uidt_nl
86 // The _downcast method.
88 << node
->name () << " *" << be_nl
89 << node
->name () << "::_downcast ( ::CORBA::ValueBase *v)" << be_nl
91 << "return dynamic_cast< ::" << node
->name () << " * > (v);"
92 << be_uidt_nl
<< "}" << be_nl_2
;
95 *os
<< "::CORBA::ValueBase *" << be_nl
96 << node
->name () << "::_copy_value (void)" << be_nl
98 << "::CORBA::ValueBase *result = 0;" << be_nl
99 << "ACE_NEW_RETURN (" << be_idt_nl
100 << "result," << be_nl
101 << node
->local_name () << " (*this)," << be_nl
102 << "0);" << be_nl
<< be_uidt_nl
103 << "return result;" << be_uidt_nl
106 // The _tao_obv_repository_id method.
107 *os
<< "const char *" << be_nl
108 << node
->name () << "::_tao_obv_repository_id (void) const"
109 << be_nl
<< "{" << be_idt_nl
110 << "return this->_tao_obv_static_repository_id ();" << be_uidt_nl
113 *os
<< "void" << be_nl
115 << "::_tao_obv_truncatable_repo_ids (Repository_Id_List& ids) const"
118 << "ids.push_back (this->_tao_obv_static_repository_id ());"
122 // _tao_match_formal_type method. Generated because ValueBase interface
123 // requires it. Since value boxes do not support inheritence, this can
124 // simply return true.
125 *os
<< "::CORBA::Boolean" << be_nl
127 << "::_tao_match_formal_type (ptrdiff_t ) const" << be_nl
129 << "return true;" << be_uidt_nl
133 if (be_global
->any_support ())
135 *os
<< "void" << be_nl
137 << "::_tao_any_destructor (void *_tao_void_pointer)" << be_nl
139 << node
->local_name () << " *_tao_tmp_pointer =" << be_idt_nl
140 << "static_cast<" << be_idt
141 << node
->local_name () << " *> ("
142 << "_tao_void_pointer);" << be_uidt
<< be_uidt_nl
143 << "::CORBA::remove_ref (_tao_tmp_pointer);" << be_uidt_nl
147 // Switch streams to the *A.cpp file if we are using this option.
148 if (be_global
->gen_anyop_files ())
150 os
= tao_cg
->anyop_source ();
153 if (be_global
->tc_support ())
155 *os
<< "// TAO extension - the virtual _type method." << be_nl
;
156 *os
<< "::CORBA::TypeCode_ptr " << node
->name ()
157 << "::_tao_type (void) const" << be_nl
;
158 *os
<< "{" << be_idt_nl
;
159 *os
<< "return ::" << node
->tc_name () << ";" << be_uidt_nl
;
160 *os
<< "}" << be_nl_2
;
163 // Make sure we are generating to *C.cpp regardless of the above.
164 os
= tao_cg
->client_stubs ();
166 AST_Type
* at
= node
->boxed_type()->unaliased_type();
167 be_type
*bt
= dynamic_cast<be_type
*> (at
);
171 ACE_ERROR_RETURN ((LM_ERROR
,
172 "(%N:%l) be_visitor_valuebox_cs::"
178 bool is_array
= false;
179 const char * unmarshal_arg
;
180 be_predefined_type
*bpt
= dynamic_cast<be_predefined_type
*> (bt
);
186 case AST_PredefinedType::PT_boolean
:
188 "::ACE_InputCDR::to_boolean (vb_object->_pd_value)";
191 case AST_PredefinedType::PT_char
:
193 "::ACE_InputCDR::to_char (vb_object->_pd_value)";
196 case AST_PredefinedType::PT_wchar
:
198 "::ACE_InputCDR::to_wchar (vb_object->_pd_value)";
201 case AST_PredefinedType::PT_octet
:
203 "::ACE_InputCDR::to_octet (vb_object->_pd_value)";
206 case AST_PredefinedType::PT_uint8
:
208 "::ACE_InputCDR::to_uint8 (vb_object->_pd_value)";
211 case AST_PredefinedType::PT_int8
:
213 "::ACE_InputCDR::to_int8 (vb_object->_pd_value)";
216 case AST_PredefinedType::PT_any
:
217 // We need to help the ">>" operator for "any" because
218 // a conversion operator is not available.
219 unmarshal_arg
= "vb_object->_pd_value.inout ()";
223 unmarshal_arg
= "vb_object->_pd_value";
226 else if (dynamic_cast<be_array
*> (bt
) != 0)
229 unmarshal_arg
= "temp";
233 unmarshal_arg
= "vb_object->_pd_value";
236 // The _tao_unmarshal method.
237 *os
<< "::CORBA::Boolean" << be_nl
238 << node
->name () << "::_tao_unmarshal (" << be_idt
<< be_idt_nl
239 << "TAO_InputCDR &strm," << be_nl
240 << node
->local_name () << " *&vb_object" << be_uidt_nl
243 << "::CORBA::Boolean is_null_object = false;" << be_nl
244 << "::CORBA::Boolean is_indirected = false;" << be_nl
245 << "TAO_InputCDR indrected_strm ((size_t) 0);" << be_nl
246 << "if ( ::CORBA::ValueBase::_tao_validate_box_type (" << be_idt
247 << be_idt
<< be_idt_nl
248 << "strm, indrected_strm," << be_nl
249 << node
->local_name () << "::_tao_obv_static_repository_id (),"
251 << "is_null_object, is_indirected"
253 << ") == false)" << be_uidt_nl
255 << "return false;" << be_uidt_nl
256 << "}" << be_uidt_nl
<< be_nl
257 << "vb_object = 0;" << be_nl
258 << "if (is_null_object)" << be_idt_nl
260 << "return true;" << be_uidt_nl
261 << "}" << be_uidt_nl
<< be_nl
262 << "if (is_indirected)" << be_idt_nl
264 << "return " << node
->name () << "::_tao_unmarshal (" << be_idt
265 << be_idt
<< be_idt_nl
266 << " indrected_strm, vb_object);"
267 << be_uidt
<< be_uidt
<< be_uidt
<< be_uidt_nl
268 << "}" << be_uidt_nl
<< be_nl
269 << "ACE_NEW_RETURN (" << be_idt_nl
270 << "vb_object," << be_nl
271 << node
->local_name () << "," << be_nl
272 << "false);" << be_uidt_nl
<< be_nl
;
276 *os
<< at
->full_name()
277 << "_forany temp (vb_object->_boxed_inout ());" << be_nl
;
280 *os
<< "return (strm >> ";
282 be_string
*str
= dynamic_cast<be_string
*> (bt
);
284 str
->max_size ()->ev ()->u
.ulval
!= 0)
286 if (str
->width () == (long) sizeof (char))
288 *os
<< "::ACE_InputCDR::to_string "
289 << "(vb_object->_pd_value, "
290 << str
->max_size ()->ev ()->u
.ulval
<< ")";
294 *os
<< "::ACE_InputCDR::to_wstring "
295 << "(vb_object->_pd_value, "
296 << str
->max_size ()->ev ()->u
.ulval
<< ")";
301 *os
<< unmarshal_arg
;
304 *os
<< ");" << be_uidt_nl
307 // _tao_unmarshal_v method. Generated because ValueBase interface
308 // requires it. But there is nothing for it to do in the valuebox
310 *os
<< "::CORBA::Boolean" << be_nl
312 << "::_tao_unmarshal_v (TAO_InputCDR &)" << be_nl
314 << "return true;" << be_uidt_nl
317 // Emit the type specific elements. The visit_* methods in this
318 // module do that work.
319 if (bt
->accept (this) == -1)
321 ACE_ERROR_RETURN ((LM_ERROR
,
322 " (%N:%l) be_visitor_valuebox_cs::visit_valuebox - "
323 "type-specific valuebox code generation failed\n"),
327 // Indicate that code is already generated for this node.
328 node
->cli_stub_gen (true);
334 be_visitor_valuebox_cs::visit_array (be_array
* node
)
336 TAO_OutStream
& os
= *this->ctx_
->stream ();
338 // Retrieve the node being visited by this be_visitor_valuebox_cs.
339 be_decl
* const vb_node
= this->ctx_
->node ();
341 TAO_INSERT_COMMENT (&os
);
343 this->emit_destructor ();
345 // _tao_marshal_v method
346 os
<< "::CORBA::Boolean" << be_nl
348 << "::_tao_marshal_v (TAO_OutputCDR & strm) const" << be_nl
350 << node
->name () << "_forany temp (this->_pd_value.ptr ());"
352 << "return (strm << temp);" << be_uidt_nl
359 be_visitor_valuebox_cs::visit_enum (be_enum
*)
361 TAO_OutStream
& os
= *this->ctx_
->stream ();
363 // Retrieve the node being visited by this be_visitor_valuebox_cs.
364 be_decl
* const vb_node
= this->ctx_
->node ();
366 TAO_INSERT_COMMENT (&os
);
368 this->emit_destructor ();
370 static char const marshal_arg
[] = "this->_pd_value";
372 // _tao_marshal_v method
373 os
<< "::CORBA::Boolean" << be_nl
375 << "::_tao_marshal_v (TAO_OutputCDR & strm) const" << be_nl
377 << "return (strm << " << marshal_arg
<< ");" << be_uidt_nl
385 be_visitor_valuebox_cs::visit_interface (be_interface
*)
387 return this->emit_for_predef_enum ("this->_pd_value");
391 be_visitor_valuebox_cs::visit_predefined_type (be_predefined_type
* node
)
393 char const * marshal_arg
;
397 case AST_PredefinedType::PT_boolean
:
399 "::ACE_OutputCDR::from_boolean (this->_pd_value)";
402 case AST_PredefinedType::PT_char
:
404 "::ACE_OutputCDR::from_char (this->_pd_value)";
407 case AST_PredefinedType::PT_wchar
:
409 "::ACE_OutputCDR::from_wchar (this->_pd_value)";
412 case AST_PredefinedType::PT_octet
:
414 "::ACE_OutputCDR::from_octet (this->_pd_value)";
417 case AST_PredefinedType::PT_uint8
:
419 "::ACE_OutputCDR::from_uint8 (this->_pd_value)";
422 case AST_PredefinedType::PT_int8
:
424 "::ACE_OutputCDR::from_int8 (this->_pd_value)";
427 case AST_PredefinedType::PT_any
:
428 marshal_arg
= "this->_pd_value.in ()";
432 marshal_arg
= "this->_pd_value";
436 return this->emit_for_predef_enum (marshal_arg
);
440 be_visitor_valuebox_cs::visit_sequence (be_sequence
*node
)
442 TAO_OutStream
*os
= this->ctx_
->stream ();
444 // Retrieve the node being visited by this be_visitor_valuebox_cs.
445 be_decl
* vb_node
= this->ctx_
->node ();
447 if (node
->anonymous ())
448 { // Our sequence is anonymous so we must generate a declaration
450 be_visitor_context
ctx (*this->ctx_
);
453 // First generate the sequence definition
454 be_visitor_sequence_cs
visitor (&ctx
);
456 if (node
->accept (&visitor
) == -1)
458 ACE_ERROR_RETURN ((LM_ERROR
,
459 "(%N:%l) be_visitor_valuebox_cs::"
466 // Retrieve the base type since we will need to do some code
467 // generation for it.
468 be_type
*bt
= dynamic_cast<be_type
*> (node
->base_type ());
472 ACE_ERROR_RETURN ((LM_ERROR
,
473 "(%N:%l) be_visitor_valuebox_cs::"
475 "Bad element type\n"),
478 be_visitor_context
ctx (*this->ctx_
);
479 ctx
.state (TAO_CodeGen::TAO_SEQUENCE_BUFFER_TYPE_CH
);
480 be_visitor_sequence_buffer_type
bt_visitor (&ctx
);
482 TAO_INSERT_COMMENT (os
);
484 if (node
->unbounded ())
486 // Public constructor with one argument of type ULong
487 *os
<< vb_node
->name () << "::" << vb_node
->local_name ()
488 << " ( ::CORBA::ULong max)" << be_nl
490 << node
->full_name () << "* p;" << be_nl
491 << "ACE_NEW (" << be_idt_nl
493 << node
->full_name () << " (max));" << be_uidt_nl
494 << "this->_pd_value = p;" << be_uidt_nl
498 // Public constructor for sequence with supplied buffer
499 *os
<< vb_node
->name () << "::" << vb_node
->local_name ()
502 if (node
->unbounded ())
504 *os
<< be_nl
<< "::CORBA::ULong max,";
507 *os
<< be_nl
<< "::CORBA::ULong length," << be_nl
;
510 if (bt
->accept (&bt_visitor
) == -1)
512 ACE_ERROR_RETURN ((LM_ERROR
,
513 "(%N:%l) be_visitor_valuebox_cs::"
515 "base type visit failed\n"),
519 *os
<< " * buf," << be_nl
520 << "::CORBA::Boolean release)" << be_uidt_nl
522 << node
->full_name () << "* p;" << be_nl
523 << "ACE_NEW (" << be_idt_nl
525 << node
->full_name () << " (";
527 if (node
->unbounded ())
532 *os
<< "length, buf, release));" << be_uidt_nl
533 << "this->_pd_value = p;" << be_uidt_nl
536 // end: Public constructor for sequence with supplied buffer
538 this->emit_destructor ();
540 // Accessor: non const
541 if (bt
->accept (&bt_visitor
) == -1)
543 ACE_ERROR_RETURN ((LM_ERROR
,
544 "(%N:%l) be_visitor_valuebox_cs::"
546 "base type visit failed\n"),
551 << vb_node
->name () << "::operator[] ( ::CORBA::ULong index)"
556 if (bt
->accept (&bt_visitor
) == -1)
558 ACE_ERROR_RETURN ((LM_ERROR
,
559 "(%N:%l) be_visitor_valuebox_cs::"
561 "base type visit failed\n"),
565 *os
<< "&) this->_pd_value->operator[] (index);" << be_uidt_nl
571 if (bt
->accept (&bt_visitor
) == -1)
573 ACE_ERROR_RETURN ((LM_ERROR
,
574 "(%N:%l) be_visitor_valuebox_cs::"
576 "base type visit failed\n"),
580 *os
<< " &" << be_nl
;
581 *os
<< vb_node
->name ()
582 << "::operator[] ( ::CORBA::ULong index) const" << be_nl
585 switch (bt
->node_type())
587 case AST_Decl::NT_wstring
:
588 *os
<< "TAO_SeqElem_WString_Manager mgr = this->_pd_value->operator[] "
590 << "return mgr._retn ();" << be_uidt_nl
;
593 case AST_Decl::NT_string
:
594 *os
<< "TAO_SeqElem_String_Manager mgr = this->_pd_value->operator[] "
596 << "return mgr._retn ();" << be_uidt_nl
;
602 if (bt
->accept (&bt_visitor
) == -1)
604 ACE_ERROR_RETURN ((LM_ERROR
,
605 "(%N:%l) be_visitor_valuebox_cs::"
607 "base type visit failed\n"),
611 *os
<< "&) this->_pd_value->operator[] (index);" << be_uidt_nl
;
614 *os
<< "}" << be_nl_2
;
616 // _tao_marshal_v method
617 *os
<< "::CORBA::Boolean" << be_nl
619 << "::_tao_marshal_v (TAO_OutputCDR & strm) const" << be_nl
621 << "return (strm << this->_pd_value.in ());" << be_uidt_nl
628 be_visitor_valuebox_cs::visit_string (be_string
*str
)
630 TAO_OutStream
& os
= *this->ctx_
->stream ();
632 // Retrieve the node being visited by this be_visitor_valuebox_cs.
633 be_decl
* const vb_node
= this->ctx_
->node ();
635 TAO_INSERT_COMMENT (&os
);
637 this->emit_destructor ();
639 // _tao_marshal_v method
640 os
<< "::CORBA::Boolean" << be_nl
642 << "::_tao_marshal_v (TAO_OutputCDR & strm) const" << be_nl
644 << "return (strm << ";
646 if (str
->max_size ()->ev ()->u
.ulval
!= 0)
648 if (str
->width () == (long) sizeof (char))
650 os
<< "::ACE_OutputCDR::from_string "
651 << "(this->_pd_value, "
652 << str
->max_size ()->ev ()->u
.ulval
<< ")";
656 os
<< "::ACE_OutputCDR::from_wstring "
657 << "(this->_pd_value, "
658 << str
->max_size ()->ev ()->u
.ulval
<< ")";
663 os
<< "this->_pd_value";
666 os
<< ");" << be_uidt_nl
673 be_visitor_valuebox_cs::visit_structure (be_structure
*)
675 TAO_OutStream
& os
= *this->ctx_
->stream ();
677 // Retrieve the node being visited by this be_visitor_valuebox_cs.
678 be_decl
* const vb_node
= this->ctx_
->node ();
680 TAO_INSERT_COMMENT (&os
);
682 this->emit_destructor ();
684 // _tao_marshal_v method
685 os
<< "::CORBA::Boolean" << be_nl
687 << "::_tao_marshal_v (TAO_OutputCDR & strm) const" << be_nl
689 << "return (strm << this->_pd_value.in ());" << be_uidt_nl
696 be_visitor_valuebox_cs::visit_typedef (be_typedef
*node
)
698 // Make a decision based on the primitive base type.
699 be_type
*bt
= node
->primitive_base_type ();
701 if (!bt
|| (bt
->accept (this) == -1))
703 ACE_ERROR_RETURN ((LM_ERROR
,
704 "(%N:%l) be_visitor_valuebox_cs::"
706 "Bad primitive type\n"),
714 be_visitor_valuebox_cs::visit_union (be_union
*)
716 TAO_OutStream
& os
= *this->ctx_
->stream ();
718 // Retrieve the node being visited by this be_visitor_valuebox_cs.
719 be_decl
* const vb_node
= this->ctx_
->node ();
721 TAO_INSERT_COMMENT (&os
);
723 this->emit_destructor ();
725 // _tao_marshal_v method
726 os
<< "::CORBA::Boolean" << be_nl
728 << "::_tao_marshal_v (TAO_OutputCDR & strm) const" << be_nl
730 << "return (strm << this->_pd_value.in ());" << be_uidt_nl
737 be_visitor_valuebox_cs::emit_destructor (void)
739 TAO_OutStream
& os
= *this->ctx_
->stream ();
741 // Retrieve the node being visited by this be_visitor_valuebox_cs.
742 be_decl
* const vb_node
= this->ctx_
->node ();
744 // Protected destructor
745 os
<< vb_node
->name () << "::~" << vb_node
->local_name () << " (void)"
746 << be_nl
<< "{" << be_nl
<< "}" << be_nl_2
;
750 be_visitor_valuebox_cs::emit_for_predef_enum (char const * marshal_arg
)
752 TAO_OutStream
& os
= *this->ctx_
->stream ();
754 // Retrieve the node being visited by this be_visitor_valuebox_cs.
755 be_decl
* const vb_node
= this->ctx_
->node ();
757 TAO_INSERT_COMMENT (&os
);
759 this->emit_destructor ();
761 // _tao_marshal_v method
762 os
<< "::CORBA::Boolean" << be_nl
764 << "::_tao_marshal_v (TAO_OutputCDR & strm) const" << be_nl
766 << "return (strm << " << marshal_arg
<< ");" << be_uidt_nl