summaryrefslogtreecommitdiff
path: root/TAO
diff options
context:
space:
mode:
authordai_y <dai_y@ae88bc3d-4319-0410-8dbf-d08b4c9d3795>2009-12-04 23:21:00 +0000
committerdai_y <dai_y@ae88bc3d-4319-0410-8dbf-d08b4c9d3795>2009-12-04 23:21:00 +0000
commiteb2510ae52e2647a294c1ab2e642bb9987bfb502 (patch)
tree0e50dd3dcea768952d89e75de7b3ead46ab825c6 /TAO
parente791ad22ad1446fa08de128b665bdb5a53cca96e (diff)
downloadATCD-eb2510ae52e2647a294c1ab2e642bb9987bfb502.tar.gz
Fri Dec 4 23:18:26 UTC 2009 Yan Dai <dai_y@ociweb.com>
Diffstat (limited to 'TAO')
-rw-r--r--TAO/ChangeLog106
-rw-r--r--TAO/MPC/config/valuetype_out_indirection.mpb6
-rw-r--r--TAO/NEWS5
-rw-r--r--TAO/TAO_IDL/be/be_visitor_valuebox/valuebox_cs.cpp25
-rw-r--r--TAO/TAO_IDL/be/be_visitor_valuetype/valuetype_cs.cpp35
-rw-r--r--TAO/tao/AnyTypeCode/Any_Impl_T.cpp1
-rw-r--r--TAO/tao/AnyTypeCode/Any_Unknown_IDL_Type.cpp10
-rw-r--r--TAO/tao/CDR.cpp34
-rw-r--r--TAO/tao/CDR.h82
-rw-r--r--TAO/tao/CDR.inl120
-rw-r--r--TAO/tao/DynamicInterface/AMH_DSI_Response_Handler.cpp43
-rw-r--r--TAO/tao/PortableServer.mpc2
-rw-r--r--TAO/tao/PortableServer/Upcall_Wrapper.cpp7
-rw-r--r--TAO/tao/Valuetype.mpc2
-rw-r--r--TAO/tao/Valuetype/ValueBase.cpp612
-rw-r--r--TAO/tao/Valuetype/ValueBase.h46
-rw-r--r--TAO/tao/Valuetype/ValueBase.inl4
-rw-r--r--TAO/tao/operation_details.cpp7
-rw-r--r--TAO/tao/tao.mpc2
-rwxr-xr-xTAO/tests/OBV/Indirection/Factory.cpp86
-rwxr-xr-xTAO/tests/OBV/Indirection/Factory.h38
-rw-r--r--TAO/tests/OBV/Indirection/Indirection.mpc38
-rw-r--r--TAO/tests/OBV/Indirection/Messenger.idl51
-rw-r--r--TAO/tests/OBV/Indirection/MessengerClient.cpp88
-rw-r--r--TAO/tests/OBV/Indirection/MessengerServer.cpp49
-rw-r--r--TAO/tests/OBV/Indirection/Messenger_i.cpp113
-rw-r--r--TAO/tests/OBV/Indirection/Messenger_i.h49
-rwxr-xr-xTAO/tests/OBV/Indirection/README40
-rwxr-xr-xTAO/tests/OBV/Indirection/run_test.pl51
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
+}
diff --git a/TAO/NEWS b/TAO/NEWS
index 2354c8bd507..9ea5c716edd 100644
--- a/TAO/NEWS
+++ b/TAO/NEWS
@@ -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;
+
+
+
+
+
+
+