diff options
author | dai_y <dai_y@ae88bc3d-4319-0410-8dbf-d08b4c9d3795> | 2009-12-04 23:21:00 +0000 |
---|---|---|
committer | dai_y <dai_y@ae88bc3d-4319-0410-8dbf-d08b4c9d3795> | 2009-12-04 23:21:00 +0000 |
commit | eb2510ae52e2647a294c1ab2e642bb9987bfb502 (patch) | |
tree | 0e50dd3dcea768952d89e75de7b3ead46ab825c6 /TAO | |
parent | e791ad22ad1446fa08de128b665bdb5a53cca96e (diff) | |
download | ATCD-eb2510ae52e2647a294c1ab2e642bb9987bfb502.tar.gz |
Fri Dec 4 23:18:26 UTC 2009 Yan Dai <dai_y@ociweb.com>
Diffstat (limited to 'TAO')
29 files changed, 1565 insertions, 187 deletions
diff --git a/TAO/ChangeLog b/TAO/ChangeLog index 20644fd90b4..51b5cbf9a8d 100644 --- a/TAO/ChangeLog +++ b/TAO/ChangeLog @@ -1,3 +1,99 @@ +Fri Dec 4 23:18:26 UTC 2009 Yan Dai <dai_y@ociweb.com> + + Merged in valuetype repository id and value indirection support + on both input and output streams from OCI (RT #13502). + + * MPC/config/valuetype_out_indirection.mpb: + + Added mpc feature to optionally turn on the indirection + support on valuetype outgoing message. It defaults to + be enabled. To be compatible with previous version TAO, + run mwc.pl with + "-features valuetype_out_indirection=0" to disable it. + + * TAO_IDL/be/be_visitor_valuebox/valuebox_cs.cpp: + * TAO_IDL/be/be_visitor_valuetype/valuetype_cs.cpp: + + Modified the valuetype unmarshall method to support + value indirection. + + * tao/Intrusive_Ref_Count_Object_T.h: + * tao/Intrusive_Ref_Count_Object_T.inl: + * tao/Intrusive_Ref_Count_Object_T.cpp: + + Added wrapper for non reference counted data type to provide reference + counting feature so it can use the TAO_Intrusive_Ref_Count_Handle + smart-pointer. + + * tao/CDR.h: + * tao/CDR.inl: + * tao/CDR.cpp: + + - Used smart point hash map for indirection maps (repository id, value + and codebase_url). The maps map the already read/written values. + - Added methods to access/update indirection maps. + - The maps are only created when valuetype data is marshalled or + demarshalled. + - Added offset(pos) method to calculate the offset between provided + position and current wr_ptr. + + * tao/Valuetype/ValueBase.h: + * tao/Valuetype/ValueBase.inl: + * tao/Valuetype/ValueBase.cpp: + + - Added repository id and value indirection support on both input + and output stream. + - The codebase_url indirection on input stream was also added but + not tested. TAO does not support codebase currently and the codebase + url indirection is added for future support. TAO can read codebase_url + from other ORB implementation but the codebase_url is not used. + - Used TAO_HAS_VALUETYPE_OUT_INDIRECTION define to optionally turn on + and off the outgoing message indirection. This is to support backward + compatibility. + + * tao/operation_details.cpp: + * tao/PortableServer/Upcall_Wrapper.cpp: + + Cleaned the indirection maps after marshalling/unmarshalling complete. + + * tao/AnyTypeCode/Any_Impl_T.cpp: + * tao/AnyTypeCode/Any_Unknown_IDL_Type.cpp: + + Made Any_Unknown_IDL_Type cdr share the maps from input cdr of the + request so previous indirection can be used during unmarshalling any. + + * tao/DynamicInterface/AMH_DSI_Response_Handler.cpp: + + Updated unmarshal method based on tao_idl changes. + + * tao/Valuetype.mpc: + * tao/PortableServer.mpc: + * tao/tao.mpc: + + Added dependency on valuetype_out_indirection feature. + + * tests/OBV/indirection/Factory.h: + * tests/OBV/indirection/Factory.cpp: + * tests/OBV/indirection/Messenger.idl: + * tests/OBV/indirection/MessengerClient.cpp: + * tests/OBV/indirection/MessengerServer.cpp: + * tests/OBV/indirection/Messenger_i.h: + * tests/OBV/indirection/Messenger_i.cpp: + * tests/OBV/indirection/README: + * tests/OBV/indirection/indirection.mpc: + * tests/OBV/indirection/run_test.pl: + + - Added automation test for indirection support in TAO. The test + based on the JacORB demo/value test. This can also be used for + interoperability test between TAO and JacORB. + - The indirection test with truncatable value was added. The test + passed between the TAO server and client, but the interoperablity + test with JacORB failed. It also failed on previous TAO version. + + * NEWS: + + Added entry for indirection support. + Fri Dec 4 21:00:38 UTC 2009 Yan Dai <dai_y@ociweb.com> * orbsvcs/orbsvcs/LoadBalancing/LB_LoadManager.h: @@ -5,17 +101,17 @@ Fri Dec 4 21:00:38 UTC 2009 Yan Dai <dai_y@ociweb.com> * orbsvcs/LoadBalancer/LoadManager.cpp: Renamed init() to initialize() to avoid Warning W8022 on borland build. - + Fri Dec 4 17:25:32 UTC 2009 Yan Dai <dai_y@ociweb.com> * NEWS: - Added entry for member validation feature in LoadBalancer. - + Added entry for member validation feature in LoadBalancer. + * orbsvcs/orbsvcs/LoadBalancing/LB_LoadManager.h: Disable Warning 8022 for borland build. - + * orbsvcs/tests/LoadBalancing/GenericFactory/DeadMemberDetection_App_Ctrl/run_test.pl: * orbsvcs/tests/LoadBalancing/GenericFactory/DeadMemberDetection_Inf_Ctrl/DeadMemberDetection_Inf_Ctrl.mpc: * orbsvcs/tests/LoadBalancing/GenericFactory/DeadMemberDetection_Inf_Ctrl/run_test.pl: @@ -425,7 +521,7 @@ Mon Nov 30 10:01:49 UTC 2009 Denis Budko <denis.budko@remedy.nl> Sun Nov 29 13:06:02 CST 2009 Johnny Willemsen <jwillemsen@remedy.nl> - * TAO version 1.7.5 released. + * TAO version 1.7.5 released. Fri Nov 27 10:12:19 UTC 2009 Denis Budko <denis.budko@remedy.nl> diff --git a/TAO/MPC/config/valuetype_out_indirection.mpb b/TAO/MPC/config/valuetype_out_indirection.mpb new file mode 100644 index 00000000000..5f4e54b293d --- /dev/null +++ b/TAO/MPC/config/valuetype_out_indirection.mpb @@ -0,0 +1,6 @@ +// -*- MPC -*- +// $Id$ + +feature(valuetype_out_indirection) { + macros += TAO_HAS_VALUETYPE_OUT_INDIRECTION +} @@ -2,7 +2,10 @@ USER VISIBLE CHANGES BETWEEN TAO-1.7.5 and TAO-1.7.6 ==================================================== . Added member validation feature to LoadBalancer. - + +. Merged in changes from OCI's distribution (RT#13502) that support + valuetype repository id and value on both input and output streams. + USER VISIBLE CHANGES BETWEEN TAO-1.7.4 and TAO-1.7.5 ==================================================== diff --git a/TAO/TAO_IDL/be/be_visitor_valuebox/valuebox_cs.cpp b/TAO/TAO_IDL/be/be_visitor_valuebox/valuebox_cs.cpp index 3e10e3f903a..fe063350d1d 100644 --- a/TAO/TAO_IDL/be/be_visitor_valuebox/valuebox_cs.cpp +++ b/TAO/TAO_IDL/be/be_visitor_valuebox/valuebox_cs.cpp @@ -133,12 +133,12 @@ be_visitor_valuebox_cs::visit_valuebox (be_valuebox *node) // _tao_match_formal_type method. Generated because ValueBase interface // requires it. Since value boxes do not support inheritence, this can - // simply return true. + // simply return 1. *os << "::CORBA::Boolean " << be_nl << node->name () << "::_tao_match_formal_type (ptrdiff_t ) const" << be_nl << "{" << be_idt_nl - << "return true;" << be_uidt_nl + << "return 1;" << be_uidt_nl << "}" << be_nl << be_nl; @@ -242,22 +242,31 @@ be_visitor_valuebox_cs::visit_valuebox (be_valuebox *node) << node->local_name () << " *&vb_object" << be_uidt_nl << ")" << be_uidt_nl << "{" << be_idt_nl - << "::CORBA::Boolean is_null_object;" << be_nl + << "::CORBA::Boolean is_null_object = 0;" << be_nl + << "::CORBA::Boolean is_indirected = 0;" << be_nl + << "TAO_InputCDR indrected_strm ((size_t) 0);" << be_nl << "if ( ::CORBA::ValueBase::_tao_validate_box_type (" << be_idt << be_idt << be_idt_nl - << "strm," << be_nl + << "strm, indrected_strm, " << be_nl << node->local_name () << "::_tao_obv_static_repository_id ()," << be_nl - << "is_null_object" + << "is_null_object, is_indirected" << be_uidt_nl << ") == false)" << be_uidt_nl << "{" << be_idt_nl - << "return false;" << be_uidt_nl + << "return 0;" << be_uidt_nl << "}" << be_uidt_nl << be_nl << "vb_object = 0;" << be_nl << "if (is_null_object)" << be_idt_nl << "{" << be_idt_nl - << "return true;" << be_uidt_nl + << "return 1;" << be_uidt_nl + << "}" << be_uidt_nl << be_nl + << "if (is_indirected)" << be_idt_nl + << "{" << be_idt_nl + << "return " << node->name () << "::_tao_unmarshal (" << be_idt + << be_idt << be_idt_nl + << " indrected_strm, vb_object);" + << be_uidt << be_uidt << be_uidt << be_uidt_nl << "}" << be_uidt_nl << be_nl << "ACE_NEW_RETURN (" << be_idt_nl << "vb_object," << be_nl @@ -304,7 +313,7 @@ be_visitor_valuebox_cs::visit_valuebox (be_valuebox *node) << node->name () << "::_tao_unmarshal_v (TAO_InputCDR &)" << be_nl << "{" << be_idt_nl - << "return true;" << be_uidt_nl + << "return 1;" << be_uidt_nl << "}" << be_nl << be_nl; // Emit the type specific elements. The visit_* methods in this diff --git a/TAO/TAO_IDL/be/be_visitor_valuetype/valuetype_cs.cpp b/TAO/TAO_IDL/be/be_visitor_valuetype/valuetype_cs.cpp index 45239e5dffa..41675e3e5c7 100644 --- a/TAO/TAO_IDL/be/be_visitor_valuetype/valuetype_cs.cpp +++ b/TAO/TAO_IDL/be/be_visitor_valuetype/valuetype_cs.cpp @@ -258,7 +258,7 @@ be_visitor_valuetype_cs::visit_valuetype (be_valuetype *node) << node->name () << "::_tao_marshal_v (TAO_OutputCDR &) const" << be_nl << "{" << be_idt_nl - << "return true;" << be_uidt_nl + << "return 1;" << be_uidt_nl << "}" << be_nl << be_nl; // The virtual _tao_unmarshal_v method. @@ -266,7 +266,7 @@ be_visitor_valuetype_cs::visit_valuetype (be_valuetype *node) << node->name () << "::_tao_unmarshal_v (TAO_InputCDR &)" << be_nl << "{" << be_idt_nl - << "return true;" << be_uidt_nl + << "return 1;" << be_uidt_nl << "}" << be_nl << be_nl; // The virtual _tao_match_formal_type method. @@ -275,7 +275,7 @@ be_visitor_valuetype_cs::visit_valuetype (be_valuetype *node) << "::_tao_match_formal_type (ptrdiff_t ) const" << be_nl << "{" << be_idt_nl - << "return false;"<< be_uidt_nl + << "return 0;"<< be_uidt_nl << "}" << be_nl << be_nl; @@ -285,14 +285,14 @@ be_visitor_valuetype_cs::visit_valuetype (be_valuetype *node) << node->name () << "::_tao_marshal__" << node->flat_name () << " (TAO_OutputCDR &, TAO_ChunkInfo&) const" << be_nl << "{" << be_idt_nl - << "return true;" << be_uidt_nl + << "return 1;" << be_uidt_nl << "}" << be_nl << be_nl; *os << "::CORBA::Boolean" << be_nl << node->name () << "::_tao_unmarshal__" << node->flat_name () << " (TAO_InputCDR &, TAO_ChunkInfo&)" << be_nl << "{" << be_idt_nl - << "return true;" << be_uidt_nl + << "return 1;" << be_uidt_nl << "}" << be_nl << be_nl; } } @@ -323,25 +323,32 @@ be_visitor_valuetype_cs::visit_valuetype (be_valuetype *node) << ")" << be_uidt_nl << "{" << be_idt_nl << "::CORBA::ValueBase *base = 0;" << be_nl + << "::CORBA::Boolean is_indirected = 0;" << be_nl + << "::CORBA::Boolean is_null_object = 0;" << be_nl << "::CORBA::Boolean const retval =" << be_idt_nl << "::CORBA::ValueBase::_tao_unmarshal_pre (" << be_idt << be_idt_nl << "strm," << be_nl << "base," << be_nl - << node->local_name () << "::_tao_obv_static_repository_id ()" - << be_uidt_nl - << ");" << be_uidt << be_uidt_nl + << node->local_name () << "::_tao_obv_static_repository_id ()," << be_nl + << "is_null_object," << be_nl + << "is_indirected" << be_uidt_nl << be_nl + << ");" << be_uidt << be_uidt_nl << be_nl << "::CORBA::ValueBase_var owner (base);" << be_nl << be_nl << "if (!retval)" << be_idt_nl - << "return false;" << be_uidt_nl << be_nl - << "if (base != 0 && ! base->_tao_unmarshal_v (strm))" << be_idt_nl - << "return false;" << be_uidt_nl << be_nl + << "return 0;" << be_uidt_nl << be_nl + << "if (is_null_object)" << be_idt_nl + << "return 1;" << be_uidt_nl << be_nl + << "if (!is_indirected && base != 0 && ! base->_tao_unmarshal_v (strm))" << be_idt_nl + << "return 0;" << be_uidt_nl << be_nl << "// Now base must be null or point to the unmarshaled object." << be_nl << "// Align the pointer to the right subobject." << be_nl - << "new_object = " << node->local_name () << "::_downcast (base);" - << be_nl << "owner._retn ();" << be_nl - << "return true;" << be_uidt_nl + << "new_object = " << node->local_name () << "::_downcast (base);" << be_nl + << "if (is_indirected)" << be_idt_nl + << "new_object->_add_ref ();" << be_uidt_nl << be_nl + << "owner._retn ();" << be_nl + << "return 1;" << be_uidt_nl << "}"; // If we inherit from CORBA::Object and/or CORBA::AbstractBase diff --git a/TAO/tao/AnyTypeCode/Any_Impl_T.cpp b/TAO/tao/AnyTypeCode/Any_Impl_T.cpp index b6ac3bd2724..fe770493a5a 100644 --- a/TAO/tao/AnyTypeCode/Any_Impl_T.cpp +++ b/TAO/tao/AnyTypeCode/Any_Impl_T.cpp @@ -9,6 +9,7 @@ #include "tao/CDR.h" #include "tao/AnyTypeCode/TypeCode.h" #include "tao/SystemException.h" +#include "tao/debug.h" #include "ace/Auto_Ptr.h" #include "ace/OS_Memory.h" diff --git a/TAO/tao/AnyTypeCode/Any_Unknown_IDL_Type.cpp b/TAO/tao/AnyTypeCode/Any_Unknown_IDL_Type.cpp index ea17e3cba50..cf5d51f9356 100644 --- a/TAO/tao/AnyTypeCode/Any_Unknown_IDL_Type.cpp +++ b/TAO/tao/AnyTypeCode/Any_Unknown_IDL_Type.cpp @@ -7,6 +7,7 @@ #include "tao/ORB_Core.h" #include "tao/SystemException.h" #include "tao/CDR.h" +#include "tao/debug.h" #include "ace/Dynamic_Service.h" #include "ace/OS_NS_string.h" @@ -149,6 +150,10 @@ TAO::Unknown_IDL_Type::_tao_decode (TAO_InputCDR & cdr) this->cdr_.char_translator (cdr.char_translator ()); this->cdr_.wchar_translator (cdr.wchar_translator ()); + this->cdr_.set_repo_id_map (cdr.get_repo_id_map ()); + this->cdr_.set_codebase_url_map (cdr.get_codebase_url_map ()); + this->cdr_.set_value_map (cdr.get_value_map ()); + // Take over the GIOP version, the input cdr can have a different // version then our current GIOP version. ACE_CDR::Octet major_version; @@ -213,6 +218,7 @@ TAO::Unknown_IDL_Type::to_value (CORBA::ValueBase* & val) const TAO_Valuetype_Adapter * const adapter = orb_core->valuetype_adapter (); + return adapter->stream_to_value (for_reading, val); } catch (::CORBA::Exception const &) @@ -253,7 +259,9 @@ TAO::Unknown_IDL_Type::to_abstract_base (CORBA::AbstractBase_ptr & obj) const TAO_Valuetype_Adapter * const adapter = orb_core->valuetype_adapter (); - return adapter->stream_to_abstract_base (for_reading, obj); + CORBA::Boolean ret = adapter->stream_to_abstract_base (for_reading, obj); + + return ret; } catch (::CORBA::Exception const &) { diff --git a/TAO/tao/CDR.cpp b/TAO/tao/CDR.cpp index ab398fabd52..9829e3121cb 100644 --- a/TAO/tao/CDR.cpp +++ b/TAO/tao/CDR.cpp @@ -257,6 +257,40 @@ TAO_OutputCDR::fragment_stream (ACE_CDR::ULong pending_alignment, } + +int +TAO_OutputCDR::offset (char* pos) +{ + int offset = 0; + const ACE_Message_Block * cur = this->current (); + + char* last = cur->wr_ptr(); + + while (cur != 0) + { + if (pos >= cur->base () && pos <= last) + { + offset += (last - pos); + break; + } + else + { + offset += (last - cur->base ()); + } + + last = cur->end (); + cur = cur->prev(); + } + + if (cur == 0) + { + throw ::CORBA::BAD_PARAM (); + } + + return offset; +} + + // **************************************************************** TAO_InputCDR::TAO_InputCDR (const TAO_OutputCDR& rhs, diff --git a/TAO/tao/CDR.h b/TAO/tao/CDR.h index 8d3125cf334..5b97e998e02 100644 --- a/TAO/tao/CDR.h +++ b/TAO/tao/CDR.h @@ -54,8 +54,13 @@ #include "tao/Basic_Types.h" #include "tao/GIOP_Message_Version.h" #include "tao/Message_Semantics.h" +#include "tao/Intrusive_Ref_Count_Handle_T.h" +#include "tao/Intrusive_Ref_Count_Object_T.h" #include "ace/CDR_Stream.h" +#include "ace/SString.h" +#include "ace/Hash_Map_Manager_T.h" +#include "ace/Null_Mutex.h" TAO_BEGIN_VERSIONED_NAMESPACE_DECL @@ -86,6 +91,17 @@ class TAO_Export TAO_OutputCDR : public ACE_OutputCDR public: /// For reading from a output CDR stream. friend class TAO_InputCDR; + typedef ACE_Hash_Map_Manager<ACE_CString, char*, ACE_Null_Mutex> Repo_Id_Map; + typedef Repo_Id_Map Codebase_URL_Map; + typedef ACE_Hash_Map_Manager<void*, char*, ACE_Null_Mutex> Value_Map; + + typedef TAO_Intrusive_Ref_Count_Object<Repo_Id_Map, ACE_Null_Mutex> RC_Repo_Id_Map; + typedef TAO_Intrusive_Ref_Count_Object<Codebase_URL_Map, ACE_Null_Mutex> RC_Codebase_URL_Map; + typedef TAO_Intrusive_Ref_Count_Object<Value_Map, ACE_Null_Mutex> RC_Value_Map; + + typedef TAO_Intrusive_Ref_Count_Handle<RC_Repo_Id_Map> Repo_Id_Map_Handle; + typedef TAO_Intrusive_Ref_Count_Handle<RC_Codebase_URL_Map> Codebase_URL_Map_Handle; + typedef TAO_Intrusive_Ref_Count_Handle<RC_Value_Map> Value_Map_Handle; // The default values for the allocators and memcpy_tradeoff // in these constructors are not 0, but are generated by the @@ -199,6 +215,31 @@ public: ACE_Time_Value * timeout (void) const; //@} + /// These methods are used by valuetype indirection support. + /// Accessor to the indirect maps. + Repo_Id_Map_Handle& get_repo_id_map (); +#ifdef TAO_HAS_VALUETYPE_CODEBASE + Codebase_URL_Map_Handle& get_codebase_url_map (); +#endif + Value_Map_Handle& get_value_map (); + + /// Updater of the maps. + /// These updaters are used to make indirect maps in original stream + /// take effect even during marshalling/demarshalling a redirected stream. + void set_repo_id_map (Repo_Id_Map_Handle& map); +#ifdef TAO_HAS_VALUETYPE_CODEBASE + Codebase_URL_Map_Handle& get_codebase_url_map (); + void set_codebase_url_map (Codebase_URL_Map_Handle& map); +#endif + void set_value_map (Value_Map_Handle& map); + + /// If indirect map is not nil and not empty, unbind all entries. + /// Called after marshalling. + void reset_vt_indirect_maps (); + + /// Calculate the offset between pos and current wr_ptr. + int offset (char* pos); + private: // disallow copying... @@ -236,6 +277,13 @@ private: /// Request/reply send timeout. ACE_Time_Value * timeout_; //@} + + /// These maps are used by valuetype indirection support. + Repo_Id_Map_Handle repo_id_map_; +#ifdef TAO_HAS_VALUETYPE_CODEBASE + Codebase_URL_Map_Handle codebase_map_; +#endif + Value_Map_Handle value_map_; }; /** @@ -261,6 +309,18 @@ private: class TAO_Export TAO_InputCDR : public ACE_InputCDR { public: + typedef ACE_Hash_Map_Manager<void*, ACE_CString, ACE_Null_Mutex> Repo_Id_Map; + typedef Repo_Id_Map Codebase_URL_Map; + typedef ACE_Hash_Map_Manager<void*, void*, ACE_Null_Mutex> Value_Map; + + typedef TAO_Intrusive_Ref_Count_Object<Repo_Id_Map, ACE_Null_Mutex> RC_Repo_Id_Map; + typedef TAO_Intrusive_Ref_Count_Object<Codebase_URL_Map, ACE_Null_Mutex> RC_Codebase_URL_Map; + typedef TAO_Intrusive_Ref_Count_Object<Value_Map, ACE_Null_Mutex> RC_Value_Map; + + typedef TAO_Intrusive_Ref_Count_Handle<RC_Repo_Id_Map> Repo_Id_Map_Handle; + typedef TAO_Intrusive_Ref_Count_Handle<RC_Codebase_URL_Map> Codebase_URL_Map_Handle; + typedef TAO_Intrusive_Ref_Count_Handle<RC_Value_Map> Value_Map_Handle; + /** * Create an input stream from an arbitrary buffer, care must be * exercised wrt alignment, because this contructor will *not* work @@ -366,9 +426,31 @@ public: static void throw_stub_exception (int error_num); static void throw_skel_exception (int error_num); + /// These methods are used by valuetype indirection support. + /// Accessor to the indirect maps. + Repo_Id_Map_Handle& get_repo_id_map (); + Codebase_URL_Map_Handle& get_codebase_url_map (); + Value_Map_Handle& get_value_map (); + + /// Updater of the maps. + /// These updaters are used to make indirect maps in original stream + /// take effect even during marshalling/demarshalling a redirected stream. + void set_repo_id_map (Repo_Id_Map_Handle& map); + void set_codebase_url_map (Codebase_URL_Map_Handle& map); + void set_value_map (Value_Map_Handle& map); + + /// If indirect map is not nil and not empty, unbind all entries. + /// Called after demarshalling. + void reset_vt_indirect_maps (); + private: /// The ORB_Core, required to extract object references. TAO_ORB_Core* orb_core_; + + /// These maps are used by valuetype indirection support. + Repo_Id_Map_Handle repo_id_map_; + Codebase_URL_Map_Handle codebase_map_; + Value_Map_Handle value_map_; }; TAO_END_VERSIONED_NAMESPACE_DECL diff --git a/TAO/tao/CDR.inl b/TAO/tao/CDR.inl index bbcbbc5a40f..70b60d2b2ee 100644 --- a/TAO/tao/CDR.inl +++ b/TAO/tao/CDR.inl @@ -65,6 +65,66 @@ TAO_OutputCDR::get_version (TAO_GIOP_Message_Version& giop_version) giop_version.major = this->major_version_; giop_version.minor = this->minor_version_; } + +ACE_INLINE TAO_OutputCDR::Repo_Id_Map_Handle& +TAO_OutputCDR::get_repo_id_map () +{ + return this->repo_id_map_; +} + +#ifdef TAO_HAS_VALUETYPE_CODEBASE +ACE_INLINE TAO_OutputCDR::Codebase_URL_Map_Handle& +TAO_OutputCDR::get_codebase_url_map () +{ + return this->codebase_map_; +} +#endif + +ACE_INLINE TAO_OutputCDR::Value_Map_Handle& +TAO_OutputCDR::get_value_map () +{ + return this->value_map_; +} + +ACE_INLINE void +TAO_OutputCDR::set_repo_id_map (TAO_OutputCDR::Repo_Id_Map_Handle& map) +{ + this->repo_id_map_ = map; +} + +#ifdef TAO_HAS_VALUETYPE_CODEBASE +ACE_INLINE void +TAO_OutputCDR::set_codebase_url_map (TAO_OutputCDR::Codebase_URL_Map_Handle& map) +{ + this->codebase_map_ = map; +} +#endif + +ACE_INLINE void +TAO_OutputCDR::set_value_map (TAO_OutputCDR::Value_Map_Handle& map) +{ + this->value_map_ = map; +} + +ACE_INLINE void +TAO_OutputCDR::reset_vt_indirect_maps () +{ + if (! this->repo_id_map_.is_nil () && this->repo_id_map_->get()->current_size () != 0) + { + this->repo_id_map_->get()->unbind_all (); + } +#ifdef TAO_HAS_VALUETYPE_CODEBASE + if (! this->codebase_map_.is_nil () && this->codebase_map_->get()->current_size () != 0) + { + this->codebase_map_->get()->unbind_all (); + } +#endif + if (! this->value_map_.is_nil () && this->value_map_->get()->current_size () != 0) + { + this->value_map_->get()->unbind_all (); + } +} + // ------------------------------------------------------------------- ACE_INLINE @@ -190,6 +250,9 @@ TAO_InputCDR::TAO_InputCDR (const TAO_InputCDR& rhs) : ACE_InputCDR (rhs), orb_core_ (rhs.orb_core_) { + this->repo_id_map_ = rhs.repo_id_map_; + this->codebase_map_ = rhs.codebase_map_; + this->value_map_ = rhs.value_map_; } ACE_INLINE @@ -200,6 +263,7 @@ TAO_InputCDR::TAO_InputCDR (ACE_InputCDR::Transfer_Contents rhs, { } + ACE_INLINE TAO_InputCDR::~TAO_InputCDR (void) { @@ -211,6 +275,61 @@ TAO_InputCDR::orb_core (void) const return this->orb_core_; } + +ACE_INLINE TAO_InputCDR::Repo_Id_Map_Handle& +TAO_InputCDR::get_repo_id_map () +{ + return this->repo_id_map_; +} + +ACE_INLINE TAO_InputCDR::Codebase_URL_Map_Handle& +TAO_InputCDR::get_codebase_url_map () +{ + return this->codebase_map_; +} + +ACE_INLINE TAO_InputCDR::Value_Map_Handle& +TAO_InputCDR::get_value_map () +{ + return this->value_map_; +} + +ACE_INLINE void +TAO_InputCDR::set_repo_id_map (TAO_InputCDR::Repo_Id_Map_Handle& map) +{ + this->repo_id_map_ = map; +} + +ACE_INLINE void +TAO_InputCDR::set_codebase_url_map (TAO_InputCDR::Codebase_URL_Map_Handle& map) +{ + this->codebase_map_ = map; +} + +ACE_INLINE void +TAO_InputCDR::set_value_map (TAO_InputCDR::Value_Map_Handle& map) +{ + this->value_map_ = map; +} + +ACE_INLINE void +TAO_InputCDR::reset_vt_indirect_maps () +{ + if (! this->repo_id_map_.is_nil () && this->repo_id_map_->get()->current_size () != 0) + { + this->repo_id_map_->get()->unbind_all (); + } + if (! this->codebase_map_.is_nil () && this->codebase_map_->get()->current_size () != 0) + { + this->codebase_map_->get()->unbind_all (); + } + if (! this->value_map_.is_nil () && this->value_map_->get()->current_size () != 0) + { + this->value_map_->get()->unbind_all (); + } +} + + // **************************************************************** ACE_INLINE CORBA::Boolean operator<< (TAO_OutputCDR &os, @@ -430,4 +549,5 @@ ACE_INLINE CORBA::Boolean operator>> (TAO_InputCDR &is, return marshal_flag; } + TAO_END_VERSIONED_NAMESPACE_DECL diff --git a/TAO/tao/DynamicInterface/AMH_DSI_Response_Handler.cpp b/TAO/tao/DynamicInterface/AMH_DSI_Response_Handler.cpp index 5cc472a9cf9..1b0282bee0a 100644 --- a/TAO/tao/DynamicInterface/AMH_DSI_Response_Handler.cpp +++ b/TAO/tao/DynamicInterface/AMH_DSI_Response_Handler.cpp @@ -255,41 +255,38 @@ TAO_AMH_DSI_Exception_Holder::_tao_unmarshal ( TAO_InputCDR &strm, TAO_AMH_DSI_Exception_Holder *&new_object) { - CORBA::ValueBase *base = 0; - CORBA::ValueFactory_var factory; - CORBA::Boolean retval = - CORBA::ValueBase::_tao_unmarshal_pre ( + ::CORBA::ValueBase *base = 0; + ::CORBA::Boolean is_indirected = 0; + ::CORBA::Boolean is_null_object = 0; + ::CORBA::Boolean const retval = + ::CORBA::ValueBase::_tao_unmarshal_pre ( strm, base, - TAO_AMH_DSI_Exception_Holder::_tao_obv_static_repository_id () + TAO_AMH_DSI_Exception_Holder::_tao_obv_static_repository_id (), + is_null_object, + is_indirected ); - if (!retval) - { - return false; - } + ::CORBA::ValueBase_var owner (base); - if (factory.in () != 0) - { - base = factory->create_for_unmarshal (); + if (!retval) + return 0; - if (base == 0) - { - return false; // %! except.? - } + if (is_null_object) + return 1; - retval = base->_tao_unmarshal_v (strm); + if (!is_indirected && base != 0 && ! base->_tao_unmarshal_v (strm)) + return 0; - if (retval == 0) - { - return false; - } - } // Now base must be null or point to the unmarshaled object. // Align the pointer to the right subobject. new_object = TAO_AMH_DSI_Exception_Holder::_downcast (base); - return retval; + if (is_indirected) + new_object->_add_ref (); + + owner._retn (); + return 1; } void diff --git a/TAO/tao/PortableServer.mpc b/TAO/tao/PortableServer.mpc index 6009de3664d..27e811f2f46 100644 --- a/TAO/tao/PortableServer.mpc +++ b/TAO/tao/PortableServer.mpc @@ -61,7 +61,7 @@ project(*idl) : tao_versioning_idl_defaults { } } -project(PortableServer) : taolib, tao_output, install, anytypecode, taoidldefaults { +project(PortableServer) : taolib, tao_output, install, anytypecode, taoidldefaults, valuetype_out_indirection { after += *idl sharedname = TAO_PortableServer dynamicflags = TAO_PORTABLESERVER_BUILD_DLL diff --git a/TAO/tao/PortableServer/Upcall_Wrapper.cpp b/TAO/tao/PortableServer/Upcall_Wrapper.cpp index fe652ebf4c2..03f43f30400 100644 --- a/TAO/tao/PortableServer/Upcall_Wrapper.cpp +++ b/TAO/tao/PortableServer/Upcall_Wrapper.cpp @@ -18,6 +18,7 @@ #include "tao/Argument.h" #include "tao/operation_details.h" #include "ace/Log_Msg.h" +#include "tao/debug.h" ACE_RCSID (PortableServer, Upcall_Wrapper, @@ -238,6 +239,8 @@ TAO::Upcall_Wrapper::pre_upcall (TAO_InputCDR & cdr, TAO_InputCDR::throw_skel_exception (errno); } } + + cdr.reset_vt_indirect_maps (); } void @@ -259,6 +262,10 @@ TAO::Upcall_Wrapper::post_upcall (TAO_ServerRequest& server_request, // Reply body marshaling completed. No other fragments to send. cdr.more_fragments (false); + +#ifdef TAO_HAS_VALUETYPE_OUT_INDIRECTION + cdr.reset_vt_indirect_maps (); +#endif } TAO_END_VERSIONED_NAMESPACE_DECL diff --git a/TAO/tao/Valuetype.mpc b/TAO/tao/Valuetype.mpc index e64e6ddd81d..2f973f8dc4a 100644 --- a/TAO/tao/Valuetype.mpc +++ b/TAO/tao/Valuetype.mpc @@ -11,7 +11,7 @@ project(*idl) : tao_versioning_idl_defaults, gen_ostream { } } -project(Valuetype) : taolib, tao_output, install, anytypecode, avoids_corba_e_micro, taoidldefaults, gen_ostream { +project(Valuetype) : taolib, tao_output, install, anytypecode, avoids_corba_e_micro, taoidldefaults, gen_ostream, valuetype_out_indirection { after += *idl sharedname = TAO_Valuetype dynamicflags = TAO_VALUETYPE_BUILD_DLL diff --git a/TAO/tao/Valuetype/ValueBase.cpp b/TAO/tao/Valuetype/ValueBase.cpp index 045d3c4fbbf..e9085095246 100644 --- a/TAO/tao/Valuetype/ValueBase.cpp +++ b/TAO/tao/Valuetype/ValueBase.cpp @@ -26,6 +26,16 @@ ACE_RCSID (Valuetype, TAO_BEGIN_VERSIONED_NAMESPACE_DECL +#define DEFAULT_INDIRECTION_MAP_SIZE 10 + +#define VERIFY_MAP(CDR, MAPNAME, MAPCLASSNAME) \ + if (strm.get_##MAPNAME ().is_nil ()) \ + { \ + CDR::MAPCLASSNAME##_Handle handle ( \ + new CDR::RC_##MAPCLASSNAME (new CDR::MAPCLASSNAME (DEFAULT_INDIRECTION_MAP_SIZE)));\ + strm.set_##MAPNAME (handle); \ + } + // Static operations in namespace CORBA. void @@ -147,8 +157,8 @@ CORBA::ValueBase::_tao_marshal (TAO_OutputCDR &strm, { return _tao_write_value (strm, this_, formal_type_id); } - - return true; + else + return 1; } @@ -169,16 +179,29 @@ CORBA::ValueBase::_tao_unmarshal (TAO_InputCDR &strm, // new_object->_tao_unmarshal_v () // new_object->_tao_unmarshal_post () + CORBA::Boolean is_null_object = 0; + CORBA::Boolean is_indirected = 0; CORBA::Boolean const retval = - CORBA::ValueBase::_tao_unmarshal_pre (strm, new_object, 0); + CORBA::ValueBase::_tao_unmarshal_pre (strm, + new_object, + 0, + is_null_object, + is_indirected); if (!retval) { - return false; + return 0; } + if (is_null_object || is_indirected) + { + return 1; + } + + // In this case, the codebase url and repo id is read, + // so continue unmarshal values. if (new_object && ! new_object->_tao_unmarshal_v (strm)) - return false; + return 0; return retval; } @@ -187,8 +210,12 @@ CORBA::ValueBase::_tao_unmarshal (TAO_InputCDR &strm, CORBA::Boolean CORBA::ValueBase::_tao_unmarshal_pre (TAO_InputCDR &strm, CORBA::ValueBase *&valuetype, - const char * const repo_id) + const char * const repo_id, + CORBA::Boolean& is_null_object, + CORBA::Boolean& is_indirected) { + void* pos = strm.rd_ptr(); + // Value factories are reference counted. When we get a new value // factory from the ORB, its reference count is increased. CORBA::ValueFactory_var factory; @@ -217,42 +244,56 @@ CORBA::ValueBase::_tao_unmarshal_pre (TAO_InputCDR &strm, CORBA::Long valuetag; Repository_Id_List ids; + ACE_CString codebase_url; + + is_indirected = 0; + is_null_object = 0; if (! strm.read_long (valuetag)) { - return false; + return 0; } if (TAO_OBV_GIOP_Flags::is_indirection_tag (valuetag)) { - //@todo: read indirection value. - if (TAO_debug_level > 0) - { - ACE_ERROR ((LM_ERROR, - ACE_TEXT ("TAO does not currently ") - ACE_TEXT ("support valuetype indirecton\n"))); - } + is_indirected = 1; - return false; + // value is redirected + return _tao_unmarshal_value_indirection (strm, valuetype); } - else if (TAO_OBV_GIOP_Flags::is_null_ref (valuetag)) + + if (TAO_OBV_GIOP_Flags::is_null_ref (valuetag)) { // null reference is unmarshalled. valuetype = 0; - return true; + is_null_object = 1; + return 1; + } + + if (TAO_OBV_GIOP_Flags::has_codebase_url (valuetag)) + { + ACE_CString codebase_url; + if (! _tao_read_codebase_url (strm, codebase_url)) + { + return 0; + } } - else if (TAO_OBV_GIOP_Flags::has_single_type_info (valuetag)) + + if (TAO_OBV_GIOP_Flags::has_single_type_info (valuetag)) { - if (! _tao_read_repository_id(strm, ids)) + ACE_CString id; + if (! _tao_read_repository_id(strm, id)) { - return false; + return 0; } + + ids.push_back (id); } else if (TAO_OBV_GIOP_Flags::has_list_type_info (valuetag)) { if (! _tao_read_repository_id_list(strm, ids)) { - return false; + return 0; } } else if (TAO_OBV_GIOP_Flags::has_no_type_info (valuetag)) @@ -268,7 +309,7 @@ CORBA::ValueBase::_tao_unmarshal_pre (TAO_InputCDR &strm, valuetag)); } - return false; + return 0; } TAO_ORB_Core *orb_core = strm.orb_core (); @@ -285,7 +326,7 @@ CORBA::ValueBase::_tao_unmarshal_pre (TAO_InputCDR &strm, } } - CORBA::Boolean require_truncation = false; + CORBA::Boolean require_truncation = 0; CORBA::Boolean const chunking = TAO_OBV_GIOP_Flags::is_chunked (valuetag); CORBA::ULong const num_ids = ids.size (); @@ -301,7 +342,7 @@ CORBA::ValueBase::_tao_unmarshal_pre (TAO_InputCDR &strm, { if (i != 0 && chunking) { - require_truncation = true; + require_truncation = 1; } break; } @@ -329,12 +370,22 @@ CORBA::ValueBase::_tao_unmarshal_pre (TAO_InputCDR &strm, if (valuetype == 0) { - return false; // %! except.? + return 0; // %! except.? } valuetype->chunking_ = chunking; - return true; + VERIFY_MAP(TAO_InputCDR, value_map, Value_Map) + + if (strm.get_value_map ()->get()->bind (pos, valuetype ) != 0) + throw CORBA::INTERNAL (); + else if (TAO_debug_level > 0) + { + ACE_DEBUG ((LM_DEBUG, + ACE_TEXT ("(%P|%t)ValueBase::_tao_unmarshal_pre bound value %X - %X\n"), + pos, valuetype)); + } + return 1; } CORBA::Boolean @@ -353,81 +404,197 @@ CORBA::ValueBase::_tao_unmarshal_post (TAO_InputCDR &) // at the end of the stream which have to cause a marshal // exception there. - return true; + return 1; } CORBA::Boolean CORBA::ValueBase::_tao_validate_box_type (TAO_InputCDR &strm, + TAO_InputCDR &indirected_strm, const char * const repo_id_expected, - CORBA::Boolean & null_object) + CORBA::Boolean & null_object, + CORBA::Boolean & is_indirected) { CORBA::Long value_tag; - - // todo: no handling for indirection yet + null_object = 0; + is_indirected = 0; if (!strm.read_long (value_tag)) { - return false; + return 0; } if (TAO_OBV_GIOP_Flags::is_null_ref (value_tag)) { // ok, null reference unmarshaled - null_object = true; - return true; + null_object = 1; + return 1; } - null_object = false; + if (TAO_OBV_GIOP_Flags::is_indirection_tag (value_tag)) + { + is_indirected = 1; + + // box value is redirected. + return _tao_unmarshal_value_indirection_pre (strm, indirected_strm); + } if (!TAO_OBV_GIOP_Flags::is_value_tag (value_tag)) { ACE_DEBUG ((LM_DEBUG, ACE_TEXT ("!CORBA::ValueBase::_tao_validate_box_type ") ACE_TEXT ("not value_tag\n"))); - return false; + return 0; } + if (TAO_OBV_GIOP_Flags::has_codebase_url (value_tag)) { // Demarshal the codebase url (but we won't be using it). - CORBA::String_var codebase_url; - - if (!strm.read_string (codebase_url.inout ())) + ACE_CString codebase_url; + if (! _tao_read_codebase_url (strm, codebase_url)) { - return false; + return 0; } } if (TAO_OBV_GIOP_Flags::has_no_type_info (value_tag)) { // No type information so assume it is the correct type. - return true; + return 1; } if (TAO_OBV_GIOP_Flags::has_single_type_info (value_tag)) { // Demarshal the repository id and check if it is the expected one. - CORBA::String_var repo_id_stream; + ACE_CString id; + _tao_read_repository_id (strm, id); - if (!strm.read_string (repo_id_stream.inout ())) - { - return false; - } - - if (!ACE_OS::strcmp (repo_id_stream.in (), repo_id_expected)) - { // Repository ids matched as expected - return true; - } + if (!ACE_OS::strcmp (id.c_str(), repo_id_expected)) + { // Repository ids matched as expected + return 1; + } } if (TAO_OBV_GIOP_Flags::has_list_type_info (value_tag)) { // Don't know how to handle a repository id list. It does not // make sense for a value box anyway. - return false; + return 0; + } + + return 0; +} + +CORBA::Boolean +CORBA::ValueBase::_tao_unmarshal_value_indirection_pre (TAO_InputCDR &strm, + TAO_InputCDR &indirected_strm) +{ + CORBA::Long offset = 0; + if (!strm.read_long (offset) || offset >= 0) + { + return 0; + } + + size_t buffer_size = -(offset) + sizeof (CORBA::Long); + // Cribbed from tc_demarshal_indirection in Typecode_CDR_Extraction.cpp + indirected_strm = TAO_InputCDR (strm.rd_ptr () + offset - sizeof (CORBA::Long), + buffer_size, + strm.byte_order ()); + + indirected_strm.set_repo_id_map (strm.get_repo_id_map ()); + indirected_strm.set_codebase_url_map (strm.get_codebase_url_map ()); + indirected_strm.set_value_map (strm.get_value_map ()); + return indirected_strm.good_bit (); +} + + +CORBA::Boolean +CORBA::ValueBase::_tao_unmarshal_value_indirection (TAO_InputCDR &strm, + CORBA::ValueBase *&value) +{ + if (strm.get_value_map().is_nil ()) + throw CORBA::INTERNAL (); + + CORBA::Long offset = 0; + if (!strm.read_long (offset) || offset >= 0) + { + return 0; + } + + void* pos = strm.rd_ptr () + offset - sizeof (CORBA::Long); + + if (TAO_debug_level > 9) + { + ACE_DEBUG ((LM_DEBUG, + ACE_TEXT ("%P|%t)ValueBase::_tao_unmarshal_value_indirection pos %X \n"), pos)); + TAO_InputCDR::Value_Map* map = strm.get_value_map()->get (); + for (TAO_InputCDR::Value_Map::ITERATOR it = map->begin (); it != map->end (); ++ it) + { + ACE_DEBUG ((LM_DEBUG, ACE_TEXT ("%P|%t)%X - %X \n"), it->ext_id_, it->int_id_)); + } + } + void * v = 0; + if (strm.get_value_map()->get()->find (pos, v) != 0) + throw CORBA::INTERNAL (); + else if (TAO_debug_level > 0) + { + ACE_DEBUG ((LM_DEBUG, + ACE_TEXT ("(%P|%t)ValueBase::_tao_unmarshal_value_indirection found %X - %X\n"), + pos,v)); + } + + value = reinterpret_cast<CORBA::ValueBase *>(v); + return 1; +} + + +CORBA::Boolean +CORBA::ValueBase::_tao_unmarshal_repo_id_indirection (TAO_InputCDR &strm, + ACE_CString& id) +{ + CORBA::Long offset = 0; + if (!strm.read_long (offset) || offset >= 0) + { + return 0; + } + + void* pos = strm.rd_ptr () + offset - sizeof (CORBA::Long); + + if (strm.get_repo_id_map()->get()->find (pos, id) != 0) + throw CORBA::INTERNAL (); + else if (TAO_debug_level > 0) + { + ACE_DEBUG ((LM_DEBUG, + ACE_TEXT ("(%P|%t)ValueBase::_tao_unmarshal_repo_id_indirection found %X - %s\n"), + pos, id.c_str ())); + } + + return 1; +} + +CORBA::Boolean +CORBA::ValueBase::_tao_unmarshal_codebase_url_indirection (TAO_InputCDR &strm, + ACE_CString& codebase_url) +{ + CORBA::Long offset = 0; + if (!strm.read_long (offset) || offset >= 0) + { + return 0; + } + + void* pos = strm.rd_ptr () + offset - sizeof (CORBA::Long); + + if (strm.get_codebase_url_map()->get()->find (pos, codebase_url) != 0) + throw CORBA::INTERNAL (); + else if (TAO_debug_level > 0) + { + ACE_DEBUG ((LM_DEBUG, + ACE_TEXT ("(%P|%t)ValueBase::_tao_unmarshal_codebase_url_indirection found %X - %s\n"), + pos, codebase_url.c_str ())); } - return false; + return 1; } + #if defined (GEN_OSTREAM_OPS) std::ostream & @@ -457,14 +624,56 @@ CORBA::ValueBase::_tao_write_special_value (TAO_OutputCDR &strm, { return strm.write_long (TAO_OBV_GIOP_Flags::Null_tag); } - //@todo: Check if the value is already written to stream. If it is then - // put indirection and return successful, otherwise does nothing - // and returns false. else { - // value not handled by this method - other code will write the value. - return false; - } +#ifdef TAO_HAS_VALUETYPE_OUT_INDIRECTION + // value indirection + + VERIFY_MAP(TAO_OutputCDR, value_map, Value_Map) + + char* pos = 0; + if (strm.get_value_map ()->get()->find ( + reinterpret_cast<void*>(const_cast <CORBA::ValueBase *> (value)), pos) == 0) + { + if (TAO_debug_level > 0) + { + ACE_DEBUG ((LM_DEBUG, + ACE_TEXT ("(%P|%t)ValueBase::_tao_write_special_value found value %X - %X\n"), + value, pos)); + } + + if (! strm.write_long (TAO_OBV_GIOP_Flags::Indirection_tag)) + return 0; + + CORBA::Long offset = - strm.offset (pos); + if (TAO_debug_level > 0) + { + ACE_DEBUG ((LM_DEBUG, + ACE_TEXT ("(%P|%t)ValueBase::_tao_write_special_value value indirection %d \n"), offset)); + } + + return strm.write_long (offset); + } + else { + if (strm.align_write_ptr (ACE_CDR::LONG_SIZE) != 0) + throw CORBA::INTERNAL (); + if (strm.get_value_map ()->get()->bind ( + reinterpret_cast<void*>(const_cast <CORBA::ValueBase *> (value)), + strm.current()->wr_ptr() ) != 0) + throw CORBA::INTERNAL (); + else if (TAO_debug_level > 0) + { + ACE_DEBUG ((LM_DEBUG, + ACE_TEXT ("(%P|%t)ValueBase::_tao_marshal bound value %X - %X \n"), + value, strm.current()->wr_ptr())); + } + + return 0; + } +#endif + + return 0; + } } @@ -475,15 +684,15 @@ CORBA::ValueBase::_tao_write_value (TAO_OutputCDR &strm, { if (! value->_tao_write_value_header (strm, formal_type_id)) { - return false; + return 0; } if (! value->_tao_marshal_v (strm)) { - return false; + return 0; } - return true; + return 1; } @@ -508,7 +717,7 @@ CORBA::ValueBase::_tao_write_value_header (TAO_OutputCDR &strm, // support unmarshaling of valuetypes that did not explicitly // marshal the type id. At least it is benign to always encode the // typecode value, even if it can be a little verbose. - CORBA::Boolean const is_formal_type = false; + CORBA::Boolean const is_formal_type = 0; ACE_UNUSED_ARG (formal_type_id); #endif /* TAO_HAS_OPTIMIZED_VALUETYPE_MARSHALING */ @@ -540,12 +749,12 @@ CORBA::ValueBase::_tao_write_value_header (TAO_OutputCDR &strm, if (! strm.write_long (valuetag) // Write <value-tag>. || (num_ids > 1 && !strm.write_long (num_ids))) // Write <num-ids>. { - return false; + return 0; } #ifndef TAO_HAS_OPTIMIMIZED_VALUETYPE_MARSHALING if (this->is_truncatable_ - || !is_formal_type /* Always evaluates to true in the + || !is_formal_type /* Always evaluates to 1 in the !TAO_HAS_OPTIMIMIZED_VALUETYPE_MARSHALING case */ || num_ids > 1) @@ -554,18 +763,73 @@ CORBA::ValueBase::_tao_write_value_header (TAO_OutputCDR &strm, // Marshal type information. for (CORBA::Long i = 0; i < num_ids; ++i ) { - if (! strm.write_string (repository_ids[i])) + if (! _tao_write_repository_id (strm, repository_ids[i])) { - return false; + return 0; } } #ifndef TAO_HAS_OPTIMIMIZED_VALUETYPE_MARSHALING } #endif /* !TAO_HAS_OPTIMIMIZED_VALUETYPE_MARSHALING */ - return true; + return 1; } + +CORBA::Boolean +CORBA::ValueBase::_tao_write_repository_id (TAO_OutputCDR &strm, + ACE_CString& id) +{ +#ifdef TAO_HAS_VALUETYPE_OUT_INDIRECTION + + VERIFY_MAP(TAO_OutputCDR, repo_id_map, Repo_Id_Map) + + if (strm.get_repo_id_map().is_nil ()) + throw CORBA::INTERNAL (); + + char* pos = 0; + if (strm.get_repo_id_map ()->get()->find (id, pos) == 0) + { + if (! strm.write_long (TAO_OBV_GIOP_Flags::Indirection_tag)) + return 0; + + CORBA::Long offset = pos - strm.current ()->wr_ptr (); + + if (TAO_debug_level > 0) + { + ACE_DEBUG ((LM_DEBUG, + ACE_TEXT ("(%P|%t)ValueBase::_tao_write_repository_id id %s indirection %d\n"), + id.c_str(), offset)); + } + + if (! strm.write_long (offset)) + return 0; + } + else + { + if (strm.align_write_ptr (ACE_CDR::LONG_SIZE) != 0) + throw CORBA::INTERNAL (); + + if (strm.get_repo_id_map ()->get ()->bind (id, strm.current()->wr_ptr ()) != 0) + throw CORBA::INTERNAL (); + else if (TAO_debug_level > 0) + { + ACE_DEBUG ((LM_DEBUG, + ACE_TEXT ("(%P|%t)ValueBase::_tao_write_repository_id bound %s - %X\n"), + id.c_str (), strm.current()->wr_ptr ())); + } + if (! strm.write_string (id.c_str ())) + return 0; + } +#else + if (! strm.write_string (id.c_str ())) + return 0; +#endif + + return 1; +} + + // this method is called by the IDL generated _tao_marshal_state() method. CORBA::Boolean TAO_ChunkInfo::start_chunk(TAO_OutputCDR &strm) @@ -576,13 +840,13 @@ TAO_ChunkInfo::start_chunk(TAO_OutputCDR &strm) { if (! reserve_chunk_size(strm)) { - return false; + return 0; } this->value_nesting_level_ ++; } - return true; + return 1; } // this method is called by the IDL generated _tao_marshal_state() method. @@ -594,23 +858,23 @@ TAO_ChunkInfo::end_chunk(TAO_OutputCDR &strm) // Write actual chunk size at the reserved chunk size place. if (! this->write_previous_chunk_size(strm)) { - return false; + return 0; } // Write an end tag which is negation of value_nesting_level_. if (! strm.write_long(- this->value_nesting_level_)) { - return false; + return 0; } // -- this->value_nesting_level_; if ( -- this->value_nesting_level_ == 0 ) { // ending chunk for outermost value - this->chunking_ = false; + this->chunking_ = 0; } } - return true; + return 1; } @@ -628,14 +892,14 @@ TAO_ChunkInfo::write_previous_chunk_size(TAO_OutputCDR &strm) // the start_chunk() and end_chunk() calls. if (chunk_size == 0) { - return false; + return 0; } // Write the actual chunk size to the reserved chunk size position // in the stream. if (!strm.replace (chunk_size, this->chunk_size_pos_)) { - return false; + return 0; } // We finish writing the actual chunk size, now we need reset the state. @@ -643,7 +907,7 @@ TAO_ChunkInfo::write_previous_chunk_size(TAO_OutputCDR &strm) this->length_to_chunk_octets_pos_ = 0; } - return true; + return 1; } @@ -668,7 +932,7 @@ TAO_ChunkInfo::reserve_chunk_size(TAO_OutputCDR &strm) // later and write the actual size. if (! strm.write_long (0)) { - return false; + return 0; } // Remember length before writing chunk data. This is used to calculate @@ -676,7 +940,7 @@ TAO_ChunkInfo::reserve_chunk_size(TAO_OutputCDR &strm) this->length_to_chunk_octets_pos_ = strm.total_length (); } - return true; + return 1; } CORBA::Boolean @@ -684,7 +948,7 @@ TAO_ChunkInfo::handle_chunking (TAO_InputCDR &strm) { if (!this->chunking_) { - return true; + return 1; } char* the_rd_ptr = strm.start()->rd_ptr (); @@ -697,14 +961,14 @@ TAO_ChunkInfo::handle_chunking (TAO_InputCDR &strm) if (the_rd_ptr < this->chunk_octets_end_pos_) { ++this->value_nesting_level_; - return true; + return 1; } //Safty check if reading is out of range of current chunk. if (this->chunk_octets_end_pos_ != 0 && the_rd_ptr > this->chunk_octets_end_pos_) { - return false; + return 0; } // Read a long value that might be an endtag, the chunk size or the value tag @@ -713,7 +977,7 @@ TAO_ChunkInfo::handle_chunking (TAO_InputCDR &strm) if (!strm.read_long (tag)) { - return false; + return 0; } if (tag < 0) @@ -726,7 +990,7 @@ TAO_ChunkInfo::handle_chunking (TAO_InputCDR &strm) ACE_TEXT ("%d > value_nesting_level %d\n"), -tag, this->value_nesting_level_), - false); + 0); } this->value_nesting_level_ = - tag; @@ -752,10 +1016,10 @@ TAO_ChunkInfo::handle_chunking (TAO_InputCDR &strm) // This should not happen since the valuetag of the nested // values are always unmarshalled in the // ValueBase::_tao_unmarshal_pre(). - return false; + return 0; } - return true; + return 1; } @@ -764,7 +1028,7 @@ TAO_ChunkInfo::skip_chunks (TAO_InputCDR &strm) { if (!this->chunking_) { - return true; + return 1; } // This function is called after reading data of the truncated parent and @@ -773,13 +1037,13 @@ TAO_ChunkInfo::skip_chunks (TAO_InputCDR &strm) CORBA::Long tag; if (!strm.read_long(tag)) { - return false; + return 0; } // end of the whole valuetype. if (tag == -1) { - return true; + return 1; } else if (tag < 0) { @@ -795,55 +1059,61 @@ TAO_ChunkInfo::skip_chunks (TAO_InputCDR &strm) return this->skip_chunks (strm); } else - return false; + return 0; } CORBA::Boolean -CORBA::ValueBase::_tao_read_repository_id_list (ACE_InputCDR& strm, +CORBA::ValueBase::_tao_read_repository_id_list (TAO_InputCDR& strm, Repository_Id_List& ids) { - CORBA::Long num_ids; + CORBA::Long num_ids = 0; if (!strm.read_long (num_ids)) { - return false; + return 0; } if (num_ids == TAO_OBV_GIOP_Flags::Indirection_tag) { - //@todo: read indirection repository ids and return true. - return false; + // Multiple repo id is not indirected. + return 0; } else { - //@todo: map repository id for indirection for (CORBA::Long i = 0; i < num_ids; ++i) { - if (!_tao_read_repository_id (strm,ids)) + ACE_CString id; + if (!_tao_read_repository_id (strm, id)) { - return false; + return 0; } + ids.push_back (id); } - } + } - return true; + return 1; } CORBA::Boolean -CORBA::ValueBase::_tao_read_repository_id (ACE_InputCDR& strm, - Repository_Id_List& ids) +CORBA::ValueBase::_tao_read_repository_id (TAO_InputCDR& strm, + ACE_CString& id) { - ACE_CString id; CORBA::ULong length = 0; - CORBA::Long offset = 0; size_t buffer_size = strm.length(); if (!strm.read_ulong (length)) { - return false; + return 0; } + VERIFY_MAP(TAO_InputCDR, repo_id_map, Repo_Id_Map) + + if (strm.get_repo_id_map ().is_nil ()) + throw CORBA::INTERNAL (); + + char * pos = strm.rd_ptr(); + // 'length' may not be the repo id length - it could be the // FFFFFFF indirection marker instead. If it is an indirection marker, we // get the offset following the indirection marker, otherwise we can follow @@ -851,40 +1121,140 @@ CORBA::ValueBase::_tao_read_repository_id (ACE_InputCDR& strm, // and re-read the length as part of the string if (TAO_OBV_GIOP_Flags::is_indirection_tag (length)) { - // Read the negative byte offset - if (!strm.read_long (offset) || offset >= 0) - { - return false; - } - - buffer_size = -(offset) + sizeof (CORBA::Long); + return _tao_unmarshal_repo_id_indirection (strm, id); } + pos -= sizeof (CORBA::ULong); + // Cribbed from tc_demarshal_indirection in Typecode_CDR_Extraction.cpp - TAO_InputCDR indir_stream (strm.rd_ptr () + offset - sizeof (CORBA::Long), - buffer_size, - strm.byte_order ()); + TAO_InputCDR id_stream (pos, + buffer_size, + strm.byte_order ()); + + if (!id_stream.good_bit ()) + { + return 0; + } + + if (! id_stream.read_string (id)) + return 0; - if (!indir_stream.good_bit ()) + // It's possible the id is read again from an indirection stream, + // so make sure the id is the same. + ACE_CString mapped_id; + if (strm.get_repo_id_map ()->get()->find (pos, mapped_id) == 0) + { + if (TAO_debug_level > 0) { - return false; + ACE_DEBUG ((LM_DEBUG, + ACE_TEXT ("(%P|%t)ValueBase::_tao_read_repository_id found %X - %s\n"), + pos, mapped_id.c_str ())); } - indir_stream.read_string (id); + if (ACE_OS::strcmp (mapped_id.c_str (), id.c_str ()) != 0) + throw CORBA::INTERNAL (); + } + else if (strm.get_repo_id_map ()->get ()->bind (pos, id) != 0) + { + throw CORBA::INTERNAL (); + } + else if (TAO_debug_level > 0) + { + ACE_DEBUG ((LM_DEBUG, + ACE_TEXT ("(%P|%t)ValueBase::_tao_read_repository_id bound %X - %s\n"), + pos, id.c_str ())); + } // Since the ID is always read from the indirection cdr we have to skip // the main CDR forward if we were in fact reading from the current // location and not rewinding back some offset. - if (offset == 0) + strm.skip_bytes (length); + + return 1; +} + + +CORBA::Boolean +CORBA::ValueBase::_tao_read_codebase_url (TAO_InputCDR& strm, + ACE_CString& codebase_url) +{ + CORBA::ULong length = 0; + + size_t buffer_size = strm.length(); + + if (!strm.read_ulong (length)) + { + return 0; + } + + VERIFY_MAP(TAO_InputCDR, codebase_url_map, Codebase_URL_Map) + + char * pos = strm.rd_ptr(); + + // 'length' may not be the codebase url length - it could be the + // FFFFFFF indirection marker instead. If it is an indirection marker, we + // get the offset following the indirection marker, otherwise we can follow + // the same logic using the offset to simply rewind to the start of length + // and re-read the length as part of the string + if (TAO_OBV_GIOP_Flags::is_indirection_tag (length)) { - strm.skip_bytes (length); + return _tao_unmarshal_codebase_url_indirection (strm, codebase_url); } - ids.push_back (id); - return true; + pos -= sizeof (CORBA::ULong); + + // Cribbed from tc_demarshal_indirection in Typecode_CDR_Extraction.cpp + TAO_InputCDR url_stream (pos, + buffer_size, + strm.byte_order ()); + + if (!url_stream.good_bit ()) + { + return 0; + } + + if (! url_stream.read_string (codebase_url)) + return 0; + + // It's possible the codebase url is read again from an indirection stream, + // so make sure the codebase url is the same. + ACE_CString mapped_url; + if (strm.get_codebase_url_map ()->get()->find (pos, mapped_url) == 0) + { + if (TAO_debug_level > 0) + { + ACE_DEBUG ((LM_DEBUG, + ACE_TEXT ("(%P|%t)ValueBase::_tao_read_codebase_url found %X - %s\n"), + pos, mapped_url.c_str ())); + } + if (ACE_OS::strcmp (mapped_url.c_str (), codebase_url.c_str ()) != 0) + throw CORBA::INTERNAL (); + } + else if (strm.get_codebase_url_map ()->get()->bind (pos, codebase_url) != 0) + { + throw CORBA::INTERNAL (); + } + else + { + if (TAO_debug_level > 0) + { + ACE_DEBUG ((LM_DEBUG, + ACE_TEXT ("(%P|%t)ValueBase::_tao_read_codebase_url bound %X - %s\n"), + pos, codebase_url.c_str ())); + } + } + + // Since the codebase url is always read from the indirection cdr we have to skip + // the main CDR forward if we were in fact reading from the current + // location and not rewinding back some offset. + + strm.skip_bytes (length); + + return 1; } + void CORBA::ValueBase::truncation_hook () { diff --git a/TAO/tao/Valuetype/ValueBase.h b/TAO/tao/Valuetype/ValueBase.h index 2cc3453c5e4..9ff13b830ce 100644 --- a/TAO/tao/Valuetype/ValueBase.h +++ b/TAO/tao/Valuetype/ValueBase.h @@ -131,7 +131,7 @@ namespace CORBA typedef ValueBase_out _out_type; typedef ACE_Vector < ACE_CString > Repository_Id_List; - + // Reference counting. /// %! virtual CORBA::ValueBase* _copy_value (void) = 0; @@ -178,17 +178,21 @@ namespace CORBA /// Both used internally and are called from T::_tao_unmarshal () static CORBA::Boolean _tao_unmarshal_pre (TAO_InputCDR &strm, - ValueBase *&, - const char * const repo_id); + CORBA::ValueBase *&valuetype, + const char * const repo_id, + CORBA::Boolean& is_null_object, + CORBA::Boolean& is_indirected); CORBA::Boolean _tao_unmarshal_post (TAO_InputCDR &strm); /// Check repository id for value box type against what is /// in the CDR stream. static CORBA::Boolean _tao_validate_box_type ( - TAO_InputCDR &strm, - const char * const repo_id_expected, - CORBA::Boolean & null_object); + TAO_InputCDR &strm, + TAO_InputCDR &indirected_strm, + const char * const repo_id_expected, + CORBA::Boolean & null_object, + CORBA::Boolean & is_indirected); #if defined (GEN_OSTREAM_OPS) @@ -235,6 +239,22 @@ namespace CORBA virtual CORBA::Boolean _tao_match_formal_type (ptrdiff_t ) const = 0; private: + + static CORBA::Boolean _tao_unmarshal_value_indirection_pre (TAO_InputCDR &strm, + TAO_InputCDR &indirected_strm); + + static CORBA::Boolean _tao_unmarshal_value_indirection (TAO_InputCDR &strm, + CORBA::ValueBase *&value); + + static CORBA::Boolean _tao_unmarshal_repo_id_indirection (TAO_InputCDR &strm, + ACE_CString& repo_id); + + static CORBA::Boolean _tao_unmarshal_codebase_url_indirection (TAO_InputCDR &strm, + ACE_CString& codebase_url); + + static CORBA::Boolean _tao_write_repository_id (TAO_OutputCDR &strm, + ACE_CString& id); + /// Write some special values such as null value or indirection value. static CORBA::Boolean _tao_write_special_value(TAO_OutputCDR &strm, const CORBA::ValueBase * value); @@ -250,14 +270,20 @@ namespace CORBA /// Read a single repository id from the CDR input stream, /// accounting for indirection. - static CORBA::Boolean _tao_read_repository_id (ACE_InputCDR& strm, - Repository_Id_List& ids); + static CORBA::Boolean _tao_read_repository_id (TAO_InputCDR& strm, + ACE_CString& id); /// Read a list of repository ids from the CDR input stream, /// accounting for indirection - static CORBA::Boolean _tao_read_repository_id_list (ACE_InputCDR& strm, + static CORBA::Boolean _tao_read_repository_id_list (TAO_InputCDR& strm, Repository_Id_List& ids); + /// Read a codebase url from the CDR input stream, + /// accounting for indirection. + static CORBA::Boolean _tao_read_codebase_url (TAO_InputCDR& strm, + ACE_CString& codebase_url); + + private: ValueBase & operator= (const ValueBase &); @@ -331,7 +357,7 @@ namespace TAO_OBV_GIOP_Flags const CORBA::Long Type_info_single = 2; const CORBA::Long Type_info_list = 6; const CORBA::Long Chunking_tag_sigbits = 0x00000008L; - const CORBA::Long Indirection_tag = 0x7fffffffL; + const CORBA::Long Indirection_tag = 0xFFFFFFFFL; const CORBA::Long Null_tag = 0x00000000L; TAO_NAMESPACE_INLINE_FUNCTION CORBA::Boolean is_null_ref (CORBA::Long tag); diff --git a/TAO/tao/Valuetype/ValueBase.inl b/TAO/tao/Valuetype/ValueBase.inl index d51a47bab83..adf3a18ebcc 100644 --- a/TAO/tao/Valuetype/ValueBase.inl +++ b/TAO/tao/Valuetype/ValueBase.inl @@ -51,9 +51,10 @@ TAO_OBV_GIOP_Flags:: is_chunked (CORBA::Long tag) ACE_INLINE CORBA::Boolean TAO_OBV_GIOP_Flags::is_indirection_tag (CORBA::Long tag) { - return (static_cast<unsigned>(tag) == 0xFFFFFFFFL); + return tag == Indirection_tag; } + ACE_INLINE CORBA::Boolean TAO_OBV_GIOP_Flags::is_indirection (CORBA::Long value) { @@ -61,6 +62,7 @@ TAO_OBV_GIOP_Flags::is_indirection (CORBA::Long value) static_cast<unsigned>(value) <= (0xFFFFFFFFL - 4)); } + ACE_INLINE CORBA::Boolean TAO_OBV_GIOP_Flags::is_block_size (CORBA::Long value) { diff --git a/TAO/tao/operation_details.cpp b/TAO/tao/operation_details.cpp index 460e7c1c31f..45b7a7ccf4a 100644 --- a/TAO/tao/operation_details.cpp +++ b/TAO/tao/operation_details.cpp @@ -7,6 +7,7 @@ #include "tao/SystemException.h" #include "tao/Argument.h" #include "tao/CDR.h" +#include "tao/debug.h" #include "ace/OS_NS_string.h" @@ -72,6 +73,10 @@ TAO_Operation_Details::marshal_args (TAO_OutputCDR &cdr) // data in the CDR stream since the operation was a marshaling // operation, not a fragmentation operation. cdr.more_fragments (false); + +#ifdef TAO_HAS_VALUETYPE_OUT_INDIRECTION + cdr.reset_vt_indirect_maps (); +#endif return true; } @@ -85,6 +90,8 @@ TAO_Operation_Details::demarshal_args (TAO_InputCDR &cdr) return false; } + cdr.reset_vt_indirect_maps (); + return true; } diff --git a/TAO/tao/tao.mpc b/TAO/tao/tao.mpc index d0059ea4208..3bb3ee07711 100644 --- a/TAO/tao/tao.mpc +++ b/TAO/tao/tao.mpc @@ -56,7 +56,7 @@ project(TAO_Core_idl) : tao_versioning_idl_defaults, gen_ostream { } -project(TAO) : acelib, install, tao_output, taodefaults, pidl, extra_core, taoidldefaults, gen_ostream, corba_e_micro, corba_e_compact, core_minimum_corba, tao_no_iiop { +project(TAO) : acelib, install, tao_output, taodefaults, pidl, extra_core, taoidldefaults, gen_ostream, corba_e_micro, corba_e_compact, core_minimum_corba, tao_no_iiop, valuetype_out_indirection { after += TAO_Core_idl sharedname = TAO dynamicflags = TAO_BUILD_DLL diff --git a/TAO/tests/OBV/Indirection/Factory.cpp b/TAO/tests/OBV/Indirection/Factory.cpp new file mode 100755 index 00000000000..6ca039340a9 --- /dev/null +++ b/TAO/tests/OBV/Indirection/Factory.cpp @@ -0,0 +1,86 @@ +#include "Factory.h" +#include "tao/AnyTypeCode/TypeCode.h" + + +void +NodeFactory::register_new_factory(CORBA::ORB& orb) { + CORBA::ValueFactoryBase_var mf = new NodeFactory; + CORBA::String_var id = ::demo::value::idl::_tc_Node->id(); + orb.register_value_factory(id.in(), mf.in()); +} + +CORBA::ValueBase* +NodeFactory::create_for_unmarshal(void) +{ + ::CORBA::ValueBase *ret_val = 0; + ACE_NEW_THROW_EX ( + ret_val, + OBV_demo::value::idl::Node, + ::CORBA::NO_MEMORY () + ); + return ret_val; +} + + +void +BoxedValueFactory::register_new_factory(CORBA::ORB& orb) { + CORBA::ValueFactoryBase_var mf = new BoxedValueFactory; + OBV_demo::value::idl::boxedValue bv; + CORBA::String_var id = bv._tao_type()->id ();; + orb.register_value_factory(id.in(), mf.in()); +} + +CORBA::ValueBase* +BoxedValueFactory::create_for_unmarshal(void) +{ + ::CORBA::ValueBase *ret_val = 0; + ACE_NEW_THROW_EX ( + ret_val, + OBV_demo::value::idl::boxedValue, + ::CORBA::NO_MEMORY () + ); + return ret_val; +} + + +void +BaseValueFactory::register_new_factory(CORBA::ORB& orb) { + CORBA::ValueFactoryBase_var mf = new BaseValueFactory; + OBV_demo::value::idl::BaseValue bv; + CORBA::String_var id = bv._tao_type()->id ();; + orb.register_value_factory(id.in(), mf.in()); +} + +CORBA::ValueBase* +BaseValueFactory::create_for_unmarshal(void) +{ + ::CORBA::ValueBase *ret_val = 0; + ACE_NEW_THROW_EX ( + ret_val, + OBV_demo::value::idl::BaseValue, + ::CORBA::NO_MEMORY () + ); + return ret_val; +} + + +void +TValueFactory::register_new_factory(CORBA::ORB& orb) { + CORBA::ValueFactoryBase_var mf = new TValueFactory; + OBV_demo::value::idl::TValue bv; + CORBA::String_var id = bv._tao_type()->id ();; + orb.register_value_factory(id.in(), mf.in()); +} + +CORBA::ValueBase* +TValueFactory::create_for_unmarshal(void) +{ + ::CORBA::ValueBase *ret_val = 0; + ACE_NEW_THROW_EX ( + ret_val, + OBV_demo::value::idl::TValue, + ::CORBA::NO_MEMORY () + ); + return ret_val; +} + diff --git a/TAO/tests/OBV/Indirection/Factory.h b/TAO/tests/OBV/Indirection/Factory.h new file mode 100755 index 00000000000..d992860a703 --- /dev/null +++ b/TAO/tests/OBV/Indirection/Factory.h @@ -0,0 +1,38 @@ +#include "tao/Valuetype/ValueFactory.h" +#include "tao/ORB.h" +#include "MessengerC.h" + +class NodeFactory : public CORBA::ValueFactoryBase +{ + public: + static void register_new_factory(CORBA::ORB& orb); + virtual CORBA::ValueBase* create_for_unmarshal(void); +}; + + +class BoxedValueFactory : public CORBA::ValueFactoryBase +{ + public: + static void register_new_factory(CORBA::ORB& orb); + virtual CORBA::ValueBase* create_for_unmarshal(void); +}; + + +class BaseValueFactory : public CORBA::ValueFactoryBase +{ + public: + static void register_new_factory(CORBA::ORB& orb); + virtual CORBA::ValueBase* create_for_unmarshal(void); +}; + + +class TValueFactory : public CORBA::ValueFactoryBase +{ + public: + static void register_new_factory(CORBA::ORB& orb); + virtual CORBA::ValueBase* create_for_unmarshal(void); +}; + + + + diff --git a/TAO/tests/OBV/Indirection/Indirection.mpc b/TAO/tests/OBV/Indirection/Indirection.mpc new file mode 100644 index 00000000000..91ac7d5e1b8 --- /dev/null +++ b/TAO/tests/OBV/Indirection/Indirection.mpc @@ -0,0 +1,38 @@ +// $Id$ + +project(*IDL): taoidldefaults, valuetype { + IDL_Files { + Messenger.idl + } + custom_only = 1 +} + +project(*Server): taoserver, valuetype { + exename = MessengerServer + after += *IDL + Source_Files { + Messenger_i.cpp + Factory.cpp + MessengerServer.cpp + } + Source_Files { + MessengerC.cpp + MessengerS.cpp + } + IDL_Files { + } +} + +project(*Client): taoclient, valuetype { + exename = MessengerClient + after += *IDL + Source_Files { + Factory.cpp + MessengerClient.cpp + } + Source_Files { + MessengerC.cpp + } + IDL_Files { + } +} diff --git a/TAO/tests/OBV/Indirection/Messenger.idl b/TAO/tests/OBV/Indirection/Messenger.idl new file mode 100644 index 00000000000..d7166448517 --- /dev/null +++ b/TAO/tests/OBV/Indirection/Messenger.idl @@ -0,0 +1,51 @@ +// $Id$ + +// Messenger.idl + +module demo { + + module value { + + module idl { + + valuetype BaseValue + { + public unsigned long basic_data; + }; + + // + // Valuetype with one-level truncatable inheritence. + // + valuetype TValue : truncatable BaseValue + { + public unsigned long data; + }; + + valuetype boxedLong long; + valuetype boxedString string; + + valuetype boxedValue + { + public boxedLong b1; + public boxedLong b2; + }; + + valuetype Node { + public long id; + public Node next; + }; + + interface ValueServer { + string receive_boxedvalue (in boxedValue b); + string receive_long (in boxedLong p1, in boxedLong p2); + string receive_string (in boxedString s1, in boxedString s2); + + string receive_list (in Node _node); + string receive_truncatable (inout TValue v); + }; + + }; + + }; + +}; diff --git a/TAO/tests/OBV/Indirection/MessengerClient.cpp b/TAO/tests/OBV/Indirection/MessengerClient.cpp new file mode 100644 index 00000000000..472e68714ca --- /dev/null +++ b/TAO/tests/OBV/Indirection/MessengerClient.cpp @@ -0,0 +1,88 @@ +// $Id$ + +#include "MessengerC.h" +#include "Factory.h" +#include <iostream> + +const char* server_ior = "file://server.ior"; +using namespace demo::value::idl; + +int ACE_TMAIN (int ac, ACE_TCHAR* av[]) { + + try { + + CORBA::ORB_var orb = CORBA::ORB_init(ac, av); + + NodeFactory::register_new_factory(* orb.in()); + BoxedValueFactory::register_new_factory(* orb.in()); + BaseValueFactory::register_new_factory(* orb.in()); + TValueFactory::register_new_factory(* orb.in()); + + CORBA::Object_var obj = orb->string_to_object(server_ior); + ValueServer_var tst = ValueServer::_narrow(obj.in()); + ACE_ASSERT(! CORBA::is_nil(tst.in())); + + // invoke operations and print the results + boxedLong* p1 = new boxedLong (774); + boxedLong* p2 = new boxedLong (775); + boxedString* s1 = new boxedString ("hello"); + boxedString* s2 = new boxedString ("world"); + boxedString* null = 0; + boxedValue* b = new OBV_demo::value::idl::boxedValue (); + b->b1 (p1); + b->b2 (p2); + boxedValue* bb = new OBV_demo::value::idl::boxedValue (); + bb->b1 (p1); + bb->b2 (p1); + + ACE_DEBUG ((LM_DEBUG, "(%P|%t)Passing two boxed values in one valuetype: %s\n", + tst->receive_boxedvalue (b))); + ACE_DEBUG ((LM_DEBUG, "(%P|%t)Passing one boxed values twice in one valuetype: %s\n", + tst->receive_boxedvalue (bb))); + ACE_DEBUG ((LM_DEBUG, "(%P|%t)Passing two integers: %s\n", + tst->receive_long (p1, p2))); + ACE_DEBUG ((LM_DEBUG, "(%P|%t)Passing one integer twice: %s\n", + tst->receive_long (p1, p1))); + ACE_DEBUG ((LM_DEBUG, "(%P|%t)Passing two strings: %s\n", + tst->receive_string (s1, s2))); + ACE_DEBUG ((LM_DEBUG, "(%P|%t)Passing null: %s\n", + tst->receive_string (s1, null))); + + Node* n4 = new OBV_demo::value::idl::Node (4, 0); + Node* n3 = new OBV_demo::value::idl::Node (3, n4); + Node* n2 = new OBV_demo::value::idl::Node (2, n3); + Node* n1 = new OBV_demo::value::idl::Node (1, n2); + + n4->next(n1); + + ACE_DEBUG ((LM_DEBUG, "(%P|%t)Passing a list structure: %s\n", + tst->receive_list (n1))); + +#if 1 + TValue* t = new OBV_demo::value::idl::TValue (); + t->data (20); + t->basic_data (10); + + ACE_DEBUG ((LM_DEBUG, "(%P|%t)Passing inout truncatable: %s\n", + tst->receive_truncatable (t))); + if (t->data () != 21 || t->basic_data () != 11) + { + std::cerr << "Received incorrect truncatable data" << std::endl; + return 1; + } +#endif + + + while (orb->work_pending()) { + orb->perform_work(); + } + + orb->destroy(); + + } catch(const CORBA::Exception& e) { + std::cerr << e << std::endl; + return 1; + } + + return 0; +} diff --git a/TAO/tests/OBV/Indirection/MessengerServer.cpp b/TAO/tests/OBV/Indirection/MessengerServer.cpp new file mode 100644 index 00000000000..8f271054949 --- /dev/null +++ b/TAO/tests/OBV/Indirection/MessengerServer.cpp @@ -0,0 +1,49 @@ +// $Id$ + +#include "Messenger_i.h" +#include "Factory.h" + +#include <iostream> +#include <fstream> +#include <fstream> + +const char* server_ior_file = "server.ior"; + + +void write_ior(const char* ior) { + std::ofstream out(server_ior_file); + out << ior; +} + +int ACE_TMAIN (int ac, ACE_TCHAR* av[]) { + + CORBA::ORB_var orb = CORBA::ORB_init(ac, av); + + NodeFactory::register_new_factory(* orb.in()); + BoxedValueFactory::register_new_factory(* orb.in()); + BaseValueFactory::register_new_factory(* orb.in()); + TValueFactory::register_new_factory(* orb.in()); + + CORBA::Object_var obj = orb->resolve_initial_references("RootPOA"); + PortableServer::POA_var poa = PortableServer::POA::_narrow(obj.in()); + + PortableServer::POAManager_var poaman = poa->the_POAManager(); + + PortableServer::Servant_var<Messenger_i> svt = new Messenger_i; + + PortableServer::ObjectId_var id = poa->activate_object(svt.in()); + obj = poa->id_to_reference(id.in()); + CORBA::String_var ior = orb->object_to_string(obj.in()); + write_ior(ior.in()); + + std::cout << "Starting server." << std::endl; + + poaman->activate(); + + orb->run(); + + poa->destroy(true, true); + orb->destroy(); + + return 0; +} diff --git a/TAO/tests/OBV/Indirection/Messenger_i.cpp b/TAO/tests/OBV/Indirection/Messenger_i.cpp new file mode 100644 index 00000000000..e20ae2c7293 --- /dev/null +++ b/TAO/tests/OBV/Indirection/Messenger_i.cpp @@ -0,0 +1,113 @@ +// $Id$ + +#include "Messenger_i.h" + +#include "tao/AnyTypeCode/TypeCode.h" + +#include <sstream> + +Messenger_i::Messenger_i() +{ +} + +Messenger_i::~Messenger_i() +{ +} + + +char * Messenger_i::receive_boxedvalue ( + ::demo::value::idl::boxedValue * b) +{ + std::ostringstream os; + if (b == 0) + os << "null boxed values"; + else + os << "boxed values: " << b->b1 ()->_value() << ", " << b->b2 ()->_value(); + + return CORBA::string_dup (os.str().c_str()); +} + + +char * Messenger_i::receive_long ( + ::demo::value::idl::boxedLong * p1, + ::demo::value::idl::boxedLong * p2) +{ + std::ostringstream os; + if (p1 == 0 || p2 == 0) + os << "one or two null values"; + else if (p1 == p2) + os << "shared long: " << p1->_value (); + else + os << "two longs: " << p1->_value () << ", " << p2->_value (); + + return CORBA::string_dup (os.str().c_str()); +} + + +char * Messenger_i::receive_string ( + ::demo::value::idl::boxedString * s1, + ::demo::value::idl::boxedString * s2) +{ + std::ostringstream os; + if (s1 == 0 || s2 == 0) + os << "one or two null values"; + else if (s1 == s2) + os << "shared string: " << s1->_value (); + else + os << "two strings: " << s1->_value () << ", " << s2->_value (); + + return CORBA::string_dup (os.str().c_str()); +} + + +char * Messenger_i::receive_list ( + ::demo::value::idl::Node * node) +{ + std::ostringstream os; + typedef ACE_Vector< ::demo::value::idl::Node *> NodeVector; + NodeVector l; + ::demo::value::idl::Node* x = node; + + while (x != 0) + { + size_t len = l.size (); + size_t i = 0; + for ( i = 0; i < len; ++i) + { + if (l[i] == x) + break; + } + + if (l[i] == x) + break; + + l.push_back (x); + x = x->next (); + } + + size_t len = l.size (); + + os << "list of length: " << len << " -- "; + + for (size_t i = 0; i < len; ++i) + { + os << l[i]->id (); + if (l[i]->next () != 0) + os << " "; + } + return CORBA::string_dup (os.str().c_str()); +} + + +char * +Messenger_i::receive_truncatable (::demo::value::idl::TValue *& v) +{ + v->data (v->data () + 1); + v->basic_data (v->basic_data () + 1); + + std::ostringstream os; + os << "truncatable basic_data " << v->basic_data () << " data " << v->data (); + return CORBA::string_dup (os.str().c_str()); +} + + diff --git a/TAO/tests/OBV/Indirection/Messenger_i.h b/TAO/tests/OBV/Indirection/Messenger_i.h new file mode 100644 index 00000000000..7d1c93c5a65 --- /dev/null +++ b/TAO/tests/OBV/Indirection/Messenger_i.h @@ -0,0 +1,49 @@ +// $Id$ + +#ifndef MESSENGER_I_H +#define MESSENGER_I_H + +#include "MessengerS.h" + +#include "tao/Valuetype/ValueFactory.h" + +class Messenger_i : public virtual POA_demo::value::idl::ValueServer +{ +public: + Messenger_i(); + + virtual char * receive_boxedvalue ( + ::demo::value::idl::boxedValue * b); + + virtual char * receive_long ( + ::demo::value::idl::boxedLong * p1, + ::demo::value::idl::boxedLong * p2); + + virtual char * receive_string ( + ::demo::value::idl::boxedString * s1, + ::demo::value::idl::boxedString * s2); + + virtual char * receive_list ( + ::demo::value::idl::Node * node); + + virtual char * receive_truncatable ( + ::demo::value::idl::TValue *& v); + +protected: + virtual ~Messenger_i(); +}; + + + + +//class NodeImpl : public virtual POA_demo::value::idl::Node +//class NodeFactory +// : public virtual CORBA::ValueFactoryBase +//{ +//public: +// static void register_new_factory(CORBA::ORB& orb); +//private: +// virtual CORBA::ValueBase* create_for_unmarshal(); +//}; + +#endif diff --git a/TAO/tests/OBV/Indirection/README b/TAO/tests/OBV/Indirection/README new file mode 100755 index 00000000000..a7312c5a46b --- /dev/null +++ b/TAO/tests/OBV/Indirection/README @@ -0,0 +1,40 @@ +// $Id$ + +This directory contains a CORBA example illustrating a simple client and +a server. The idl is similar to jacorb demo/value test. The test is used to +test indirection support in TAO and also can be used as interoperability +test between TAO and JacORB. + + +How to Run +---------- + +Start the server : +------------------ +./server + + +Start the client: +------------------ +./client + + + +Exeuction via Perl Script +------------------------- + +A Perl script has been created to automate the steps shown +above. This script can be run via the following command: + +./run_test.pl + + +NOTE: + + If you run on Windows platform, go to Debug or Release directory to run the + script via following command: + + perl ../run_test.pl + + + diff --git a/TAO/tests/OBV/Indirection/run_test.pl b/TAO/tests/OBV/Indirection/run_test.pl new file mode 100755 index 00000000000..0808ee9c8d4 --- /dev/null +++ b/TAO/tests/OBV/Indirection/run_test.pl @@ -0,0 +1,51 @@ +# $Id$ + +eval '(exit $?0)' && eval 'exec perl -S $0 ${1+"$@"}' + & eval 'exec perl -S $0 $argv:q' + if 0; + +use Env (ACE_ROOT); +use lib "$ACE_ROOT/bin"; +use PerlACE::TestTarget; + +$iorfile = "server.ior"; + +my $server = PerlACE::TestTarget::create_target (1) || die "Create target 1 failed\n"; +my $client = PerlACE::TestTarget::create_target (2) || die "Create target 2 failed\n"; + +$server->DeleteFile($iorfile); + +my $server_iorfile = $server->LocalFile ($iorfile); + +$S = $server->CreateProcess("MessengerServer"); +$S->Spawn(); + +if ($server->WaitForFileTimed ($iorfile, $server->ProcessStartWaitInterval()) == -1) { + print STDERR "ERROR: cannot find file <$server_iorfile>\n"; + $S->Kill(); + exit 1; +} + +$C = $client->CreateProcess("MessengerClient"); +$C->Spawn(); + +$CRET = $C->WaitKill($client->ProcessStartWaitInterval()); +$S->Kill(); + +# clean-up + +$server->DeleteFile($iorfile); + +if ($CRET != 0) { + print STDERR "ERROR: Client returned <$CRET>\n"; + exit 1 ; +} + +exit 0; + + + + + + + |