Merge pull request #1844 from jrw972/monterey
[ACE_TAO.git] / TAO / TAO_IDL / be / be_visitor_valuebox / valuebox_cs.cpp
blob5c36bea5b0fa6ced8fa8b27c1783cdaac2d31d8b
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 (void)
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 << be_idt << be_idt_nl
59 << node->name () << " * p" << be_uidt_nl
60 << ")" << be_uidt_nl
61 << "{" << be_idt_nl
62 << "::CORBA::add_ref (p);" << be_uidt_nl
63 << "}";
65 *os << be_nl_2
66 << "void" << be_nl
67 << "TAO::Value_Traits<" << node->name () << ">::remove_ref ("
68 << be_idt << be_idt_nl
69 << node->name () << " * p" << be_uidt_nl
70 << ")" << be_uidt_nl
71 << "{" << be_idt_nl
72 << "::CORBA::remove_ref (p);" << be_uidt_nl
73 << "}";
75 *os << be_nl_2
76 << "void" << be_nl
77 << "TAO::Value_Traits<" << node->name () << ">::release ("
78 << be_idt << be_idt_nl
79 << node->name () << " * p" << be_uidt_nl
80 << ")" << be_uidt_nl
81 << "{" << be_idt_nl
82 << "::CORBA::remove_ref (p);" << be_uidt_nl
83 << "}";
86 // The _downcast method.
87 *os << be_nl_2
88 << node->name () << " *" << be_nl
89 << node->name () << "::_downcast ( ::CORBA::ValueBase *v)" << be_nl
90 << "{" << be_idt_nl
91 << "return dynamic_cast< ::" << node->name () << " * > (v);"
92 << be_uidt_nl << "}" << be_nl_2;
94 // _copy_value method
95 *os << "::CORBA::ValueBase *" << be_nl
96 << node->name () << "::_copy_value (void)" << be_nl
97 << "{" << be_idt_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
104 << "}" << be_nl_2;
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
111 << "}" << be_nl_2;
113 *os << "void" << be_nl
114 << node->name ()
115 << "::_tao_obv_truncatable_repo_ids (Repository_Id_List& ids) const"
116 << be_nl
117 << "{" << be_idt_nl
118 << "ids.push_back (this->_tao_obv_static_repository_id ());"
119 << be_uidt_nl
120 << "}" << be_nl_2;
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
126 << node->name ()
127 << "::_tao_match_formal_type (ptrdiff_t ) const" << be_nl
128 << "{" << be_idt_nl
129 << "return true;" << be_uidt_nl
130 << "}" << be_nl_2;
133 if (be_global->any_support ())
135 *os << "void" << be_nl
136 << node->name ()
137 << "::_tao_any_destructor (void *_tao_void_pointer)" << be_nl
138 << "{" << be_idt_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
144 << "}" << be_nl_2;
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);
169 if (!bt)
171 ACE_ERROR_RETURN ((LM_ERROR,
172 "(%N:%l) be_visitor_valuebox_cs::"
173 "visit_valuebox - "
174 "Bad type\n"),
175 -1);
178 bool is_array = false;
179 const char * unmarshal_arg;
180 be_predefined_type *bpt = dynamic_cast<be_predefined_type*> (bt);
182 if (bpt != 0)
184 switch (bpt->pt())
186 case AST_PredefinedType::PT_boolean:
187 unmarshal_arg =
188 "::ACE_InputCDR::to_boolean (vb_object->_pd_value)";
189 break;
191 case AST_PredefinedType::PT_char:
192 unmarshal_arg =
193 "::ACE_InputCDR::to_char (vb_object->_pd_value)";
194 break;
196 case AST_PredefinedType::PT_wchar:
197 unmarshal_arg =
198 "::ACE_InputCDR::to_wchar (vb_object->_pd_value)";
199 break;
201 case AST_PredefinedType::PT_octet:
202 unmarshal_arg =
203 "::ACE_InputCDR::to_octet (vb_object->_pd_value)";
204 break;
206 case AST_PredefinedType::PT_uint8:
207 unmarshal_arg =
208 "::ACE_InputCDR::to_uint8 (vb_object->_pd_value)";
209 break;
211 case AST_PredefinedType::PT_int8:
212 unmarshal_arg =
213 "::ACE_InputCDR::to_int8 (vb_object->_pd_value)";
214 break;
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 ()";
220 break;
222 default:
223 unmarshal_arg = "vb_object->_pd_value";
226 else if (dynamic_cast<be_array*> (bt) != 0)
228 is_array = true;
229 unmarshal_arg = "temp";
231 else
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
241 << ")" << be_uidt_nl
242 << "{" << be_idt_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 (),"
250 << be_nl
251 << "is_null_object, is_indirected"
252 << be_uidt_nl
253 << ") == false)" << be_uidt_nl
254 << "{" << be_idt_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
259 << "{" << be_idt_nl
260 << "return true;" << be_uidt_nl
261 << "}" << be_uidt_nl << be_nl
262 << "if (is_indirected)" << be_idt_nl
263 << "{" << 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;
274 if (is_array)
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);
283 if (str != 0 &&
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 << ")";
292 else
294 *os << "::ACE_InputCDR::to_wstring "
295 << "(vb_object->_pd_value, "
296 << str->max_size ()->ev ()->u.ulval << ")";
299 else
301 *os << unmarshal_arg;
304 *os << ");" << be_uidt_nl
305 << "}" << be_nl_2;
307 // _tao_unmarshal_v method. Generated because ValueBase interface
308 // requires it. But there is nothing for it to do in the valuebox
309 // case.
310 *os << "::CORBA::Boolean" << be_nl
311 << node->name ()
312 << "::_tao_unmarshal_v (TAO_InputCDR &)" << be_nl
313 << "{" << be_idt_nl
314 << "return true;" << be_uidt_nl
315 << "}" << be_nl_2;
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"),
324 -1);
327 // Indicate that code is already generated for this node.
328 node->cli_stub_gen (true);
330 return 0;
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
347 << vb_node->name ()
348 << "::_tao_marshal_v (TAO_OutputCDR & strm) const" << be_nl
349 << "{" << be_idt_nl
350 << node->name () << "_forany temp (this->_pd_value.ptr ());"
351 << be_nl
352 << "return (strm << temp);" << be_uidt_nl
353 << "}" << be_nl_2;
355 return 0;
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
374 << vb_node->name ()
375 << "::_tao_marshal_v (TAO_OutputCDR & strm) const" << be_nl
376 << "{" << be_idt_nl
377 << "return (strm << " << marshal_arg << ");" << be_uidt_nl
378 << "}" << be_nl_2;
380 return 0;
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;
395 switch (node->pt ())
397 case AST_PredefinedType::PT_boolean:
398 marshal_arg =
399 "::ACE_OutputCDR::from_boolean (this->_pd_value)";
400 break;
402 case AST_PredefinedType::PT_char:
403 marshal_arg =
404 "::ACE_OutputCDR::from_char (this->_pd_value)";
405 break;
407 case AST_PredefinedType::PT_wchar:
408 marshal_arg =
409 "::ACE_OutputCDR::from_wchar (this->_pd_value)";
410 break;
412 case AST_PredefinedType::PT_octet:
413 marshal_arg =
414 "::ACE_OutputCDR::from_octet (this->_pd_value)";
415 break;
417 case AST_PredefinedType::PT_uint8:
418 marshal_arg =
419 "::ACE_OutputCDR::from_uint8 (this->_pd_value)";
420 break;
422 case AST_PredefinedType::PT_int8:
423 marshal_arg =
424 "::ACE_OutputCDR::from_int8 (this->_pd_value)";
425 break;
427 case AST_PredefinedType::PT_any:
428 marshal_arg = "this->_pd_value.in ()";
429 break;
431 default:
432 marshal_arg = "this->_pd_value";
433 break;
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
449 // for it.
450 be_visitor_context ctx (*this->ctx_);
451 ctx.node (node);
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::"
460 "visit_sequence - "
461 "codegen failed\n"),
462 -1);
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 ());
470 if (bt == 0)
472 ACE_ERROR_RETURN ((LM_ERROR,
473 "(%N:%l) be_visitor_valuebox_cs::"
474 "visit_sequence - "
475 "Bad element type\n"),
476 -1);
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
489 << "{" << be_idt_nl
490 << node->full_name () << "* p;" << be_nl
491 << "ACE_NEW (" << be_idt_nl
492 << "p," << be_nl
493 << node->full_name () << " (max));" << be_uidt_nl
494 << "this->_pd_value = p;" << be_uidt_nl
495 << "}" << be_nl_2;
498 // Public constructor for sequence with supplied buffer
499 *os << vb_node->name () << "::" << vb_node->local_name ()
500 << " (" << be_idt;
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::"
514 "visit_valuebox - "
515 "base type visit failed\n"),
516 -1);
519 *os << " * buf," << be_nl
520 << "::CORBA::Boolean release)" << be_uidt_nl
521 << "{" << be_idt_nl
522 << node->full_name () << "* p;" << be_nl
523 << "ACE_NEW (" << be_idt_nl
524 << "p," << be_nl
525 << node->full_name () << " (";
527 if (node->unbounded ())
529 *os << "max, ";
532 *os << "length, buf, release));" << be_uidt_nl
533 << "this->_pd_value = p;" << be_uidt_nl
534 << "}" << be_nl_2;
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::"
545 "visit_valuebox - "
546 "base type visit failed\n"),
547 -1);
550 *os << " &" << be_nl
551 << vb_node->name () << "::operator[] ( ::CORBA::ULong index)"
552 << be_nl
553 << "{" << be_idt_nl
554 << "return (";
556 if (bt->accept (&bt_visitor) == -1)
558 ACE_ERROR_RETURN ((LM_ERROR,
559 "(%N:%l) be_visitor_valuebox_cs::"
560 "visit_valuebox - "
561 "base type visit failed\n"),
562 -1);
565 *os << "&) this->_pd_value->operator[] (index);" << be_uidt_nl
566 << "}" << be_nl_2;
568 // Accessor: const
569 *os << "const ";
571 if (bt->accept (&bt_visitor) == -1)
573 ACE_ERROR_RETURN ((LM_ERROR,
574 "(%N:%l) be_visitor_valuebox_cs::"
575 "visit_sequence - "
576 "base type visit failed\n"),
577 -1);
580 *os << " &" << be_nl;
581 *os << vb_node->name ()
582 << "::operator[] ( ::CORBA::ULong index) const" << be_nl
583 << "{" << be_idt_nl;
585 switch (bt->node_type())
587 case AST_Decl::NT_wstring:
588 *os << "TAO_SeqElem_WString_Manager mgr = this->_pd_value->operator[] "
589 "(index);" << be_nl
590 << "return mgr._retn ();" << be_uidt_nl;
591 break;
593 case AST_Decl::NT_string:
594 *os << "TAO_SeqElem_String_Manager mgr = this->_pd_value->operator[] "
595 "(index);" << be_nl
596 << "return mgr._retn ();" << be_uidt_nl;
597 break;
599 default:
600 *os << "return (";
602 if (bt->accept (&bt_visitor) == -1)
604 ACE_ERROR_RETURN ((LM_ERROR,
605 "(%N:%l) be_visitor_valuebox_cs::"
606 "visit_sequence - "
607 "base type visit failed\n"),
608 -1);
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
618 << vb_node->name ()
619 << "::_tao_marshal_v (TAO_OutputCDR & strm) const" << be_nl
620 << "{" << be_idt_nl
621 << "return (strm << this->_pd_value.in ());" << be_uidt_nl
622 << "}" << be_nl_2;
624 return 0;
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
641 << vb_node->name ()
642 << "::_tao_marshal_v (TAO_OutputCDR & strm) const" << be_nl
643 << "{" << be_idt_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 << ")";
654 else
656 os << "::ACE_OutputCDR::from_wstring "
657 << "(this->_pd_value, "
658 << str->max_size ()->ev ()->u.ulval << ")";
661 else
663 os << "this->_pd_value";
666 os << ");" << be_uidt_nl
667 << "}" << be_nl_2;
669 return 0;
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
686 << vb_node->name ()
687 << "::_tao_marshal_v (TAO_OutputCDR & strm) const" << be_nl
688 << "{" << be_idt_nl
689 << "return (strm << this->_pd_value.in ());" << be_uidt_nl
690 << "}" << be_nl_2;
692 return 0;
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::"
705 "visit_typedef - "
706 "Bad primitive type\n"),
707 -1);
710 return 0;
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
727 << vb_node->name ()
728 << "::_tao_marshal_v (TAO_OutputCDR & strm) const" << be_nl
729 << "{" << be_idt_nl
730 << "return (strm << this->_pd_value.in ());" << be_uidt_nl
731 << "}" << be_nl_2;
733 return 0;
736 void
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
763 << vb_node->name ()
764 << "::_tao_marshal_v (TAO_OutputCDR & strm) const" << be_nl
765 << "{" << be_idt_nl
766 << "return (strm << " << marshal_arg << ");" << be_uidt_nl
767 << "}" << be_nl_2;
769 return 0;