diff options
author | coryan <coryan@ae88bc3d-4319-0410-8dbf-d08b4c9d3795> | 1998-08-14 20:12:03 +0000 |
---|---|---|
committer | coryan <coryan@ae88bc3d-4319-0410-8dbf-d08b4c9d3795> | 1998-08-14 20:12:03 +0000 |
commit | da49b08671e5d87c9996bb0bcc63c661447f83b2 (patch) | |
tree | 4b92710abc7aef7d79efb811391b9254038b5480 | |
parent | 66e74009620c1297b07ce26dab97f586ed76edc7 (diff) | |
download | ATCD-da49b08671e5d87c9996bb0bcc63c661447f83b2.tar.gz |
ChangeLogTag:Fri Aug 14 14:44:49 1998 Carlos O'Ryan <coryan@cs.wustl.edu>
30 files changed, 1108 insertions, 160 deletions
diff --git a/TAO/ChangeLog-98c b/TAO/ChangeLog-98c index fee3399a36c..7348f4b39f7 100644 --- a/TAO/ChangeLog-98c +++ b/TAO/ChangeLog-98c @@ -1,3 +1,77 @@ +Fri Aug 14 14:44:49 1998 Carlos O'Ryan <coryan@cs.wustl.edu> + + * tao/IIOP_Interpreter.cpp: + * tao/deep_free.cpp: + * tao/encode.cpp: + * tao/decode.cpp: + Completed support for object references inside structures. + + * tao/Object.h: + * tao/Object.i: + * tao/Object.cpp: + * tao/varout.h: + * tao/varout.i: + * tao/varout.cpp: + Added a new class to represent an object reference when + contained inside a structure, it is similar to a T_var class + + * tao/Sequence.h: + * tao/Sequence.i: + * tao/Sequence.cpp: + * tao/Sequence_T.h: + * tao/Sequence_T.i: + * tao/Sequence_T.cpp: + Sequences contain new methods (_upcast() and _downcast()) that + help in the correct marshaling and demarshaling of sequences of + object references. + New parametric classes were added to support sequences of + pseudo-objects. + + + * TAO_IDL/be_include/be_sequence.h: + * TAO_IDL/be/be_sequence.cpp: + * TAO_IDL/be/be_visitor_sequence/sequence_cs.cpp: + * TAO_IDL/be/be_visitor_sequence/sequence_ch.cpp: + Added support for the new TAO_Unbounded_Pseudo_Sequence<T> used + for pseudo-objects. + + * TAO_IDL/be/be_visitor_sequence/gen_unbounded_obj_sequence_ch.cpp: + * TAO_IDL/be/be_visitor_sequence/gen_bounded_obj_sequence_ch.cpp: + Generate the new _upcast() and _downcast() methods for sequences + of objects. + + * TAO_IDL/be/be_visitor_interface/any_op_cs.cpp: + Generate the template instantiation for the + TAO_Object_Field_T<T> class. + + * TAO_IDL/be/be_visitor_field/field_ch.cpp: + Object references in structures are defined using a + TAO_Object_Field_T<T> object. + + * orbsvcs/orbsvcs/CosTrading.idl: + * orbsvcs/orbsvcs/Trader/Trader_Interfaces.cpp: + * orbsvcs/orbsvcs/Trader/Trader_Utils.cpp: + The ORB supports object rereferences inside structures. + + * orbsvcs/orbsvcs/CosPropertyService.idl: + Cosmetic changes. + + * tests/Param_Test/Makefile: + * tests/Param_Test/README: + * tests/Param_Test/run_test.pl: + * tests/Param_Test/driver.cpp: + * tests/Param_Test/objref_struct.cpp: + * tests/Param_Test/objref_struct.h: + * tests/Param_Test/options.cpp: + * tests/Param_Test/options.h: + * tests/Param_Test/param_test.idl: + * tests/Param_Test/param_test_i.cpp: + * tests/Param_Test/param_test_i.h: + * tests/Param_Test/tests.h: + * tests/Param_Test/ub_objref_seq.cpp: + Cleanup the object reference sequence test and added a test for + sequences inside structures. + Fri Aug 14 09:46:44 1998 David L. Levine <levine@cs.wustl.edu> * orbsvcs/orbsvcs/Sched/DynSched.cpp (calculate_utilization_params): diff --git a/TAO/TAO_IDL/be/be_sequence.cpp b/TAO/TAO_IDL/be/be_sequence.cpp index fa7645f2901..317e420cbf4 100644 --- a/TAO/TAO_IDL/be/be_sequence.cpp +++ b/TAO/TAO_IDL/be/be_sequence.cpp @@ -192,7 +192,7 @@ be_sequence::managed_type (void) (prim_type); if (bpd->pt () == AST_PredefinedType::PT_pseudo) { - this->mt_ = be_sequence::MNG_OBJREF; + this->mt_ = be_sequence::MNG_PSEUDO; } else { @@ -349,7 +349,8 @@ be_sequence::instance_name () // generate the appropriate sequence type switch (this->managed_type ()) { - case be_sequence::MNG_OBJREF: // sequence of objrefs + case be_sequence::MNG_PSEUDO: + case be_sequence::MNG_OBJREF: if (this->unbounded ()) ACE_OS::sprintf (namebuf, "_TAO_Unbounded_Object_Sequence_%s", diff --git a/TAO/TAO_IDL/be/be_visitor_field/field_ch.cpp b/TAO/TAO_IDL/be/be_visitor_field/field_ch.cpp index 5e1cdbd1a16..832c0a9ea0f 100644 --- a/TAO/TAO_IDL/be/be_visitor_field/field_ch.cpp +++ b/TAO/TAO_IDL/be/be_visitor_field/field_ch.cpp @@ -207,8 +207,10 @@ be_visitor_field_ch::visit_interface (be_interface *node) bt = node; // if not a typedef and we are defined in the use scope, we must be defined - os->indent (); // start from current indentation level - *os << bt->nested_type_name (this->ctx_->scope (), "_var"); + os->indent (); + *os << "TAO_Object_Field_T<" + << bt->nested_type_name (this->ctx_->scope (), "") + << ">"; return 0; } @@ -227,8 +229,10 @@ be_visitor_field_ch::visit_interface_fwd (be_interface_fwd *node) bt = node; // if not a typedef and we are defined in the use scope, we must be defined - os->indent (); // start from current indentation level - *os << bt->nested_type_name (this->ctx_->scope (), "_var"); + os->indent (); + *os << "TAO_Object_Field_T<" + << bt->nested_type_name (this->ctx_->scope (), "") + << ">"; return 0; } diff --git a/TAO/TAO_IDL/be/be_visitor_interface/any_op_cs.cpp b/TAO/TAO_IDL/be/be_visitor_interface/any_op_cs.cpp index 3fada47aff2..72c66b66368 100644 --- a/TAO/TAO_IDL/be/be_visitor_interface/any_op_cs.cpp +++ b/TAO/TAO_IDL/be/be_visitor_interface/any_op_cs.cpp @@ -103,6 +103,13 @@ be_visitor_interface_any_op_cs::visit_interface (be_interface *node) << "return 0; // failure" << be_uidt_nl << "}\n\n"; + *os << "#if defined (ACE_HAS_EXPLICIT_TEMPLATE_INSTANTIATION)" << be_idt_nl + << "template class TAO_Object_Field_T<" + << node->name () << ">;" << be_uidt_nl + << "#elif defined (ACE_HAS_TEMPLATE_INSTANTIATION_PRAGMA)" << be_nl + << "# pragma instantiate TAO_Object_Field_T<" + << node->name () << ">" << be_nl + << "#endif /* ACE_HAS_EXPLICIT_TEMPLATE_INSTANTIATION */\n\n"; // all we have to do is to visit the scope and generate code if (this->visit_scope (node) == -1) diff --git a/TAO/TAO_IDL/be/be_visitor_sequence/gen_bounded_obj_sequence_ch.cpp b/TAO/TAO_IDL/be/be_visitor_sequence/gen_bounded_obj_sequence_ch.cpp index 25d9a54410e..1bc9d75dcc2 100644 --- a/TAO/TAO_IDL/be/be_visitor_sequence/gen_bounded_obj_sequence_ch.cpp +++ b/TAO/TAO_IDL/be/be_visitor_sequence/gen_bounded_obj_sequence_ch.cpp @@ -233,17 +233,48 @@ be_visitor_sequence_ch::gen_bounded_obj_sequence (be_sequence *node) // _shrink_buffer *os << "virtual void _shrink_buffer (CORBA::ULong nl, CORBA::ULong ol)" << be_nl << "{" << be_idt_nl; - pt->accept(visitor); *os <<" **tmp = ACE_reinterpret_cast ("; - pt->accept (visitor); *os << " **, this->buffer_);" << be_nl + pt->accept(visitor); + *os <<" **tmp = ACE_reinterpret_cast ("; + pt->accept (visitor); + *os << " **, this->buffer_);" << be_nl << be_nl << "for (CORBA::ULong i = nl; i < ol; ++i)" << be_nl << "{" << be_idt_nl << "CORBA::release (tmp[i]);" << be_nl - << "tmp[i] = "; pt->accept (visitor); *os << "::_nil ();" << be_uidt_nl + << "tmp[i] = "; + pt->accept (visitor); + *os << "::_nil ();" << be_uidt_nl << "}" << be_uidt_nl - << "}" << be_nl - << be_uidt_nl - << "};" << be_nl; + << "}\n" << be_nl; + + if (pt->node_type () != AST_Decl::NT_pre_defined) + { + // Pseudo objects do not require this methods. + *os << "virtual void _downcast (" << be_idt << be_idt_nl + << "void* target," << be_nl + << "CORBA_Object *src," << be_nl + << "CORBA_Environment &env" << be_uidt_nl + << ")" << be_uidt_nl + << "{" << be_idt_nl; + pt->accept (visitor); + *os << " **tmp = ACE_static_cast ("; + pt->accept (visitor); + *os << "**, target);" << be_nl + << "*tmp = "; + pt->accept (visitor); + *os << "::_narrow (src, env);" << be_uidt_nl + << "}\n" << be_nl; + + *os << "virtual CORBA_Object* _upcast (void *src) const" << be_nl + << "{" << be_idt_nl; + pt->accept (visitor); + *os << " **tmp = ACE_static_cast ("; + pt->accept (visitor); + *os << "**, src);" << be_nl + << "return *tmp;" << be_uidt_nl + << "}" << be_nl; + } + *os << "};\n"; os->gen_endif (); diff --git a/TAO/TAO_IDL/be/be_visitor_sequence/gen_unbounded_obj_sequence_ch.cpp b/TAO/TAO_IDL/be/be_visitor_sequence/gen_unbounded_obj_sequence_ch.cpp index fb009f118c4..10a80a03edb 100644 --- a/TAO/TAO_IDL/be/be_visitor_sequence/gen_unbounded_obj_sequence_ch.cpp +++ b/TAO/TAO_IDL/be/be_visitor_sequence/gen_unbounded_obj_sequence_ch.cpp @@ -246,8 +246,36 @@ be_visitor_sequence_ch::gen_unbounded_obj_sequence (be_sequence *node) << "CORBA::release (tmp[i]);" << be_nl << "tmp[i] = "; pt->accept (visitor); *os << "::_nil ();" << be_uidt_nl << "}" << be_uidt_nl - << "}" << be_uidt_nl - << "};" << be_nl; + << "}" << be_uidt_nl; + + if (pt->node_type () != AST_Decl::NT_pre_defined) + { + // Pseudo objects do not require this methods. + *os << "virtual void _downcast (" << be_idt << be_idt_nl + << "void* target," << be_nl + << "CORBA_Object *src," << be_nl + << "CORBA_Environment &env" << be_uidt_nl + << ")" << be_uidt_nl + << "{" << be_idt_nl; + pt->accept (visitor); + *os << " **tmp = ACE_static_cast ("; + pt->accept (visitor); + *os << "**, target);" << be_nl + << "*tmp = "; + pt->accept (visitor); + *os << "::_narrow (src, env);" << be_uidt_nl + << "}\n" << be_nl; + + *os << "virtual CORBA_Object* _upcast (void *src) const" << be_nl + << "{" << be_idt_nl; + pt->accept (visitor); + *os << " **tmp = ACE_static_cast ("; + pt->accept (visitor); + *os << "**, src);" << be_nl + << "return *tmp;" << be_uidt_nl + << "}" << be_nl; + } + *os << "};\n"; os->gen_endif (); // endif macro diff --git a/TAO/TAO_IDL/be/be_visitor_sequence/sequence_ch.cpp b/TAO/TAO_IDL/be/be_visitor_sequence/sequence_ch.cpp index d77b77ae704..6d867a39bb9 100644 --- a/TAO/TAO_IDL/be/be_visitor_sequence/sequence_ch.cpp +++ b/TAO/TAO_IDL/be/be_visitor_sequence/sequence_ch.cpp @@ -67,13 +67,19 @@ be_visitor_sequence_ch::gen_base_sequence_class (be_sequence *node) // generate the appropriate sequence type switch (node->managed_type ()) { - case be_sequence::MNG_OBJREF: // sequence of objrefs + case be_sequence::MNG_OBJREF: if (node->unbounded ()) *os << "TAO_Unbounded_Object_Sequence<"; else *os << "TAO_Bounded_Object_Sequence<"; break; - case be_sequence::MNG_STRING: // sequence of strings + case be_sequence::MNG_PSEUDO: + if (node->unbounded ()) + *os << "TAO_Unbounded_Pseudo_Sequence<"; + else + *os << "TAO_Bounded_Pseudo_Sequence<"; + break; + case be_sequence::MNG_STRING: if (node->unbounded ()) *os << "TAO_Unbounded_String_Sequence"; else @@ -145,7 +151,8 @@ be_visitor_sequence_ch::instantiate_sequence (be_sequence *node) // generate the appropriate sequence type switch (node->managed_type ()) { - case be_sequence::MNG_OBJREF: // sequence of objrefs + case be_sequence::MNG_PSEUDO: + case be_sequence::MNG_OBJREF: if (node->unbounded ()) this->gen_unbounded_obj_sequence (node); else diff --git a/TAO/TAO_IDL/be/be_visitor_sequence/sequence_cs.cpp b/TAO/TAO_IDL/be/be_visitor_sequence/sequence_cs.cpp index 4fd02027959..e656f71cc67 100644 --- a/TAO/TAO_IDL/be/be_visitor_sequence/sequence_cs.cpp +++ b/TAO/TAO_IDL/be/be_visitor_sequence/sequence_cs.cpp @@ -71,13 +71,19 @@ be_visitor_sequence_cs::gen_base_sequence_class (be_sequence *node) // generate the appropriate sequence type switch (node->managed_type ()) { - case be_sequence::MNG_OBJREF: // sequence of objrefs + case be_sequence::MNG_OBJREF: if (node->unbounded ()) *os << "TAO_Unbounded_Object_Sequence<"; else *os << "TAO_Bounded_Object_Sequence<"; break; - case be_sequence::MNG_STRING: // sequence of strings + case be_sequence::MNG_PSEUDO: + if (node->unbounded ()) + *os << "TAO_Unbounded_Pseudo_Sequence<"; + else + *os << "TAO_Bounded_Pseudo_Sequence<"; + break; + case be_sequence::MNG_STRING: if (node->unbounded ()) *os << "TAO_Unbounded_String_Sequence"; else diff --git a/TAO/TAO_IDL/be_include/be_sequence.h b/TAO/TAO_IDL/be_include/be_sequence.h index 49c64393f48..3bd5ac71433 100644 --- a/TAO/TAO_IDL/be_include/be_sequence.h +++ b/TAO/TAO_IDL/be_include/be_sequence.h @@ -43,7 +43,8 @@ public: MNG_UNKNOWN , MNG_NONE, MNG_STRING, - MNG_OBJREF + MNG_OBJREF, + MNG_PSEUDO }; // =Operations diff --git a/TAO/orbsvcs/orbsvcs/CosPropertyService.idl b/TAO/orbsvcs/orbsvcs/CosPropertyService.idl index 55b81f81000..b3dfc3dce48 100644 --- a/TAO/orbsvcs/orbsvcs/CosPropertyService.idl +++ b/TAO/orbsvcs/orbsvcs/CosPropertyService.idl @@ -2,7 +2,7 @@ // $Id$ -// =================================================================================== +// ================================================================ // // = LIBRARY // cos @@ -11,12 +11,13 @@ // CosPropertyService.idl // // = DESCRITION -// The property service, downloaded from ftp://ftp.omg.org/pub/docs/1995/95-06-01.ps +// The property service, downloaded from +// ftp://ftp.omg.org/pub/docs/1995/95-06-01.ps // // = AUTHOR // Alexander Babu Arulanthu <alex@cs.wustl.edu> // -// ====================================================================================== +// ================================================================ module CosPropertyService { @@ -26,8 +27,8 @@ module CosPropertyService // of the type system. // // = DESCRIPTION - // The data types and interfaces to deal with property names, property values, - // property modes etc. + // The data types and interfaces to deal with property names, + // property values, property modes etc. // = Data Types. diff --git a/TAO/orbsvcs/orbsvcs/CosTrading.idl b/TAO/orbsvcs/orbsvcs/CosTrading.idl index 55f3e213a0f..54111f88ddf 100644 --- a/TAO/orbsvcs/orbsvcs/CosTrading.idl +++ b/TAO/orbsvcs/orbsvcs/CosTrading.idl @@ -13,8 +13,6 @@ // // ======================================================================== -#define TAO_HAS_OBJECT_IN_STRUCT_MARSHAL_BUG - module CosTrading { // forward references to our interfaces @@ -343,13 +341,8 @@ module CosTrading { struct LinkInfo { -#ifdef TAO_HAS_OBJECT_IN_STRUCT_MARSHAL_BUG - string target; - string target_reg; -#else Lookup target; Register target_reg; -#endif FollowOption def_pass_on_follow_rule; FollowOption limiting_follow_rule; }; @@ -544,11 +537,7 @@ module CosTradingDynamic }; struct DynamicProp { -#ifdef TAO_HAS_OBJECT_IN_STRUCT_MARSHAL_BUG - string eval_if; -#else DynamicPropEval eval_if; -#endif /* TAO_HAS_OBJECT_IN_STRUCT_MARSHAL_BUG */ TypeCode returned_type; any extra_info; }; diff --git a/TAO/orbsvcs/orbsvcs/Trader/Trader_Interfaces.cpp b/TAO/orbsvcs/orbsvcs/Trader/Trader_Interfaces.cpp index 39ce157ce37..5203ad57aaf 100644 --- a/TAO/orbsvcs/orbsvcs/Trader/Trader_Interfaces.cpp +++ b/TAO/orbsvcs/orbsvcs/Trader/Trader_Interfaces.cpp @@ -631,17 +631,8 @@ federated_query (const CosTrading::LinkNameSeq& links, TAO_TRY_ENV); TAO_CHECK_ENV; - CosTrading::Lookup_var remote_lookup; -#ifdef TAO_HAS_OBJECT_IN_STRUCT_MARSHAL_BUG - CORBA::ORB_ptr orb = TAO_ORB_Core_instance ()-> orb (); - CORBA::Object_var obj = - orb->string_to_object (link_info->target, TAO_TRY_ENV); - TAO_CHECK_ENV; - remote_lookup = CosTrading::Lookup::_narrow (obj.in (), TAO_TRY_ENV); - TAO_CHECK_ENV; -#else - remote_lookup = CosTrading::Lookup::_duplicate (link_info->target); -#endif /* TAO_HAS_OBJECT_IN_STRUCT_MARSHAL_BUG */ + CosTrading::Lookup_var remote_lookup = + CosTrading::Lookup::_duplicate (link_info->target); // Perform the federated query. remote_lookup->query (type, @@ -763,16 +754,8 @@ forward_query (const char* next_hop, link_interface->describe_link (next_hop, TAO_TRY_ENV); TAO_CHECK_ENV; - CosTrading::Lookup_var remote_lookup; -#ifdef TAO_HAS_OBJECT_IN_STRUCT_MARSHAL_BUG - CORBA::ORB_ptr orb = TAO_ORB_Core_instance ()-> orb (); - CORBA::Object_var obj = orb->string_to_object (link_info->target, TAO_TRY_ENV); - TAO_CHECK_ENV; - remote_lookup = CosTrading::Lookup::_narrow (obj.in (), TAO_TRY_ENV); - TAO_CHECK_ENV; -#else - remote_lookup = CosTrading::Lookup::_duplicate (link_info->target); -#endif /* TAO_HAS_OBJECT_IN_STRUCT_MARSHAL_BUG */ + CosTrading::Lookup_var remote_lookup = + CosTrading::Lookup::_duplicate (link_info->target); CORBA::Object_var us = this->_this (TAO_TRY_ENV); TAO_CHECK_ENV; @@ -1182,16 +1165,9 @@ resolve (const CosTrading::TraderName &name, link_info = link_if->describe_link (name[0], TAO_TRY_ENV); TAO_CHECK_ENV; -#ifdef TAO_HAS_OBJECT_IN_STRUCT_MARSHAL_BUG - CORBA::ORB_ptr orb = TAO_ORB_Core_instance ()-> orb (); - CORBA::Object_var obj = orb->string_to_object (link_info->target_reg, TAO_TRY_ENV); - TAO_CHECK_ENV; - remote_reg = CosTrading::Register::_narrow (obj.in (), TAO_TRY_ENV); + remote_reg = + CosTrading::Register::_narrow (link_info->target_reg, TAO_TRY_ENV); TAO_CHECK_ENV; -#else - remote_reg = CosTrading::Register::_narrow (link_info->target_reg); -#endif /* TAO_HAS_OBJECT_IN_STRUCT_MARSHAL_BUG */ - } TAO_CATCHANY { @@ -1672,13 +1648,7 @@ add_link (const char *name, // Create a link info structure for this link of the federation. CosTrading::Link::LinkInfo link_info; -#ifdef TAO_HAS_OBJECT_IN_STRUCT_MARSHAL_BUG - CORBA::ORB_ptr orb = TAO_ORB_Core_instance ()-> orb (); - link_info.target = orb->object_to_string (target, _env); - TAO_CHECK_ENV_RETURN_VOID (_env); -#else link_info.target = CosTrading::Lookup::_duplicate (target); -#endif /* TAO_HAS_OBJECT_IN_STRUCT_MARSHAL_BUG */ link_info.def_pass_on_follow_rule = def_pass_on_follow_rule; link_info.limiting_follow_rule = limiting_follow_rule; @@ -1737,32 +1707,14 @@ TAO_Link<TRADER_LOCK_TYPE,MAP_LOCK_TYPE>::describe_link (const char *name, new_link_info->def_pass_on_follow_rule = old_link_info.def_pass_on_follow_rule; new_link_info->limiting_follow_rule = old_link_info.limiting_follow_rule; -#ifdef TAO_HAS_OBJECT_IN_STRUCT_MARSHAL_BUG - CORBA::ORB_ptr orb = TAO_ORB_Core_instance ()-> orb (); - CORBA::Object_var obj = - orb->string_to_object (old_link_info.target, _env); - TAO_CHECK_ENV_RETURN (_env, new_link_info); - CosTrading::Lookup_var remote_lookup = - CosTrading::Lookup::_narrow (obj.in (), _env); - TAO_CHECK_ENV_RETURN (_env, new_link_info); -#endif /* TAO_HAS_OBJECT_IN_STRUCT_MARSHAL_BUG */ - new_link_info->target = old_link_info.target; // Delayed retrieval of register interface. // This avoids the nested upcall that would occur were we to invoke // this method in the add_link method. -#ifdef TAO_HAS_OBJECT_IN_STRUCT_MARSHAL_BUG - CosTrading::Register_var remote_register = remote_lookup->register_if (_env); - TAO_CHECK_ENV_RETURN (_env, new_link_info); - new_link_info->target_reg = - orb->object_to_string (remote_register.in (), _env); - TAO_CHECK_ENV_RETURN (_env, new_link_info); -#else new_link_info->target_reg = old_link_info.target->register_if (_env); TAO_CHECK_ENV_RETURN (_env, new_link_info); -#endif /* TAO_HAS_OBJECT_IN_STRUCT_MARSHAL_BUG */ // return the link information for this link name. return new_link_info; diff --git a/TAO/orbsvcs/orbsvcs/Trader/Trader_Utils.cpp b/TAO/orbsvcs/orbsvcs/Trader/Trader_Utils.cpp index 9dc8341eab0..5f3631ea52d 100644 --- a/TAO/orbsvcs/orbsvcs/Trader/Trader_Utils.cpp +++ b/TAO/orbsvcs/orbsvcs/Trader/Trader_Utils.cpp @@ -266,7 +266,6 @@ TAO_Property_Evaluator::property_value (int index, else if (this->supports_dp_) { // Property is defined at this point. - CosTradingDynamic::DynamicPropEval_var dp_eval; CosTradingDynamic::DynamicProp* dp_struct; const CORBA::String_var name = this->props_[index].name; const CORBA::Any& value = this->props_[index].value; @@ -274,16 +273,8 @@ TAO_Property_Evaluator::property_value (int index, // Extract the DP_Struct. value >>= dp_struct; -#if defined TAO_HAS_OBJECT_IN_STRUCT_MARSHAL_BUG - CORBA::ORB_ptr orb = TAO_ORB_Core_instance ()->orb (); - CORBA::Object_var obj = orb->string_to_object (dp_struct->eval_if, _env); - TAO_CHECK_ENV_RETURN (_env, 0); - dp_eval = CosTradingDynamic::DynamicPropEval::_narrow (obj.in (), _env); - TAO_CHECK_ENV_RETURN (_env, 0); -#else - dp_eval = + CosTradingDynamic::DynamicPropEval_var dp_eval = CosTradingDynamic::DynamicPropEval::_duplicate (dp_struct->eval_if); -#endif /* TAO_HAS_OBJECT_IN_STRUCT_MARSHAL_BUG */ if (CORBA::is_nil (dp_eval.in ())) { @@ -467,12 +458,7 @@ construct_dynamic_prop (const char* name, CosTradingDynamic::DynamicPropEval_var dp_eval = this->_this (TAO_TRY_ENV); -#if defined TAO_HAS_OBJECT_IN_STRUCT_MARSHAL_BUG - CORBA::ORB_ptr orb = TAO_ORB_Core_instance ()-> orb (); - dp_struct->eval_if = orb->object_to_string (dp_eval.in (), TAO_TRY_ENV); -#else dp_struct->eval_if = dp_eval; -#endif /* TAO_HAS_OBJECT_IN_STRUCT_MARSHAL_BUG */ TAO_CHECK_ENV; diff --git a/TAO/tao/IIOP_Interpreter.cpp b/TAO/tao/IIOP_Interpreter.cpp index 674519ec16b..ff93db56664 100644 --- a/TAO/tao/IIOP_Interpreter.cpp +++ b/TAO/tao/IIOP_Interpreter.cpp @@ -168,7 +168,7 @@ declare_entry (CORBA::Any, tk_any); declare_entry (CORBA::TypeCode_ptr, tk_TypeCode); declare_entry (CORBA::Principal_ptr, tk_Principal); -declare_entry (CORBA::Object_ptr, tk_objref); +declare_entry (TAO_Object_Field_T<CORBA_Object>, tk_objref); declare_entry (CORBA::String, tk_string); #if !defined (TAO_NO_COPY_OCTET_SEQUENCES) diff --git a/TAO/tao/Object.cpp b/TAO/tao/Object.cpp index 7f3fc766d9e..8f6904e327d 100644 --- a/TAO/tao/Object.cpp +++ b/TAO/tao/Object.cpp @@ -257,3 +257,19 @@ CORBA::Object::_use_locate_requests (CORBA::Boolean use_it) iiopobj->use_locate_requests (use_it); } + +// **************************************************************** + +TAO_Object_Field::~TAO_Object_Field (void) +{ +} + +#if defined (ACE_HAS_EXPLICIT_TEMPLATE_INSTANTIATION) + +template class TAO_Object_Field_T<CORBA_Object>; + +#elif defined (ACE_HAS_TEMPLATE_INSTANTIATION_PRAGMA) + +#pragma instantiate TAO_Object_Field_T<CORBA_Object> + +#endif /* ACE_HAS_EXPLICIT_TEMPLATE_INSTANTIATION */ diff --git a/TAO/tao/Object.h b/TAO/tao/Object.h index 58ae31182f0..0850f510974 100644 --- a/TAO/tao/Object.h +++ b/TAO/tao/Object.h @@ -28,15 +28,22 @@ class TAO_ServantBase; class STUB_Object; +class CORBA_Object; +typedef CORBA_Object* CORBA_Object_ptr; + class TAO_Export CORBA_Object { public: - static CORBA::Object_ptr _duplicate (CORBA::Object_ptr obj); + static CORBA_Object_ptr _duplicate (CORBA_Object_ptr obj); // increment the ref count - static CORBA::Object_ptr _nil (void); + static CORBA_Object_ptr _nil (void); // return a NUL object + static CORBA_Object_ptr _narrow (CORBA_Object_ptr obj, + CORBA::Environment& env); + // no-op it is just here to simplify some templates. + // These calls correspond to over-the-wire operations, or at least // do so in many common cases. The normal implementation assumes a // particular simple, efficient, protocol-neutral interface for @@ -197,6 +204,35 @@ private: CORBA::Object_ptr &ptr_; }; +class TAO_Object_Field +{ + // = TITLE + // Base class to represent fields (in structures) corresponding to + // object references. + // + // = DESCRIPTION + // When an object reference appears in a structure the marshaling + // and demarhsaling of the structure gets complicated: + // the interpreter can only marshal CORBA_Object_ptr when it + // dermarshal it creates on of those objects. + // The downcasting to the right type must be executed by classes + // with compile-time knowledge of the object type. + // The solution addopted in TAO is to create a special manager + // class for that field called TAO_Object_Field_T<T> (see + // varout.h), this class serves as an abstract interface to + // manipulate instances of those classes (by the interpreter, of + // course). + // +public: + virtual ~TAO_Object_Field (void); + // destructor + + virtual void _downcast (CORBA_Object* base_ptr, + CORBA_Environment& env) = 0; + virtual CORBA_Object* _upcast (void) = 0; + virtual void _release (void) = 0; +}; + #if defined (__ACE_INLINE__) # include "tao/Object.i" #endif /* __ACE_INLINE__ */ diff --git a/TAO/tao/Object.i b/TAO/tao/Object.i index 98ece395a43..aa84c3361c2 100644 --- a/TAO/tao/Object.i +++ b/TAO/tao/Object.i @@ -24,7 +24,7 @@ CORBA_Object::_decr_refcnt (void) } ACE_INLINE CORBA_Object_ptr -CORBA_Object::_duplicate (CORBA::Object_ptr obj) +CORBA_Object::_duplicate (CORBA_Object_ptr obj) { if (obj) obj->_incr_refcnt (); @@ -39,6 +39,12 @@ CORBA_Object::_nil (void) return 0; } +ACE_INLINE CORBA_Object_ptr +CORBA_Object::_narrow (CORBA_Object_ptr obj, CORBA::Environment&) +{ + return obj; +} + ACE_INLINE CORBA::Boolean CORBA::is_nil (CORBA::Object_ptr obj) { diff --git a/TAO/tao/Sequence.cpp b/TAO/tao/Sequence.cpp index 7538f768bd7..aa5faa52340 100644 --- a/TAO/tao/Sequence.cpp +++ b/TAO/tao/Sequence.cpp @@ -21,6 +21,21 @@ void TAO_Base_Sequence::_shrink_buffer (CORBA::ULong, CORBA::ULong) // default is no op. } +void +TAO_Base_Sequence::_downcast (void*, + CORBA_Object*, + CORBA_Environment &) +{ + // default is no op. + // @@ TODO Maybe throw an exception? +} + +CORBA_Object* +TAO_Base_Sequence::_upcast (void*) const +{ + return 0; +} + // ************************************************************* // Operations for class TAO_Unbounded_Base_Sequence // ************************************************************* diff --git a/TAO/tao/Sequence.h b/TAO/tao/Sequence.h index 816845bc653..a765cdd4660 100644 --- a/TAO/tao/Sequence.h +++ b/TAO/tao/Sequence.h @@ -18,6 +18,9 @@ #if !defined (TAO_SEQUENCE_H) # define TAO_SEQUENCE_H +class CORBA_Object; +class CORBA_Environment; + class TAO_Export TAO_Base_Sequence { // = TITLE @@ -55,6 +58,16 @@ public: // release the objects only from position <0> to <length-1>; so // shrink and then delete could result in a memory leak. + virtual void _downcast (void* target, + CORBA_Object* src, + CORBA_Environment &env); + // Used for sequences of objects to downcast a recently demarshalled + // object reference into the right type. + + virtual CORBA_Object* _upcast (void* src) const; + // Used for sequences of object to convert from the derived type + // into the Object class. + protected: TAO_Base_Sequence (void); // Default constructor. @@ -461,6 +474,10 @@ private: // **************************************************************** + + +// **************************************************************** + #if defined (__ACE_INLINE__) #include "tao/Sequence.i" #endif /* __ACE_INLINE__ */ diff --git a/TAO/tao/Sequence_T.cpp b/TAO/tao/Sequence_T.cpp index af795395a12..34ca0ad9d28 100644 --- a/TAO/tao/Sequence_T.cpp +++ b/TAO/tao/Sequence_T.cpp @@ -125,19 +125,8 @@ operator= (const TAO_Bounded_Sequence<T, MAX> &rhs) if (this->release_) { -#if 0 // We never need to reallocate the buffer because they are // always of size MAX. - if (this->maximum_ < rhs.maximum_) - { - // free the old buffer - T *tmp = ACE_reinterpret_cast (T *, - this->buffer_); - TAO_Bounded_Sequence<T>::freebuf (tmp); - this->buffer_ = - TAO_Bounded_Sequence<T>::allocbuf (rhs.maximum_); - } -#endif /* 0 */ } else this->buffer_ = @@ -372,7 +361,7 @@ template<class T> void TAO_Unbounded_Object_Sequence<T>::_shrink_buffer (CORBA::ULong nl, CORBA::ULong ol) { - T **tmp = ACE_reinterpret_cast (T**, this->buffer_); + T **tmp = ACE_static_cast (T**, this->buffer_); for (CORBA::ULong i = nl; i < ol; ++i) { @@ -381,6 +370,24 @@ TAO_Unbounded_Object_Sequence<T>::_shrink_buffer (CORBA::ULong nl, } } +template <class T> void +TAO_Unbounded_Object_Sequence<T>::_downcast (void* target, + CORBA_Object* src, + CORBA_Environment &env) +{ + T **tmp = ACE_static_cast (T**, target); + + *tmp = T::_narrow (src, env); +} + +template <class T> CORBA_Object* +TAO_Unbounded_Object_Sequence<T>::_upcast (void* src) const +{ + T **tmp = ACE_static_cast (T**, src); + + return *tmp; +} + // ************************************************************* // Operations for class TAO_Bounded_Object_Sequence // ************************************************************* @@ -425,14 +432,6 @@ TAO_Bounded_Object_Sequence<T, MAX>::operator= } // No need to reallocate the buffer since it is always of size // MAX -#if 0 - if (this->maximum_ < rhs.maximum_) - { - TAO_Bounded_Object_Sequence<T, MAX>::freebuf (tmp); - this->buffer_ = - TAO_Bounded_Object_Sequence<T, MAX>::allocbuf (rhs.maximum_); - } -#endif /* 0 */ } else this->buffer_ = @@ -508,6 +507,304 @@ TAO_Bounded_Object_Sequence<T, MAX>::_shrink_buffer (CORBA::ULong nl, } } +template <class T, CORBA::ULong MAX> void +TAO_Bounded_Object_Sequence<T, MAX>::_downcast (void* target, + CORBA_Object* src, + CORBA_Environment &env) +{ + T **tmp = ACE_static_cast (T**, target); + + *tmp = T::_narrow (src, env); +} + +template <class T, CORBA::ULong MAX> CORBA_Object* +TAO_Bounded_Object_Sequence<T, MAX>::_upcast (void* src) const +{ + T **tmp = ACE_static_cast (T**, src); + + return *tmp; +} + +// ************************************************************* +// Operations for class TAO_Unbounded_Pseudo_Sequence +// ************************************************************* + +// constructor for unbounded seq +template <class T> +TAO_Unbounded_Pseudo_Sequence<T>:: +TAO_Unbounded_Pseudo_Sequence (CORBA::ULong maximum) + : TAO_Unbounded_Base_Sequence (maximum, + TAO_Unbounded_Pseudo_Sequence<T>::allocbuf (maximum)) +{ +} + +template <class T> +TAO_Unbounded_Pseudo_Sequence<T>:: +TAO_Unbounded_Pseudo_Sequence (const TAO_Unbounded_Pseudo_Sequence<T> &rhs) + : TAO_Unbounded_Base_Sequence (rhs) +{ + T **tmp1 = TAO_Unbounded_Pseudo_Sequence<T>::allocbuf (this->maximum_); + T ** const tmp2 = ACE_reinterpret_cast (T ** ACE_CAST_CONST, rhs.buffer_); + + for (CORBA::ULong i = 0; i < rhs.length_; ++i) + tmp1[i] = T::_duplicate (tmp2[i]); + + this->buffer_ = tmp1; +} + +template<class T> +TAO_Unbounded_Pseudo_Sequence<T>::~TAO_Unbounded_Pseudo_Sequence (void) +{ + this->_deallocate_buffer (); +} + +// assignment operator +template <class T> +TAO_Unbounded_Pseudo_Sequence<T>& +TAO_Unbounded_Pseudo_Sequence<T>:: +operator= (const TAO_Unbounded_Pseudo_Sequence<T> &rhs) +{ + if (this == &rhs) + return *this; + + if (this->release_) + { + T **tmp = ACE_reinterpret_cast (T **, + this->buffer_); + + for (CORBA::ULong i = 0; i < this->length_; ++i) + { + CORBA::release (tmp[i]); + tmp[i] = T::_nil (); + } + if (this->maximum_ < rhs.maximum_) + { + TAO_Unbounded_Pseudo_Sequence<T>::freebuf (tmp); + this->buffer_ = + TAO_Unbounded_Pseudo_Sequence<T>::allocbuf (rhs.maximum_); + } + } + else + this->buffer_ = + TAO_Unbounded_Pseudo_Sequence<T>::allocbuf (rhs.maximum_); + + TAO_Unbounded_Base_Sequence::operator= (rhs); + + T **tmp1 = ACE_reinterpret_cast (T **, this->buffer_); + T ** const tmp2 = ACE_reinterpret_cast (T ** ACE_CAST_CONST, rhs.buffer_); + + for (CORBA::ULong i = 0; i < rhs.length_; ++i) + tmp1[i] = T::_duplicate (tmp2[i]); + + return *this; +} + +template <class T> T ** +TAO_Unbounded_Pseudo_Sequence<T>::allocbuf (CORBA::ULong nelems) +{ + T **buf; + + ACE_NEW_RETURN (buf, T*[nelems], 0); + + for (CORBA::ULong i = 0; i < nelems; i++) + buf[i] = T::_nil (); + + return buf; +} + +template <class T> void +TAO_Unbounded_Pseudo_Sequence<T>::freebuf (T **buffer) +{ + if (buffer == 0) + return; + + // {orbos/97-05-15:16.11} The freebuf function ensures that the + // destructor for each element is called before the buffer is + // destroyed, except for string elements, which are freed using + // string_free(), and object reference elements, which are freed + // using release(). The freebuf function will ignore null pointers + // passed to it. + + // @@ How are we supposed to implement that! We don't know the + // length of the buffer here. + // Mark the length in the first four bytes? For the moment we let + // that be. + + delete[] buffer; +} + +template<class T> +void TAO_Unbounded_Pseudo_Sequence<T>::_allocate_buffer (CORBA::ULong length) +{ + T **tmp = TAO_Unbounded_Pseudo_Sequence<T>::allocbuf (length); + + if (this->buffer_ != 0) + { + T **old = ACE_reinterpret_cast (T**, this->buffer_); + for (CORBA::ULong i = 0; i < this->length_; ++i) + // Only call duplicate when we did not own the previous + // buffer, since after this method we own it we must also own + // the objects. If we already own the objects there is no + // need to copy them, if we did we would also have to remove + // the old instances. + if (!this->release_) + tmp[i] = T::_duplicate (old[i]); + else + tmp[i] = old[i]; + + if (this->release_) + delete[] old; + } + this->buffer_ = tmp; +} + +template<class T> +void TAO_Unbounded_Pseudo_Sequence<T>::_deallocate_buffer (void) +{ + if (this->buffer_ == 0 || this->release_ == 0) + return; + T **tmp = ACE_reinterpret_cast (T**, this->buffer_); + for (CORBA::ULong i = 0; i < this->length_; ++i) + { + CORBA::release (tmp[i]); + tmp[i] = T::_nil (); + } + TAO_Unbounded_Pseudo_Sequence<T>::freebuf (tmp); + this->buffer_ = 0; +} + +template<class T> void +TAO_Unbounded_Pseudo_Sequence<T>::_shrink_buffer (CORBA::ULong nl, + CORBA::ULong ol) +{ + T **tmp = ACE_static_cast (T**, this->buffer_); + + for (CORBA::ULong i = nl; i < ol; ++i) + { + CORBA::release (tmp[i]); + tmp[i] = T::_nil (); + } +} + +// ************************************************************* +// Operations for class TAO_Bounded_Pseudo_Sequence +// ************************************************************* + +template <class T, CORBA::ULong MAX> +TAO_Bounded_Pseudo_Sequence<T, MAX>:: +TAO_Bounded_Pseudo_Sequence (void) + : TAO_Bounded_Base_Sequence (MAX, + TAO_Bounded_Pseudo_Sequence<T, MAX>::allocbuf (MAX)) +{ +} + +template <class T, CORBA::ULong MAX> +TAO_Bounded_Pseudo_Sequence<T, MAX>:: +TAO_Bounded_Pseudo_Sequence (const TAO_Bounded_Pseudo_Sequence<T, MAX> &rhs) + : TAO_Bounded_Base_Sequence (rhs) +{ + T **tmp1 = + TAO_Bounded_Pseudo_Sequence<T, MAX>::allocbuf (MAX); + T ** const tmp2 = ACE_reinterpret_cast (T** ACE_CAST_CONST, rhs.buffer_); + for (CORBA::ULong i = 0; i < rhs.length_; i++) + tmp1[i] = T::_duplicate (tmp2[i]); + this->buffer_ = tmp1; +} + +template <class T, CORBA::ULong MAX> +TAO_Bounded_Pseudo_Sequence<T, MAX>& +TAO_Bounded_Pseudo_Sequence<T, MAX>::operator= +(const TAO_Bounded_Pseudo_Sequence<T, MAX> &rhs) +{ + if (this == &rhs) + return *this; + + if (this->release_) + { + T **tmp = ACE_reinterpret_cast (T **, this->buffer_); + + for (CORBA::ULong i = 0; i < this->length_; ++i) + { + CORBA::release (tmp[i]); + tmp[i] = T::_nil (); + } + // No need to reallocate the buffer since it is always of size + // MAX + } + else + this->buffer_ = + TAO_Bounded_Pseudo_Sequence<T, MAX>::allocbuf (rhs.maximum_); + + TAO_Bounded_Base_Sequence::operator= (rhs); + + T **tmp1 = ACE_reinterpret_cast (T **, this->buffer_); + T ** const tmp2 = ACE_reinterpret_cast (T ** ACE_CAST_CONST, rhs.buffer_); + for (CORBA::ULong i=0; i < rhs.length_; ++i) + tmp1[i] = T::_duplicate (tmp2[i]); + return *this; +} + +template <class T, CORBA::ULong MAX> T ** +TAO_Bounded_Pseudo_Sequence<T, MAX>::allocbuf (CORBA::ULong) +{ + T **buf; + + ACE_NEW_RETURN (buf, T*[MAX], 0); + + for (CORBA::ULong i = 0; i < MAX; i++) + buf[i] = T::_nil (); + + return buf; +} + +template <class T, CORBA::ULong MAX> void +TAO_Bounded_Pseudo_Sequence<T, MAX>::freebuf (T **buffer) +{ + // How much do we deallocate? Easy! allocbuf() always creates MAX + // elements and initialize them to T::_nil(). So we can be + // complaint and call CORBA::release() on each one. + for (CORBA::ULong i = 0; i < MAX; ++i) + if (buffer[i] != T::_nil ()) + { + CORBA::release (buffer[i]); + buffer[i] = T::_nil (); + } + + delete[] buffer; +} + +template<class T, CORBA::ULong MAX> void +TAO_Bounded_Pseudo_Sequence<T, MAX>::_allocate_buffer (CORBA::ULong length) +{ + // For this class memory is never reallocated so the implementation + // is *really* simple. + this->buffer_ = + TAO_Bounded_Pseudo_Sequence<T, MAX>::allocbuf (length); +} + +template<class T, CORBA::ULong MAX> +void TAO_Bounded_Pseudo_Sequence<T, MAX>::_deallocate_buffer (void) +{ + if (this->buffer_ == 0 || this->release_ == 0) + return; + T **tmp = ACE_reinterpret_cast (T **, this->buffer_); + TAO_Bounded_Pseudo_Sequence<T, MAX>::freebuf (tmp); + this->buffer_ = 0; +} + +template<class T, CORBA::ULong MAX> void +TAO_Bounded_Pseudo_Sequence<T, MAX>::_shrink_buffer (CORBA::ULong nl, + CORBA::ULong ol) +{ + T **tmp = ACE_reinterpret_cast (T **, this->buffer_); + + for (CORBA::ULong i = nl; i < ol; ++i) + { + CORBA::release (tmp[i]); + tmp[i] = T::_nil (); + } +} + // ************************************************************* // Operations for class TAO_Bounded_String_Sequence // ************************************************************* @@ -553,14 +850,8 @@ TAO_Bounded_String_Sequence<MAX>::operator= CORBA::string_free (tmp[i]); tmp[i] = 0; } -#if 0 - if (this->maximum_ < rhs.maximum_) - { - TAO_Bounded_String_Sequence<T, MAX>::freebuf (tmp); - this->buffer_ = - TAO_Unbounded_String_Sequence<T, MAX>::allocbuf (rhs.maximum_); - } -#endif /* 0 */ + // No need to reallocate because the buffer is supposed to be of + // <MAX> size. } else this->buffer_ = diff --git a/TAO/tao/Sequence_T.h b/TAO/tao/Sequence_T.h index 9a5601ae42b..d1863ca1e13 100644 --- a/TAO/tao/Sequence_T.h +++ b/TAO/tao/Sequence_T.h @@ -310,10 +310,10 @@ class TAO_Unbounded_Object_Sequence : public TAO_Unbounded_Base_Sequence // pseudo objects, object references and strings. // = SPEC - // 16.8 Mapping for Structured Types - // The mapping for struct, union, and sequence (but not array) is a - // C++ struct or class with a default constructor, a copy - // constructor, an assignment operator, and a destructor. + // 16.8 Mapping for Structured Types + // The mapping for struct, union, and sequence (but not array) is a + // C++ struct or class with a default constructor, a copy + // constructor, an assignment operator, and a destructor. // public: // = Initialization and termination methods. @@ -412,6 +412,10 @@ public: virtual void _deallocate_buffer (void); virtual void _shrink_buffer (CORBA::ULong new_length, CORBA::ULong old_length); + virtual void _downcast (void* target, + CORBA_Object* src, + CORBA_Environment &env); + virtual CORBA_Object* _upcast (void* src) const; }; // ************************************************************* @@ -423,9 +427,8 @@ class TAO_Bounded_Object_Sequence : public TAO_Bounded_Base_Sequence // Parametric sequence for types that require managers. // // = DESCRIPTION - // Some IDL types require that sequences on them have a "manager" - // class, in charge of handling the object lifetime, examples are - // pseudo objects, object references and strings. + // Please see the documentation for the unbounded case. + // public: // = Initialization and termination methods. @@ -465,6 +468,117 @@ public: virtual void _deallocate_buffer (void); virtual void _shrink_buffer (CORBA::ULong new_length, CORBA::ULong old_length); + virtual void _downcast (void* target, + CORBA_Object* src, + CORBA_Environment &env); + virtual CORBA_Object* _upcast (void* src) const; +}; + +// ************************************************************* + +template<class T> +class TAO_Unbounded_Pseudo_Sequence : public TAO_Unbounded_Base_Sequence +{ + // = TITLE + // Parametric sequence for pseudo objects. + // + // = DESCRIPTION + // Some IDL types (including pseudo objects) require that + // sequences on them have a "manager" class, in charge of handling + // the object lifetime. + // This parametric class implements those sequences. In general + // the sequence is similar to Object_Sequente, except for some + // TAO internal details. The complete documentation of each method + // is provided in TAO_Unbounded_Object_Sequece +public: + // = Initialization and termination methods. + + TAO_Unbounded_Pseudo_Sequence (void); + // default ctor + + TAO_Unbounded_Pseudo_Sequence (CORBA::ULong max); + // Constructor with a "hint" for the maximum capacity. + + TAO_Unbounded_Pseudo_Sequence (CORBA::ULong maximum, + CORBA::ULong length, + T* *data, + CORBA::Boolean release=0); + // Constructor with a given buffer. + + TAO_Unbounded_Pseudo_Sequence(const TAO_Unbounded_Pseudo_Sequence<T> &); + // Copy ctor, deep copies. + + ~TAO_Unbounded_Pseudo_Sequence (void); + // dtor releases all the contained elements. + + TAO_Unbounded_Pseudo_Sequence<T> &operator= (const TAO_Unbounded_Pseudo_Sequence <T> &); + // The assignment operator first releases all object reference + // members and frees all string members, and then performs a + // deepcopy to create a new structure. + + TAO_Object_Manager<T> operator[] (CORBA::ULong index) const; + // read-write accessor + + static T **allocbuf (CORBA::ULong); + // The allocbuf function allocates a vector of T elements that can + // be passed to the T *data constructor. + + static void freebuf (T **); + // Release all the elements. + + // The Base_Sequence functions, please see "tao/Sequence.h" + virtual void _allocate_buffer (CORBA::ULong length); + virtual void _deallocate_buffer (void); + virtual void _shrink_buffer (CORBA::ULong new_length, + CORBA::ULong old_length); +}; + +// ************************************************************* + +template<class T, CORBA::ULong MAX> +class TAO_Bounded_Pseudo_Sequence : public TAO_Bounded_Base_Sequence +{ + // = TITLE + // Bounded version of TAO_Unbounded_Psuedo_Sequence. + // + // = DESCRIPTION + // Please see the documentation for the unbounded case. + // +public: + // = Initialization and termination methods. + + TAO_Bounded_Pseudo_Sequence (void); + // default ctor. + + TAO_Bounded_Pseudo_Sequence (CORBA::ULong length, + T* *value, + CORBA::Boolean release=0); + // Constructor from data. + + TAO_Bounded_Pseudo_Sequence (const TAO_Bounded_Pseudo_Sequence<T,MAX> &); + // Copy constructor. + + ~TAO_Bounded_Pseudo_Sequence (void); + // destructor + + TAO_Bounded_Pseudo_Sequence &operator= (const TAO_Bounded_Pseudo_Sequence<T,MAX> &); + // Assignment from another Bounded sequence. + + TAO_Object_Manager<T> operator[] (CORBA::ULong index) const; + // Read-write accessor. + + static T **allocbuf (CORBA::ULong length); + // Allocate storage for a sequence.. + + static void freebuf (T **buffer); + // Free a buffer allocated by allocbuf() and release each element on + // it. + + // The Base_Sequence functions, please see "tao/sequence.h" + virtual void _allocate_buffer (CORBA::ULong length); + virtual void _deallocate_buffer (void); + virtual void _shrink_buffer (CORBA::ULong new_length, + CORBA::ULong old_length); }; // ************************************************************* diff --git a/TAO/tao/Sequence_T.i b/TAO/tao/Sequence_T.i index eaca5865c42..8ab52ad0560 100644 --- a/TAO/tao/Sequence_T.i +++ b/TAO/tao/Sequence_T.i @@ -313,6 +313,61 @@ TAO_Bounded_Object_Sequence<T, MAX>::operator[] (CORBA::ULong index) const } // ************************************************************* +// class TAO_Unbounded_Pseudo_Sequence +// ************************************************************* + +//default constructor +template <class T> ACE_INLINE +TAO_Unbounded_Pseudo_Sequence<T>::TAO_Unbounded_Pseudo_Sequence (void) +{ +} + +template <class T> ACE_INLINE +TAO_Unbounded_Pseudo_Sequence<T>:: +TAO_Unbounded_Pseudo_Sequence (CORBA::ULong maximum, + CORBA::ULong length, + T* *value, + CORBA::Boolean release) + : TAO_Unbounded_Base_Sequence (maximum, length, value, release) +{ +} + +template <class T> ACE_INLINE TAO_Object_Manager<T> +TAO_Unbounded_Pseudo_Sequence<T>::operator[] (CORBA::ULong index) const +{ + ACE_ASSERT (index < this->maximum_); + T ** const tmp = ACE_reinterpret_cast (T ** ACE_CAST_CONST, this->buffer_); + return TAO_Object_Manager<T> (tmp + index, this->release_); +} + +// ************************************************************* +// class TAO_Bounded_Pseudo_Sequence +// ************************************************************* + +template<class T, CORBA::ULong MAX> ACE_INLINE +TAO_Bounded_Pseudo_Sequence<T,MAX>::~TAO_Bounded_Pseudo_Sequence (void) +{ + this->_deallocate_buffer (); +} + +template <class T, CORBA::ULong MAX> ACE_INLINE +TAO_Bounded_Pseudo_Sequence<T,MAX>:: +TAO_Bounded_Pseudo_Sequence (CORBA::ULong length, + T **value, + CORBA::Boolean release) + : TAO_Bounded_Base_Sequence (MAX, length, value, release) +{ +} + +template <class T, CORBA::ULong MAX> ACE_INLINE TAO_Object_Manager<T> +TAO_Bounded_Pseudo_Sequence<T, MAX>::operator[] (CORBA::ULong index) const +{ + ACE_ASSERT (index < this->maximum_); + T **const tmp = ACE_reinterpret_cast (T ** ACE_CAST_CONST, this->buffer_); + return TAO_Object_Manager<T> (tmp + index, this->release_); +} + +// ************************************************************* // class TAO_Bounded_String_Sequence // ************************************************************* diff --git a/TAO/tao/corba.h b/TAO/tao/corba.h index 5ee93974f74..665110dfd2b 100644 --- a/TAO/tao/corba.h +++ b/TAO/tao/corba.h @@ -175,6 +175,7 @@ operator>>(TAO_InputCDR&, TAO_opaque&); #include "tao/Request.h" #include "tao/Stub.h" #include "tao/Object.h" +#include "tao/varout.h" #include "tao/Typecode.h" // Marshaling diff --git a/TAO/tao/decode.cpp b/TAO/tao/decode.cpp index 13c0ffc1731..86664cb6bd9 100644 --- a/TAO/tao/decode.cpp +++ b/TAO/tao/decode.cpp @@ -799,7 +799,6 @@ TAO_Marshal_Struct::decode (CORBA::TypeCode_ptr tc, stream->read_wchar (*(CORBA::WChar *) data); break; case CORBA::tk_TypeCode: - case CORBA::tk_objref: case CORBA::tk_any: case CORBA::tk_Principal: case CORBA::tk_struct: @@ -812,6 +811,17 @@ TAO_Marshal_Struct::decode (CORBA::TypeCode_ptr tc, case CORBA::tk_wstring: retval = stream->decode (param, data, 0, env); break; + + case CORBA::tk_objref: + { + CORBA_Object_ptr object; + retval = stream->decode (param, &object, 0, env); + TAO_Object_Field* field = + ACE_static_cast(TAO_Object_Field*, data); + field->_downcast (object, env); + } + break; + default: break; } @@ -1237,7 +1247,6 @@ TAO_Marshal_Sequence::decode (CORBA::TypeCode_ptr tc, break; // handle all aggregate types here - case CORBA::tk_objref: case CORBA::tk_string: case CORBA::tk_wstring: case CORBA::tk_any: @@ -1260,6 +1269,26 @@ TAO_Marshal_Sequence::decode (CORBA::TypeCode_ptr tc, if (retval == CORBA::TypeCode::TRAVERSE_CONTINUE) return CORBA::TypeCode::TRAVERSE_CONTINUE; break; + + case CORBA::tk_objref: + { + size = sizeof (CORBA_Object_ptr); + while (bounds-- && + retval == CORBA::TypeCode::TRAVERSE_CONTINUE) + { + CORBA_Object_ptr ptr; + retval = stream->decode (tc2, &ptr, 0, env); + if (env.exception () != 0) break; + seq->_downcast (value, ptr, env); + if (env.exception () != 0) break; + CORBA::release (ptr); + value += size; + } + if (retval == CORBA::TypeCode::TRAVERSE_CONTINUE) + return retval; + } + break; + default: break; } // end of switch @@ -1269,9 +1298,10 @@ TAO_Marshal_Sequence::decode (CORBA::TypeCode_ptr tc, else return CORBA::TypeCode::TRAVERSE_CONTINUE; } - // error exit - env.exception (new CORBA::MARSHAL (CORBA::COMPLETED_NO)); - dmsg ("marshaling TAO_Marshal_Sequence::decode detected error"); + // If an error was detected but no exception was raised then raise a + // marshal exception. + if (env.exception () == 0) + env.exception (new CORBA::MARSHAL (CORBA::COMPLETED_NO)); return CORBA::TypeCode::TRAVERSE_STOP; } diff --git a/TAO/tao/deep_free.cpp b/TAO/tao/deep_free.cpp index 3e73054bc22..140be7b3dbd 100644 --- a/TAO/tao/deep_free.cpp +++ b/TAO/tao/deep_free.cpp @@ -216,9 +216,16 @@ TAO_Marshal_Struct::deep_free (CORBA::TypeCode_ptr tc, case CORBA::tk_Principal: retval = TAO_Marshal_Principal::deep_free (param, source, dest, env); break; + case CORBA::tk_objref: - retval = TAO_Marshal_ObjRef::deep_free (param, source, dest, env); + { + TAO_Object_Field* field = + ACE_static_cast (TAO_Object_Field*,source); + field->_release (); + retval = CORBA::TypeCode::TRAVERSE_CONTINUE; + } break; + case CORBA::tk_struct: retval = TAO_Marshal_Struct::deep_free (param, source, dest, env); break; diff --git a/TAO/tao/encode.cpp b/TAO/tao/encode.cpp index 53fa33609e9..00b63cca8c7 100644 --- a/TAO/tao/encode.cpp +++ b/TAO/tao/encode.cpp @@ -440,9 +440,19 @@ TAO_Marshal_Struct::encode (CORBA::TypeCode_ptr tc, case CORBA::tk_string: case CORBA::tk_wstring: case CORBA::tk_TypeCode: - case CORBA::tk_objref: retval = stream->encode (param, data, 0, env); break; + + case CORBA::tk_objref: + { + TAO_Object_Field* field = + ACE_static_cast(TAO_Object_Field*, data); + CORBA_Object_ptr ptr = + field->_upcast (); + retval = stream->encode (param, &ptr, 0, env); + } + break; + default: break; } @@ -865,7 +875,6 @@ TAO_Marshal_Sequence::encode (CORBA::TypeCode_ptr tc, case CORBA::tk_any: case CORBA::tk_TypeCode: case CORBA::tk_Principal: - case CORBA::tk_objref: case CORBA::tk_struct: case CORBA::tk_union: case CORBA::tk_string: @@ -885,6 +894,24 @@ TAO_Marshal_Sequence::encode (CORBA::TypeCode_ptr tc, if (retval == CORBA::TypeCode::TRAVERSE_CONTINUE) return CORBA::TypeCode::TRAVERSE_CONTINUE; break; + + case CORBA::tk_objref: + { + size = sizeof (CORBA_Object_ptr); + while (bounds-- && + retval == CORBA::TypeCode::TRAVERSE_CONTINUE) + { + CORBA_Object_ptr ptr = + seq->_upcast (value); + retval = stream->encode (tc2, &ptr, 0, env); + if (env.exception () != 0) break; + value += size; + } + if (retval == CORBA::TypeCode::TRAVERSE_CONTINUE) + return retval; + } + break; + default: break; } // end of switch @@ -902,9 +929,10 @@ TAO_Marshal_Sequence::encode (CORBA::TypeCode_ptr tc, return CORBA::TypeCode::TRAVERSE_CONTINUE; } - // error exit - env.exception (new CORBA::MARSHAL (CORBA::COMPLETED_NO)); - dmsg ("marshaling TAO_Marshal_Sequence::encode detected error"); + // If an error was detected but no exception was raised then raise a + // marshal exception. + if (env.exception () == 0) + env.exception (new CORBA::MARSHAL (CORBA::COMPLETED_NO)); return CORBA::TypeCode::TRAVERSE_STOP; } diff --git a/TAO/tao/orbconf.h b/TAO/tao/orbconf.h index 130e754bc24..8685f827c03 100644 --- a/TAO/tao/orbconf.h +++ b/TAO/tao/orbconf.h @@ -225,10 +225,6 @@ #undef major #endif /* major*/ -// TAO has problems encoding/decoding object references inside -// structs. -#define TAO_HAS_OBJECT_IN_STRUCT_MARSHAL_BUG - // For Win16, near/far pointers reflect same/other segment addressing. // Of course, ACE doesn't support Win16, so why bother? diff --git a/TAO/tao/varout.cpp b/TAO/tao/varout.cpp new file mode 100644 index 00000000000..33340e2ec6b --- /dev/null +++ b/TAO/tao/varout.cpp @@ -0,0 +1,55 @@ +/* -*- C++ -*- */ +// $Id$ + +// ============================================================================ +// +// = LIBRARY +// TAO +// +// = FILENAME +// varout.cpp +// +// = DESCRIPTION +// Templates for _var and _out types +// +// = AUTHOR +// +// Aniruddha Gokhale +// Carlos O'Ryan +// ============================================================================ + +#if !defined (TAO_VAROUT_C) +#define TAO_VAROUT_C + +#include "tao/varout.h" + +#if !defined (__ACE_INLINE__) +#include "tao/varout.i" +#endif /* __ACE_INLINE__ */ + +ACE_RCSID(tao, varout, "$Id$") + +template<class T> void +TAO_Object_Field_T<T>::_downcast (CORBA_Object* base_ptr, + CORBA_Environment &env) +{ + CORBA::release (this->ptr_); + this->ptr_ = 0; + this->ptr_ = T::_narrow (base_ptr, env); + if (env.exception () != 0) return; +} + +template<class T> CORBA_Object* +TAO_Object_Field_T<T>::_upcast (void) +{ + return this->ptr_; +} + +template<class T> void +TAO_Object_Field_T<T>::_release (void) +{ + CORBA::release (this->ptr_); + this->ptr_ = 0; +} + +#endif /* TAO_VAROUT_C */ diff --git a/TAO/tao/varout.h b/TAO/tao/varout.h index 5c9d7e3c7f8..96ae1416ffc 100644 --- a/TAO/tao/varout.h +++ b/TAO/tao/varout.h @@ -1,7 +1,6 @@ /* -*- C++ -*- */ // $Id$ - // ============================================================================ // // = LIBRARY @@ -21,6 +20,88 @@ #if !defined (TAO_VAROUT_H) #define TAO_VAROUT_H +class CORBA_Object; + +template <class T> +class TAO_Object_Field_T : public TAO_Object_Field +{ + // = TITLE + // Parametric class to implement structure fields corresponding to + // object references. + // + // = DESCRIPTION + // When an object reference appears in a structure the marshaling + // and demarhsaling of the structure gets complicated: + // the interpreter can only marshal CORBA_Object_ptr when it + // dermarshal it creates on of those objects. + // The downcasting to the right type must be executed by classes + // with compile-time knowledge of the object type. + // The solution addopted in TAO is to create a special manager + // class for that field, +public: + TAO_Object_Field_T (void); + // default constructor + + TAO_Object_Field_T (T* object); + // constructor from a T*, assumes ownership of <object> i.e. it + // *will* release it. + + TAO_Object_Field_T (const TAO_Object_Field_T<T> &); + // copy constructor + + virtual ~TAO_Object_Field_T (void); + // destructor + + TAO_Object_Field_T<T> &operator= (T* object); + // Assignment from a T*, it assumes ownership of <object>. + + TAO_Object_Field_T<T> &operator= (const TAO_Object_Field_T<T> &); + // Assignment operator, in duplicates the underlying objects. + + T* operator-> (void) const; + // smart pointer (const) + + operator const T* &() const; + // cast operator + + operator T* &(); + // cast operator + + // = operations for parameter passing modes + + T* in (void) const; + // for in type parameter + + T* &inout (void); + // for inout type parameter + + T* &out (void); + // for out parameter + + T* _retn (void); + // for return type + + T* ptr (void) const; + // TAO extension for access to the underlying pointer. + + virtual void _downcast (CORBA_Object* base_ptr, + CORBA_Environment& env); + virtual CORBA_Object* _upcast (void); + virtual void _release (void); + // Implement the TAO_Object_Field methods. + +private: + T* ptr_; +}; + +// **************************************************************** +// The following classes are experimental, some of them do *not* +// compile and produce errors in compilers that check templates before +// instantiation time. In the future we may use them to implement +// several classes generated by IDL compiler, possibly reducing the +// complexity of the compiler. +// **************************************************************** +#if 0 template <class T> class TAO_Fixed_var // = TITLE @@ -622,5 +703,18 @@ public: private: T_ptr &ptr_; }; +#endif /* 0 */ + +#if defined (__ACE_INLINE__) +#include "tao/varout.i" +#endif /* __ACE_INLINE__ */ + +#if defined (ACE_TEMPLATES_REQUIRE_SOURCE) +#include "tao/varout.cpp" +#endif /* ACE_TEMPLATES_REQUIRE_SOURCE */ + +#if defined (ACE_TEMPLATES_REQUIRE_PRAGMA) +#pragma implementation ("varout.cpp") +#endif /* ACE_TEMPLATES_REQUIRE_PRAGMA */ #endif /* TAO_VAROUT_H */ diff --git a/TAO/tao/varout.i b/TAO/tao/varout.i new file mode 100644 index 00000000000..132628d1cf7 --- /dev/null +++ b/TAO/tao/varout.i @@ -0,0 +1,100 @@ +// +// $Id$ +// + +template<class T> ACE_INLINE +TAO_Object_Field_T<T>::TAO_Object_Field_T (void) + : ptr_ (0) +{ +} + +template<class T> ACE_INLINE +TAO_Object_Field_T<T>::TAO_Object_Field_T (T* object) + : ptr_ (object) +{ +} + +template<class T> ACE_INLINE +TAO_Object_Field_T<T>::TAO_Object_Field_T (const TAO_Object_Field_T<T>& rhs) + : ptr_ (T::_duplicate (rhs.ptr_)) +{ +} + +template<class T> ACE_INLINE +TAO_Object_Field_T<T>::~TAO_Object_Field_T (void) +{ + CORBA::release (this->ptr_); +} + +template<class T> ACE_INLINE TAO_Object_Field_T<T> & +TAO_Object_Field_T<T>::operator= (T* object) +{ + CORBA::release (this->ptr_); + this->ptr_ = object; + return *this; +} + +template<class T> ACE_INLINE TAO_Object_Field_T<T> & +TAO_Object_Field_T<T>::operator= (const TAO_Object_Field_T<T> &rhs) +{ + if (this != &rhs) + { + CORBA::release (this->ptr_); + this->ptr_ = T::_duplicate (rhs.ptr_); + } + return *this; +} + +template<class T> ACE_INLINE T* +TAO_Object_Field_T<T>::ptr (void) const +{ + return this->ptr_; +} + +template<class T> ACE_INLINE +TAO_Object_Field_T<T>::operator const T* &() const +{ + return this->ptr_; +} + +template<class T> ACE_INLINE +TAO_Object_Field_T<T>::operator T* &() +{ + return this->ptr_; +} + +template<class T> ACE_INLINE T* +TAO_Object_Field_T<T>::operator-> (void) const +{ + return this->ptr_; +} + +template<class T> ACE_INLINE T* +TAO_Object_Field_T<T>::in (void) const +{ + return this->ptr_; +} + +template<class T> ACE_INLINE T* & +TAO_Object_Field_T<T>::inout (void) +{ + return this->ptr_; +} + +template<class T> ACE_INLINE T* & +TAO_Object_Field_T<T>::out (void) +{ + CORBA::release (this->ptr_); + this->ptr_ = 0; + return this->ptr_; +} + +template<class T> ACE_INLINE T* +TAO_Object_Field_T<T>::_retn (void) +{ + // yield ownership of managed obj reference + T* val = this->ptr_; + this->ptr_ = 0; + return val; +} + |