diff options
author | sma <sma@ae88bc3d-4319-0410-8dbf-d08b4c9d3795> | 2012-02-29 16:55:18 +0000 |
---|---|---|
committer | sma <sma@ae88bc3d-4319-0410-8dbf-d08b4c9d3795> | 2012-02-29 16:55:18 +0000 |
commit | fdb2c99dcc82b15544bd050a22bf41f94e0c2902 (patch) | |
tree | 0f75240e920b19cc7fe4f444544ebcfa03e51392 /TAO | |
parent | d6dde55b9a8d9e54133561c0eff3451bb933ab1d (diff) | |
download | ATCD-fdb2c99dcc82b15544bd050a22bf41f94e0c2902.tar.gz |
ChangeLogTag: Wed Feb 29 16:36:300 UTC 2012 Simon Massey <simon dot massey at prismtech dot com>
Impliment DynValue, DynValueBox and DynValueCommon types
Diffstat (limited to 'TAO')
43 files changed, 4692 insertions, 408 deletions
diff --git a/TAO/ChangeLog b/TAO/ChangeLog index 18b5c85b94b..6cb4895effd 100644 --- a/TAO/ChangeLog +++ b/TAO/ChangeLog @@ -1,3 +1,92 @@ +Wed Feb 29 16:30:00 UTC 2012 Simon Massey <simon dot massey at prismtech dot com> + + * TAO_IDL/be/be_visitor_typecode/value_typecode.cpp: + Allow VM_TRUNCATABLE to be recorded in the typecode. + + * TAO_IDL/be/be_visitor_valuetype/any_op_cs.cpp: + Stop the Any insertion of Valuetypes setting the any typecode to + the fully derived type. This was stopping the value from being + extracted (as the tc was wrong at extraction, or the embedded + Any_Impl_T<base *> class wouldn't dynamic_cast to the Any_Impl_T<derived *>. + + * tao/AnyTypeCode/Amy_Impl.cpp: + When marshaling the any, If it is holding a valueType, send the + fully derived typecode of the type being held instead of the + Any embedded typecode. This effectivly takes over from the change + to Any insertion above. (The value of the valuetype is always + sent as the fully derived type, so the typecode must match what is + actually sent.) This allows CORBA::Anys to hold a base pointer to + a derived valuetype and marshal it correctly whilst still allowing + the user to manipulate the value in the Any without locking + themselves out! + + * tao/AnyTypeCode/Any_Unknown_IDL_Type.cpp: + Add debug output to a silent Marshaling exception. + + * tao/AnyTypeCode/append.cpp: + * tao/AnyTypeCode/skip.cpp: + The code for value/event types needed to recognise ValueBox types + and behave slightly differently. + + * tao/AnyTypeCode/typecode.cpp: + Tidy up of code. + + * tao/Valuetype/ValueBase.h: + * tao/Valuetype/ValueBase.cpp: + Add quite a lot of extra debug output during error cases. + Fix some CDR alignment bugs with indirection. + Added missing _copy_value () virtual call. + Split _tao_unmarshal_pre() into two sub functions + _tao_unmarshal_header () and _tao_unmarshal_find_factory(). + Make _tao_write_repository_id () and _tao_write_special_value () + accessable (should be friends of DynValue but proved problematic + so made them public). + Move indirection Map macros from code to header for sharing with + DynValue_i.cpp + + * tao/DynaicAny/DynAny_i.h: + * tao/DynaicAny/DynAny_i.cpp: + * tao/DynaicAny/DynAnyFactory.cpp: + * tao/DynaicAny/DynArray_i.h: + * tao/DynaicAny/DynArray_i.cpp: + * tao/DynaicAny/DynEnum_i.h: + * tao/DynaicAny/DynEnum_i.cpp: + * tao/DynaicAny/DynSequence_i.h: + * tao/DynaicAny/DynSequence_i.cpp: + * tao/DynaicAny/DynStruct_i.h: + * tao/DynaicAny/DynStruct_i.cpp: + * tao/DynaicAny/DynUnion_i.h: + * tao/DynaicAny/DynUnion_i.cpp: + Modified to cater for the "Allow_Truncation" boolean and + creation methods. + + * tao/DynaicAny/DynAnyUtils_T.h: + * tao/DynaicAny/DynAnyUtils_T.cpp: + * tao/DynaicAny/DynCommon.h: + * tao/DynaicAny/DynCommon.cpp: + Modified to cater for the "Allow_Truncation" boolean and + creation methods and to add the ValueType and ValueBox + types to the list. + + * tao/DynaicAny/DynValue_i.h: + * tao/DynaicAny/DynValue_i.cpp: + * tao/DynaicAny/DynValueBox_i.h: + * tao/DynaicAny/DynValueBox_i.cpp: + * tao/DynaicAny/DynValueCommon_i.h: + * tao/DynaicAny/DynValueCommon_i.cpp: + Impliment these types. + + * tao/bin/tao_orb_tests.lst + * tests/DynValue_Test/Analyzer.h: + * tests/DynValue_Test/Analyzer.cpp: + * tests/DynValue_Test/DynValue_Test.idl: + * tests/DynValue_Test/DynValue_Test.mpc: + * tests/DynValue_Test/main.cpp: + * tests/DynValue_Test/run_test.pl: + * tests/DynValue_Test/ValueTypes_impl.h: + * tests/DynValue_Test/ValueTypes_impl.cpp: + Added test for changes above. + Wed Feb 29 12:19:53 UTC 2012 Johnny Willemsen <jwillemsen@remedy.nl> * tao/IFR_Client/IFR_Base.pidl: @@ -3,6 +3,27 @@ USER VISIBLE CHANGES BETWEEN TAO-2.0.8 and TAO-2.1.0 . Added new rle compressor and enabled ZIOP by default +. Implimented DynValue, DynValueBox and DynValueCommon and their + creation/use by TAO_DynAnyFactory:: + create_dyn_any (), create_dyn_any_from_type_code (), + create_dyn_any_without_truncation (), create_multiple_dyn_anys () + and create_multiple_anys (). + +. Correct the interaction of CORBA::ValueTypes and CORBA::Anys. + The insertion into an Any of a ValueType base pointer + used to set the Anys typecode to the fully derived valuetype. + This allowed the any to be marshaled correctly sending the + derived typecode and value over the wire. However it also + stopped the user from extracting the valuetype from the any + as the typecode for, or the actual pointer type being used for, + the extraction couldn't match the any's internal two different + types. The any's typecode is now simply set to match the base + pointer which allows for the correct insertion/extraction from + the any, whilst the marshalling code for anys containing + valuetypes now sends the fully derived typecode of the fully + derived data it is marshalling instead of the anys embedded + (possiably base valuetype) typecode. + USER VISIBLE CHANGES BETWEEN TAO-2.0.7 and TAO-2.0.8 ==================================================== diff --git a/TAO/TAO_IDL/be/be_visitor_typecode/value_typecode.cpp b/TAO/TAO_IDL/be/be_visitor_typecode/value_typecode.cpp index d36fcc3bd2a..9a53b8b79ba 100644 --- a/TAO/TAO_IDL/be/be_visitor_typecode/value_typecode.cpp +++ b/TAO/TAO_IDL/be/be_visitor_typecode/value_typecode.cpp @@ -143,10 +143,12 @@ TAO::be_visitor_value_typecode::visit_valuetype (be_valuetype * node) // ValueModifier // - // TAO doesn't support CUSTOM or TRUNCATABLE valuetypes. Go - // with VM_NONE or VM_ABSTRACT. + // TAO doesn't support CUSTOM valuetypes. Go + // with VM_TRUNCATABLE, VM_NONE or VM_ABSTRACT. os << "::CORBA::" - << (node->is_abstract () ? "VM_ABSTRACT" : "VM_NONE") << "," << be_nl; + << (node->is_abstract () ? "VM_ABSTRACT" : + (node->truncatable () ? "VM_TRUNCATABLE" : + "VM_NONE")) << "," << be_nl; // Concrete base type. AST_Type * const concrete_base = diff --git a/TAO/TAO_IDL/be/be_visitor_valuetype/any_op_cs.cpp b/TAO/TAO_IDL/be/be_visitor_valuetype/any_op_cs.cpp index 609fa5af54d..2f5510ca27b 100644 --- a/TAO/TAO_IDL/be/be_visitor_valuetype/any_op_cs.cpp +++ b/TAO/TAO_IDL/be/be_visitor_valuetype/any_op_cs.cpp @@ -1,4 +1,3 @@ - //============================================================================= /** * @file any_op_cs.cpp @@ -115,7 +114,7 @@ be_visitor_valuetype_any_op_cs::visit_valuetype (be_valuetype *node) << be_idt << be_idt_nl << "_tao_any," << be_nl << node->local_name () << "::_tao_any_destructor," << be_nl - << "(*_tao_elem)->_tao_type ()," << be_nl + << node->tc_name ()->last_component () << "," << be_nl << "*_tao_elem" << be_uidt_nl << ");" << be_uidt << be_uidt_nl << "}" << be_nl_2; @@ -167,7 +166,7 @@ be_visitor_valuetype_any_op_cs::visit_valuetype (be_valuetype *node) << be_idt << be_idt_nl << "_tao_any," << be_nl << node->name () << "::_tao_any_destructor," << be_nl - << "(*_tao_elem)->_tao_type ()," << be_nl + << node->tc_name () << "," << be_nl << "*_tao_elem" << be_uidt_nl << ");" << be_uidt << be_uidt_nl << "}" << be_nl_2; diff --git a/TAO/bin/tao_orb_tests.lst b/TAO/bin/tao_orb_tests.lst index 5204dc10f22..30a1f64d321 100644 --- a/TAO/bin/tao_orb_tests.lst +++ b/TAO/bin/tao_orb_tests.lst @@ -352,6 +352,7 @@ TAO/tests/DSI_AMH/run_test.pl: !MINIMUM !CORBA_E_COMPACT !CORBA_E_MICRO TAO/tests/DII_AMI_Forward/run_test.pl: !MINIMUM !CORBA_E_COMPACT !CORBA_E_MICRO TAO/tests/DynAny_Test/run_test.pl: !MINIMUM !CORBA_E_COMPACT !CORBA_E_MICRO TAO/tests/DynUnion_Test/run_test.pl: !MINIMUM !CORBA_E_COMPACT !CORBA_E_MICRO +TAO/tests/DynValue_Test/run_test.pl: !MINIMUM !CORBA_E_COMPACT !CORBA_E_MICRO TAO/tests/Connection_Purging/run_test.pl: !ST !ACE_FOR_TAO TAO/tests/Server_Connection_Purging/run_test.pl: !Win32 TAO/tests/LongUpcalls/run_test.pl: !MINIMUM !CORBA_E_COMPACT !CORBA_E_MICRO diff --git a/TAO/tao/AnyTypeCode/Any_Impl.cpp b/TAO/tao/AnyTypeCode/Any_Impl.cpp index 6bf1047c835..84e3e71903a 100644 --- a/TAO/tao/AnyTypeCode/Any_Impl.cpp +++ b/TAO/tao/AnyTypeCode/Any_Impl.cpp @@ -4,6 +4,7 @@ #include "tao/AnyTypeCode/Any_Impl.h" #include "tao/AnyTypeCode/TypeCode.h" #include "tao/AnyTypeCode/Marshal.h" +#include "tao/Valuetype/ValueBase.h" #include "tao/CORBA_String.h" #include "tao/SystemException.h" @@ -29,11 +30,27 @@ TAO::Any_Impl::~Any_Impl (void) CORBA::Boolean TAO::Any_Impl::marshal (TAO_OutputCDR &cdr) { - if ((cdr << this->type_) == 0) + CORBA::ValueBase * vb = 0; + if (this->to_value (vb) && vb) + { + // Since we ARE a value type, we need to + // send the ACTUAL derived typecode for + // the type we are marshaling NOT the + // typecode of the base pointer that may + // have been inserted into the any. + if (cdr << vb->_tao_type () == 0) + { + return false; + } + } + // Otherwise send the typecode of the inserted type. + else if ((cdr << this->type_) == 0) { return false; } + // Once the typecode has been marshaled send the actual + // value (this is polymorphic for valuetypes) return this->marshal_value (cdr); } diff --git a/TAO/tao/AnyTypeCode/Any_Unknown_IDL_Type.cpp b/TAO/tao/AnyTypeCode/Any_Unknown_IDL_Type.cpp index 00656c63098..f880ebde6cc 100644 --- a/TAO/tao/AnyTypeCode/Any_Unknown_IDL_Type.cpp +++ b/TAO/tao/AnyTypeCode/Any_Unknown_IDL_Type.cpp @@ -34,6 +34,13 @@ TAO::Unknown_IDL_Type::Unknown_IDL_Type (CORBA::TypeCode_ptr tc, } catch (::CORBA::Exception const &) { + if (TAO_debug_level > 0) + { + ACE_DEBUG ((LM_DEBUG, + ACE_TEXT ("TAO (%P|%t) %N:%l ") + ACE_TEXT ("silent marshaling exception ") + ACE_TEXT ("in TAO::Unknown_IDL_Type::Unknown_IDL_Type\n"))); + } } } diff --git a/TAO/tao/AnyTypeCode/TypeCode.cpp b/TAO/tao/AnyTypeCode/TypeCode.cpp index c026a815d07..8733afe0e17 100644 --- a/TAO/tao/AnyTypeCode/TypeCode.cpp +++ b/TAO/tao/AnyTypeCode/TypeCode.cpp @@ -85,11 +85,9 @@ CORBA::TypeCode::equivalent (TypeCode_ptr tc) const const_cast<CORBA::TypeCode_ptr> (this); CORBA::TypeCode_var unaliased_this = TAO::unaliased_typecode (mutable_this); - CORBA::TypeCode_var unaliased_tc = TAO::unaliased_typecode (tc); CORBA::TCKind const this_kind = unaliased_this->kind (); - CORBA::TCKind const tc_kind = unaliased_tc->kind (); if (tc_kind != this_kind) @@ -98,17 +96,12 @@ CORBA::TypeCode::equivalent (TypeCode_ptr tc) const try { char const * const this_id = unaliased_this->id (); - char const * const tc_id = unaliased_tc->id (); - if (ACE_OS::strlen (this_id) == 0 - || ACE_OS::strlen (tc_id) == 0) - { - return unaliased_this->equivalent_i (unaliased_tc.in ()); - } - else if (ACE_OS::strcmp (this_id, tc_id) != 0) + if (ACE_OS::strlen (this_id) != 0 + && ACE_OS::strlen (tc_id) != 0) { - return false; + return ACE_OS::strcmp (this_id, tc_id) == 0; } } catch (const ::CORBA::TypeCode::BadKind&) @@ -116,10 +109,9 @@ CORBA::TypeCode::equivalent (TypeCode_ptr tc) const // Some TypeCodes do not support the id() operation. Ignore the // failure, and continue equivalence verification using TypeCode // subclass-specific techniques. - return unaliased_this->equivalent_i (unaliased_tc.in ()); } - return true; + return unaliased_this->equivalent_i (unaliased_tc.in ()); } char const * diff --git a/TAO/tao/AnyTypeCode/append.cpp b/TAO/tao/AnyTypeCode/append.cpp index 8aa760c8064..7bfc19d89e1 100644 --- a/TAO/tao/AnyTypeCode/append.cpp +++ b/TAO/tao/AnyTypeCode/append.cpp @@ -1178,41 +1178,47 @@ TAO_Marshal_Value::append (CORBA::TypeCode_ptr tc, } } - // Handle our base valuetype if any. - CORBA::TypeCode_var param = - tc->concrete_base_type (); - - CORBA::TCKind const param_kind = param->kind (); - - if (param_kind != CORBA::tk_null) + CORBA::TypeCode_var param; + if (CORBA::tk_value_box == tc->kind ()) { - retval = this->append (param.in (), - src, - dest - ); - - if (retval != TAO::TRAVERSE_CONTINUE) + param = tc->content_type (); + retval = TAO_Marshal_Object::perform_append (param.in (), + src, + dest + ); + } + else // tc->kind () must be tk_value or tk_event + { + // Handle our base valuetype if any. + param = tc->concrete_base_type (); + if (CORBA::tk_null != param->kind ()) { - return retval; + retval = this->append (param.in (), + src, + dest + ); } - } - // Number of fields in the struct. - const CORBA::ULong member_count = - tc->member_count (); - - for (CORBA::ULong i = 0; - i < member_count && retval == TAO::TRAVERSE_CONTINUE; - ++i) - { - // get member type - param = tc->member_type (i); + if (retval == TAO::TRAVERSE_CONTINUE) + { + // Number of fields in the struct. + const CORBA::ULong member_count = + tc->member_count (); - retval = - TAO_Marshal_Object::perform_append (param.in (), - src, - dest - ); + for (CORBA::ULong i = 0; + i < member_count && retval == TAO::TRAVERSE_CONTINUE; + ++i) + { + // get member type + param = tc->member_type (i); + + retval = + TAO_Marshal_Object::perform_append (param.in (), + src, + dest + ); + } + } } if (retval == TAO::TRAVERSE_CONTINUE) diff --git a/TAO/tao/AnyTypeCode/skip.cpp b/TAO/tao/AnyTypeCode/skip.cpp index 0741c2e62d5..f724a6fa75a 100644 --- a/TAO/tao/AnyTypeCode/skip.cpp +++ b/TAO/tao/AnyTypeCode/skip.cpp @@ -1,4 +1,3 @@ - //============================================================================= /** * @file skip.cpp @@ -851,7 +850,6 @@ TAO::traverse_status TAO_Marshal_Value::skip (CORBA::TypeCode_ptr tc, TAO_InputCDR *stream) { TAO::traverse_status retval = TAO::TRAVERSE_CONTINUE; - CORBA::TypeCode_var param; // Use the same method to skip over our base valuetype. // To achive this we'll need to distinguish between @@ -932,32 +930,37 @@ TAO_Marshal_Value::skip (CORBA::TypeCode_ptr tc, TAO_InputCDR *stream) } - // Handle our base valuetype if any. - param = tc->concrete_base_type (); - - CORBA::TCKind const k = param->kind (); + CORBA::TypeCode_var param; - if (k != CORBA::tk_null) + if (CORBA::tk_value_box == tc->kind ()) { - retval = this->skip (param.in (), stream); - - if (retval != TAO::TRAVERSE_CONTINUE) + param = tc->content_type (); + retval = TAO_Marshal_Object::perform_skip (param.in (), stream); + } + else // tc->kind () must be tk_value or tk_event + { + // Handle our base valuetype if any. + param = tc->concrete_base_type (); + if (CORBA::tk_null != param->kind ()) { - return retval; + retval = this->skip (param.in (), stream); } - } - // Number of fields in the valuetype. - CORBA::ULong const member_count = - tc->member_count (); - - for (CORBA::ULong i = 0; - i < member_count && retval == TAO::TRAVERSE_CONTINUE; - ++i) - { - param = tc->member_type (i); + if (retval == TAO::TRAVERSE_CONTINUE) + { + // Number of fields in the valuetype. + CORBA::ULong const member_count = + tc->member_count (); - retval = TAO_Marshal_Object::perform_skip (param.in (), stream); + for (CORBA::ULong i = 0; + i < member_count && retval == TAO::TRAVERSE_CONTINUE; + ++i) + { + param = tc->member_type (i); + retval = TAO_Marshal_Object::perform_skip ( + param.in (), stream); + } + } } if (retval == TAO::TRAVERSE_CONTINUE) diff --git a/TAO/tao/DynamicAny/DynAnyFactory.cpp b/TAO/tao/DynamicAny/DynAnyFactory.cpp index 7bdbc0e9660..bd4a02e470b 100644 --- a/TAO/tao/DynamicAny/DynAnyFactory.cpp +++ b/TAO/tao/DynamicAny/DynAnyFactory.cpp @@ -36,7 +36,8 @@ TAO_DynAnyFactory::create_dyn_any (const CORBA::Any & value) return TAO::MakeDynAnyUtils::make_dyn_any_t<const CORBA::Any&> ( value._tao_get_typecode (), - value); + value, + true ); // Allow truncation } DynamicAny::DynAny_ptr @@ -47,29 +48,81 @@ TAO_DynAnyFactory::create_dyn_any_from_type_code (CORBA::TypeCode_ptr type) return TAO::MakeDynAnyUtils::make_dyn_any_t<CORBA::TypeCode_ptr> ( type, - type); + type, + true ); // Allow truncation } DynamicAny::DynAny_ptr TAO_DynAnyFactory::create_dyn_any_without_truncation ( - const CORBA::Any & /* value */) + const CORBA::Any &value) { - throw ::CORBA::NO_IMPLEMENT (); + return + TAO::MakeDynAnyUtils::make_dyn_any_t<const CORBA::Any&> ( + value._tao_get_typecode (), + value, + false ); // Do NOT allow truncation } DynamicAny::DynAnySeq * TAO_DynAnyFactory::create_multiple_dyn_anys ( - const DynamicAny::AnySeq & /* values */, - ::CORBA::Boolean /* allow_truncate */) + const DynamicAny::AnySeq &values, + ::CORBA::Boolean allow_truncate) { - throw ::CORBA::NO_IMPLEMENT (); + // NOTE: Since each any is self contained and holds a streamed + // representation of the DynAny contents, it is not possiable + // to make the collection of the anys we are creating to + // refer to the same duplicate DynValue if it crops up in + // seporate enteries of the values sequence. Internally + // within each any, indirection will occur if a DynValue + // self references with one of its own members. + + const CORBA::ULong length = values.length (); + + DynamicAny::DynAnySeq_var retseq; + ACE_NEW_THROW_EX ( + retseq.out (), + DynamicAny::DynAnySeq (length), + CORBA::NO_MEMORY ()); + retseq->length (length); + + for (CORBA::ULong i= 0u; i < length; ++i) + { + retseq[i]= + (allow_truncate ? + this->create_dyn_any (values[i]) : + this->create_dyn_any_without_truncation (values[i])); + } + + return retseq._retn (); } DynamicAny::AnySeq * TAO_DynAnyFactory::create_multiple_anys ( - const DynamicAny::DynAnySeq & /* values */) + const DynamicAny::DynAnySeq &values) { - throw ::CORBA::NO_IMPLEMENT (); + // NOTE: Since each any is self contained and holds a streamed + // representation of the DynAny contents, it is not possiable + // to make the collection of the anys we are creating to + // refer to the same duplicate DynValue if it crops up in + // seporate enteries of the values sequence. Internally + // within each any, indirection will occur if a DynValue + // self references with one of its own members. + + const CORBA::ULong length = values.length (); + + DynamicAny::AnySeq_var retseq; + ACE_NEW_THROW_EX ( + retseq.out (), + DynamicAny::AnySeq (length), + CORBA::NO_MEMORY ()); + retseq->length (length); + + for (CORBA::ULong i= 0u; i < length; ++i) + { + retseq[i]= *values[i]->to_any (); + } + + return retseq._retn (); } // Utility function called by all the DynAny classes diff --git a/TAO/tao/DynamicAny/DynAnyUtils_T.cpp b/TAO/tao/DynamicAny/DynAnyUtils_T.cpp index e06958dcec7..9034d7fbd21 100644 --- a/TAO/tao/DynamicAny/DynAnyUtils_T.cpp +++ b/TAO/tao/DynamicAny/DynAnyUtils_T.cpp @@ -23,6 +23,8 @@ #include "tao/DynamicAny/DynSequence_i.h" #include "tao/DynamicAny/DynStruct_i.h" #include "tao/DynamicAny/DynUnion_i.h" +#include "tao/DynamicAny/DynValue_i.h" +#include "tao/DynamicAny/DynValueBox_i.h" #include "tao/DynamicAny/DynAnyFactory.h" @@ -107,15 +109,59 @@ namespace TAO template<typename DA_IMPL, typename ANY_TC> DynamicAny::DynAny_ptr - CreateDynAnyUtils<DA_IMPL, ANY_TC>::create_dyn_any_t (ANY_TC any_tc) + CreateDynAnyUtils<DA_IMPL, ANY_TC>::create_dyn_any_t ( + ANY_TC any_tc, + CORBA::Boolean allow_truncation) { DA_IMPL *p = 0; ACE_NEW_THROW_EX (p, - DA_IMPL, + DA_IMPL (allow_truncation), CORBA::NO_MEMORY ()); ACE_Auto_Basic_Ptr<DA_IMPL> dp (p); - p->init (any_tc); + try + { + p->init (any_tc); + } + catch (DA_IMPL *original) + { + // Currently only TAO_DynValue_i can throw the original (duplicate + // of a previously found TAO_DynValue_i). The new BLANK one created + // above on which we called init() will be deleted automatically by + // the ACE_Auto_Basic_Ptr. + + return original; + } + + return dp.release (); + } + + template<typename DA_IMPL, typename ANY_TC> + DynamicAny::DynAny_ptr + CreateDynAnyUtils<DA_IMPL, ANY_TC>::create_dyn_any_t ( + CORBA::TypeCode_ptr tc, + ANY_TC any_tc, + CORBA::Boolean allow_truncation) + { + DA_IMPL *p = 0; + ACE_NEW_THROW_EX (p, + DA_IMPL (allow_truncation), + CORBA::NO_MEMORY ()); + + ACE_Auto_Basic_Ptr<DA_IMPL> dp (p); + try + { + p->init (tc, any_tc); + } + catch (DA_IMPL *original) + { + // Currently only TAO_DynValue_i can throw the original (duplicate + // of a previously found TAO_DynValue_i). The new BLANK one created + // above on which we called init() will be deleted automatically by + // the ACE_Auto_Basic_Ptr. + + return original; + } return dp.release (); } @@ -124,79 +170,100 @@ namespace TAO { template<typename ANY_TC> DynamicAny::DynAny_ptr - make_dyn_any_t (CORBA::TypeCode_ptr tc, ANY_TC any_tc) + make_dyn_any_t ( + CORBA::TypeCode_ptr tc, + ANY_TC any_tc, + CORBA::Boolean allow_truncation) { switch (TAO_DynAnyFactory::unalias (tc)) { - case CORBA::tk_null: - case CORBA::tk_void: - case CORBA::tk_short: - case CORBA::tk_long: - case CORBA::tk_ushort: - case CORBA::tk_ulong: - case CORBA::tk_float: - case CORBA::tk_double: - case CORBA::tk_longlong: - case CORBA::tk_ulonglong: - case CORBA::tk_longdouble: - case CORBA::tk_boolean: - case CORBA::tk_char: - case CORBA::tk_wchar: - case CORBA::tk_octet: - case CORBA::tk_any: - case CORBA::tk_TypeCode: - case CORBA::tk_objref: - case CORBA::tk_string: - case CORBA::tk_wstring: - return - CreateDynAnyUtils< - TAO_DynAny_i, - ANY_TC>::create_dyn_any_t (any_tc); - case CORBA::tk_struct: - case CORBA::tk_except: - return - CreateDynAnyUtils< - TAO_DynStruct_i, - ANY_TC>::create_dyn_any_t (any_tc); - case CORBA::tk_sequence: - if (TAO_DynCommon::is_basic_type_seq (tc)) - { - return - CreateDynAnyUtils< - TAO_DynAny_i, - ANY_TC>::create_dyn_any_t (any_tc); - } - else - { - return - CreateDynAnyUtils< - TAO_DynSequence_i, - ANY_TC>::create_dyn_any_t (any_tc); - } - case CORBA::tk_union: - return - CreateDynAnyUtils< - TAO_DynUnion_i, - ANY_TC>::create_dyn_any_t (any_tc); - case CORBA::tk_enum: - return - CreateDynAnyUtils< - TAO_DynEnum_i, - ANY_TC>::create_dyn_any_t (any_tc); - case CORBA::tk_array: - return - CreateDynAnyUtils< - TAO_DynArray_i, - ANY_TC>::create_dyn_any_t (any_tc); - case CORBA::tk_fixed: + case CORBA::tk_null: + case CORBA::tk_void: + case CORBA::tk_short: + case CORBA::tk_long: + case CORBA::tk_ushort: + case CORBA::tk_ulong: + case CORBA::tk_float: + case CORBA::tk_double: + case CORBA::tk_longlong: + case CORBA::tk_ulonglong: + case CORBA::tk_longdouble: + case CORBA::tk_boolean: + case CORBA::tk_char: + case CORBA::tk_wchar: + case CORBA::tk_octet: + case CORBA::tk_any: + case CORBA::tk_TypeCode: + case CORBA::tk_objref: + case CORBA::tk_string: + case CORBA::tk_wstring: + return + CreateDynAnyUtils< + TAO_DynAny_i, + ANY_TC>::create_dyn_any_t (any_tc, allow_truncation); + + case CORBA::tk_struct: + case CORBA::tk_except: + return + CreateDynAnyUtils< + TAO_DynStruct_i, + ANY_TC>::create_dyn_any_t (any_tc, allow_truncation); + + case CORBA::tk_sequence: + if (TAO_DynCommon::is_basic_type_seq (tc)) + { + return + CreateDynAnyUtils< + TAO_DynAny_i, + ANY_TC>::create_dyn_any_t (any_tc, allow_truncation); + } + else + { + return + CreateDynAnyUtils< + TAO_DynSequence_i, + ANY_TC>::create_dyn_any_t (any_tc, allow_truncation); + } + + case CORBA::tk_union: + return + CreateDynAnyUtils< + TAO_DynUnion_i, + ANY_TC>::create_dyn_any_t (any_tc, allow_truncation); + + case CORBA::tk_enum: + return + CreateDynAnyUtils< + TAO_DynEnum_i, + ANY_TC>::create_dyn_any_t (any_tc, allow_truncation); + + case CORBA::tk_array: + return + CreateDynAnyUtils< + TAO_DynArray_i, + ANY_TC>::create_dyn_any_t (any_tc, allow_truncation); + case CORBA::tk_value: + return + CreateDynAnyUtils< + TAO_DynValue_i, + ANY_TC>::create_dyn_any_t (any_tc, allow_truncation); + case CORBA::tk_value_box: + return + CreateDynAnyUtils< + TAO_DynValueBox_i, + ANY_TC>::create_dyn_any_t (any_tc, allow_truncation); + + case CORBA::tk_fixed: case CORBA::tk_abstract_interface: case CORBA::tk_component: case CORBA::tk_home: throw ::CORBA::NO_IMPLEMENT (); + case CORBA::tk_native: throw DynamicAny::DynAnyFactory::InconsistentTypeCode (); + default: break; } diff --git a/TAO/tao/DynamicAny/DynAnyUtils_T.h b/TAO/tao/DynamicAny/DynAnyUtils_T.h index 4eef1f6d36b..6a1966dc9e5 100644 --- a/TAO/tao/DynamicAny/DynAnyUtils_T.h +++ b/TAO/tao/DynamicAny/DynAnyUtils_T.h @@ -56,21 +56,32 @@ namespace TAO }; // Used by MakeDynAnyUtils below, parameterized on the type of - // impl class and on {Any | TypeCode}. + // impl class and on {Any | TypeCode | inputCDR}. template<typename DA_IMPL, typename ANY_TC> struct CreateDynAnyUtils { static DynamicAny::DynAny_ptr - create_dyn_any_t (ANY_TC any_tc); + create_dyn_any_t ( + ANY_TC any_tc, + CORBA::Boolean allow_truncation= true); + + static DynamicAny::DynAny_ptr + create_dyn_any_t ( + CORBA::TypeCode_ptr tc, + ANY_TC any_tc, + CORBA::Boolean allow_truncation= true); }; // Code common to DynAnyFactory create_* calls, parameterized on - // {Any | TypeCode}. + // {Any | TypeCode | inputCDR}. namespace MakeDynAnyUtils { template<typename ANY_TC> DynamicAny::DynAny_ptr - make_dyn_any_t (CORBA::TypeCode_ptr tc, ANY_TC any_tc); + make_dyn_any_t ( + CORBA::TypeCode_ptr tc, + ANY_TC any_tc, + CORBA::Boolean allow_truncation= true); } } diff --git a/TAO/tao/DynamicAny/DynAny_i.cpp b/TAO/tao/DynamicAny/DynAny_i.cpp index 06f33e73a24..66045521d96 100644 --- a/TAO/tao/DynamicAny/DynAny_i.cpp +++ b/TAO/tao/DynamicAny/DynAny_i.cpp @@ -17,7 +17,8 @@ TAO_BEGIN_VERSIONED_NAMESPACE_DECL -TAO_DynAny_i::TAO_DynAny_i (void) +TAO_DynAny_i::TAO_DynAny_i (CORBA::Boolean allow_truncation) + : TAO_DynCommon (allow_truncation) { } @@ -381,12 +382,14 @@ TAO_DynAny_i::equal (DynamicAny::DynAny_ptr rhs) DynamicAny::DynAny_var rhs_dyn = TAO::MakeDynAnyUtils::make_dyn_any_t<const CORBA::Any&> ( rhs_v->_tao_get_typecode (), - *rhs_v); + *rhs_v, + this->allow_truncation_ ); DynamicAny::DynAny_var lhs_dyn = TAO::MakeDynAnyUtils::make_dyn_any_t<const CORBA::Any&> ( lhs_v->_tao_get_typecode (), - *lhs_v); + *lhs_v, + this->allow_truncation_ ); CORBA::Boolean const b = rhs_dyn->equal (lhs_dyn.in ()); diff --git a/TAO/tao/DynamicAny/DynAny_i.h b/TAO/tao/DynamicAny/DynAny_i.h index cda8f29c50a..d5a422d2339 100644 --- a/TAO/tao/DynamicAny/DynAny_i.h +++ b/TAO/tao/DynamicAny/DynAny_i.h @@ -45,7 +45,7 @@ class TAO_DynamicAny_Export TAO_DynAny_i { public: /// Constructor. - TAO_DynAny_i (void); + TAO_DynAny_i (CORBA::Boolean allow_truncation=true); /// Destructor. ~TAO_DynAny_i (void); diff --git a/TAO/tao/DynamicAny/DynArray_i.cpp b/TAO/tao/DynamicAny/DynArray_i.cpp index 70abecc88e9..2e060b4614d 100644 --- a/TAO/tao/DynamicAny/DynArray_i.cpp +++ b/TAO/tao/DynamicAny/DynArray_i.cpp @@ -13,7 +13,8 @@ TAO_BEGIN_VERSIONED_NAMESPACE_DECL -TAO_DynArray_i::TAO_DynArray_i (void) +TAO_DynArray_i::TAO_DynArray_i (CORBA::Boolean allow_truncation) + : TAO_DynCommon (allow_truncation) { } @@ -91,7 +92,8 @@ TAO_DynArray_i::init (const CORBA::Any & any) this->da_members_[i] = TAO::MakeDynAnyUtils::make_dyn_any_t<const CORBA::Any&> ( field_any._tao_get_typecode (), - field_any); + field_any, + this->allow_truncation_ ); // Move to the next field in the CDR stream. (void) TAO_Marshal_Object::perform_skip (field_tc.in (), &cdr); @@ -125,7 +127,8 @@ TAO_DynArray_i::init (CORBA::TypeCode_ptr tc) this->da_members_[i] = TAO::MakeDynAnyUtils::make_dyn_any_t<CORBA::TypeCode_ptr> ( elemtype.in (), - elemtype.in ()); + elemtype.in (), + this->allow_truncation_ ); } } @@ -243,7 +246,8 @@ TAO_DynArray_i::set_elements (const DynamicAny::AnySeq & value) this->da_members_[i] = TAO::MakeDynAnyUtils::make_dyn_any_t<const CORBA::Any&> ( value[i]._tao_get_typecode (), - value[i]); + value[i], + this->allow_truncation_ ); } else { @@ -383,7 +387,8 @@ TAO_DynArray_i::from_any (const CORBA::Any& any) this->da_members_[i] = TAO::MakeDynAnyUtils::make_dyn_any_t<const CORBA::Any&> ( field_any._tao_get_typecode (), - field_any); + field_any, + this->allow_truncation_ ); // Move to the next field in the CDR stream. (void) TAO_Marshal_Object::perform_skip (field_tc.in (), &cdr); diff --git a/TAO/tao/DynamicAny/DynArray_i.h b/TAO/tao/DynamicAny/DynArray_i.h index fbaf71a7a5c..f03f5cfcb8e 100644 --- a/TAO/tao/DynamicAny/DynArray_i.h +++ b/TAO/tao/DynamicAny/DynArray_i.h @@ -46,7 +46,7 @@ class TAO_DynamicAny_Export TAO_DynArray_i { public: /// Constructor. - TAO_DynArray_i (void); + TAO_DynArray_i (CORBA::Boolean allow_truncation=true); /// Destructor. ~TAO_DynArray_i (void); diff --git a/TAO/tao/DynamicAny/DynCommon.cpp b/TAO/tao/DynamicAny/DynCommon.cpp index 60eab3cb278..3438fc983f6 100644 --- a/TAO/tao/DynamicAny/DynCommon.cpp +++ b/TAO/tao/DynamicAny/DynCommon.cpp @@ -25,7 +25,8 @@ TAO_BEGIN_VERSIONED_NAMESPACE_DECL -TAO_DynCommon::TAO_DynCommon (void) +TAO_DynCommon::TAO_DynCommon (CORBA::Boolean allow_truncation) + : allow_truncation_ (allow_truncation) { } @@ -334,7 +335,7 @@ TAO_DynCommon::insert_val (CORBA::ValueBase *value) if (this->has_components_) { DynamicAny::DynAny_var cc = - this->check_component (); + this->check_component (true); cc->insert_val (value); } @@ -668,7 +669,8 @@ TAO_DynCommon::get_dyn_any (void) return TAO::MakeDynAnyUtils::make_dyn_any_t<const CORBA::Any&> ( any.in ()._tao_get_typecode (), - any.in ()); + any.in (), + this->allow_truncation_ ); } CORBA::ValueBase * @@ -682,7 +684,7 @@ TAO_DynCommon::get_val (void) if (this->has_components_) { DynamicAny::DynAny_var cc = - this->check_component (); + this->check_component (true); return cc->get_val (); } @@ -800,7 +802,8 @@ TAO_DynCommon::copy (void) DynamicAny::DynAny_ptr retval = TAO::MakeDynAnyUtils::make_dyn_any_t<const CORBA::Any&> ( any.in ()._tao_get_typecode (), - any.in ()); + any.in (), + this->allow_truncation_ ); return retval; } @@ -1168,9 +1171,15 @@ TAO_DynCommon::set_flag (DynamicAny::DynAny_ptr component, TAO::DynAnyFlagUtils<TAO_DynUnion_i>::set_flag_t (component, destroying); break; - case CORBA::tk_fixed: case CORBA::tk_value: + TAO::DynAnyFlagUtils<TAO_DynValue_i>::set_flag_t (component, + destroying); + break; case CORBA::tk_value_box: + TAO::DynAnyFlagUtils<TAO_DynValueBox_i>::set_flag_t (component, + destroying); + break; + case CORBA::tk_fixed: throw ::CORBA::NO_IMPLEMENT (); default: TAO::DynAnyFlagUtils<TAO_DynAny_i>::set_flag_t (component, @@ -1180,7 +1189,7 @@ TAO_DynCommon::set_flag (DynamicAny::DynAny_ptr component, } DynamicAny::DynAny_ptr -TAO_DynCommon::check_component (void) +TAO_DynCommon::check_component (CORBA::Boolean isValueType) { if (this->current_position_ == -1) { @@ -1192,31 +1201,37 @@ TAO_DynCommon::check_component (void) CORBA::TypeCode_var tc = cc->type (); - CORBA::TCKind kind = TAO_DynAnyFactory::unalias (tc.in ()); - // We are here because we are a component that is the target of // an insert_*() call on our container. It is // illegal to insert anything into a component that itself has // components. - switch (kind) - { + switch (TAO_DynAnyFactory::unalias (tc.in ())) + { case CORBA::tk_array: case CORBA::tk_except: case CORBA::tk_struct: case CORBA::tk_union: throw DynamicAny::DynAny::TypeMismatch (); - case CORBA::tk_sequence: - if (TAO_DynCommon::is_basic_type_seq (tc.in ())) + + case CORBA::tk_value: + if (!isValueType) { - return cc._retn (); + throw DynamicAny::DynAny::TypeMismatch (); } - else + break; + + case CORBA::tk_sequence: + if (!TAO_DynCommon::is_basic_type_seq (tc.in ())) { throw DynamicAny::DynAny::TypeMismatch (); } + break; + default: - return cc._retn (); - } + break; + } + + return cc._retn (); } void diff --git a/TAO/tao/DynamicAny/DynCommon.h b/TAO/tao/DynamicAny/DynCommon.h index c62d2f71328..8275462a520 100644 --- a/TAO/tao/DynamicAny/DynCommon.h +++ b/TAO/tao/DynamicAny/DynCommon.h @@ -34,7 +34,7 @@ class TAO_DynamicAny_Export TAO_DynCommon { public: /// Constructor. - TAO_DynCommon (void); + TAO_DynCommon (CORBA::Boolean allow_truncation); /// Destructor. virtual ~TAO_DynCommon (void); @@ -202,7 +202,7 @@ public: // Utility functions. - DynamicAny::DynAny_ptr check_component (void); + DynamicAny::DynAny_ptr check_component (CORBA::Boolean isValueType = false); void check_type (CORBA::TypeCode_ptr tc); @@ -245,6 +245,9 @@ protected: /// and get_*, defined in this base class. CORBA::Any any_; + /// Are we allowed to truncate any valuetypes in our hyarchy? + CORBA::Boolean allow_truncation_; + private: // Utility functions used by insert_* and get_*. diff --git a/TAO/tao/DynamicAny/DynEnum_i.cpp b/TAO/tao/DynamicAny/DynEnum_i.cpp index 1325a5a3053..76298dc8e53 100644 --- a/TAO/tao/DynamicAny/DynEnum_i.cpp +++ b/TAO/tao/DynamicAny/DynEnum_i.cpp @@ -12,7 +12,8 @@ TAO_BEGIN_VERSIONED_NAMESPACE_DECL -TAO_DynEnum_i::TAO_DynEnum_i (void) +TAO_DynEnum_i::TAO_DynEnum_i (CORBA::Boolean allow_truncation) + : TAO_DynCommon (allow_truncation) { } diff --git a/TAO/tao/DynamicAny/DynEnum_i.h b/TAO/tao/DynamicAny/DynEnum_i.h index c2734f02c09..abc638cfd42 100644 --- a/TAO/tao/DynamicAny/DynEnum_i.h +++ b/TAO/tao/DynamicAny/DynEnum_i.h @@ -46,7 +46,7 @@ class TAO_DynamicAny_Export TAO_DynEnum_i { public: /// Constructor. - TAO_DynEnum_i (void); + TAO_DynEnum_i (CORBA::Boolean allow_truncation=true); /// Destructor. ~TAO_DynEnum_i (void); diff --git a/TAO/tao/DynamicAny/DynSequence_i.cpp b/TAO/tao/DynamicAny/DynSequence_i.cpp index 6ef16221c4f..9383ae59ac0 100644 --- a/TAO/tao/DynamicAny/DynSequence_i.cpp +++ b/TAO/tao/DynamicAny/DynSequence_i.cpp @@ -13,7 +13,8 @@ TAO_BEGIN_VERSIONED_NAMESPACE_DECL -TAO_DynSequence_i::TAO_DynSequence_i (void) +TAO_DynSequence_i::TAO_DynSequence_i (CORBA::Boolean allow_truncation) + : TAO_DynCommon (allow_truncation) { } @@ -95,7 +96,9 @@ TAO_DynSequence_i::init (const CORBA::Any& any) // based on the type of field_any. this->da_members_[i] = TAO::MakeDynAnyUtils::make_dyn_any_t<const CORBA::Any&> ( - field_any._tao_get_typecode (), field_any); + field_any._tao_get_typecode (), + field_any, + this->allow_truncation_ ); // Move to the next field in the CDR stream. (void) TAO_Marshal_Object::perform_skip (field_tc.in (), &cdr); @@ -226,7 +229,8 @@ TAO_DynSequence_i::set_length (CORBA::ULong length) this->da_members_[i] = TAO::MakeDynAnyUtils::make_dyn_any_t<CORBA::TypeCode_ptr> ( elemtype.in (), - elemtype.in ()); + elemtype.in (), + this->allow_truncation_ ); } } else if (length < this->component_count_) @@ -332,7 +336,8 @@ TAO_DynSequence_i::set_elements (const DynamicAny::AnySeq & value) this->da_members_[i] = TAO::MakeDynAnyUtils::make_dyn_any_t<const CORBA::Any&> ( value[i]._tao_get_typecode (), - value[i]); + value[i], + this->allow_truncation_ ); } else { @@ -528,7 +533,8 @@ TAO_DynSequence_i::from_any (const CORBA::Any & any) this->da_members_[i] = TAO::MakeDynAnyUtils::make_dyn_any_t<const CORBA::Any&> ( field_any._tao_get_typecode (), - field_any); + field_any, + this->allow_truncation_ ); // Move to the next field in the CDR stream. (void) TAO_Marshal_Object::perform_skip (field_tc.in (), &cdr); diff --git a/TAO/tao/DynamicAny/DynSequence_i.h b/TAO/tao/DynamicAny/DynSequence_i.h index 4089347a8ef..c914c8618e7 100644 --- a/TAO/tao/DynamicAny/DynSequence_i.h +++ b/TAO/tao/DynamicAny/DynSequence_i.h @@ -46,7 +46,7 @@ class TAO_DynamicAny_Export TAO_DynSequence_i { public: /// Constructor. - TAO_DynSequence_i (void); + TAO_DynSequence_i (CORBA::Boolean allow_truncation=true); /// Destructor. ~TAO_DynSequence_i (void); diff --git a/TAO/tao/DynamicAny/DynStruct_i.cpp b/TAO/tao/DynamicAny/DynStruct_i.cpp index 4a01641c93b..cd8b8daa053 100644 --- a/TAO/tao/DynamicAny/DynStruct_i.cpp +++ b/TAO/tao/DynamicAny/DynStruct_i.cpp @@ -13,7 +13,8 @@ TAO_BEGIN_VERSIONED_NAMESPACE_DECL -TAO_DynStruct_i::TAO_DynStruct_i (void) +TAO_DynStruct_i::TAO_DynStruct_i (CORBA::Boolean allow_truncation) + : TAO_DynCommon (allow_truncation) { } @@ -122,7 +123,8 @@ TAO_DynStruct_i::set_from_any (const CORBA::Any & any) this->da_members_[i] = TAO::MakeDynAnyUtils::make_dyn_any_t<const CORBA::Any&> ( field_any._tao_get_typecode (), - field_any); + field_any, + this->allow_truncation_); // Move to the next field in the CDR stream. (void) TAO_Marshal_Object::perform_skip (field_tc.in (), &in); @@ -158,7 +160,8 @@ TAO_DynStruct_i::init (CORBA::TypeCode_ptr tc) this->da_members_[i] = TAO::MakeDynAnyUtils::make_dyn_any_t<CORBA::TypeCode_ptr> ( mtype.in (), - mtype.in ()); + mtype.in (), + this->allow_truncation_); } } @@ -326,7 +329,8 @@ TAO_DynStruct_i::set_members (const DynamicAny::NameValuePairSeq & values) this->da_members_[i] = TAO::MakeDynAnyUtils::make_dyn_any_t<const CORBA::Any&> ( values[i].value._tao_get_typecode (), - values[i].value); + values[i].value, + this->allow_truncation_); } this->current_position_ = length ? 0 : -1; @@ -492,7 +496,8 @@ TAO_DynStruct_i::from_any (const CORBA::Any & any) this->da_members_[i] = TAO::MakeDynAnyUtils::make_dyn_any_t<const CORBA::Any&> ( field_any._tao_get_typecode (), - field_any); + field_any, + this->allow_truncation_); // Move to the next field in the CDR stream. (void) TAO_Marshal_Object::perform_skip (field_tc.in (), &in); diff --git a/TAO/tao/DynamicAny/DynStruct_i.h b/TAO/tao/DynamicAny/DynStruct_i.h index 4c459fb7cdc..19b98abc906 100644 --- a/TAO/tao/DynamicAny/DynStruct_i.h +++ b/TAO/tao/DynamicAny/DynStruct_i.h @@ -46,7 +46,7 @@ class TAO_DynamicAny_Export TAO_DynStruct_i { public: /// Constructor. - TAO_DynStruct_i (void); + TAO_DynStruct_i (CORBA::Boolean allow_truncation=true); /// Destructor. ~TAO_DynStruct_i (void); diff --git a/TAO/tao/DynamicAny/DynUnion_i.cpp b/TAO/tao/DynamicAny/DynUnion_i.cpp index 99f50c6bf52..b19832b4ceb 100644 --- a/TAO/tao/DynamicAny/DynUnion_i.cpp +++ b/TAO/tao/DynamicAny/DynUnion_i.cpp @@ -14,7 +14,8 @@ TAO_BEGIN_VERSIONED_NAMESPACE_DECL -TAO_DynUnion_i::TAO_DynUnion_i (void) +TAO_DynUnion_i::TAO_DynUnion_i (CORBA::Boolean allow_truncation) + : TAO_DynCommon (allow_truncation) { } @@ -91,7 +92,8 @@ TAO_DynUnion_i::init (CORBA::TypeCode_ptr tc) this->discriminator_ = TAO::MakeDynAnyUtils::make_dyn_any_t<CORBA::TypeCode_ptr> ( disc_tc.in (), - disc_tc.in ()); + disc_tc.in (), + this->allow_truncation_ ); CORBA::ULong label_val; first_label >>= label_val; TAO_DynEnum_i::_narrow (this->discriminator_.in ()) @@ -102,7 +104,8 @@ TAO_DynUnion_i::init (CORBA::TypeCode_ptr tc) this->discriminator_ = TAO::MakeDynAnyUtils::make_dyn_any_t<const CORBA::Any&> ( first_label.in ()._tao_get_typecode (), - first_label.in ()); + first_label.in (), + this->allow_truncation_ ); } CORBA::TypeCode_var first_type = @@ -113,7 +116,8 @@ TAO_DynUnion_i::init (CORBA::TypeCode_ptr tc) this->member_ = TAO::MakeDynAnyUtils::make_dyn_any_t<CORBA::TypeCode_ptr> ( first_type.in (), - first_type.in ()); + first_type.in (), + this->allow_truncation_ ); } // **************************************************************** @@ -185,7 +189,8 @@ TAO_DynUnion_i::set_from_any (const CORBA::Any & any) this->discriminator_ = TAO::MakeDynAnyUtils::make_dyn_any_t<const CORBA::Any&> ( disc_any._tao_get_typecode (), - disc_any); + disc_any, + this->allow_truncation_ ); // Move to the next field in the CDR stream. (void) TAO_Marshal_Object::perform_skip (disc_tc.in (), &in); @@ -231,7 +236,8 @@ TAO_DynUnion_i::set_from_any (const CORBA::Any & any) this->member_ = TAO::MakeDynAnyUtils::make_dyn_any_t<const CORBA::Any&> ( member_any._tao_get_typecode (), - member_any); + member_any, + this->allow_truncation_ ); this->member_slot_ = i; } @@ -269,7 +275,8 @@ TAO_DynUnion_i::set_from_any (const CORBA::Any & any) this->member_ = TAO::MakeDynAnyUtils::make_dyn_any_t<const CORBA::Any&> ( default_any._tao_get_typecode (), - default_any); + default_any, + this->allow_truncation_ ); this->member_slot_ = index; } @@ -376,7 +383,8 @@ TAO_DynUnion_i::set_discriminator (DynamicAny::DynAny_ptr value) this->member_ = TAO::MakeDynAnyUtils::make_dyn_any_t<CORBA::TypeCode_ptr> ( member_tc.in (), - member_tc.in ()); + member_tc.in (), + this->allow_truncation_ ); // Named active member (CORBA 2.3.1). this->current_position_ = 1; @@ -451,7 +459,8 @@ TAO_DynUnion_i::set_to_default_member (void) this->member_ = TAO::MakeDynAnyUtils::make_dyn_any_t<CORBA::TypeCode_ptr> ( default_tc.in (), - default_tc.in ()); + default_tc.in (), + this->allow_truncation_ ); // Default member active (CORBA 2.3.1). this->current_position_ = 0; diff --git a/TAO/tao/DynamicAny/DynUnion_i.h b/TAO/tao/DynamicAny/DynUnion_i.h index b24eb486ebb..ec4ae72c54f 100644 --- a/TAO/tao/DynamicAny/DynUnion_i.h +++ b/TAO/tao/DynamicAny/DynUnion_i.h @@ -45,7 +45,7 @@ class TAO_DynamicAny_Export TAO_DynUnion_i { public: /// Constructor. - TAO_DynUnion_i (void); + TAO_DynUnion_i (CORBA::Boolean allow_truncation=true); /// Destructor. ~TAO_DynUnion_i (void); diff --git a/TAO/tao/DynamicAny/DynValueBox_i.cpp b/TAO/tao/DynamicAny/DynValueBox_i.cpp index de4dce9bf8c..1b0346c708a 100644 --- a/TAO/tao/DynamicAny/DynValueBox_i.cpp +++ b/TAO/tao/DynamicAny/DynValueBox_i.cpp @@ -2,10 +2,21 @@ // $Id$ #include "tao/DynamicAny/DynValueBox_i.h" +#include "tao/DynamicAny/DynAnyFactory.h" +#include "tao/DynamicAny/DynAnyUtils_T.h" + +#include "tao/AnyTypeCode/Marshal.h" +#include "tao/AnyTypeCode/Any_Unknown_IDL_Type.h" +#include "tao/AnyTypeCode/AnyTypeCode_methods.h" + +#include "tao/CDR.h" TAO_BEGIN_VERSIONED_NAMESPACE_DECL -TAO_DynValueBox_i::TAO_DynValueBox_i (void) +TAO_DynValueBox_i::TAO_DynValueBox_i (CORBA::Boolean allow_truncation) + : TAO_DynCommon (allow_truncation) + , TAO_DynAny_i(allow_truncation) + , TAO_DynValueCommon_i (allow_truncation) { } @@ -13,29 +24,377 @@ TAO_DynValueBox_i::~TAO_DynValueBox_i (void) { } +void +TAO_DynValueBox_i::set_to_value (void) +{ + if (CORBA::is_nil (this->boxed_.in ())) + { + set_to_null (); + } + else + { + this->is_null_ = false; + this->component_count_ = 1u; + this->current_position_ = 0; + } +} + +void +TAO_DynValueBox_i::check_typecode (CORBA::TypeCode_ptr tc) +{ + CORBA::TCKind kind = TAO_DynAnyFactory::unalias (tc); + if (kind == CORBA::tk_value_box) + { + return; + } + + throw DynamicAny::DynAnyFactory::InconsistentTypeCode (); +} + +void +TAO_DynValueBox_i::init (CORBA::TypeCode_ptr tc) +{ + this->check_typecode (tc); + this->type_ = CORBA::TypeCode::_duplicate (tc); + + // member_type() does not work with aliased type codes. + CORBA::TypeCode_var unaliased_tc = + TAO_DynAnyFactory::strip_alias (this->type_.in ()); + CORBA::TypeCode_var + mtype (unaliased_tc->content_type ()); + this->boxed_ = + TAO::MakeDynAnyUtils::make_dyn_any_t<CORBA::TypeCode_ptr> + (mtype.in (), mtype.in (), this->allow_truncation_); + + this->init_common (); + this->set_to_null (); + +} + +void +TAO_DynValueBox_i::init (const CORBA::Any & any) +{ + CORBA::TypeCode_ptr tc = any._tao_get_typecode (); + this->check_typecode (tc); + this->type_ = CORBA::TypeCode::_duplicate (tc); + this->set_from_any (any); +} + +TAO_DynValueBox_i * +TAO_DynValueBox_i::_narrow (CORBA::Object_ptr _tao_objref) +{ + return (CORBA::is_nil (_tao_objref)) ? + 0 : + dynamic_cast<TAO_DynValueBox_i *> (_tao_objref); +} + CORBA::Any * TAO_DynValueBox_i::get_boxed_value (void) { - throw ::CORBA::NO_IMPLEMENT (); + if (this->destroyed_) + { + throw ::CORBA::OBJECT_NOT_EXIST (); + } + + if (CORBA::is_nil (this->boxed_.in ())) + { + throw DynamicAny::DynAny::InvalidValue (); + } + + return this->boxed_->to_any (); } void -TAO_DynValueBox_i::set_boxed_value (const CORBA::Any & /* boxed */) +TAO_DynValueBox_i::set_boxed_value (const CORBA::Any & boxed) { - throw ::CORBA::NO_IMPLEMENT (); + if (this->destroyed_) + { + throw ::CORBA::OBJECT_NOT_EXIST (); + } + + // content_type() does not work with aliased type codes. + CORBA::TypeCode_var unaliased_tc = + TAO_DynAnyFactory::strip_alias (this->type_.in ()); + CORBA::TypeCode_var my_tc = unaliased_tc->content_type (); + CORBA::TypeCode_var value_tc = boxed._tao_get_typecode (); + if (!my_tc->equivalent (value_tc.in ())) + { + throw DynamicAny::DynAny::TypeMismatch (); + } + + this->boxed_ = + TAO::MakeDynAnyUtils::make_dyn_any_t<const CORBA::Any&> + (boxed._tao_get_typecode (), boxed, this->allow_truncation_); + this->set_to_value (); } DynamicAny::DynAny_ptr TAO_DynValueBox_i::get_boxed_value_as_dyn_any (void) { - throw ::CORBA::NO_IMPLEMENT (); + if (this->destroyed_) + { + throw ::CORBA::OBJECT_NOT_EXIST (); + } + + if (CORBA::is_nil (this->boxed_.in ())) + { + throw DynamicAny::DynAny::InvalidValue (); + } + + // A deep copy is made only by copy() (CORBA 2.4.2 section 9.2.3.6). + // Set the flag so the caller can't destroy. + this->set_flag (this->boxed_.in (), 0); + + return DynamicAny::DynAny::_duplicate (this->boxed_.in ()); +} + +void +TAO_DynValueBox_i::set_boxed_value_as_dyn_any (DynamicAny::DynAny_ptr boxed ) +{ + if (this->destroyed_) + { + throw ::CORBA::OBJECT_NOT_EXIST (); + } + + // content_type() does not work with aliased type codes. + CORBA::TypeCode_var unaliased_tc = + TAO_DynAnyFactory::strip_alias (this->type_.in ()); + CORBA::TypeCode_var my_tc = unaliased_tc->content_type (); + CORBA::TypeCode_var value_tc = boxed->type (); + if (!my_tc->equivalent (value_tc.in ())) + { + throw DynamicAny::DynAny::TypeMismatch (); + } + this->boxed_ = boxed->copy (); + this->set_to_value (); } void -TAO_DynValueBox_i::set_boxed_value_as_dyn_any (DynamicAny::DynAny_ptr /* boxed */) +TAO_DynValueBox_i::from_any (const CORBA::Any & any) { - throw ::CORBA::NO_IMPLEMENT (); + if (this->destroyed_) + { + throw ::CORBA::OBJECT_NOT_EXIST (); + } + + CORBA::TypeCode_var tc = any.type (); + if (!this->type_->equivalent (tc.in ())) + { + throw DynamicAny::DynAny::TypeMismatch (); + } + + this->set_from_any (any); } -TAO_END_VERSIONED_NAMESPACE_DECL +CORBA::Boolean +TAO_DynValueBox_i::equal (DynamicAny::DynAny_ptr rhs) +{ + if (this->destroyed_) + { + throw ::CORBA::OBJECT_NOT_EXIST (); + } + + CORBA::TypeCode_var tc = rhs->type (); + if (!tc->equivalent (this->type_.in ())) + { + return false; + } + + DynamicAny::DynValueBox_ptr rhs_v= + dynamic_cast<DynamicAny::DynValueBox_ptr> (rhs); + if (this->is_null () != rhs_v->is_null ()) + { + return false; + } + + if (!this->is_null ()) + { + DynamicAny::DynAny_var + tmp (rhs->current_component ()); + return tmp->equal (this->boxed_.in ()); + } + + return true; +} + +void +TAO_DynValueBox_i::destroy (void) +{ + if (this->destroyed_) + { + throw ::CORBA::OBJECT_NOT_EXIST (); + } + + if (!this->ref_to_component_ || this->container_is_destroying_) + { + // Do a deep destroy. + if (!CORBA::is_nil (this->boxed_.in ())) + { + this->set_flag (this->boxed_.in (), 1); + this->boxed_.in ()->destroy (); + } + + this->destroyed_ = 1; + } +} + +DynamicAny::DynAny_ptr +TAO_DynValueBox_i::current_component (void) +{ + if (this->destroyed_) + { + throw ::CORBA::OBJECT_NOT_EXIST (); + } + + // Is this an NULL ValueBoxtype? + if (this->is_null_) + { + return DynamicAny::DynAny::_nil (); + } + + this->set_flag (this->boxed_.in (), 0); + return DynamicAny::DynAny::_duplicate (this->boxed_.in ()); +} + +// This code is common to from_any() and the init() overload that takes +// an Any argument. +void +TAO_DynValueBox_i::set_from_any (const CORBA::Any & any) +{ + // Get the CDR stream of the Any, if there isn't one, make one. + TAO_OutputCDR out; + TAO_InputCDR in (static_cast<ACE_Message_Block *> (0)); + TAO::Any_Impl *impl = any.impl (); + if (impl->encoded ()) + { + TAO::Unknown_IDL_Type *unk = + dynamic_cast<TAO::Unknown_IDL_Type *> (impl); + if (!unk) + throw CORBA::INTERNAL (); + + in = unk->_tao_get_cdr (); + } + else + { + impl->marshal_value (out); + TAO_InputCDR tmp_in (out); + in = tmp_in; + } + + while (true) + { + TAO_InputCDR indrected_strm ((size_t) 0); + CORBA::Boolean is_indirected= false; + CORBA::Boolean is_null_object= false; + + // Read in the ValueBox header (to skip over it) and check + // for the null type. + if (!CORBA::ValueBase::_tao_validate_box_type ( + in, + indrected_strm, + this->type_.in ()->id (), + is_null_object, + is_indirected) || + is_null_object) + { + this->set_to_null (); + return; + } + + if (!is_indirected) + { + break; + } + + in = indrected_strm; + } + + // content_type() does not work with aliased type codes. + CORBA::TypeCode_var unaliased_tc = + TAO_DynAnyFactory::strip_alias (this->type_.in ()); + CORBA::TypeCode_var boxed_tc (unaliased_tc->content_type ()); + TAO::Unknown_IDL_Type * unk = 0; + ACE_NEW_THROW_EX (unk, + TAO::Unknown_IDL_Type (boxed_tc.in (), in), + CORBA::NO_MEMORY ()); + CORBA::Any boxed_any; + boxed_any.replace (unk); + this->boxed_ = + TAO::MakeDynAnyUtils::make_dyn_any_t<const CORBA::Any&> + (boxed_any._tao_get_typecode (), boxed_any, this->allow_truncation_); + this->init_common (); +} + +CORBA::Any_ptr +TAO_DynValueBox_i::to_any (void) +{ + if (this->destroyed_) + { + throw ::CORBA::OBJECT_NOT_EXIST (); + } + TAO_OutputCDR out_cdr; + + // Is this an NULL Valuetype? + if (!CORBA::ValueBase::_tao_write_special_value ( + out_cdr, reinterpret_cast <CORBA::ValueBase *> ( + this->is_null_ ? 0 : this ) )) + { + // Build <value-tag>, which states if chunking is used + // and if type information ((list of) repository id(s)) + // is provided. + CORBA::Long valuetag = + TAO_OBV_GIOP_Flags::Value_tag_base | + TAO_OBV_GIOP_Flags::Type_info_single; + + ACE_CString type_id (this->type_->id ()); + + // Write <value-tag> & Marshal type information. + if (!out_cdr.write_long (valuetag) || + !CORBA::ValueBase::_tao_write_repository_id (out_cdr, type_id)) + { + throw CORBA::INTERNAL (); + } + + // Now write the boxed value itself + + TAO_InputCDR boxed_in_cdr (static_cast<ACE_Message_Block *> (0)); + CORBA::Any_var boxed_any (this->boxed_->to_any ()); + TAO::Any_Impl * boxed_impl = boxed_any->impl (); + if (boxed_impl->encoded ()) + { + TAO::Unknown_IDL_Type * boxed_unk= + dynamic_cast<TAO::Unknown_IDL_Type *> (boxed_impl); + if (!boxed_unk) + { + throw CORBA::INTERNAL (); + } + boxed_in_cdr = boxed_unk->_tao_get_cdr (); + } + else + { + TAO_OutputCDR boxed_out_cdr; + boxed_impl->marshal_value (boxed_out_cdr); + TAO_InputCDR tmp (boxed_out_cdr); + boxed_in_cdr = tmp; + } + + CORBA::TypeCode_var boxed_tc = this->boxed_->type (); + (void) TAO_Marshal_Object::perform_append (boxed_tc.in (), + &boxed_in_cdr, + &out_cdr); + } + + // Convert the out_cdr into a new any. + TAO_InputCDR in_cdr (out_cdr); + TAO::Unknown_IDL_Type * unk = 0; + ACE_NEW_THROW_EX (unk, + TAO::Unknown_IDL_Type (this->type_.in (), in_cdr), + CORBA::NO_MEMORY ()); + CORBA::Any_ptr retval = 0; + ACE_NEW_THROW_EX (retval, CORBA::Any, CORBA::NO_MEMORY ()); + retval->replace (unk); + return retval; +} + +TAO_END_VERSIONED_NAMESPACE_DECL diff --git a/TAO/tao/DynamicAny/DynValueBox_i.h b/TAO/tao/DynamicAny/DynValueBox_i.h index 2d5cff6ba6c..a2614f2cd1e 100644 --- a/TAO/tao/DynamicAny/DynValueBox_i.h +++ b/TAO/tao/DynamicAny/DynValueBox_i.h @@ -8,7 +8,7 @@ * * $Id$ * - * @author Jeff Parsons <parsons@cs.wustl.edu> + * @author Simon Massey <simon dot massey at prismtech dot com> */ //============================================================================= @@ -40,10 +40,22 @@ class TAO_DynamicAny_Export TAO_DynValueBox_i public virtual TAO_DynValueCommon_i { public: - TAO_DynValueBox_i (void); + /// Constructor. + TAO_DynValueBox_i (CORBA::Boolean allow_truncation=true); + /// Destructor. ~TAO_DynValueBox_i (void); + /// Initialize using just a TypeCode. + void init (CORBA::TypeCode_ptr tc); + + /// Initialize using an Any. + void init (const CORBA::Any& any); + + // = LocalObject methods. + static TAO_DynValueBox_i *_narrow (CORBA::Object_ptr obj); + + // = Functions specific to DynValueBox. virtual CORBA::Any * get_boxed_value (void); virtual void set_boxed_value (const CORBA::Any & boxed); @@ -51,6 +63,35 @@ public: virtual DynamicAny::DynAny_ptr get_boxed_value_as_dyn_any (void); virtual void set_boxed_value_as_dyn_any (DynamicAny::DynAny_ptr boxed); + + // = DynAny common functions not implemented in class TAO_DynCommon. + virtual void from_any (const CORBA::Any & value); + + virtual CORBA::Any * to_any (void); + + virtual CORBA::Boolean equal (DynamicAny::DynAny_ptr dyn_any); + + virtual void destroy (void); + + virtual DynamicAny::DynAny_ptr current_component (void); + + // = DynValueCommon needed to be provided here + virtual void set_to_value (void); + +private: + /// Check if the typecode is acceptable. + void check_typecode (CORBA::TypeCode_ptr tc); + + /// Code common to the constructor from an Any arg and the member + /// function from_any(). + void set_from_any (const CORBA::Any &any); + + // = Use copy() or assign() instead of these. + TAO_DynValueBox_i (const TAO_DynValueBox_i &src); + TAO_DynValueBox_i &operator= (const TAO_DynValueBox_i &src); + + /// The boxed component of DynValueBox is another DynAny. + DynamicAny::DynAny_var boxed_; }; TAO_END_VERSIONED_NAMESPACE_DECL diff --git a/TAO/tao/DynamicAny/DynValueCommon_i.cpp b/TAO/tao/DynamicAny/DynValueCommon_i.cpp index 5414599eb2c..76373fb3aec 100644 --- a/TAO/tao/DynamicAny/DynValueCommon_i.cpp +++ b/TAO/tao/DynamicAny/DynValueCommon_i.cpp @@ -2,10 +2,19 @@ // $Id$ #include "tao/DynamicAny/DynValueCommon_i.h" +//#include "tao/DynamicAny/DynAnyUtils_T.h" + +//#include "tao/AnyTypeCode/Marshal.h" +#include "tao/AnyTypeCode/Any_Unknown_IDL_Type.h" +//#include "tao/AnyTypeCode/AnyTypeCode_methods.h" +//#include "tao/CDR.h" +//#include "tao/Valuetype/ValueBase.h" TAO_BEGIN_VERSIONED_NAMESPACE_DECL -TAO_DynValueCommon_i::TAO_DynValueCommon_i (void) +TAO_DynValueCommon_i::TAO_DynValueCommon_i (CORBA::Boolean allow_truncation) + : TAO_DynCommon (allow_truncation) + , TAO_DynAny_i (allow_truncation) { } @@ -16,20 +25,33 @@ TAO_DynValueCommon_i::~TAO_DynValueCommon_i (void) CORBA::Boolean TAO_DynValueCommon_i::is_null (void) { - throw ::CORBA::NO_IMPLEMENT (); + return this->is_null_; } void TAO_DynValueCommon_i::set_to_null (void) { - throw ::CORBA::NO_IMPLEMENT (); + this->is_null_ = true; + this->component_count_ = 0u; + this->current_position_ = -1; } void -TAO_DynValueCommon_i::set_to_value (void) +TAO_DynValueCommon_i::init_common (void) { - throw ::CORBA::NO_IMPLEMENT (); + this->ref_to_component_ = false; + this->container_is_destroying_ = false; + this->has_components_ = true; + this->destroyed_ = false; + this->set_to_value (); } -TAO_END_VERSIONED_NAMESPACE_DECL +TAO_DynValueCommon_i * +TAO_DynValueCommon_i::_narrow (CORBA::Object_ptr _tao_objref) +{ + return (CORBA::is_nil (_tao_objref)) ? + 0 : + dynamic_cast<TAO_DynValueCommon_i *> (_tao_objref); +} +TAO_END_VERSIONED_NAMESPACE_DECL diff --git a/TAO/tao/DynamicAny/DynValueCommon_i.h b/TAO/tao/DynamicAny/DynValueCommon_i.h index 462eb86b53e..817fbf8ccbe 100644 --- a/TAO/tao/DynamicAny/DynValueCommon_i.h +++ b/TAO/tao/DynamicAny/DynValueCommon_i.h @@ -8,7 +8,7 @@ * * $Id$ * - * @author Jeff Parsons <parsons@cs.wustl.edu> + * @author Simon Massey <simon dot massey at prismtech dot com> */ //============================================================================= @@ -40,15 +40,35 @@ class TAO_DynamicAny_Export TAO_DynValueCommon_i public virtual TAO_DynAny_i { public: - TAO_DynValueCommon_i (void); + /// Constructor. + TAO_DynValueCommon_i (CORBA::Boolean allow_truncation=true); + /// Destructor. ~TAO_DynValueCommon_i (void); + // = LocalObject methods. + static TAO_DynValueCommon_i *_narrow (CORBA::Object_ptr obj); + + /// Called by DynValue and DynValueBox init() functions. + void init_common (void); + + // = Functions specific to DynValueCommon. virtual CORBA::Boolean is_null (void); virtual void set_to_null (void); - virtual void set_to_value (void); + virtual void set_to_value (void) = 0; + +private: + // = Use copy() or assign() instead of these. + TAO_DynValueCommon_i (const TAO_DynValueCommon_i &src); + TAO_DynValueCommon_i &operator= (const TAO_DynValueCommon_i &src); + + /// Check if the typecode is acceptable. Needs to be provided by DynValue or DynValueBox + virtual void check_typecode (CORBA::TypeCode_ptr tc)=0; + +protected: + CORBA::Boolean is_null_; }; TAO_END_VERSIONED_NAMESPACE_DECL diff --git a/TAO/tao/DynamicAny/DynValue_i.cpp b/TAO/tao/DynamicAny/DynValue_i.cpp index 45545248f4d..ed5f4a239a2 100644 --- a/TAO/tao/DynamicAny/DynValue_i.cpp +++ b/TAO/tao/DynamicAny/DynValue_i.cpp @@ -2,10 +2,22 @@ // $Id$ #include "tao/DynamicAny/DynValue_i.h" +#include "tao/DynamicAny/DynAnyFactory.h" +#include "tao/DynamicAny/DynAnyUtils_T.h" + +#include "tao/AnyTypeCode/Marshal.h" +#include "tao/AnyTypeCode/Any_Unknown_IDL_Type.h" +#include "tao/AnyTypeCode/AnyTypeCode_methods.h" + +#include "tao/CDR.h" +#include "tao/Valuetype/ValueBase.h" TAO_BEGIN_VERSIONED_NAMESPACE_DECL -TAO_DynValue_i::TAO_DynValue_i (void) +TAO_DynValue_i::TAO_DynValue_i (CORBA::Boolean allow_truncation) + : TAO_DynCommon (allow_truncation) + , TAO_DynAny_i (allow_truncation) + , TAO_DynValueCommon_i (allow_truncation) { } @@ -13,42 +25,1196 @@ TAO_DynValue_i::~TAO_DynValue_i (void) { } -char * +void +TAO_DynValue_i::init (const CORBA::Any & any) +{ + this->init_helper (any._tao_get_typecode ()); + this->from_any_helper (any); + + // init() is called only from DynAnyFactory create_* + // methods. These are the only functions that can + // throw MustTruncate, so once init () has completed + // revert to always allowing truncation. + this->allow_truncation_ = true; +} + +void +TAO_DynValue_i::init (CORBA::TypeCode_ptr tc, TAO_InputCDR &in) +{ + this->init_helper (tc); + this->from_inputCDR (in); + + // init() is called only from DynAnyFactory create_* + // methods. These are the only functions that can + // throw MustTruncate, so once init () has completed + // revert to always allowing truncation. + this->allow_truncation_ = true; +} + +void +TAO_DynValue_i::init (CORBA::TypeCode_ptr tc) +{ + this->init_helper (tc); + + // Each member is now (recursively) set-up + // with its own correct typecode. + + for (CORBA::ULong i = 0u; + i < this->component_count_; + ++i) + { + CORBA::TypeCode_var + member_type ( + get_member_type (this->da_base_types_, i)); + + this->da_members_[i] = TAO::MakeDynAnyUtils:: + make_dyn_any_t<CORBA::TypeCode_ptr> + (member_type.in (), member_type.in (), this->allow_truncation_); + } + + this->set_to_null (); + + // init() is called only from DynAnyFactory create_* + // methods. These are the only functions that can + // throw MustTruncate, so once init () has completed + // revert to always allowing truncation. + this->allow_truncation_ = true; +} + +void +TAO_DynValue_i::init_helper (CORBA::TypeCode_ptr tc) +{ + // Ensure we have been given a valid ValueType + // typecode and then store a copy of the original. + + this->check_typecode (tc); + this->type_ = CORBA::TypeCode::_duplicate (tc); + + // Work out how many total members and types there + // are in total in this derived->base hiarchy. + + get_base_types ( + tc, + this->da_base_types_, + &this->component_count_); + this->da_members_.size (this->component_count_); + + // And initalize all of the DynCommon mix-in + + this->init_common (); +} + +void +TAO_DynValue_i::get_base_types ( + CORBA::TypeCode_ptr tc, + BaseTypesList_t &base_types, + CORBA::ULong *total_member_count) +{ + // First initalize to the fully derived type we are + // starting with. + + CORBA::ULong numberOfBases = 1u; + base_types.size (numberOfBases); + base_types[0] = TAO_DynAnyFactory::strip_alias (tc); + if (total_member_count) + { + *total_member_count = + base_types[0]->member_count (); + } + + // Obtain each derived type's basetype and add this to + // the list. + + CORBA::TypeCode_var + base (base_types[0]->concrete_base_type()); + while (base.in() && + CORBA::tk_value == + (base= // assignment + TAO_DynAnyFactory::strip_alias (base.in())) + ->kind ()) + { + if (total_member_count) + { + *total_member_count += base->member_count (); + } + + base_types.size (numberOfBases + 1); + base_types[numberOfBases++] = + CORBA::TypeCode::_duplicate (base); + base = base->concrete_base_type(); + } +} + +CORBA::TypeCode_ptr +TAO_DynValue_i::get_correct_base_type ( + const BaseTypesList_t &base_types, + CORBA::ULong &index) +{ + // We work backwards through the list of derived types, + // so index 0 is the first member of the extreme base type + // (assuming it has any members) once we run out of that + // base types members we move up the list to the next + // derived type until that type's members are exhausted + // and so on until we reach the member we have asked for. + + CORBA::ULong + currentBase = base_types.size (); + if (!currentBase) + { + ACE_DEBUG ((LM_DEBUG, + ACE_TEXT ("TAO (%P|%t) - %N:%l TAO_DynValue_i::get_correct_base_type () ") + ACE_TEXT ("BaseTypesList_t is not initialised\n"))); + return 0; + } + + while (base_types[--currentBase]->member_count () <= index) + { + index -= base_types[currentBase]->member_count (); + if (!currentBase) + { + ACE_DEBUG ((LM_DEBUG, + ACE_TEXT ("TAO (%P|%t) - %N:%l TAO_DynValue_i::get_correct_base_type () ") + ACE_TEXT ("BaseTypesList_t is not large enough\n"))); + return 0; + } + } + + // Note that the "index" has now been reduced to the range + // of the returning base_type. + return base_types[currentBase].in (); +} + +CORBA::TypeCode_ptr +TAO_DynValue_i::get_member_type ( + const BaseTypesList_t &base_types, + CORBA::ULong index) +{ + const CORBA::TypeCode_ptr + base = get_correct_base_type (base_types, index); + return base->member_type (index); +} + +const char * +TAO_DynValue_i::get_member_name ( + const BaseTypesList_t &base_types, + CORBA::ULong index) +{ + const CORBA::TypeCode_ptr + base = get_correct_base_type (base_types, index); + return base->member_name (index); +} + +void +TAO_DynValue_i::set_to_value (void) +{ + this->component_count_ = + static_cast <CORBA::ULong> (this->da_members_.size ()); + this->current_position_ = + this->component_count_ ? 0 : -1; + this->is_null_ = false; +} + +void +TAO_DynValue_i::check_typecode (CORBA::TypeCode_ptr tc) +{ + if (CORBA::tk_value == TAO_DynAnyFactory::unalias (tc)) + { + return; + } + + throw DynamicAny::DynAnyFactory::InconsistentTypeCode (); +} + +TAO_DynValue_i * +TAO_DynValue_i::_narrow (CORBA::Object_ptr _tao_objref) +{ + return (CORBA::is_nil (_tao_objref)) ? + 0 : + dynamic_cast<TAO_DynValue_i *> (_tao_objref); +} + +DynamicAny::FieldName TAO_DynValue_i::current_member_name (void) { - throw ::CORBA::NO_IMPLEMENT (); + if (this->destroyed_) + { + throw ::CORBA::OBJECT_NOT_EXIST (); + } + + if (-1 == this->current_position_) + { + throw DynamicAny::DynAny::InvalidValue (); + } + + return CORBA::string_dup ( + this->get_member_name ( + this->da_base_types_, + this->current_position_)); } CORBA::TCKind TAO_DynValue_i::current_member_kind (void) { - throw ::CORBA::NO_IMPLEMENT (); + if (this->destroyed_) + { + throw ::CORBA::OBJECT_NOT_EXIST (); + } + + if (-1 == this->current_position_) + { + throw DynamicAny::DynAny::InvalidValue (); + } + + CORBA::TypeCode_var tc ( + get_member_type ( + this->da_base_types_, + this->current_position_)); + return TAO_DynAnyFactory::unalias (tc.in ()); } DynamicAny::NameValuePairSeq * TAO_DynValue_i::get_members (void) { - throw ::CORBA::NO_IMPLEMENT (); + if (this->destroyed_) + { + throw ::CORBA::OBJECT_NOT_EXIST (); + } + + // Create the return NameValuePairSeq + DynamicAny::NameValuePairSeq *members = 0; + ACE_NEW_THROW_EX ( + members, + DynamicAny::NameValuePairSeq (this->component_count_), + CORBA::NO_MEMORY ()); + members->length (this->component_count_); + DynamicAny::NameValuePairSeq_var + safe_retval (members); + + // Assign member name and value to each slot. + for (CORBA::ULong i = 0u; + i < this->component_count_; + ++i) + { + safe_retval[i].id = CORBA::string_dup ( + this->get_member_name (this->da_base_types_, i)); + CORBA::Any_var + temp (this->da_members_[i]->to_any ()); + safe_retval[i].value = temp.in (); + } + + return safe_retval._retn (); } void -TAO_DynValue_i::set_members (const DynamicAny::NameValuePairSeq & /* value */) +TAO_DynValue_i::set_members ( + const DynamicAny::NameValuePairSeq &values) { - throw ::CORBA::NO_IMPLEMENT (); + if (this->destroyed_) + { + throw ::CORBA::OBJECT_NOT_EXIST (); + } + + // Check lengths match. + const CORBA::ULong length = values.length (); + if (length != + static_cast <CORBA::ULong> + (this->da_members_.size ())) + { + throw DynamicAny::DynAny::InvalidValue (); + } + + // Check each member typecodes match. + CORBA::ULong i; + for (i = 0u; i < length; ++i) + { + CORBA::TypeCode_var my_member ( + get_member_type (this->da_base_types_, i)); + CORBA::TypeCode_var value_member ( + values[i].value.type ()); + if (!my_member->equivalent (value_member.in ())) + { + throw DynamicAny::DynAny::TypeMismatch (); + } + } + + // Copy in the new values to each member () + for (i = 0u; i < length; ++i) + { + this->da_members_[i] = TAO::MakeDynAnyUtils:: + make_dyn_any_t<const CORBA::Any&> ( + values[i].value._tao_get_typecode (), + values[i].value, + this->allow_truncation_); + } + + this->set_to_value (); } DynamicAny::NameDynAnyPairSeq * TAO_DynValue_i::get_members_as_dyn_any (void) { - throw ::CORBA::NO_IMPLEMENT (); + if (this->destroyed_) + { + throw ::CORBA::OBJECT_NOT_EXIST (); + } + + // Create the return NameDynAnyPairSeq + DynamicAny::NameDynAnyPairSeq *members = 0; + ACE_NEW_THROW_EX ( + members, + DynamicAny::NameDynAnyPairSeq (this->component_count_), + CORBA::NO_MEMORY ()); + members->length (this->component_count_); + DynamicAny::NameDynAnyPairSeq_var + safe_retval (members); + + // Assign name and value to each pearl on the string. + for (CORBA::ULong i = 0u; + i < this->component_count_; + ++i) + { + safe_retval[i].id = CORBA::string_dup ( + this->get_member_name (this->da_base_types_, i)); + + // A deep copy is made only by copy() + // (CORBA 2.4.2 section 9.2.3.6). + // Set the flag so the caller can't destroy. + this->set_flag (this->da_members_[i].in (), 0); + + safe_retval[i].value = + DynamicAny::DynAny::_duplicate ( + this->da_members_[i].in ()); + } + + return safe_retval._retn (); } void TAO_DynValue_i::set_members_as_dyn_any ( - const DynamicAny::NameDynAnyPairSeq & /* value */) + const DynamicAny::NameDynAnyPairSeq & values) { - throw ::CORBA::NO_IMPLEMENT (); + if (this->destroyed_) + { + throw ::CORBA::OBJECT_NOT_EXIST (); + } + + // Check lengths match. + CORBA::ULong length = values.length (); + if (length != + static_cast <CORBA::ULong> ( + this->da_members_.size ())) + { + throw DynamicAny::DynAny::InvalidValue (); + } + + // Check each member typecodes match. + CORBA::ULong i = 0u; + for (; i < length; ++i) + { + CORBA::TypeCode_var + my_member ( + get_member_type (this->da_base_types_, i)), + value_member ( + values[i].value->type ()); + if (!my_member->equivalent (value_member.in ())) + { + throw DynamicAny::DynAny::TypeMismatch (); + } + } + + // Copy in the new values to each member () + for (i = 0u; i < length; ++i) + { + this->da_members_[i] = values[i].value->copy (); + } + + this->set_to_value (); } -TAO_END_VERSIONED_NAMESPACE_DECL +void +TAO_DynValue_i::from_any (const CORBA::Any &any) +{ + if (this->destroyed_) + { + throw ::CORBA::OBJECT_NOT_EXIST (); + } + + CORBA::TypeCode_var + tc (any.type ()); + if (!this->type_->equivalent (tc.in ())) + { + throw DynamicAny::DynAny::TypeMismatch (); + } + + this->from_any_helper (any); +} + +CORBA::Boolean +TAO_DynValue_i::equal (DynamicAny::DynAny_ptr rhs) +{ + if (this->destroyed_) + { + throw ::CORBA::OBJECT_NOT_EXIST (); + } + + CORBA::TypeCode_var tc (rhs->type ()); + if (!tc->equivalent (this->type_.in ()) || + this->component_count_ != + rhs->component_count () ) + { + return false; + } + + TAO_DynValue_i *rhs_v= + dynamic_cast<TAO_DynValue_i *> (rhs); + + if (!rhs_v || this->is_null () != rhs_v->is_null ()) + { + return false; + } + if (!this->is_null ()) + { + for (CORBA::ULong i = 0u; + i < this->component_count_; + ++i) + { + if (!rhs_v->da_members_[i] + ->equal (this->da_members_[i].in ())) + { + return false; + } + } + } + + return true; +} + +void +TAO_DynValue_i::destroy (void) +{ + if (this->destroyed_) + { + throw ::CORBA::OBJECT_NOT_EXIST (); + } + + if (!this->ref_to_component_ || + this->container_is_destroying_) + { + // Do a deep destroy. + this->component_count_ = + static_cast <CORBA::ULong> ( + this->da_members_.size () ); + + for (CORBA::ULong i = 0u; + i < this->component_count_; + ++i) + { + this->set_flag (da_members_[i].in (), 1); + this->da_members_[i]->destroy (); + } + + this->destroyed_ = 1; + } +} + +DynamicAny::DynAny_ptr +TAO_DynValue_i::current_component (void) +{ + if (this->destroyed_) + { + throw ::CORBA::OBJECT_NOT_EXIST (); + } + + if (-1 == this->current_position_) + { + return DynamicAny::DynAny::_nil (); + } + + const CORBA::ULong index = + static_cast <CORBA::ULong> (this->current_position_); + this->set_flag (this->da_members_[index].in (), 0); + + return DynamicAny::DynAny::_duplicate ( + this->da_members_[index].in () ); +} + +// Overrides TAO_DynCommon::insert_val (). Since we ARE +// a ValueType, it does not make sense to pass the value +// type input down to the current_component to deal with +// (even though we are a constructed type and should do +// so with any other type of input). If we don't assume +// the value type is for us, it will get passed down +// (recursivly) to the terminal non-valuetype member +// which then will be wrong type for the valuetype input +// we started with. +void +TAO_DynValue_i::insert_val (CORBA::ValueBase *value) +{ + if (this->destroyed_) + { + throw ::CORBA::OBJECT_NOT_EXIST (); + } + + // If the arg is 0 we can't do this kind of type + // checking, and the call to _tao_marshal() below + // will handle the null value correctly in any case. + if (value) + { + const char + *value_id = value->_tao_obv_repository_id (), + *my_id = this->type_->id (); + + // Valuetypes, unlike interfaces, don't have a + // virtual method to check for a more derived + // type when the repo ids don't match. Valuetypes + // have only a static _downcast() method, which + // can't be used here, so if the repo ids don't + // match, we're hosed. + if (ACE_OS::strcmp (value_id, my_id)) + { + throw DynamicAny::DynAny::TypeMismatch (); + } + } + + // This will handle null values correctly, or + // otherwise make a virtual call to marshal the state. + TAO_OutputCDR out; + if (!CORBA::ValueBase::_tao_marshal (out, value)) + { + ACE_DEBUG ((LM_DEBUG, + ACE_TEXT ("TAO (%P|%t) - %N:%l TAO_DynValue_i::insert_val ") + ACE_TEXT ("can not marshal value\n") )); + throw DynamicAny::DynAny::InvalidValue (); + } + + TAO_InputCDR in (out); + this->from_inputCDR (in); +} + +// Overrides TAO_DynCommon::get_val (). Since we ARE +// a ValueType, it does not make sense to pass the get +// request down to the current_component to deal with +// (even though we are a constructed type and should +// do so with any other type of output). If we don't +// assume the value type is us, it will get passed down +// (recursivly) to the terminal non-valuetype member +// which then will be wrong type for the valuetype +// output we want. +CORBA::ValueBase * +TAO_DynValue_i::get_val (void) +{ + if (this->destroyed_) + { + throw ::CORBA::OBJECT_NOT_EXIST (); + } + + // Convert this value into an output stream + TAO_OutputCDR out_cdr; + this->to_outputCDR (out_cdr); + + // Now read in this stream to create the actual value. + TAO_InputCDR for_reading (out_cdr); + CORBA::ValueBase *retval = 0; + if (!CORBA::ValueBase::_tao_unmarshal ( + for_reading, retval )) + { + throw DynamicAny::DynAny::InvalidValue (); + } + + return retval; +} + +CORBA::Any_ptr +TAO_DynValue_i::to_any (void) +{ + if (this->destroyed_) + { + throw ::CORBA::OBJECT_NOT_EXIST (); + } + + // First create the value as an output stream + TAO_OutputCDR out_cdr; + this->to_outputCDR (out_cdr); + + // Convert the out_cdr into a new any. + TAO_InputCDR in_cdr (out_cdr); + TAO::Unknown_IDL_Type *unk = 0; + ACE_NEW_THROW_EX ( + unk, + TAO::Unknown_IDL_Type (this->type_.in (), in_cdr), + CORBA::NO_MEMORY () ); + CORBA::Any_ptr retval = 0; + ACE_NEW_THROW_EX ( + retval, + CORBA::Any, + CORBA::NO_MEMORY ()); + retval->replace (unk); + return retval; +} + +// This code is common to from_any() and the init(any). +// Basically the type information for our DynValue has +// already been set-up, we are now just copying the any +// value into our type. +void +TAO_DynValue_i::from_any_helper (const CORBA::Any & any) +{ + // Get the CDR stream of the Any, if there isn't one, + // make one by marshalling the value into a new stream. + + TAO_OutputCDR out; + TAO_InputCDR in (static_cast<ACE_Message_Block *> (0)); + TAO::Any_Impl *impl = any.impl (); + if (impl->encoded ()) + { + TAO::Unknown_IDL_Type *unk = + dynamic_cast<TAO::Unknown_IDL_Type *> (impl); + if (!unk) + { + throw CORBA::INTERNAL (); + } + + in = unk->_tao_get_cdr (); + } + else + { + impl->marshal_value (out); + TAO_InputCDR tmp_in (out); + in = tmp_in; + } + + this->from_inputCDR (in); +} + +void +TAO_DynValue_i::to_outputCDR (TAO_OutputCDR &out_cdr) +{ + // Is this an NULL Valuetype? If so we need to + // output the special NULL value type header. + // Note that we don't actually have a CORBA::ValueBase * + // which this call expects as we are actually dealing + // with DynValue * instead. However the pointer isn't + // actually dereferanced by the _tao_write_special_value() + // call, its address (as a void *) is just used to + // check for the null value and any previous writen + // value for the indirection header and the saving of + // this current location for this new valuetype if it + // is not indirected (this time). + if (!CORBA::ValueBase::_tao_write_special_value ( + out_cdr, + reinterpret_cast <CORBA::ValueBase *> + (this->is_null_ ? 0 : this) )) + { + // OK since a special_value hasn't been written we are + // NOT a NULL or indirect ValueType. We need to create + // a normal valuetype header, which states if chunking + // is being used and if CodeBaseURL and type information + // ((none, single or list of) repository id(s)) is being + // provided. TAO NEVER sends a codebase URL and ALWAYS + // lists the full list of repository ids that are + // VM_TRUNCATABLE. + + CORBA::Long valuetag = + TAO_OBV_GIOP_Flags::Value_tag_base | + TAO_OBV_GIOP_Flags::Type_info_single; + + const CORBA::ULong num_ids = this->da_base_types_.size (); + CORBA::ULong trunc_ids; + for (trunc_ids= 0u; trunc_ids < num_ids - 1u; ++trunc_ids) + { + if (CORBA::VM_TRUNCATABLE != + this->da_base_types_[trunc_ids]->type_modifier ()) + { + break; // Found the first type that is not truncatable + } + } + ++trunc_ids; // Include non-truncatable id that stopped us. + + if (1u < trunc_ids) + { + valuetag |= + TAO_OBV_GIOP_Flags::Type_info_list; + } + + CORBA::Boolean we_are_chunking = (1u < trunc_ids); + if (!we_are_chunking) + { + for (CORBA::ULong i= trunc_ids - 1u; i < num_ids; ++i) + { + if (CORBA::VM_CUSTOM == + this->da_base_types_[i]->type_modifier ()) + { + we_are_chunking = true; + break; + } + } + } + + if (we_are_chunking) + { + valuetag |= + TAO_OBV_GIOP_Flags::Chunking_tag_sigbits; + } + + // Start writing out the value header (and if + // necessary, the number of repo_ids we are + // going to write). + if (!out_cdr.write_long (valuetag) || + (1u < trunc_ids && !out_cdr.write_ulong (trunc_ids)) ) + { + ACE_DEBUG ((LM_DEBUG, + ACE_TEXT ("TAO (%P|%t) - %N:%l TAO_DynValue_i::to_outputCDR() ") + ACE_TEXT ("problem writing <value-tag> header\n"))); + throw CORBA::INTERNAL (); + } + + // Marshal out the list of repo_ids we are sending from + // the most derived type_id to the most base type_id in + // order. NOTE these type_ids are the real / full / + // non-dealliased versions not the dealliased ones that + // are stored in the da_base_types_[] list. + CORBA::ULong i= 0u; + for (CORBA::TypeCode_var + next (CORBA::TypeCode::_duplicate (this->type_)); + i < trunc_ids; + ++i) + { + ACE_CString repo_id (next->id ()); + if (!CORBA::ValueBase:: + _tao_write_repository_id (out_cdr, repo_id) ) + { + ACE_DEBUG ((LM_DEBUG, + ACE_TEXT ("TAO (%P|%t) - %N:%l TAO_DynValue_i::to_outputCDR() ") + ACE_TEXT ("problem writing header repo_ids\n"))); + throw CORBA::INTERNAL (); + } + + // Using the dealliased tc for this current type, find + // the next non-dealliased base typecode. + next = this->da_base_types_[i]->concrete_base_type (); + } + + // Write out the start chunking markers for the number + // of base types we are writing. If we are not a truncatable + // type there are none to write (i.e. we are writing one + // less than the trunc_ids we actually have). + TAO_ChunkInfo ci (we_are_chunking); + for (i= 0u; i < trunc_ids - 1u; ++i) + { + if (!ci.start_chunk (out_cdr)) + { + ACE_DEBUG ((LM_DEBUG, + ACE_TEXT ("TAO (%P|%t) - %N:%l TAO_DynValue_i::to_outputCDR() ") + ACE_TEXT ("problem writing basetype start chucks\n"))); + throw CORBA::INTERNAL (); + } + } + + // Now write out every member's value (add further chunking + // marks for each seporate base-type's state). + CORBA::Boolean need_first = true; + CORBA::ULong + currentBase= num_ids, // Note NOT just the trunc_ids + currentBaseMember = 0u; + for (CORBA::ULong currentMember= 0u; + currentMember < this->component_count_; + ++currentMember) + { + // Are we starting a new base-type + if (!currentBaseMember) + { + // Move on to the next derived type in the + // list of our type hyarchy + while (!this->da_base_types_[--currentBase] + ->member_count ()) + { + // Skipping over all types that have no + // state (i.e. no members to write). + } + + if (currentBase < trunc_ids || need_first) + { + need_first = false; + // Start chunk for this base-type's STATE + if (!ci.start_chunk (out_cdr)) + { + ACE_DEBUG ((LM_DEBUG, + ACE_TEXT ("TAO (%P|%t) - %N:%l TAO_DynValue_i::to_outputCDR() ") + ACE_TEXT ("problem writing base-type ") + ACE_TEXT ("%u state start chuck\n"), + currentBase )); + throw CORBA::INTERNAL (); + } + } + } + + // Recursive step - Add this member to the out_cdr + if (TAO_DynValue_i *member= // Assignment + dynamic_cast<TAO_DynValue_i *> + (this->da_members_[currentMember].in ())) + { + member->to_outputCDR (out_cdr); + } + else + { + CORBA::Any_var + any (this->da_members_[currentMember]->to_any ()); + TAO::Any_Impl *impl = any->impl (); + if (impl->encoded ()) + { + // Already encoded as a stream, convert this + // into an unknown and copy the stream over. + TAO::Unknown_IDL_Type + *unk= dynamic_cast<TAO::Unknown_IDL_Type *> (impl); + if (!unk) + { + ACE_DEBUG ((LM_DEBUG, + ACE_TEXT ("TAO (%P|%t) - %N:%l TAO_DynValue_i::to_outputCDR() ") + ACE_TEXT ("problem obtaining Unknown_IDL_Type\n"))); + throw CORBA::INTERNAL (); + } + + // Create a new input CDR for this member's + // marshaled representation. + TAO_InputCDR + in_cdr (unk->_tao_get_cdr ()); + + // Ok append this member's value to the output stream. + CORBA::TypeCode_var + tc (this->da_members_[currentMember]->type ()); + + (void) TAO_Marshal_Object::perform_append ( + tc.in (), + &in_cdr, + &out_cdr); + } + else + { + // Just need to marshal this value into the stream. + impl->marshal_value (out_cdr); + } + } + + // Are we ending the current base-type? + if (this->da_base_types_[currentBase]->member_count () + <= ++currentBaseMember) + { + // Remind us to start again with the next derived type + // for the next member to be writen. + currentBaseMember= 0u; + + // We must end the chunk we started for this + // base-type's STATE if we have written the whole state. + if (currentBase < trunc_ids && !ci.end_chunk (out_cdr)) + { + ACE_DEBUG ((LM_DEBUG, + ACE_TEXT ("TAO (%P|%t) - %N:%l TAO_DynValue_i::to_outputCDR() ") + ACE_TEXT ("problem writing base-type ") + ACE_TEXT ("%u state end chuck\n"), + currentBase )); + throw CORBA::INTERNAL (); + } + } + } + + // Write out the end chunking markers for the number + // of base types we have writen. + for (i= 1u; i < trunc_ids; ++i) + { + if (!ci.end_chunk (out_cdr)) + { + ACE_DEBUG ((LM_DEBUG, + ACE_TEXT ("TAO (%P|%t) - %N:%l TAO_DynValue_i::to_outputCDR() ") + ACE_TEXT ("problem writing basetype end chucks\n"))); + throw CORBA::INTERNAL (); + } + } + } +} + +void +TAO_DynValue_i::from_inputCDR (TAO_InputCDR &strm) +{ + // Save the start of this ValueType position in the input stream + // to allow caching for later indirections. + VERIFY_MAP (TAO_InputCDR, value_map, Value_Map); + if (strm.align_read_ptr (ACE_CDR::LONG_SIZE)) + { + this->set_to_null (); + throw CORBA::INTERNAL (); + } + void *const start_of_valuetype = strm.rd_ptr(); + + // Read in the ValueType header + CORBA::ValueBase::Repository_Id_List ids; + CORBA::Boolean + is_null_object= false, + is_indirected= false, + is_chunked = false, + result = CORBA::ValueBase::_tao_unmarshal_header ( + strm, this->type_.in ()->id (), ids, + is_null_object, is_indirected, is_chunked); + + if (!result) + { + ACE_DEBUG ((LM_ERROR, + ACE_TEXT ("TAO (%P|%t) - %N:%l TAO_DynValue_i::from_inputCDR() ") + ACE_TEXT ("_tao_unmarshal_header() failed\n") )); + this->set_to_null (); + throw CORBA::INTERNAL (); + } + if (is_null_object) + { + this->set_to_null (); + return; + } + if (is_indirected) + { + // Effectivly this member? is the same ValueType as previous + // seen either in another member of this container OR the + // whole container itself. (Possiably can happen as a + // circular linked list?) + if (TAO_debug_level) + { + ACE_DEBUG ((LM_ERROR, + ACE_TEXT ("TAO (%P|%t) - %N:%l TAO_DynValue_i::from_inputCDR() ") + ACE_TEXT ("Any contains Indirected ValueType\n") )); + } + + // Force the originally created container to empty, it is up + // to the caller to delete it and replace it with the duplicate + // we are now about to find. + this->set_to_null (); + + // Read the offset from the stream (should be negative to point + // back to original) + CORBA::Long offset = 0; + if (!strm.read_long (offset) || 0 <= offset) + { + ACE_DEBUG ((LM_ERROR, + ACE_TEXT ("TAO (%P|%t) - %N:%l TAO_DynValue_i::from_inputCDR() ") + ACE_TEXT ("Can't read/understand ") + ACE_TEXT ("Indirected ValueType offset\n") )); + throw CORBA::INTERNAL (); + } + + // Work out the input stream location of the original valuetype + // and find the address of the original TAO_DynValue_i that we + // created last time and stored in the map. + void + *pos = strm.rd_ptr () + offset - sizeof (CORBA::Long), + *original = 0; + if (strm.get_value_map()->get()->find (pos, original)) + { + ACE_DEBUG ((LM_ERROR, + ACE_TEXT ("TAO (%P|%t) - %N:%l TAO_DynValue_i::from_inputCDR() ") + ACE_TEXT ("Can't find Indirected ValueType ") + ACE_TEXT ("offset in map\n") )); + throw CORBA::INTERNAL (); + } + + // Since this is a void * convert it back to our real type and + // throw it for the caller to catch and replace "this" + // TAO_DynValue_i. + TAO_DynValue_i *this_one_instead= + reinterpret_cast<TAO_DynValue_i *> (original); + this_one_instead->_add_ref (); + throw this_one_instead; + } + + // Ok since we are not indirected (this time), record "this" + // DynValue_i for later possiable indirections to use. + if (strm.get_value_map ()->get() + ->bind ( + start_of_valuetype, + reinterpret_cast<void *> (this))) + { + ACE_DEBUG ((LM_DEBUG, + ACE_TEXT ("TAO (%P|%t) - %N:%l TAO_DynValue_i::from_inputCDR() ") + ACE_TEXT ("Failed to record this into value_map\n") )); + throw CORBA::INTERNAL (); + } + + // Work out how many total types there + // are in this derived->base hiarchy. + const CORBA::ULong + num_fields = static_cast <CORBA::ULong> (this->da_members_.size ()), + num_ids = static_cast <CORBA::ULong> (ids.size ()); + + // Work out if the encoded valuetype inside the any is + // required to be truncated into our DynValue. + CORBA::Boolean requires_truncation = false; + const char *const our_id = this->da_base_types_[0]->id (); + CORBA::ULong i; + for (i= 0u; i < num_ids; ++i) + { + // Does the current id match our DynValue id? + if (!strcmp (our_id, ids[i].c_str ())) + { + break; // Found a match, we have our answer + } + + if (!this->allow_truncation_) + { + throw DynamicAny::MustTruncate (); + } + + // Since this does not match we must be attempting + // to truncated to a base-type, thus the incomming + // any must be chuncked and this outer type must + // allow truncation. + if (!is_chunked) + { + ACE_DEBUG ((LM_ERROR, + ACE_TEXT ("TAO (%P|%t) - %N:%l TAO_DynValue_i::from_inputCDR()\n") + ACE_TEXT (" type %C requires truncation to %C but is not chunked type.\n"), + ids[i].c_str (), + our_id )); + this->set_to_null (); + throw DynamicAny::DynAny::TypeMismatch (); + } + + requires_truncation = true; + } + if (i == num_ids) + { + ACE_DEBUG ((LM_DEBUG, + ACE_TEXT ("TAO (%P|%t) - %N:%l TAO_DynValue_i::from_inputCDR() ") + ACE_TEXT ("couldn't find matching repo_id!\n"))); + this->set_to_null (); + throw DynamicAny::DynAny::TypeMismatch (); + } + + // Read in the start chunking markers for the number + // of base types we are reading. If we are not a derived + // type there are none to read (i.e. we are reading one + // less than the num_ids we actually have received). + + TAO_ChunkInfo ci (is_chunked, 1); + for (i= 0u; i < num_ids - 1u; ++i) + { + if (!ci.handle_chunking (strm)) + { + ACE_DEBUG ((LM_DEBUG, + ACE_TEXT ("TAO (%P|%t) - %N:%l TAO_DynValue_i::from_inputCDR() ") + ACE_TEXT ("problem reading basetype start chucks\n"))); + this->set_to_null (); + throw DynamicAny::DynAny::InvalidValue (); + } + } + + // Now read in every member's value (reading further chunking + // marks for each seporate base-type's state we pass). + CORBA::Boolean need_first = true; + CORBA::ULong + currentBase= this->da_base_types_.size (), + currentBaseMember = 0u; + for (CORBA::ULong currentMember= 0u; + currentMember < num_fields; + ++currentMember) + { + // Are we starting a new base-type + if (!currentBaseMember) + { + // Move on to the next derived type in the + // list of our type hyarchy + while (!this->da_base_types_[--currentBase] + ->member_count ()) + { + // Skipping over all types that have no + // state (i.e. no members to write). + } + + if (currentBase < num_ids || need_first) + { + // Read past the start chunk for this base-type's state + if (!ci.handle_chunking (strm)) + { + ACE_DEBUG ((LM_DEBUG, + ACE_TEXT ("TAO (%P|%t) - %N:%l TAO_DynValue_i::from_inputCDR() ") + ACE_TEXT ("problem reading base-type ") + ACE_TEXT ("%u state start chuck\n"), + currentBase )); + this->set_to_null (); + throw DynamicAny::DynAny::InvalidValue (); + } + } + } + + // OK read in the current member + CORBA::TypeCode_var + field_tc (this->da_base_types_[currentBase] + ->member_type (currentBaseMember)); + if (CORBA::tk_value == field_tc->kind ()) + { + // This is recursive, keep reading from our inputCDR + // this allows for indirection + this->da_members_[currentMember]= + TAO::CreateDynAnyUtils<TAO_DynValue_i, TAO_InputCDR &> + ::create_dyn_any_t ( + field_tc.in (), + strm, + this->allow_truncation_); + } + else + { + // Need to create an any for this field. + TAO_InputCDR unk_in (strm); + TAO::Unknown_IDL_Type *unk= 0; + ACE_NEW_THROW_EX ( + unk, + TAO::Unknown_IDL_Type (field_tc.in (), unk_in), + CORBA::NO_MEMORY ()); + + CORBA::Any field_any; + field_any.replace (unk); + + // This recursive step will call the correct + // constructor based on the type of field_any. + this->da_members_[currentMember] = TAO::MakeDynAnyUtils:: + make_dyn_any_t<const CORBA::Any&> ( + field_any._tao_get_typecode (), + field_any, + this->allow_truncation_); + + // Since the above Unknown used its own inputCDR we need + // to move onto the next field in the real CDR stream as + // IF we had just read the actual value from it. + (void) TAO_Marshal_Object::perform_skip ( + field_tc.in (), + &strm); + } + + // Are we ending the current base-type? + if (this->da_base_types_[currentBase]->member_count () + <= ++currentBaseMember) + { + // Remind us to start again with the next derived type + // for the next member to be writen. + currentBaseMember= 0u; + + if (currentBase < num_ids) + { + // We must end the chunk that was started for this + // base-type's state. + if (!( (currentBase || !requires_truncation) ? + ci.handle_chunking (strm) : + ci.skip_chunks (strm) )) + { + ACE_DEBUG ((LM_DEBUG, + ACE_TEXT ("TAO (%P|%t) - %N:%l TAO_DynValue_i::from_inputCDR() ") + ACE_TEXT ("problem reading base-type ") + ACE_TEXT ("%u state end chuck\n"), + currentBase )); + this->set_to_null (); + throw DynamicAny::DynAny::InvalidValue (); + } + } + } + } + + this->set_to_value (); +} + +TAO_END_VERSIONED_NAMESPACE_DECL diff --git a/TAO/tao/DynamicAny/DynValue_i.h b/TAO/tao/DynamicAny/DynValue_i.h index 03d25734cd8..ab389ccf813 100644 --- a/TAO/tao/DynamicAny/DynValue_i.h +++ b/TAO/tao/DynamicAny/DynValue_i.h @@ -8,7 +8,7 @@ * * $Id$ * - * @author Jeff Parsons <parsons@cs.wustl.edu> + * @author Simon Massey <simon dot massey at prismtech dot com> */ //============================================================================= @@ -40,11 +40,26 @@ class TAO_DynamicAny_Export TAO_DynValue_i public virtual TAO_DynValueCommon_i { public: - TAO_DynValue_i (void); + /// Constructor. + TAO_DynValue_i (CORBA::Boolean allow_truncation=true); + /// Destructor. ~TAO_DynValue_i (void); - virtual char * current_member_name (void); + /// Initialize using an Any. + void init (const CORBA::Any& any); + + /// Initialize using a TypeCode and an input stream + void init (CORBA::TypeCode_ptr tc, TAO_InputCDR &in); + + /// Initialize using just a TypeCode. + void init (CORBA::TypeCode_ptr tc); + + // = LocalObject methods. + static TAO_DynValue_i *_narrow (CORBA::Object_ptr obj); + + // = Functions specific to DynValue. + virtual DynamicAny::FieldName current_member_name (void); virtual CORBA::TCKind current_member_kind (void); @@ -56,6 +71,87 @@ public: virtual void set_members_as_dyn_any ( const DynamicAny::NameDynAnyPairSeq & value); + + // = DynAny common functions not implemented in class TAO_DynCommon. + virtual void from_any (const CORBA::Any & value); + + virtual CORBA::Any * to_any (void); + + virtual CORBA::Boolean equal (DynamicAny::DynAny_ptr dyn_any); + + virtual void destroy (void); + + virtual DynamicAny::DynAny_ptr current_component (void); + + virtual void insert_val (CORBA::ValueBase * value); + + virtual CORBA::ValueBase * get_val (void); + + // = DynValueCommon needed to be provided here + virtual void set_to_value (void); + +private: + /// List of base types. + typedef ACE_Array_Base<CORBA::TypeCode_var> BaseTypesList_t; + + /// Decompose the given TypeCode into its hiarchical list of + /// basetypes. The first element of the list is our actual type, + /// each basetype follows in order backwards down the hiarchy. + /// All types stored in the list are de-aliased. Optionally + /// return the total_member_count of the fully derived type. + static void get_base_types ( + CORBA::TypeCode_ptr, + BaseTypesList_t &, + CORBA::ULong *total_member_count = 0); + + /// Return the unaliased valuetype typecode that corresponds to + /// index (0..total_members-1) from the given hiarchical list of + /// the derived type and it basetypes. + static CORBA::TypeCode_ptr get_correct_base_type ( + const BaseTypesList_t &base_types, + CORBA::ULong &index); + + /// Return the member_type at index (0..total_members-1) from + /// the given hiarchical list of the derived type and it basetypes. + static CORBA::TypeCode_ptr get_member_type ( + const BaseTypesList_t &, + CORBA::ULong index); + + /// Return the member_name at index (0..total_members-1) from + /// the given hiarchical list of the derived type and it basetypes. + static const char * get_member_name ( + const BaseTypesList_t &, + CORBA::ULong index); + + /// Check if the typecode is acceptable. + void check_typecode (CORBA::TypeCode_ptr tc); + + /// Common code from the init() functions, initializes the + /// private bits from the given TypeCode + void init_helper (CORBA::TypeCode_ptr tc); + + /// Code common to the init(Any) and the member + /// function from_any(). + void from_any_helper (const CORBA::Any &any); + + /// Write the value to the output stream. + void to_outputCDR (TAO_OutputCDR &); + + /// Read the value from the input stream + void from_inputCDR (TAO_InputCDR &); + + /// These are not implimented! + /// Use copy() or assign() instead of these. + TAO_DynValue_i (const TAO_DynValue_i &src); + TAO_DynValue_i &operator= (const TAO_DynValue_i &src); + + /// Each component of DynValue and DynValueBox is also a DynAny. + ACE_Array_Base<DynamicAny::DynAny_var> da_members_; + + /// First element of this is our type, each basetype follows + /// in order backwards down the hiarchy. All types stored are + /// de-aliased. + BaseTypesList_t da_base_types_; }; TAO_END_VERSIONED_NAMESPACE_DECL diff --git a/TAO/tao/Valuetype/ValueBase.cpp b/TAO/tao/Valuetype/ValueBase.cpp index 3c853ac06fc..6a152cfaede 100644 --- a/TAO/tao/Valuetype/ValueBase.cpp +++ b/TAO/tao/Valuetype/ValueBase.cpp @@ -23,16 +23,6 @@ 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 @@ -176,16 +166,16 @@ CORBA::ValueBase::_tao_unmarshal (TAO_InputCDR &strm, // new_object->_tao_unmarshal_v () // new_object->_tao_unmarshal_post () - CORBA::Boolean is_null_object = false; - CORBA::Boolean is_indirected = false; - CORBA::Boolean const retval = - CORBA::ValueBase::_tao_unmarshal_pre (strm, - new_object, - 0, - is_null_object, - is_indirected); + CORBA::Boolean + is_null_object = false, + is_indirected = false; - if (!retval) + if (!CORBA::ValueBase::_tao_unmarshal_pre ( + strm, + new_object, + 0, // repo_id to be obtained from strm + is_null_object, + is_indirected )) { return false; } @@ -195,30 +185,20 @@ CORBA::ValueBase::_tao_unmarshal (TAO_InputCDR &strm, return true; } - // 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 retval; + // If we have now obtained the ValueType + // continue by unmarshalling the values into it. + return (new_object) ? + new_object->_tao_unmarshal_v (strm) : false; } - CORBA::Boolean -CORBA::ValueBase::_tao_unmarshal_pre (TAO_InputCDR &strm, - CORBA::ValueBase *&valuetype, - const char * const repo_id, - CORBA::Boolean& is_null_object, - CORBA::Boolean& is_indirected) +CORBA::ValueBase::_tao_unmarshal_pre ( + TAO_InputCDR &strm, + CORBA::ValueBase *&valuetype, + const char *const fallback_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; - // %! yet much to do ... look for +++ ! // 1. Get the <value-tag> (else it may be <indirection-tag> or <null-ref>). @@ -241,152 +221,214 @@ CORBA::ValueBase::_tao_unmarshal_pre (TAO_InputCDR &strm, // from the <value-tag>, then use the repository id parameter // (it _must_ be right). - CORBA::Long valuetag; + CORBA::Boolean is_chunked = false; + + // Save the position of the start of the ValueType + // to allow caching for later indirection. + if (strm.align_read_ptr (ACE_CDR::LONG_SIZE)) + { + return false; + } + void *const start_of_valuetype = strm.rd_ptr(); + Repository_Id_List ids; - ACE_CString codebase_url; + CORBA::Boolean result = + CORBA::ValueBase::_tao_unmarshal_header ( + strm, fallback_repo_id, ids, + is_null_object, is_indirected, is_chunked); + + if (!result || is_null_object) + { + valuetype = 0; + return result; + } + if (is_indirected) + { + return _tao_unmarshal_value_indirection (strm, valuetype); + } + CORBA::ValueBase::_tao_unmarshal_find_factory ( + strm, start_of_valuetype, valuetype, ids, is_chunked); + + return true; +} + +CORBA::Boolean +CORBA::ValueBase::_tao_unmarshal_header ( + TAO_InputCDR &strm, + const char *const fallback_repo_id, + Repository_Id_List &ids, + CORBA::Boolean &is_null_object, + CORBA::Boolean &is_indirected, + CORBA::Boolean &is_chunked) +{ is_indirected = false; is_null_object = false; + is_chunked = false; - if (! strm.read_long (valuetag)) + CORBA::Long valuetag; + if (!strm.read_long (valuetag)) { return false; } - if (TAO_OBV_GIOP_Flags::is_indirection_tag (valuetag)) - { - is_indirected = true; - - // value is redirected - return _tao_unmarshal_value_indirection (strm, valuetype); - } + is_chunked = TAO_OBV_GIOP_Flags::is_chunked (valuetag); if (TAO_OBV_GIOP_Flags::is_null_ref (valuetag)) { // null reference is unmarshalled. - valuetype = 0; is_null_object = true; return true; } + if (TAO_OBV_GIOP_Flags::is_indirection_tag (valuetag)) + { + // value is redirected + is_indirected = true; + return true; + } + if (TAO_OBV_GIOP_Flags::has_codebase_url (valuetag)) { + // We don't do anything with this url, but it needs + // to be read and ignored. ACE_CString codebase_url; - if (! _tao_read_codebase_url (strm, codebase_url)) + if (!_tao_read_codebase_url (strm, codebase_url)) { return false; } } + // Obtain the repo_id(s) of the type we are reading + if (TAO_OBV_GIOP_Flags::has_single_type_info (valuetag)) { ACE_CString id; - if (! _tao_read_repository_id(strm, id)) + if (!_tao_read_repository_id(strm, id)) { return false; } - ids.push_back (id); } else if (TAO_OBV_GIOP_Flags::has_list_type_info (valuetag)) { - if (! _tao_read_repository_id_list(strm, ids)) + if (!_tao_read_repository_id_list(strm, ids)) { return false; } } else if (TAO_OBV_GIOP_Flags::has_no_type_info (valuetag)) { - ids.push_back (repo_id); + if (fallback_repo_id) + { + ids.push_back (fallback_repo_id); + } + else + { + ACE_ERROR (( + LM_ERROR, + ACE_TEXT ("TAO (%P|%t) - %N:%l ValueBase::_tao_unmarshal_pre, ") + ACE_TEXT ("unknown repo_id\n") )); + return false; + } } else { - if (TAO_debug_level > 0) + if (TAO_debug_level) { - ACE_ERROR ((LM_ERROR, - ACE_TEXT ("TAO (%P|%t) - ValueBase::_tao_unmarshal_pre, ") - ACE_TEXT ("unknown value tag: %x\n"), - valuetag)); + ACE_ERROR (( + LM_ERROR, + ACE_TEXT ("TAO (%P|%t) - %N:%l ValueBase::_tao_unmarshal_pre, ") + ACE_TEXT ("unknown value tag: %x\n"), + valuetag )); } - return 0; + return false; } - TAO_ORB_Core *orb_core = strm.orb_core (); + return true; +} - if (orb_core == 0) +void +CORBA::ValueBase::_tao_unmarshal_find_factory ( + TAO_InputCDR &strm, + void *const start_of_valuetype, + CORBA::ValueBase *&valuetype, + Repository_Id_List &ids, + CORBA::Boolean &is_chunked) +{ + valuetype = 0; + + TAO_ORB_Core *orb_core = strm.orb_core (); + if (!orb_core) { orb_core = TAO_ORB_Core_instance (); - - if (TAO_debug_level > 0) + if (TAO_debug_level) { - ACE_DEBUG ((LM_WARNING, - ACE_TEXT ("TAO (%P|%t) - ValueBase::_tao_unmarshal_pre, ") - ACE_TEXT ("WARNING: extracting valuetype using ") - ACE_TEXT ("default ORB_Core\n"))); + ACE_DEBUG (( + LM_WARNING, + ACE_TEXT ("TAO (%P|%t) - %N:%l ValueBase::_tao_unmarshal_find_factory, ") + ACE_TEXT ("WARNING: extracting valuetype using default ORB_Core\n") )); } } - CORBA::Boolean require_truncation = false; - CORBA::Boolean const chunking = - TAO_OBV_GIOP_Flags::is_chunked (valuetag); - CORBA::ULong const num_ids = ids.size (); - // Find the registered factory for this unmarshalling valuetype. If any // factory for the valuetype in its truncatable derivation hierarchy // is registered, the factory is used to create value for unmarshalling. - for (CORBA::ULong i = 0; i < num_ids; ++i) + // Value factories are reference counted. When we get a new value factory + // from the ORB, its reference count is increased. + + CORBA::ValueFactory_var factory; + CORBA::Boolean requires_truncation = false; + const CORBA::ULong num_ids = ids.size (); + const char *id = (num_ids) ? ids[0].c_str () : "{Null}"; + for (CORBA::ULong i = 0u; i < num_ids; ++i) { factory = orb_core->orb ()->lookup_value_factory (ids[i].c_str ()); - if (factory.in() != 0) { - if (i != 0 && chunking) - { - require_truncation = true; - } + id = ids[i].c_str (); + requires_truncation = (i != 0u); break; } } - if (factory.in() == 0) + // Obtain the actual ValueType from the factory + if (factory.in() == 0 || !(valuetype = factory->create_for_unmarshal ())) { - if (TAO_debug_level > 0) + if (TAO_debug_level) { ACE_ERROR ((LM_ERROR, - ACE_TEXT ("TAO (%P|%t) - ValueBase::_tao_unmarshal_pre, ") - ACE_TEXT ("OBV factory is null, id = %C\n"), - repo_id)); + ACE_TEXT ("TAO (%P|%t) - %N:%l ValueBase::_tao_unmarshal_find_factory, ") + ACE_TEXT ("OBV factory is null, id=%C\n"), + id)); } throw ::CORBA::MARSHAL (CORBA::OMGVMCID | 1, CORBA::COMPLETED_MAYBE); } - valuetype = factory->create_for_unmarshal (); - - if (require_truncation) + if (requires_truncation) { valuetype->truncation_hook (); } + valuetype->chunking_ = is_chunked; - if (valuetype == 0) + // Cache the start of this ValueType for later possiable indirection + VERIFY_MAP (TAO_InputCDR, value_map, Value_Map); + if (strm.get_value_map ()->get()->bind (start_of_valuetype, valuetype) != 0) { - return 0; // %! except.? + ACE_DEBUG ((LM_DEBUG, + ACE_TEXT ("TAO (%P|%t) - %N:%l ValueBase::_tao_unmarshal_find_factory, ") + ACE_TEXT ("Failed to bound value %x=%x, id=%C\n"), + start_of_valuetype, valuetype, id )); + } + else if (TAO_debug_level) + { + ACE_DEBUG ((LM_DEBUG, + ACE_TEXT ("TAO (%P|%t) - %N:%l ValueBase::_tao_unmarshal_find_factory, ") + ACE_TEXT ("bound value %x=%x, id=%C\n"), + start_of_valuetype, valuetype, id )); } - - valuetype->chunking_ = chunking; - - 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 ("TAO (%P|%t) - ValueBase::_tao_unmarshal_pre, bound value %X - %X\n"), - pos, valuetype)); - } - return true; } CORBA::Boolean @@ -442,7 +484,7 @@ CORBA::ValueBase::_tao_validate_box_type (TAO_InputCDR &strm, if (!TAO_OBV_GIOP_Flags::is_value_tag (value_tag)) { ACE_DEBUG ((LM_DEBUG, - ACE_TEXT ("TAO (%P|%t) - CORBA::ValueBase::_tao_validate_box_type, ") + ACE_TEXT ("TAO (%P|%t) - %N:%l CORBA::ValueBase::_tao_validate_box_type, ") ACE_TEXT ("not value_tag\n"))); return false; } @@ -526,25 +568,30 @@ CORBA::ValueBase::_tao_unmarshal_value_indirection (TAO_InputCDR &strm, void* pos = strm.rd_ptr () + offset - sizeof (CORBA::Long); - if (TAO_debug_level > 9) + if (9 < TAO_debug_level) { ACE_DEBUG ((LM_DEBUG, - ACE_TEXT ("TAO (%P|%t) ValueBase::_tao_unmarshal_value_indirection, pos %X \n"), pos)); + ACE_TEXT ("TAO (%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 ("TAO (%P|%t) ValueBase::_tao_unmarshal_value_indirection, %X - %X \n"), it->ext_id_, it->int_id_)); + ACE_DEBUG ((LM_DEBUG, ACE_TEXT ("TAO (%P|%t) ValueBase::_tao_unmarshal_value_indirection, %x=%x\n"), it->ext_id_, it->int_id_)); } } void * v = 0; if (strm.get_value_map()->get()->find (pos, v) != 0) { + ACE_DEBUG ((LM_DEBUG, + ACE_TEXT ("TAO (%P|%t) - %N:%l ") + ACE_TEXT ("ValueBase::_tao_unmarshal_value_indirection, ") + ACE_TEXT ("did not find %x in map %x\n"), + pos, (void *) strm.get_value_map()->get())); throw CORBA::INTERNAL (); } - else if (TAO_debug_level > 0) + else if (TAO_debug_level) { ACE_DEBUG ((LM_DEBUG, - ACE_TEXT ("TAO (%P|%t) - ValueBase::_tao_unmarshal_value_indirection, found %X - %X\n"), + ACE_TEXT ("TAO (%P|%t) - %N:%l ValueBase::_tao_unmarshal_value_indirection, found %x=%x\n"), pos,v)); } @@ -568,10 +615,10 @@ CORBA::ValueBase::_tao_unmarshal_repo_id_indirection (TAO_InputCDR &strm, { throw CORBA::INTERNAL (); } - else if (TAO_debug_level > 0) + else if (TAO_debug_level) { ACE_DEBUG ((LM_DEBUG, - ACE_TEXT ("TAO (%P|%t) - ValueBase::_tao_unmarshal_repo_id_indirection, found %X - %C\n"), + ACE_TEXT ("TAO (%P|%t) - %N:%l ValueBase::_tao_unmarshal_repo_id_indirection, found %x=%C\n"), pos, id.c_str ())); } @@ -594,10 +641,10 @@ CORBA::ValueBase::_tao_unmarshal_codebase_url_indirection (TAO_InputCDR &strm, { throw CORBA::INTERNAL (); } - else if (TAO_debug_level > 0) + else if (TAO_debug_level) { ACE_DEBUG ((LM_DEBUG, - ACE_TEXT ("TAO (%P|%t) - ValueBase::_tao_unmarshal_codebase_url_indirection, found %X - %C\n"), + ACE_TEXT ("TAO (%P|%t) - %N:%l ValueBase::_tao_unmarshal_codebase_url_indirection, found %x=%C\n"), pos, codebase_url.c_str ())); } @@ -639,29 +686,29 @@ CORBA::ValueBase::_tao_write_special_value (TAO_OutputCDR &strm, #ifdef TAO_HAS_VALUETYPE_OUT_INDIRECTION // value indirection - VERIFY_MAP(TAO_OutputCDR, value_map, Value_Map) - + 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) + if (TAO_debug_level) { ACE_DEBUG ((LM_DEBUG, - ACE_TEXT ("(%P|%t)ValueBase::_tao_write_special_value, found value %X - %X\n"), + 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)) + if (!strm.write_long (TAO_OBV_GIOP_Flags::Indirection_tag)) { return false; } - CORBA::Long const offset = - strm.offset (pos); - if (TAO_debug_level > 0) + CORBA::Long const offset= -strm.offset (pos); + if (TAO_debug_level) { ACE_DEBUG ((LM_DEBUG, - ACE_TEXT ("TAO (%P|%t) - ValueBase::_tao_write_special_value, indirection %d\n"), offset)); + ACE_TEXT ("TAO (%P|%t) - %N:%l ValueBase::_tao_write_special_value, indirection %d=%x\n"), + offset, (void *)(strm.current()->wr_ptr () + offset) )); } return strm.write_long (offset); @@ -677,10 +724,10 @@ CORBA::ValueBase::_tao_write_special_value (TAO_OutputCDR &strm, { throw CORBA::INTERNAL (); } - else if (TAO_debug_level > 0) + else if (TAO_debug_level) { ACE_DEBUG ((LM_DEBUG, - ACE_TEXT ("TAO (%P|%t) - ValueBase::_tao_marshal, bound value %X - %X \n"), + ACE_TEXT ("TAO (%P|%t) - %N:%l ValueBase::_tao_marshal, bound value %x=%x\n"), value, strm.current()->wr_ptr())); } @@ -798,30 +845,25 @@ CORBA::ValueBase::_tao_write_repository_id (TAO_OutputCDR &strm, { #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 (); - } - + VERIFY_MAP (TAO_OutputCDR, repo_id_map, Repo_Id_Map); 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 = - strm.offset (pos); - - if (TAO_debug_level > 0) - { - ACE_DEBUG ((LM_DEBUG, - ACE_TEXT ("TAO (%P|%t) - ValueBase::_tao_write_repository_id, id %C indirection %d\n"), - id.c_str(), offset)); - } - - if (! strm.write_long (offset)) - return false; + if (!strm.write_long (TAO_OBV_GIOP_Flags::Indirection_tag)) + { + return false; + } + CORBA::Long offset= -strm.offset (pos); + if (TAO_debug_level) + { + ACE_DEBUG ((LM_DEBUG, + ACE_TEXT ("TAO (%P|%t) - %N:%l ValueBase::_tao_write_repository_id, id %C indirection %d\n"), + id.c_str(), offset)); + } + if (!strm.write_long (offset)) + { + return false; + } } else { @@ -829,23 +871,26 @@ CORBA::ValueBase::_tao_write_repository_id (TAO_OutputCDR &strm, { 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) + if (TAO_debug_level) { ACE_DEBUG ((LM_DEBUG, - ACE_TEXT ("TAO (%P|%t) - ValueBase::_tao_write_repository_id, bound %C - %X\n"), + ACE_TEXT ("TAO (%P|%t) - %N:%l ValueBase::_tao_write_repository_id, bound %C - %x\n"), id.c_str (), strm.current()->wr_ptr ())); } if (! strm.write_string (id.c_str ())) - return false; + { + return false; + } } #else if (! strm.write_string (id.c_str ())) - return 0; + { + return 0; + } #endif return 1; @@ -1007,7 +1052,7 @@ TAO_ChunkInfo::handle_chunking (TAO_InputCDR &strm) if (-tag > this->value_nesting_level_) { ACE_ERROR_RETURN ((LM_ERROR, - ACE_TEXT ("TAO (%P|%t) - TAO_ChunkInfo::handle_chunking, received end tag ") + ACE_TEXT ("TAO (%P|%t) - %N:%l TAO_ChunkInfo::handle_chunking, received end tag ") ACE_TEXT ("%d > value_nesting_level %d\n"), -tag, this->value_nesting_level_), @@ -1128,11 +1173,7 @@ CORBA::ValueBase::_tao_read_repository_id (TAO_InputCDR& strm, return 0; } - VERIFY_MAP(TAO_InputCDR, repo_id_map, Repo_Id_Map) - - if (strm.get_repo_id_map ().is_nil ()) - throw CORBA::INTERNAL (); - + VERIFY_MAP (TAO_InputCDR, repo_id_map, Repo_Id_Map); char * pos = strm.rd_ptr(); // 'length' may not be the repo id length - it could be the @@ -1165,24 +1206,29 @@ CORBA::ValueBase::_tao_read_repository_id (TAO_InputCDR& strm, ACE_CString mapped_id; if (strm.get_repo_id_map ()->get()->find (pos, mapped_id) == 0) { - if (TAO_debug_level > 0) + if (TAO_debug_level) { ACE_DEBUG ((LM_DEBUG, - ACE_TEXT ("TAO (%P|%t) - ValueBase::_tao_read_repository_id, found %X - %C\n"), + ACE_TEXT ("TAO (%P|%t) - %N:%l ValueBase::_tao_read_repository_id, found %x=%C\n"), pos, mapped_id.c_str ())); } if (ACE_OS::strcmp (mapped_id.c_str (), id.c_str ()) != 0) - throw CORBA::INTERNAL (); + { + ACE_DEBUG ((LM_DEBUG, + ACE_TEXT ("TAO (%P|%t) - %N:%l ValueBase::_tao_read_repository_id, found %C in map for %C\n"), + mapped_id.c_str (), id.c_str ())); + throw CORBA::INTERNAL (); + } } else if (strm.get_repo_id_map ()->get ()->bind (pos, id) != 0) { throw CORBA::INTERNAL (); } - else if (TAO_debug_level > 0) + else if (TAO_debug_level) { ACE_DEBUG ((LM_DEBUG, - ACE_TEXT ("TAO (%P|%t) - ValueBase::_tao_read_repository_id, bound %X - %C\n"), + ACE_TEXT ("TAO (%P|%t) - %N:%l ValueBase::_tao_read_repository_id, bound %x=%C\n"), pos, id.c_str ())); } @@ -1209,8 +1255,7 @@ CORBA::ValueBase::_tao_read_codebase_url (TAO_InputCDR& strm, return 0; } - VERIFY_MAP(TAO_InputCDR, codebase_url_map, Codebase_URL_Map) - + 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 @@ -1243,10 +1288,10 @@ CORBA::ValueBase::_tao_read_codebase_url (TAO_InputCDR& strm, ACE_CString mapped_url; if (strm.get_codebase_url_map ()->get()->find (pos, mapped_url) == 0) { - if (TAO_debug_level > 0) + if (TAO_debug_level) { ACE_DEBUG ((LM_DEBUG, - ACE_TEXT ("TAO (%P|%t) - ValueBase::_tao_read_codebase_url, found %X - %C\n"), + ACE_TEXT ("TAO (%P|%t) - %N:%l ValueBase::_tao_read_codebase_url, found %x=%C\n"), pos, mapped_url.c_str ())); } if (ACE_OS::strcmp (mapped_url.c_str (), codebase_url.c_str ()) != 0) @@ -1258,10 +1303,10 @@ CORBA::ValueBase::_tao_read_codebase_url (TAO_InputCDR& strm, } else { - if (TAO_debug_level > 0) + if (TAO_debug_level) { ACE_DEBUG ((LM_DEBUG, - ACE_TEXT ("TAO (%P|%t) - ValueBase::_tao_read_codebase_url, bound %X - %C\n"), + ACE_TEXT ("TAO (%P|%t) - %N:%l ValueBase::_tao_read_codebase_url, bound %x=%C\n"), pos, codebase_url.c_str ())); } } diff --git a/TAO/tao/Valuetype/ValueBase.h b/TAO/tao/Valuetype/ValueBase.h index 01f74b564cb..2da58404e5e 100644 --- a/TAO/tao/Valuetype/ValueBase.h +++ b/TAO/tao/Valuetype/ValueBase.h @@ -43,6 +43,15 @@ 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); \ + } else do {} while (0) + class TAO_Valuetype_Export TAO_ChunkInfo { public: @@ -132,9 +141,23 @@ namespace CORBA typedef ACE_Vector < ACE_CString > Repository_Id_List; - // Reference counting. - /// %! virtual CORBA::ValueBase* _copy_value (void) = 0; + // This is only temporary, it is _not_ the Right Thing To Do. + // Currently nothing should break, as TAO neither uses + // _copy_value() nor generates code which uses _copy_value(), and + // any user code which depends on the declaration of + // _copy_value() must override it anyway, so it should never get + // called. + // N.B. - see bugzilla #1391 / TAO#84. Fix is pending. + virtual CORBA::ValueBase* _copy_value (void) + { + ACE_VERSIONED_NAMESPACE_NAME::__ace_assert ( + __FILE__, + __LINE__, + ACE_TEXT_CHAR_TO_TCHAR ("CORBA::ValueBase::_copy_value() Not implimented see bugzilla #1391")); + return 0; + }; + // Reference counting. virtual void _add_ref (void) = 0; virtual void _remove_ref (void) = 0; virtual CORBA::ULong _refcount_value (void) = 0; @@ -179,9 +202,17 @@ namespace CORBA /// Both used internally and are called from T::_tao_unmarshal () static CORBA::Boolean _tao_unmarshal_pre (TAO_InputCDR &strm, CORBA::ValueBase *&valuetype, - const char * const repo_id, - CORBA::Boolean& is_null_object, - CORBA::Boolean& is_indirected); + const char *const repo_id, + CORBA::Boolean &is_null_object, + CORBA::Boolean &is_indirected); + + static CORBA::Boolean _tao_unmarshal_header ( + TAO_InputCDR &strm, + const char *const fallback_repo_id, + Repository_Id_List &ids, + CORBA::Boolean &is_null_object, + CORBA::Boolean &is_indirected, + CORBA::Boolean &is_chunked); CORBA::Boolean _tao_unmarshal_post (TAO_InputCDR &strm); @@ -239,6 +270,12 @@ namespace CORBA virtual CORBA::Boolean _tao_match_formal_type (ptrdiff_t ) const = 0; private: + static void _tao_unmarshal_find_factory ( + TAO_InputCDR &strm, + void *start_of_valuetype, + CORBA::ValueBase *&valuetype, + Repository_Id_List &ids, + CORBA::Boolean &is_chunked); static CORBA::Boolean _tao_unmarshal_value_indirection_pre (TAO_InputCDR &strm, TAO_InputCDR &indirected_strm); @@ -251,13 +288,14 @@ namespace CORBA static CORBA::Boolean _tao_unmarshal_codebase_url_indirection (TAO_InputCDR &strm, ACE_CString& codebase_url); - + public: 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); + private: /// Write whole value. static CORBA::Boolean _tao_write_value(TAO_OutputCDR &strm, const CORBA::ValueBase * value, diff --git a/TAO/tests/DynValue_Test/Analyzer.cpp b/TAO/tests/DynValue_Test/Analyzer.cpp new file mode 100644 index 00000000000..22356bb9d12 --- /dev/null +++ b/TAO/tests/DynValue_Test/Analyzer.cpp @@ -0,0 +1,542 @@ +// $Id$ + +#include "Analyzer.h" +#include "tao/DynamicAny/DynCommon.h" + +DynAnyAnalyzer::DynAnyAnalyzer (int argc, ACE_TCHAR *argv[]) + : level_ (1u), + orb_ (CORBA::ORB_init (argc, argv)), + dany_fact_ (0) +{ + if (CORBA::is_nil (orb_.in ())) + { + ACE_DEBUG ((LM_ERROR, "Could not init orb\n")); + throw 0; + } + + CORBA::Object_var + obj (orb_->resolve_initial_references ("DynAnyFactory")); + dany_fact_ = DynamicAny::DynAnyFactory::_narrow(obj.in ()); + if (CORBA::is_nil (dany_fact_.in ())) + { + ACE_DEBUG ((LM_ERROR, "Nil dynamic any factory after narrow\n")); + throw 0; + } +} + +DynamicAny::DynAny_ptr +DynAnyAnalyzer::DynAny_NoTrunc (const CORBA::Any &any) +{ + return this->dany_fact_ + ->create_dyn_any_without_truncation (any); +} + +DynamicAny::DynAny_ptr +DynAnyAnalyzer::DynAny (const CORBA::Any &any) +{ + return this->dany_fact_ + ->create_dyn_any (any); +} + +DynamicAny::DynAny_ptr +DynAnyAnalyzer::DynAny (const CORBA::TypeCode_ptr &tc) +{ + return this->dany_fact_ + ->create_dyn_any_from_type_code (tc); +} + +void +DynAnyAnalyzer::register_factory ( + CORBA::ValueFactoryBase_var factory) +{ + factory_id * new_fact ( + dynamic_cast<factory_id *> (factory.in()) ); + tab("Registering factory for ValueType "); + ACE_DEBUG ((LM_DEBUG, "%C\n", new_fact->id ())); + CORBA::ValueFactoryBase_var old_fact ( + orb_->register_value_factory ( + new_fact->id (), factory.in () ) ); +} + +void +DynAnyAnalyzer::get_base_types ( + CORBA::TypeCode_ptr tc, + BaseTypesList_t &base_types, + CORBA::ULong *total_member_count) +{ + // First initalize to the fully derived type we are + // starting with. + + CORBA::ULong numberOfBases = 1u; + base_types.size (numberOfBases); + base_types[0] = TAO_DynAnyFactory::strip_alias (tc); + if (total_member_count) + { + *total_member_count = base_types[0]->member_count (); + } + + // Obtain each derived type's basetype and add this to the list + + CORBA::TypeCode_var + base (base_types[0]->concrete_base_type()); + while (0 != base.in() && + CORBA::tk_value == + (base = TAO_DynAnyFactory::strip_alias (base.in())) + ->kind ()) + { + if (total_member_count) + { + *total_member_count += base->member_count (); + } + + base_types.size (numberOfBases + 1); + base_types[numberOfBases++] = CORBA::TypeCode::_duplicate (base); + base = base->concrete_base_type(); + } +} + +CORBA::TypeCode_ptr +DynAnyAnalyzer::get_correct_base_type ( + const BaseTypesList_t &base_types, + CORBA::ULong &index) +{ + // We work backwards through the list of derived types, + // so index 0 is the first member of the extreme base type + // (assuming it has any members) once we run out of that + // base types members we move up the list to the next + // derived type until that type's members are exhausted + // and so on until we reach the member we have asked for. + + CORBA::ULong + currentBase = base_types.size (); + if (!currentBase) + { + ACE_DEBUG ((LM_DEBUG, + ACE_TEXT ("TAO_DynValue_i::get_correct_base_type () ") + ACE_TEXT ("BaseTypesList_t is not initialised\n"))); + return 0; + } + + while (base_types[--currentBase]->member_count () <= index) + { + index -= base_types[currentBase]->member_count (); + if (!currentBase) + { + ACE_DEBUG ((LM_DEBUG, + ACE_TEXT ("TAO_DynValue_i::get_correct_base_type () ") + ACE_TEXT ("BaseTypesList_t is not large enough\n"))); + return 0; + } + } + + // Note that the "index" has now been reduced to the range + // of the returning base_type. + return base_types[currentBase].in (); +} + +#define CASEE(type,CT,str) case CORBA::tk_##type: {\ + CORBA::CT b = da->get_##type();\ + if (!newline) tab(""); ACE_DEBUG ((LM_DEBUG, str , b));\ +} break; + +void +DynAnyAnalyzer::analyze ( + DynamicAny::DynAny_ptr da, + CORBA::Boolean newline) +{ + CORBA::TypeCode_var tc (da->type ()); + CORBA::TCKind kind (tc->kind ()); + CORBA::TypeCode_var + dup (CORBA::TypeCode::_duplicate (tc.in ())); + + // strip aliases + while (CORBA::tk_alias == kind) + { + dup = dup->content_type (); + kind = dup->kind (); + } + + switch (kind) + { + case CORBA::tk_value_box: + { + DynamicAny::DynValueBox_var + box (DynamicAny::DynValueBox::_narrow (da)); + + if (!newline) + { + tab (""); + } + if (box->is_null ()) + { + ACE_DEBUG ((LM_DEBUG, "{NULL} ")); + } + ACE_DEBUG ((LM_DEBUG, "ValueBox Type: %C \"%C\": ", + tc->name (), tc->id ()) ); + if (box->is_null ()) + { + ACE_DEBUG ((LM_DEBUG, "\n")); + } + else + { + DynamicAny::DynAny_var + cc (box->current_component ()); + this->analyze (cc.in (), true); + } + } + break; // end tk_valuebox + + case CORBA::tk_value: + { + DynamicAny::DynValue_var + dvt (DynamicAny::DynValue::_narrow (da)); + + if (!newline) + { + tab (""); + } + if (dvt->is_null ()) + { + ACE_DEBUG ((LM_DEBUG, "{NULL} ")); + } + + BaseTypesList_t base_types; + get_base_types (tc, base_types); + + for (CORBA::ULong i= 0u; i < base_types.size(); ++i) + { + if (i) + { + tab (": "); + } + else + { + ACE_DEBUG ((LM_DEBUG, "ValueType: ")); + } + + switch (base_types[i]->type_modifier ()) + { + case CORBA::VM_CUSTOM: + ACE_DEBUG ((LM_DEBUG, "Custom ")); + break; + + case CORBA::VM_ABSTRACT: + ACE_DEBUG ((LM_DEBUG, "Abstract ")); + break; + + case CORBA::VM_TRUNCATABLE: + ACE_DEBUG ((LM_DEBUG, "Truncatable ")); + break; + + default: + break; + } + + ACE_DEBUG ((LM_DEBUG, "%C \"%C\"\n", + base_types[i]->name (), + base_types[i]->id () )); + ++level_; + } + level_ -= base_types.size(); + + if (!(dvt->is_null ())) + { + CORBA::ULong member_number = 0u; + ++level_; + if (da->seek (0)) do + { + DynamicAny::DynAny_var + cc (dvt->current_component ()); + DynamicAny::FieldName_var + fn (dvt->current_member_name ()); + CORBA::ULong sub_member_number = member_number; + const CORBA::TypeCode_ptr + base = get_correct_base_type ( + base_types, + sub_member_number); + const char *const visability = + ((CORBA::PRIVATE_MEMBER == + base->member_visibility (sub_member_number)) ? + "Private" : "Public "); + tab ("["); + ACE_DEBUG ((LM_DEBUG, "%03u] %C \"%C\": ", + ++member_number, visability, fn.in () )); + if (CORBA::is_nil (cc.in ())) + { + ACE_DEBUG ((LM_DEBUG, " {Null}\n")); + } + else + { + this->analyze (cc.in (), true); + } + } while (da->next ()); + else + { + tab("{Has No Members}\n"); + } + --level_; + } + } + break; // end tk_value + + case CORBA::tk_struct: + { + DynamicAny::DynStruct_var + ds (DynamicAny::DynStruct::_narrow (da)); + + if (newline) + { + ACE_DEBUG ((LM_DEBUG, "\n")); + } + tab ("Struct: "); + ACE_DEBUG ((LM_DEBUG, "%C \"%C\"", + tc->name (), tc->id () )); + if (da->seek (0)) + { + ACE_DEBUG ((LM_DEBUG, "\n")); + ++level_; + do + { + DynamicAny::DynAny_var + cc (ds->current_component ()); + DynamicAny::FieldName_var + fn (ds->current_member_name ()); + + tab ("Member = "); + ACE_DEBUG ((LM_DEBUG, "%C\n", fn.in ())); + if (!CORBA::is_nil (cc.in ())) + { + this->analyze (cc.in ()); + } + } while (da->next ()); + --level_; + } + else + { + ACE_DEBUG ((LM_DEBUG, " Null\n")); + } + } + break; // end tk_struct + + case CORBA::tk_union: + { + if (newline) + { + ACE_DEBUG ((LM_DEBUG, "\n")); + } + tab ("Union: "); + ACE_DEBUG ((LM_DEBUG, "%C \"%C\"", + tc->name (), tc->id () )); + DynamicAny::DynUnion_var + value (DynamicAny::DynUnion::_narrow (da)); + if (value->has_no_active_member ()) + { + ACE_DEBUG ((LM_DEBUG, " No Active member\n")); + } + else + { + ACE_DEBUG ((LM_DEBUG, "\n")); + DynamicAny::DynAny_var disc (value->member ()); + if (!CORBA::is_nil (disc.in ())) + { + ++level_; + this->analyze (disc.in ()); + --level_; + } + } + } + break; // end tk_union + + case CORBA::tk_enum: + { + DynamicAny::DynEnum_var + value (DynamicAny::DynEnum::_narrow (da)); + + if (newline) + { + ACE_DEBUG ((LM_DEBUG, "\n")); + } + tab ("Enum: "); + ACE_DEBUG ((LM_DEBUG, "%C \"%C\"", + tc->name (), tc->id () )); + CORBA::String_var s (value->get_as_string ()); + ACE_DEBUG ((LM_DEBUG, " value %C\n", s.in())); + } + break; // end tk_enum + + case CORBA::tk_sequence: + { + if (TAO_DynCommon::is_basic_type_seq (tc.in ())) + { + if (newline) ACE_DEBUG ((LM_DEBUG, "\n")); + this->analyze_basic_seq (dup.in (), da); + } + else + { + DynamicAny::DynSequence_var + ds (DynamicAny::DynSequence::_narrow (da)); + + int i = 0; + if (newline) + { + ACE_DEBUG ((LM_DEBUG, "\n")); + } + tab ("Sequence:\n"); + if (ds->seek (0)) + { + ++level_; + do + { + tab (""); + ACE_DEBUG ((LM_DEBUG, "[%03d]\n", i)); + DynamicAny::DynAny_var + cc (ds->current_component ()); + if (!CORBA::is_nil (cc.in ())) + { + analyze (cc.in ()); + } + ++i; + } while (da->next ()); + --level_; + } + } + } + break; // end tk_sequence + + case CORBA::tk_array: + { + if (newline) + { + ACE_DEBUG ((LM_DEBUG, "\n")); + } + tab ("Array\n"); + --level_; + + CORBA::ULong const len = dup->length (); + for (CORBA::ULong i = 0u; i < len; ++i) + { + tab (""); + ACE_DEBUG ((LM_DEBUG, "[%03d]\n", i)); + DynamicAny::DynAny_var + cc (da->current_component()); + if (!CORBA::is_nil (cc.in ())) + { + analyze (cc.in ()); + } + da->next (); + } + --level_; + } + break; // end tk_array + + case CORBA::tk_any: + { + tab ("Any\n"); + CORBA::Any_var any (da->get_any ()); + DynamicAny::DynAny_var + dynany (DynAny (any.in ())); + if (!CORBA::is_nil (dynany.in ())) + { + ++level_; + this->analyze (dynany.in ()); + --level_; + } + } + break; // end tk_any + + CASEE (boolean, Boolean, "(bool) = %d\n"); + CASEE (short, Short, "(short) = %hd\n"); + CASEE (ushort, UShort, "(unsigned short) = %hu\n"); + CASEE (long, Long, "(long) = %d\n"); + CASEE (ulong, ULong, "(unsigned long) = %u\n"); + CASEE (longlong, LongLong, "(longlong) %Ld\n"); + CASEE (ulonglong, ULongLong, "(unsigned longlong) %Lu\n"); + CASEE (char, Char, "(char) = %c\n"); + CASEE (float, Float, "(float) = %f\n"); + CASEE (double, Double, "(double) = %f\n"); + CASEE (octet, Octet, "(octet) = %c\n"); + + case CORBA::tk_string: + { + CORBA::String_var b (da->get_string ()); + if (!newline) + { + tab(""); + } + ACE_DEBUG ((LM_DEBUG, "(string) = \"%C\"\n", + b.in () )); + } + break; // end tk_string + + case CORBA::tk_TypeCode: + { + const CORBA::TCKind + kind =da->get_typecode ()->kind (); + if (!newline) + { + tab(""); + } + ACE_DEBUG ((LM_DEBUG, "(TypeCode) = %d\n", + static_cast<int> (kind) )); + } + break; // end tk_TypeCode + + default: + { + const CORBA::TCKind + kind = tc->kind (); + if (newline) + { + ACE_DEBUG ((LM_DEBUG, "\n")); + } + tab ("***Unhandled*** TypeCode = "); + ACE_DEBUG ((LM_DEBUG, "%d\n", + static_cast<int> (kind) )); + } + break; + } +} + +#define CASEBS(type,CT,str) case CORBA::tk_##type: {\ + CORBA::CT##Seq_var seq (da->get_##type##_seq ());\ + ++level_; CORBA::ULong len = seq->length ();\ + tab ("length = "); ACE_DEBUG ((LM_DEBUG, "%u\n", len));\ + for (CORBA::ULong i = 0; i < len; ++i) {\ + CORBA::CT b = seq[i];\ + tab (""); ACE_DEBUG ((LM_DEBUG, "[%3d] ", i));\ + ACE_DEBUG ((LM_DEBUG, str, b)); }\ + --level_;\ +} break; + +void +DynAnyAnalyzer::analyze_basic_seq ( + CORBA::TypeCode_ptr tc, + DynamicAny::DynAny_ptr da) +{ + CORBA::TypeCode_var ct (tc->content_type ()); + CORBA::TCKind tk = ct->kind (); + + tab ("BASIC Type Sequence - "); + switch (tk) + { + CASEBS (boolean, Boolean, "Value (bool) = %d\n"); + CASEBS (octet, Octet, "Value (octet) = %c\n"); + CASEBS (char, Char, "Value (char) = %c\n"); + CASEBS (wchar, WChar, "Value (wchar) = %u\n"); + CASEBS (short, Short, "Value (short) = %d\n"); + CASEBS (ushort, UShort, "Value (ushort) = %u\n"); + CASEBS (long, Long, "Value (long) = %d\n"); + CASEBS (ulong, ULong, "Value (ulong) = %u\n"); + CASEBS (longlong, LongLong, "Value (longlong) = %Ld\n"); + CASEBS (ulonglong, ULongLong, "Value (ulonglong) = %Lu\n"); + CASEBS (float, Float, "Value (float) = %f\n"); + CASEBS (double, Double, "Value (double) = %f\n"); + + case CORBA::tk_longdouble: + default: + ACE_DEBUG ((LM_DEBUG, + "***Unhandled*** TypeCode = %d\n", + static_cast<int> (tk) )); + break; + } +} diff --git a/TAO/tests/DynValue_Test/Analyzer.h b/TAO/tests/DynValue_Test/Analyzer.h new file mode 100644 index 00000000000..c40fcf876fb --- /dev/null +++ b/TAO/tests/DynValue_Test/Analyzer.h @@ -0,0 +1,60 @@ +// $Id$ + +#ifndef INCLUDE_ANALYZER_H +#define INCLUDE_ANALYZER_H + +#include "ValueTypes_impl.h" +#include "tao/DynamicAny/DynAnyFactory.h" + +//============= class DynAnyAnalyzer ============ + +class DynAnyAnalyzer +{ +private: + unsigned int level_; + CORBA::ORB_var orb_; + DynamicAny::DynAnyFactory_var dany_fact_; + +public: + DynAnyAnalyzer (int argc, ACE_TCHAR *argv[]); + ~DynAnyAnalyzer (void) {orb_->destroy ();} + + DynamicAny::DynAny_ptr DynAny_NoTrunc (const CORBA::Any &); + DynamicAny::DynAny_ptr DynAny (const CORBA::Any &); + DynamicAny::DynAny_ptr DynAny (const CORBA::TypeCode_ptr &); + + void register_factory (CORBA::ValueFactoryBase_var factory); + + void analyze ( + DynamicAny::DynAny_ptr da, + CORBA::Boolean newline = false); + +private: + /// List of base types. + typedef ACE_Array_Base<CORBA::TypeCode_var> BaseTypesList_t; + + void tab (const char p[]) + { + for (unsigned int i = 0u; i < level_ ; ++i) + ACE_DEBUG ((LM_DEBUG, "..")); + ACE_DEBUG ((LM_DEBUG, "%C", p)); + } + + void analyze_basic_seq ( + CORBA::TypeCode_ptr tc, + DynamicAny::DynAny_ptr da); + + static void get_base_types ( + CORBA::TypeCode_ptr tc, + BaseTypesList_t &base_types, + CORBA::ULong *total_member_count = 0); + + /// Return the unaliased valuetype typecode that corresponds to + /// index (0..total_members-1) from the given hiarchical list of + /// the derived type and it basetypes. + static CORBA::TypeCode_ptr get_correct_base_type ( + const BaseTypesList_t &base_types, + CORBA::ULong &index); +}; + +#endif // INCLUDE_ANALYZER_H diff --git a/TAO/tests/DynValue_Test/DynValue_Test.idl b/TAO/tests/DynValue_Test/DynValue_Test.idl new file mode 100644 index 00000000000..185aadab761 --- /dev/null +++ b/TAO/tests/DynValue_Test/DynValue_Test.idl @@ -0,0 +1,36 @@ +// $Id$ + +module DynValue_Test +{ + abstract valuetype avt + { + void print (); + }; + + valuetype BaseValue : avt + { + public unsigned short Base_us1; + public unsigned short Base_us2; + }; + + valuetype BoxedLong long; + + valuetype NestedValue + { + public short Nested_s1; + public short Nested_s2; + }; + + valuetype NullValue + { + }; + + valuetype Trunc : truncatable BaseValue + { + public BoxedLong Trunc_bl; + public NestedValue Trunc_nested; + private NullValue Trunc_null1; + private NullValue Trunc_null2; + private NullValue Trunc_null3; + }; +}; diff --git a/TAO/tests/DynValue_Test/DynValue_Test.mpc b/TAO/tests/DynValue_Test/DynValue_Test.mpc new file mode 100644 index 00000000000..64b6c55fa37 --- /dev/null +++ b/TAO/tests/DynValue_Test/DynValue_Test.mpc @@ -0,0 +1,28 @@ +// $Id$ + +project(*IDL): dynamicany { + IDL_Files { + DynValue_Test.idl + idlflags += -SS + } + custom_only = 1 +} + + +project(DynValue_Test): dynamicany, typecodefactory { + exename = DynValue_Test + after += *IDL + Source_Files { + main.cpp + ValueTypes_impl.cpp + Analyzer.cpp + DynValue_TestC.cpp + } + Header_Files { + ValueTypes_impl.h + Analyzer.h + DynValue_TestC.h + } + IDL_Files { + } +} diff --git a/TAO/tests/DynValue_Test/ValueTypes_impl.cpp b/TAO/tests/DynValue_Test/ValueTypes_impl.cpp new file mode 100644 index 00000000000..d8fca9ed7dd --- /dev/null +++ b/TAO/tests/DynValue_Test/ValueTypes_impl.cpp @@ -0,0 +1,152 @@ +// $Id$ + +#include "ValueTypes_impl.h" +#include "tao/AnyTypeCode/TypeCode.h" + +//============= "BaseValue" Value Type implimentation ======= + +BaseValue_impl::~BaseValue_impl () +{ +} + +CORBA::ValueBase * +BaseValue_impl::_copy_value () +{ + CORBA::ValueBase *vb= 0; + ACE_NEW_THROW_EX ( + vb, + BaseValue_impl (this->Base_us1 (), this->Base_us2 ()), + CORBA::NO_MEMORY ()); + return vb; +} + +void +BaseValue_impl::print () +{ + ACE_DEBUG ((LM_DEBUG, "BaseValue (Base_us1 %u, Base_us2 %u)\n", + this->Base_us1 (), + this->Base_us2 () )); +} + +const char * BaseValue_Factory::id () const +{ + return DynValue_Test::_tc_BaseValue->id (); +} + +CORBA::ValueBase * BaseValue_Factory::create_for_unmarshal () +{ + CORBA::ValueBase *vb= 0; + ACE_NEW_THROW_EX (vb, BaseValue_impl (), CORBA::NO_MEMORY ()); + return vb; +} + +//============= "Nested" Value Type implimentation ======= + +NestedValue_impl::~NestedValue_impl () +{ +} + +CORBA::ValueBase * NestedValue_impl::_copy_value () +{ + CORBA::ValueBase *vb= 0; + ACE_NEW_THROW_EX ( + vb, + NestedValue_impl (this->Nested_s1 (), this->Nested_s2 ()), + CORBA::NO_MEMORY ()); + return vb; +} + +const char * NestedValue_Factory::id () const +{ + return DynValue_Test::_tc_NestedValue->id (); +} + +CORBA::ValueBase * NestedValue_Factory::create_for_unmarshal () +{ + CORBA::ValueBase *vb= 0; + ACE_NEW_THROW_EX (vb, NestedValue_impl (), CORBA::NO_MEMORY ()); + return vb; +} + +//============= "Null" Value Type implimentation ======= + +NullValue_impl::~NullValue_impl () +{ +} + +CORBA::ValueBase * NullValue_impl::_copy_value () +{ + CORBA::ValueBase *vb= 0; + ACE_NEW_THROW_EX (vb, NullValue_impl (), CORBA::NO_MEMORY ()); + return vb; +} + +const char * NullValue_Factory::id () const +{ + return DynValue_Test::_tc_NullValue->id (); +} + +CORBA::ValueBase * NullValue_Factory::create_for_unmarshal () +{ + CORBA::ValueBase *vb= 0; + ACE_NEW_THROW_EX (vb, NullValue_impl (), CORBA::NO_MEMORY ()); + return vb; +} + +//============= "Trunc" Value Type implimentation ======= + +Trunc_impl::~Trunc_impl () +{ +} + +CORBA::ValueBase * Trunc_impl::_copy_value () +{ + CORBA::ValueBase *vb= 0; + ACE_NEW_THROW_EX ( + vb, + Trunc_impl ( + this->Base_us1(), + this->Base_us2(), + dynamic_cast<DynValue_Test::BoxedLong *> + (this->Trunc_bl ()->_copy_value()), + dynamic_cast<NestedValue_impl *> + (this->Trunc_nested ()->_copy_value()), + dynamic_cast<NullValue_impl *> + (this->Trunc_null1 ()->_copy_value()), + dynamic_cast<NullValue_impl *> + (this->Trunc_null2 ()->_copy_value()), + dynamic_cast<NullValue_impl *> + (this->Trunc_null3 ()->_copy_value()) ), + CORBA::NO_MEMORY ()); + return vb; +} + +void +Trunc_impl::print () +{ + ACE_DEBUG ((LM_DEBUG, + ACE_TEXT ("BaseValue (Base_us1 %u, Base_us2 %u) ") + ACE_TEXT ("Trunc (Trunc_bl (long %d), ") + ACE_TEXT ("Trunc_nested (Nested_s1 %d, Nested_s2 %d), ") + ACE_TEXT ("3xTrunc_null (%x %x %x))\n"), + this->Base_us1 (), + this->Base_us2 (), + this->Trunc_bl()->_value (), + this->Trunc_nested()->Nested_s1 (), + this->Trunc_nested()->Nested_s2 (), + (void *) this->Trunc_null1(), + (void *) this->Trunc_null2(), + (void *) this->Trunc_null3() )); +} + +const char * Trunc_Factory::id () const +{ + return DynValue_Test::_tc_Trunc->id (); +} + +CORBA::ValueBase * Trunc_Factory::create_for_unmarshal () +{ + CORBA::ValueBase *vb= 0; + ACE_NEW_THROW_EX (vb, Trunc_impl (), CORBA::NO_MEMORY ()); + return vb; +} diff --git a/TAO/tests/DynValue_Test/ValueTypes_impl.h b/TAO/tests/DynValue_Test/ValueTypes_impl.h new file mode 100644 index 00000000000..185b6926074 --- /dev/null +++ b/TAO/tests/DynValue_Test/ValueTypes_impl.h @@ -0,0 +1,111 @@ +// $Id$ + +#ifndef INCLUDE_VALUETYPE_IMPL_H +#define INCLUDE_VALUETYPE_IMPL_H + +#include "DynValue_TestC.h" + +//============= Factory_id helper mix-in class =========== + +class factory_id : public virtual CORBA::ValueFactoryBase +{ +public: + virtual const char * id () const = 0; +}; + +//============= "BaseValue" Value Type implimentation ======= + +class BaseValue_impl : public virtual OBV_DynValue_Test::BaseValue, + public virtual CORBA::DefaultValueRefCountBase +{ +public: + BaseValue_impl () {} + BaseValue_impl (CORBA::UShort us1, CORBA::UShort us2) + :BaseValue (us1,us2) {} + virtual ~BaseValue_impl (); + virtual CORBA::ValueBase * _copy_value (void); + virtual void print (); +}; + +class BaseValue_Factory : public factory_id +{ +public: + const char * id () const; + virtual CORBA::ValueBase * create_for_unmarshal (); +}; + +//============= "Nested" Value Type implimentation ======= + +class NestedValue_impl : public virtual OBV_DynValue_Test::NestedValue, + public virtual CORBA::DefaultValueRefCountBase +{ +public: + NestedValue_impl () {} + NestedValue_impl (CORBA::Short s1, CORBA::Short s2) + :NestedValue (s1,s2) {} + virtual ~NestedValue_impl (); + virtual CORBA::ValueBase * _copy_value (void); +}; + +class NestedValue_Factory : public factory_id +{ +public: + const char * id () const; + virtual CORBA::ValueBase * create_for_unmarshal (); +}; + +//============= "Null" Value Type implimentation ======= + +class NullValue_impl : public virtual OBV_DynValue_Test::NullValue, + public virtual CORBA::DefaultValueRefCountBase +{ +public: + NullValue_impl () {} + virtual ~NullValue_impl (); + virtual CORBA::ValueBase * _copy_value (void); +}; + +class NullValue_Factory : public factory_id +{ +public: + const char * id () const; + virtual CORBA::ValueBase * create_for_unmarshal (); +}; + +//============= "Trunc" Value Type implimentation ======= + +class Trunc_impl : public virtual OBV_DynValue_Test::Trunc, + public virtual CORBA::DefaultValueRefCountBase +{ +public: + Trunc_impl () {} + Trunc_impl ( + CORBA::UShort us1, + CORBA::UShort us2, + DynValue_Test::BoxedLong *bl, + NestedValue_impl *nv1, + NullValue_impl *nv2, + NullValue_impl *nv3, + NullValue_impl *nv4) + { + this->Base_us1 (us1); + this->Base_us2 (us2); + this->Trunc_bl (bl); + this->Trunc_nested (nv1); + this->Trunc_null1 (nv2); + this->Trunc_null2 (nv3); + this->Trunc_null3 (nv4); + } + virtual ~Trunc_impl (); + virtual CORBA::ValueBase * _copy_value (); + virtual void print (); +}; + +class Trunc_Factory : public factory_id +{ +public: + const char * id () const; + virtual CORBA::ValueBase * create_for_unmarshal (); +}; + +#endif // INCLUDE_VALUETYPE_IMPL_H diff --git a/TAO/tests/DynValue_Test/main.cpp b/TAO/tests/DynValue_Test/main.cpp new file mode 100644 index 00000000000..79936879319 --- /dev/null +++ b/TAO/tests/DynValue_Test/main.cpp @@ -0,0 +1,1231 @@ +// $Id$ + +#include "Analyzer.h" + +//============= Test main() ============ +int ACE_TMAIN (int argc, ACE_TCHAR *argv[]) +{ + try + { + DynAnyAnalyzer analyzer (argc, argv); + + //////////////////////////////////////////// + // DynValue_Test::BoxedLong + //////////////////////////////////////////// + + const CORBA::Long l1= -157; + + ACE_DEBUG ((LM_DEBUG, + "%N:%l Creating DynValue_Test::BoxedLong\n")); + DynValue_Test::BoxedLong *p_myBoxedLong =0; + ACE_NEW_THROW_EX ( + p_myBoxedLong, + DynValue_Test::BoxedLong (l1), + CORBA::NO_MEMORY ()); + DynValue_Test::BoxedLong_var myBoxedLong (p_myBoxedLong); + ACE_DEBUG ((LM_DEBUG, + "..%N:%l checking value, long is %d\n", + myBoxedLong->_value () )); + if (l1 != myBoxedLong->_value ()) + { + ACE_DEBUG ((LM_DEBUG, + "..%N:%l FAILED should have been %d\n", l1)); + return 1; + } + + ACE_DEBUG ((LM_DEBUG, "..%N:%l Inserting into an any\n")); + CORBA::Any myAny; + myAny <<= myBoxedLong.in (); + + ACE_DEBUG ((LM_DEBUG, "..%N:%l Extracting from an any\n")); + DynValue_Test::BoxedLong + *myBoxedLongExtracted = + reinterpret_cast<DynValue_Test::BoxedLong *> (9); + if (!(myAny >>= myBoxedLongExtracted)) + { + ACE_DEBUG ((LM_DEBUG, "..%N:%l FAILED extraction\n")); + return 1; + } + if (!myBoxedLongExtracted) + { + ACE_DEBUG ((LM_DEBUG, + "..%N:%l FAILED Null pointer extracted\n")); + return 1; + } + if (reinterpret_cast<DynValue_Test::BoxedLong *> (9) + == myBoxedLongExtracted) + { + ACE_DEBUG ((LM_DEBUG, "..%N:%l FAILED pointer NOT extracted\n")); + return 1; + } + ACE_DEBUG ((LM_DEBUG, + "..%N:%l checking value, long is %d\n", + myBoxedLongExtracted->_value () )); + if (l1 != myBoxedLongExtracted->_value ()) + { + ACE_DEBUG ((LM_DEBUG, + "..%N:%l FAILED should have been %d\n", l1)); + return 1; + } + + ACE_DEBUG ((LM_DEBUG, "..%N:%l Creating dynamic any from any\n")); + DynamicAny::DynAny_var dany_boxed (analyzer.DynAny (myAny)); + analyzer.analyze (dany_boxed.in ()); + + ACE_DEBUG ((LM_DEBUG, "..%N:%l Testing dynamic any for non-null\n")); + DynamicAny::DynValueCommon *dvc = + dynamic_cast<DynamicAny::DynValueCommon *> (dany_boxed.in ()); + if (!dvc) + { + ACE_DEBUG ((LM_DEBUG, + "..%N:%l FAILURE can not obtain DynamicAny::DynValueCommon *\n")); + return 1; + } + if (dvc->is_null ()) + { + ACE_DEBUG ((LM_DEBUG, "..%N:%l FAILED this dynamic any is NULL!\n")); + return 1; + } + + ACE_DEBUG ((LM_DEBUG, + "..%N:%l Creating dynamic any from IDL generated typecode\n")); + DynamicAny::DynAny_var + dany (analyzer.DynAny (DynValue_Test::_tc_BoxedLong)); + analyzer.analyze (dany.in ()); + + ACE_DEBUG ((LM_DEBUG, + "..%N:%l Testing typecode generated dynamic any for null\n")); + dvc= dynamic_cast<DynamicAny::DynValueCommon *> (dany.in ()); + if (!dvc) + { + ACE_DEBUG ((LM_DEBUG, + "..%N:%l FAILURE can not obtain DynamicAny::DynValueCommon\n")); + return 1; + } + if (!(dvc->is_null ())) + { + ACE_DEBUG ((LM_DEBUG, + "..%N:%l FAILED this dynamic any has a value!\n")); + return 1; + } + + ACE_DEBUG ((LM_DEBUG, + "..%N:%l Testing for inequality with original dyanamic any\n")); + if (dany->equal (dany_boxed.in ())) + { + ACE_DEBUG ((LM_DEBUG, + "..%N:%l FAILED they test equal before setting shorts\n")); + return 1; + } + + ACE_DEBUG ((LM_DEBUG, + "..%N:%l Setting to value and test for inequality with original dyanamic any\n")); + dvc->set_to_value (); + analyzer.analyze (dany.in ()); + if (dany->equal (dany_boxed.in ())) + { + ACE_DEBUG ((LM_DEBUG, + "..%N:%l FAILED they test equal before setting long\n")); + return 1; + } + + ACE_DEBUG ((LM_DEBUG, + "..%N:%l Setting the long of the typecode generated dynamic any\n")); + dany->insert_long (l1); + analyzer.analyze (dany.in ()); + + ACE_DEBUG ((LM_DEBUG, + "..%N:%l Testing for equality with original dyanamic any\n")); + if (!(dany->equal (dany_boxed.in ()))) + { + ACE_DEBUG ((LM_DEBUG, + "..%N:%l FAILED they test unequal after setting long\n")); + return 1; + } + + ACE_DEBUG ((LM_DEBUG, + "..%N:%l Setting typecode dynamic any back to NULL\n")); + dvc->set_to_null (); + analyzer.analyze (dany.in ()); + + ACE_DEBUG ((LM_DEBUG, + "..%N:%l Setting the original dynamic any to NULL object\n")); + dvc= dynamic_cast<DynamicAny::DynValueCommon *> (dany_boxed.in ()); + if (!dvc) + { + ACE_DEBUG ((LM_DEBUG, + "..%N:%l FAILURE can not obtain DynamicAny::DynValueCommon *\n")); + return 1; + } + dvc->set_to_null (); + analyzer.analyze (dany_boxed.in ()); + + ACE_DEBUG ((LM_DEBUG, + "..%N:%l Testing for equality with typecode dyanamic any\n")); + if (!(dany->equal (dany_boxed.in ()))) + { + ACE_DEBUG ((LM_DEBUG, "..%N:%l FAILED they test unequal!\n")); + return 1; + } + + ACE_DEBUG ((LM_DEBUG, + "..%N:%l Converting from NULL dynamic any back to any\n")); + CORBA::Any_var myAny_var (dany_boxed->to_any ()); + + ACE_DEBUG ((LM_DEBUG, "..%N:%l Extracting from this any\n")); + myBoxedLongExtracted= + reinterpret_cast<DynValue_Test::BoxedLong *> (9); + if (!(myAny_var.in () >>= myBoxedLongExtracted)) + { + ACE_DEBUG ((LM_DEBUG, "..%N:%l FAILED extraction\n")); + return 1; + } + if (reinterpret_cast<DynValue_Test::BoxedLong *> (9) + == myBoxedLongExtracted) + { + ACE_DEBUG ((LM_DEBUG, "..%N:%l FAILED pointer NOT extracted\n")); + return 1; + } + if (myBoxedLongExtracted) + { + ACE_DEBUG ((LM_DEBUG, "..%N:%l FAILED non-null pointer extracted\n")); + return 1; + } + + ACE_DEBUG ((LM_DEBUG, "..%N:%l Setting the dynamic any to VALUE object\n")); + dvc->set_to_value (); + analyzer.analyze (dany_boxed.in ()); + + ACE_DEBUG ((LM_DEBUG, + "..%N:%l Resetting Typecode dynamic any from original any\n")); + dany->from_any (myAny); + analyzer.analyze (dany.in ()); + + ACE_DEBUG ((LM_DEBUG, + "..%N:%l Testing for equality with original dyanamic any\n")); + if (!(dany->equal (dany_boxed.in ()))) + { + ACE_DEBUG ((LM_DEBUG, "..%N:%l FAILED they test unequal!\n")); + return 1; + } + + ACE_DEBUG ((LM_DEBUG, + "..%N:%l Converting from dynamic any back to any\n")); + myAny_var = dany_boxed->to_any (); + + ACE_DEBUG ((LM_DEBUG, "..%N:%l Extracting from this any\n")); + myBoxedLongExtracted= + reinterpret_cast<DynValue_Test::BoxedLong *> (9); + if (!(myAny_var.in () >>= myBoxedLongExtracted)) + { + ACE_DEBUG ((LM_DEBUG, "..%N:%l FAILED extraction\n")); + return 1; + } + if (!myBoxedLongExtracted) + { + ACE_DEBUG ((LM_DEBUG, "..%N:%l FAILED null pointer extracted\n")); + return 1; + } + if (reinterpret_cast<DynValue_Test::BoxedLong *> (9) + == myBoxedLongExtracted) + { + ACE_DEBUG ((LM_DEBUG, "..%N:%l FAILED pointer NOT extracted\n")); + return 1; + } + ACE_DEBUG ((LM_DEBUG, + "..%N:%l checking value, long is %d\n", + myBoxedLongExtracted->_value () )); + if (l1 != myBoxedLongExtracted->_value ()) + { + ACE_DEBUG ((LM_DEBUG, + "..%N:%l FAILED should have been %d\n", l1)); + return 1; + } + + ACE_DEBUG ((LM_DEBUG, + "..%N:%l Attempting to get_long from dynamic any\n")); + CORBA::Long myLongExtracted = dany_boxed->get_long (); + ACE_DEBUG ((LM_DEBUG, + "..%N:%l checking value, long is %d\n", + myLongExtracted )); + if (l1 != myLongExtracted) + { + ACE_DEBUG ((LM_DEBUG, + "..%N:%l FAILED should have been %d\n", l1)); + return 1; + } + + //////////////////////////////////////////// + // DynValue_Test::NestedValue + //////////////////////////////////////////// + + const CORBA::Short s1= -17; + const CORBA::Short s2= -23; + + ACE_DEBUG ((LM_DEBUG, + "\n%N:%l Creating DynValue_Test::NestedValue\n")); + DynValue_Test::NestedValue *p_myNestedValue =0; + ACE_NEW_THROW_EX ( + p_myNestedValue, + NestedValue_impl(s1, s2), + CORBA::NO_MEMORY ()); + DynValue_Test::NestedValue_var myNestedValue (p_myNestedValue); + ACE_DEBUG ((LM_DEBUG, + "..%N:%l checking value, shorts are %hd, %hd\n", + myNestedValue->Nested_s1 (), + myNestedValue->Nested_s2 () )); + if (s1 != myNestedValue->Nested_s1 () || + s2 != myNestedValue->Nested_s2 ()) + { + ACE_DEBUG ((LM_DEBUG, + "..%N:%l FAILED should have been %hd, %hd\n", + s1, s2)); + return 1; + } + + ACE_DEBUG ((LM_DEBUG, "..%N:%l Inserting into an any\n")); + myAny <<= myNestedValue.in (); + + ACE_DEBUG ((LM_DEBUG, "..%N:%l Extracting from an any\n")); + DynValue_Test::NestedValue::_ptr_type + myNestedValueExtracted = + reinterpret_cast<DynValue_Test::NestedValue::_ptr_type> (9); + if (!(myAny >>= myNestedValueExtracted)) + { + ACE_DEBUG ((LM_DEBUG, "..%N:%l FAILED extraction\n")); + return 1; + } + if (!myNestedValueExtracted) + { + ACE_DEBUG ((LM_DEBUG, + "..%N:%l FAILED Null pointer extracted\n")); + return 1; + } + if (reinterpret_cast<DynValue_Test::NestedValue::_ptr_type> (9) + == myNestedValueExtracted) + { + ACE_DEBUG ((LM_DEBUG, "..%N:%l FAILED pointer NOT extracted\n")); + return 1; + } + ACE_DEBUG ((LM_DEBUG, "..%N:%l checking value, shorts are %hd, %hd\n", + myNestedValueExtracted->Nested_s1 (), + myNestedValueExtracted->Nested_s2 ())); + if (s1 != myNestedValueExtracted->Nested_s1 () || + s2 != myNestedValueExtracted->Nested_s2 () ) + { + ACE_DEBUG ((LM_DEBUG, + "..%N:%l FAILED should have been %hd, %hd\n", s1, s2)); + return 1; + } + + ACE_DEBUG ((LM_DEBUG, "..%N:%l Creating dynamic any from any\n")); + DynamicAny::DynAny_var dany_nested = analyzer.DynAny (myAny); + analyzer.analyze (dany_nested.in ()); + + ACE_DEBUG ((LM_DEBUG, "..%N:%l Testing dynamic any for non-null\n")); + dvc = dynamic_cast<DynamicAny::DynValueCommon *> + (dany_nested.in ()); + if (!dvc) + { + ACE_DEBUG ((LM_DEBUG, + "..%N:%l FAILURE can not obtain DynamicAny::DynValueCommon *\n")); + return 1; + } + if (dvc->is_null ()) + { + ACE_DEBUG ((LM_DEBUG, "..%N:%l FAILED this dynamic any is NULL!\n")); + return 1; + } + + ACE_DEBUG ((LM_DEBUG, + "..%N:%l Creating dynamic any from IDL generated typecode\n")); + dany = analyzer.DynAny (DynValue_Test::_tc_NestedValue); + analyzer.analyze (dany.in ()); + + ACE_DEBUG ((LM_DEBUG, + "..%N:%l Testing typecode generated dynamic any for null\n")); + dvc= dynamic_cast<DynamicAny::DynValueCommon *> (dany.in ()); + if (!dvc) + { + ACE_DEBUG ((LM_DEBUG, + "..%N:%l FAILURE can not obtain DynamicAny::DynValueCommon\n")); + return 1; + } + if (!(dvc->is_null ())) + { + ACE_DEBUG ((LM_DEBUG, + "..%N:%l FAILED this dynamic any has a value!\n")); + return 1; + } + + ACE_DEBUG ((LM_DEBUG, + "..%N:%l Testing for inequality with original dyanamic any\n")); + if (dany->equal (dany_nested.in ())) + { + ACE_DEBUG ((LM_DEBUG, + "..%N:%l FAILED they test equal before setting shorts\n")); + return 1; + } + + ACE_DEBUG ((LM_DEBUG, + "..%N:%l Setting to value and test for inequality with original dyanamic any\n")); + dvc->set_to_value (); + analyzer.analyze (dany.in ()); + if (dany->equal (dany_nested.in ())) + { + ACE_DEBUG ((LM_DEBUG, + "..%N:%l FAILED they test equal before setting shorts\n")); + return 1; + } + + ACE_DEBUG ((LM_DEBUG, + "..%N:%l Setting the shorts of the typecode generated dynamic any\n")); + dany->rewind (); + dany->insert_short (s1); + if (!(dany->next ())) + { + ACE_DEBUG ((LM_DEBUG, "..%N:%l FAILED to move on to second short\n")); + return 1; + } + dany->insert_short (s2); + analyzer.analyze (dany.in ()); + + ACE_DEBUG ((LM_DEBUG, + "..%N:%l Testing for equality with original dyanamic any\n")); + if (!(dany->equal (dany_nested.in ()))) + { + ACE_DEBUG ((LM_DEBUG, + "..%N:%l FAILED they test unequal after setting shorts\n")); + return 1; + } + + ACE_DEBUG ((LM_DEBUG, + "..%N:%l Setting typecode dynamic any back to NULL\n")); + dvc->set_to_null (); + analyzer.analyze (dany.in ()); + + ACE_DEBUG ((LM_DEBUG, + "..%N:%l Setting the original dynamic any to NULL object\n")); + dvc= dynamic_cast<DynamicAny::DynValueCommon *> (dany_nested.in ()); + if (!dvc) + { + ACE_DEBUG ((LM_DEBUG, + "..%N:%l FAILURE can not obtain DynamicAny::DynValueCommon *\n")); + return 1; + } + dvc->set_to_null (); + analyzer.analyze (dany_nested.in ()); + + ACE_DEBUG ((LM_DEBUG, + "..%N:%l Testing for equality with typecode dyanamic any\n")); + if (!(dany->equal (dany_nested.in ()))) + { + ACE_DEBUG ((LM_DEBUG, "..%N:%l FAILED they test unequal!\n")); + return 1; + } + + ACE_DEBUG ((LM_DEBUG, + "..%N:%l Converting from NULL dynamic any back to any\n")); + myAny_var = dany_nested->to_any (); + + ACE_DEBUG ((LM_DEBUG, "..%N:%l Extracting from this any\n")); + myNestedValueExtracted= + reinterpret_cast<DynValue_Test::NestedValue::_ptr_type> (9); + if (!(myAny_var.in () >>= myNestedValueExtracted)) + { + ACE_DEBUG ((LM_DEBUG, "..%N:%l FAILED extraction\n")); + return 1; + } + if (reinterpret_cast<DynValue_Test::NestedValue::_ptr_type> (9) + == myNestedValueExtracted) + { + ACE_DEBUG ((LM_DEBUG, "..%N:%l FAILED pointer NOT extracted\n")); + return 1; + } + if (myNestedValueExtracted) + { + ACE_DEBUG ((LM_DEBUG, "..%N:%l FAILED non-null pointer extracted\n")); + return 1; + } + + ACE_DEBUG ((LM_DEBUG, "..%N:%l Setting the dynamic any to VALUE object\n")); + dvc->set_to_value (); + analyzer.analyze (dany_nested.in ()); + + ACE_DEBUG ((LM_DEBUG, + "..%N:%l Resetting Typecode dynamic any from original any\n")); + dany->from_any (myAny); + analyzer.analyze (dany.in ()); + + ACE_DEBUG ((LM_DEBUG, + "..%N:%l Testing for equality with original dyanamic any\n")); + if (!(dany->equal (dany_nested.in ()))) + { + ACE_DEBUG ((LM_DEBUG, "..%N:%l FAILED they test unequal!\n")); + return 1; + } + + ACE_DEBUG ((LM_DEBUG, + "..%N:%l Converting from dynamic any back to any\n")); + myAny_var = dany_nested->to_any (); + + ACE_DEBUG ((LM_DEBUG, + "..%N:%l Attempting to extract from this any (without factory)\n")); + myNestedValueExtracted= + reinterpret_cast<DynValue_Test::NestedValue::_ptr_type> (9); + if (myAny_var.in () >>= myNestedValueExtracted) + { + ACE_DEBUG ((LM_DEBUG, + "..%N:%l FAILED the extraction occured without factory\n")); + return 1; + } + + ACE_DEBUG ((LM_DEBUG, + "..%N:%l Attempting to get_val from dynamic any (without factory)\n")); + try + { + myNestedValueExtracted= + dynamic_cast<DynValue_Test::NestedValue*> ( + dany_nested->get_val ()); + if (myNestedValueExtracted) + { + ACE_DEBUG ((LM_DEBUG, + "..%N:%l FAILED get_val successful without factory\n")); + return 1; + } + } + catch (const CORBA::MARSHAL &) + { + // Expected with no factory registered + } + + CORBA::ValueFactoryBase *vf= 0; + ACE_NEW_THROW_EX (vf, NestedValue_Factory, CORBA::NO_MEMORY ()); + analyzer.register_factory (vf); + + ACE_DEBUG ((LM_DEBUG, + "..%N:%l Extracting from this any (now with factory)\n")); + if (!(myAny_var.in () >>= myNestedValueExtracted)) + { + ACE_DEBUG ((LM_DEBUG, "..%N:%l FAILED the extraction\n")); + return 1; + } + if (!myNestedValueExtracted) + { + ACE_DEBUG ((LM_DEBUG, "..%N:%l FAILED Null pointer extracted\n")); + return 1; + } + if (reinterpret_cast<DynValue_Test::NestedValue::_ptr_type> (9) + == myNestedValueExtracted) + { + ACE_DEBUG ((LM_DEBUG, "..%N:%l FAILED pointer NOT extracted\n")); + return 1; + } + ACE_DEBUG ((LM_DEBUG, "..%N:%l checking value, shorts are %hd, %hd\n", + myNestedValueExtracted->Nested_s1 (), + myNestedValueExtracted->Nested_s2 ())); + if (s1 != myNestedValueExtracted->Nested_s1 () || + s2 != myNestedValueExtracted->Nested_s2 () ) + { + ACE_DEBUG ((LM_DEBUG, + "..%N:%l FAILED should have been %hd, %hd\n", s1, s2)); + return 1; + } + + ACE_DEBUG ((LM_DEBUG, + "..%N:%l Attempting to get_val from dynamic any (now with factory)\n")); + myNestedValueExtracted= + dynamic_cast<DynValue_Test::NestedValue*> ( + dany_nested->get_val ()); + if (!myNestedValueExtracted) + { + ACE_DEBUG ((LM_DEBUG, + "..%N:%l FAILED get_val unsuccessful even with factory\n")); + return 1; + } + ACE_DEBUG ((LM_DEBUG, "..%N:%l checking value, shorts are %hd, %hd\n", + myNestedValueExtracted->Nested_s1 (), + myNestedValueExtracted->Nested_s2 ())); + if (s1 != myNestedValueExtracted->Nested_s1 () || + s2 != myNestedValueExtracted->Nested_s2 () ) + { + ACE_DEBUG ((LM_DEBUG, + "..%N:%l FAILED should have been %hd, %hd\n", s1, s2)); + return 1; + } + myNestedValueExtracted->_remove_ref (); + + //////////////////////////////////////////// + // DynValue_Test::NullValue + //////////////////////////////////////////// + + ACE_DEBUG ((LM_DEBUG, "\n%N:%l Creating DynValue_Test::NullValue\n")); + DynValue_Test::NullValue *p_myNullValue =0; + ACE_NEW_THROW_EX (p_myNullValue, NullValue_impl, CORBA::NO_MEMORY ()); + DynValue_Test::NullValue_var myNullValue (p_myNullValue); + + ACE_DEBUG ((LM_DEBUG, "..%N:%l Inserting into an any\n")); + myAny <<= myNullValue.in (); + + ACE_DEBUG ((LM_DEBUG, "..%N:%l Extracting from an any\n")); + DynValue_Test::NullValue::_ptr_type myNullValueExtracted= + reinterpret_cast<DynValue_Test::NullValue::_ptr_type> (9); + if (!(myAny >>= myNullValueExtracted)) + { + ACE_DEBUG ((LM_DEBUG, "..%N:%l FAILED extraction\n")); + return 1; + } + if (!myNullValueExtracted) + { + ACE_DEBUG ((LM_DEBUG, "..%N:%l FAILED Null pointer extracted\n")); + return 1; + } + if (reinterpret_cast<DynValue_Test::NullValue::_ptr_type> (9) + == myNullValueExtracted) + { + ACE_DEBUG ((LM_DEBUG, "..%N:%l FAILED pointer NOT extracted\n")); + return 1; + } + + ACE_DEBUG ((LM_DEBUG, "..%N:%l Creating dynamic any from any\n")); + DynamicAny::DynAny_var dany_null (analyzer.DynAny (myAny)); + analyzer.analyze (dany_null.in ()); + + ACE_DEBUG ((LM_DEBUG, "..%N:%l Testing dynamic any for non-null\n")); + dvc= dynamic_cast<DynamicAny::DynValueCommon *> (dany_null.in ()); + if (!dvc) + { + ACE_DEBUG ((LM_DEBUG, + "..%N:%l FAILURE can not obtain DynamicAny::DynValueCommon *\n")); + return 1; + } + if (dvc->is_null ()) + { + ACE_DEBUG ((LM_DEBUG, "..%N:%l FAILED this dynamic any is NULL!\n")); + return 1; + } + + ACE_DEBUG ((LM_DEBUG, + "..%N:%l Creating dynamic any from IDL generated typecode\n")); + dany = analyzer.DynAny (DynValue_Test::_tc_NullValue); + analyzer.analyze (dany.in ()); + + ACE_DEBUG ((LM_DEBUG, + "..%N:%l Testing typecode generated dynamic any for null\n")); + dvc= dynamic_cast<DynamicAny::DynValueCommon *> (dany.in ()); + if (!dvc) + { + ACE_DEBUG ((LM_DEBUG, + "..%N:%l FAILURE can not obtain DynamicAny::DynValueCommon *\n")); + return 1; + } + if (!(dvc->is_null ())) + { + ACE_DEBUG ((LM_DEBUG, "..%N:%l FAILED this dynamic any has a value!\n")); + return 1; + } + + ACE_DEBUG ((LM_DEBUG, + "..%N:%l Testing for inequality with original dyanamic any\n")); + if (dany->equal (dany_null.in ())) + { + ACE_DEBUG ((LM_DEBUG, + "..%N:%l FAILED they test equal before setting to a value\n")); + return 1; + } + + ACE_DEBUG ((LM_DEBUG, + "..%N:%l Setting to value and test for equality with original dyanamic any\n")); + dvc->set_to_value (); + analyzer.analyze (dany.in ()); + if (!(dany->equal (dany_null.in ()))) + { + ACE_DEBUG ((LM_DEBUG, "..%N:%l FAILED they test unequal\n")); + return 1; + } + + ACE_DEBUG ((LM_DEBUG, "..%N:%l Setting typecode dynamic any back to NULL\n")); + dvc->set_to_null (); + analyzer.analyze (dany.in ()); + + ACE_DEBUG ((LM_DEBUG, "..%N:%l Setting the original dynamic any to NULL object\n")); + dvc= dynamic_cast<DynamicAny::DynValueCommon *> (dany_null.in ()); + if (!dvc) + { + ACE_DEBUG ((LM_DEBUG, + "..%N:%l FAILURE can not obtain DynamicAny::DynValueCommon\n")); + return 1; + } + dvc->set_to_null (); + analyzer.analyze (dany_null.in ()); + + ACE_DEBUG ((LM_DEBUG, "..%N:%l Testing for equality with typecode dyanamic any\n")); + if (!(dany->equal (dany_null.in ()))) + { + ACE_DEBUG ((LM_DEBUG, "..%N:%l FAILED they test unequal!\n")); + return 1; + } + + ACE_DEBUG ((LM_DEBUG, "..%N:%l Converting from NULL dynamic any back to any\n")); + myAny_var= dany_null->to_any (); + + ACE_DEBUG ((LM_DEBUG, "..%N:%l Extracting from this any\n")); + myNullValueExtracted= reinterpret_cast<DynValue_Test::NullValue::_ptr_type> (9); + if (!(myAny_var.in () >>= myNullValueExtracted)) + { + ACE_DEBUG ((LM_DEBUG, "..%N:%l FAILED extraction\n")); + return 1; + } + if (reinterpret_cast<DynValue_Test::NullValue::_ptr_type> (9) + == myNullValueExtracted) + { + ACE_DEBUG ((LM_DEBUG, "..%N:%l FAILED pointer NOT extracted\n")); + return 1; + } + if (myNullValueExtracted) + { + ACE_DEBUG ((LM_DEBUG, "..%N:%l FAILED non-null pointer extracted\n")); + return 1; + } + + ACE_DEBUG ((LM_DEBUG, "..%N:%l Setting the original dynamic any to VALUE object\n")); + dvc->set_to_value (); + analyzer.analyze (dany_null.in ()); + + ACE_DEBUG ((LM_DEBUG, "..%N:%l Resetting Typecode dynamic any from original any\n")); + dany->from_any (myAny); + analyzer.analyze (dany.in ()); + + ACE_DEBUG ((LM_DEBUG, "..%N:%l Testing for equality with original dyanamic any\n")); + if (!(dany->equal (dany_null.in ()))) + { + ACE_DEBUG ((LM_DEBUG, "..%N:%l FAILED they test unequal!\n")); + return 1; + } + + ACE_DEBUG ((LM_DEBUG, "..%N:%l Converting from dynamic any back to any\n")); + myAny_var = dany_null->to_any (); + + ACE_DEBUG ((LM_DEBUG, "..%N:%l Attempting to extract from this any (without factory)\n")); + myNullValueExtracted= reinterpret_cast<DynValue_Test::NullValue::_ptr_type> (9); + if (myAny_var.in () >>= myNullValueExtracted) + { + ACE_DEBUG ((LM_DEBUG, "..%N:%l FAILED the extraction occured without factory\n")); + return 1; + } + + ACE_DEBUG ((LM_DEBUG, "..%N:%l Attempting to get_val from dynamic any (without factory)\n")); + try + { + myNullValueExtracted= dynamic_cast<DynValue_Test::NullValue*> (dany_null->get_val ()); + if (myNullValueExtracted) + { + ACE_DEBUG ((LM_DEBUG, "..%N:%l FAILED get_val successful without factory\n")); + return 1; + } + } + catch (const CORBA::MARSHAL &) + { + // Expected with no factory registered + } + + ACE_NEW_THROW_EX (vf, NullValue_Factory, CORBA::NO_MEMORY ()); + analyzer.register_factory (vf); + + ACE_DEBUG ((LM_DEBUG, "..%N:%l Extracting from this any (now with factory)\n")); + if (!(myAny_var.in () >>= myNullValueExtracted)) + { + ACE_DEBUG ((LM_DEBUG, "..%N:%l FAILED the extraction\n")); + return 1; + } + if (!myNullValueExtracted) + { + ACE_DEBUG ((LM_DEBUG, "..%N:%l FAILED Null pointer extracted\n")); + return 1; + } + if (reinterpret_cast<DynValue_Test::NullValue::_ptr_type> (9) == myNullValueExtracted) + { + ACE_DEBUG ((LM_DEBUG, "..%N:%l FAILED pointer NOT extracted\n")); + return 1; + } + + ACE_DEBUG ((LM_DEBUG, "..%N:%l Attempting to get_val from dynamic any (now with factory)\n")); + myNullValueExtracted= dynamic_cast<DynValue_Test::NullValue*> (dany_null->get_val ()); + if (!myNullValueExtracted) + { + ACE_DEBUG ((LM_DEBUG, "..%N:%l FAILED get_val unsuccessful even with factory\n")); + return 1; + } + myNullValueExtracted->_remove_ref (); + + //////////////////////////////////////////// + // DynValue_Test::Trunc + //////////////////////////////////////////// + + const CORBA::Short us1= 12345; + const CORBA::Short us2= 321; + + DynValue_Test::NullValue *p_myNullValue2 =0; + ACE_NEW_THROW_EX (p_myNullValue2, NullValue_impl, CORBA::NO_MEMORY ()); + DynValue_Test::NullValue_var myNullValue2 (p_myNullValue2); + + ACE_DEBUG ((LM_DEBUG, "\n%N:%l Creating DynValue_Test::Trunc\n")); + DynValue_Test::Trunc *p_myTrunc =0; + ACE_NEW_THROW_EX ( + p_myTrunc, + Trunc_impl ( + us1, + us2, + myBoxedLong.in (), + dynamic_cast<NestedValue_impl *> (myNestedValue.in ()), + dynamic_cast<NullValue_impl *> (myNullValue.in ()), + dynamic_cast<NullValue_impl *> (myNullValue.in ()), + dynamic_cast<NullValue_impl *> (myNullValue2.in ()) ), + CORBA::NO_MEMORY ()); + DynValue_Test::Trunc_var myTrunc (p_myTrunc); + + ACE_DEBUG ((LM_DEBUG, "..%N:%l checking embedded values, ")); + myTrunc->print (); + if (us1 != myTrunc.in ()->Base_us1 () || + us2 != myTrunc.in ()->Base_us2 () || + l1 != myTrunc.in ()->Trunc_bl()->_value () || + s1 != myTrunc.in ()->Trunc_nested()->Nested_s1 () || + s2 != myTrunc.in ()->Trunc_nested()->Nested_s2 () ) + { + ACE_DEBUG ((LM_DEBUG, "..%N:%l FAILED should have been %u, %u, %d and %d, %d\n", us1, us2, l1, s1, s2)); + return 1; + } + + ACE_DEBUG ((LM_DEBUG, "..%N:%l Inserting into an any\n")); + myAny <<= myTrunc.in (); + + ACE_DEBUG ((LM_DEBUG, "..%N:%l Extracting from an any\n")); + DynValue_Test::Trunc::_ptr_type myTruncExtracted= + reinterpret_cast<DynValue_Test::Trunc::_ptr_type> (9); + if (!(myAny >>= myTruncExtracted)) + { + ACE_DEBUG ((LM_DEBUG, "..%N:%l FAILED extraction\n")); + return 1; + } + if (!myTruncExtracted) + { + ACE_DEBUG ((LM_DEBUG, "..%N:%l FAILED Null pointer extracted\n")); + return 1; + } + ACE_DEBUG ((LM_DEBUG, "..%N:%l checking embedded values, ")); + myTruncExtracted->print (); + if (us1 != myTruncExtracted->Base_us1 () || + us2 != myTruncExtracted->Base_us2 () || + l1 != myTruncExtracted->Trunc_bl()->_value () || + s1 != myTruncExtracted->Trunc_nested()->Nested_s1 () || + s2 != myTruncExtracted->Trunc_nested()->Nested_s2 () ) + { + ACE_DEBUG ((LM_DEBUG, "..%N:%l FAILED should have been %u, %u, %d and %d, %d\n", us1, us2, l1, s1, s2)); + return 1; + } + + ACE_DEBUG ((LM_DEBUG, "..%N:%l Creating dynamic any from any\n")); + DynamicAny::DynAny_var dany_trunc (analyzer.DynAny (myAny)); + analyzer.analyze (dany_trunc.in ()); + + ACE_DEBUG ((LM_DEBUG, "..%N:%l Testing dynamic any for non-null\n")); + dvc= dynamic_cast<DynamicAny::DynValueCommon *> (dany_trunc.in ()); + if (!dvc) + { + ACE_DEBUG ((LM_DEBUG, "..%N:%l FAILURE can not obtain DynamicAny::DynValueCommon *\n")); + return 1; + } + if (dvc->is_null ()) + { + ACE_DEBUG ((LM_DEBUG, "..%N:%l FAILED this dynamic any is NULL!\n")); + return 1; + } + + ACE_DEBUG ((LM_DEBUG, "..%N:%l Creating dynamic any from IDL generated typecode DynValue_Test::_tc_Trunc\n")); + dany = analyzer.DynAny (DynValue_Test::_tc_Trunc); + analyzer.analyze (dany.in ()); + + ACE_DEBUG ((LM_DEBUG, "..%N:%l Testing typecode generated dynamic any for null\n")); + dvc= dynamic_cast<DynamicAny::DynValueCommon *> (dany.in ()); + if (!dvc) + { + ACE_DEBUG ((LM_DEBUG, "..%N:%l FAILURE can not obtain DynamicAny::DynValueCommon *\n")); + return 1; + } + if (!(dvc->is_null ())) + { + ACE_DEBUG ((LM_DEBUG, "..%N:%l FAILED this dynamic any has a value!\n")); + return 1; + } + + ACE_DEBUG ((LM_DEBUG, "..%N:%l Testing for inequality with original dyanamic any\n")); + if (dany->equal (dany_trunc.in ())) + { + ACE_DEBUG ((LM_DEBUG, "..%N:%l FAILED they test equal before setting shorts\n")); + return 1; + } + + ACE_DEBUG ((LM_DEBUG, "..%N:%l Setting to value and testing for inequality with original dyanamic any\n")); + dvc->set_to_value (); + analyzer.analyze (dany.in ()); + if (dany->equal (dany_trunc.in ())) + { + ACE_DEBUG ((LM_DEBUG, "..%N:%l FAILED they test equal before setting members\n")); + return 1; + } + + ACE_DEBUG ((LM_DEBUG, "..%N:%l Setting the members of the typecode generated dynamic any\n")); + dany->rewind (); + dany->insert_ushort (us1); + if (!(dany->next ())) + { + ACE_DEBUG ((LM_DEBUG, "..%N:%l FAILED to move on to 2nd member\n")); + return 1; + } + dany->insert_ushort (us2); + if (!(dany->next ())) + { + ACE_DEBUG ((LM_DEBUG, "..%N:%l FAILED to move on to 3rd member\n")); + return 1; + } + DynamicAny::DynValueCommon_var + dmem (dynamic_cast<DynamicAny::DynValueCommon *> (dany->current_component ())); + if (!dmem.in()) + { + ACE_DEBUG ((LM_DEBUG, "..%N:%l FAILURE can not obtain 3rd current_component ()\n")); + return 1; + } + dmem->set_to_value (); + dmem->insert_long (l1); + if (!(dany->next ())) + { + ACE_DEBUG ((LM_DEBUG, "..%N:%l FAILED to move on to 4th member\n")); + return 1; + } + dmem= dynamic_cast<DynamicAny::DynValueCommon *> (dany->current_component ()); + if (!dmem.in()) + { + ACE_DEBUG ((LM_DEBUG, "..%N:%l FAILURE can not obtain 4th current_component ()\n")); + return 1; + } + dmem->set_to_value (); + dmem->insert_val (myNestedValue.in ()); + if (!(dany->next ())) + { + ACE_DEBUG ((LM_DEBUG, "..%N:%l FAILED to move on to 5th member\n")); + return 1; + } + dmem= dynamic_cast<DynamicAny::DynValueCommon *> (dany->current_component ()); + if (!dmem.in()) + { + ACE_DEBUG ((LM_DEBUG, "..%N:%l FAILURE can not obtain 5th current_component ()\n")); + return 1; + } + dmem->set_to_value (); + dmem->insert_val (myNullValue.in ()); + if (!(dany->next ())) + { + ACE_DEBUG ((LM_DEBUG, "..%N:%l FAILED to move on to 6th member\n")); + return 1; + } + dmem= dynamic_cast<DynamicAny::DynValueCommon *> (dany->current_component ()); + if (!dmem.in()) + { + ACE_DEBUG ((LM_DEBUG, "..%N:%l FAILURE can not obtain 6th current_component ()\n")); + return 1; + } + dmem->set_to_value (); + dmem->insert_val (myNullValue.in ()); + if (!(dany->next ())) + { + ACE_DEBUG ((LM_DEBUG, "..%N:%l FAILED to move on to 7th member\n")); + return 1; + } + dmem= dynamic_cast<DynamicAny::DynValueCommon *> (dany->current_component ()); + if (!dmem.in()) + { + ACE_DEBUG ((LM_DEBUG, "..%N:%l FAILURE can not obtain 7th current_component ()\n")); + return 1; + } + dmem->set_to_value (); + dmem->insert_val (myNullValue2.in ()); + analyzer.analyze (dany.in ()); + + ACE_DEBUG ((LM_DEBUG, "..%N:%l Testing for equality with original dyanamic any\n")); + if (!(dany->equal (dany_trunc.in ()))) + { + ACE_DEBUG ((LM_DEBUG, "..%N:%l FAILED they test unequal after setting members\n")); + return 1; + } + + ACE_DEBUG ((LM_DEBUG, "..%N:%l Setting typecode dynamic any back to NULL\n")); + dvc->set_to_null (); + analyzer.analyze (dany.in ()); + + ACE_DEBUG ((LM_DEBUG, "..%N:%l Setting the original dynamic any to NULL object\n")); + dvc = dynamic_cast<DynamicAny::DynValueCommon *> (dany_trunc.in ()); + if (!dvc) + { + ACE_DEBUG ((LM_DEBUG, "..%N:%l FAILURE can not obtain DynamicAny::DynValueCommon *\n")); + return 1; + } + dvc->set_to_null (); + analyzer.analyze (dany_trunc.in ()); + + ACE_DEBUG ((LM_DEBUG, "..%N:%l Testing for equality with typecode dyanamic any\n")); + if (!(dany->equal (dany_trunc.in ()))) + { + ACE_DEBUG ((LM_DEBUG, "..%N:%l FAILED they test unequal!\n")); + return 1; + } + + ACE_DEBUG ((LM_DEBUG, "..%N:%l Converting from NULL dynamic any back to any\n")); + myAny_var= dany_trunc->to_any (); + + ACE_DEBUG ((LM_DEBUG, "..%N:%l Extracting from this any\n")); + myTruncExtracted= reinterpret_cast<DynValue_Test::Trunc::_ptr_type> (9); + if (!(myAny_var.in () >>= myTruncExtracted)) + { + ACE_DEBUG ((LM_DEBUG, "..%N:%l FAILED extraction\n")); + return 1; + } + if (reinterpret_cast<DynValue_Test::Trunc::_ptr_type> (9) == myTruncExtracted) + { + ACE_DEBUG ((LM_DEBUG, "..%N:%l FAILED pointer NOT extracted\n")); + return 1; + } + if (myTruncExtracted) + { + ACE_DEBUG ((LM_DEBUG, "..%N:%l FAILED non-null pointer extracted\n")); + return 1; + } + + ACE_DEBUG ((LM_DEBUG, "..%N:%l Setting the dynamic any to VALUE object\n")); + dvc->set_to_value (); + analyzer.analyze (dany_trunc.in ()); + + ACE_DEBUG ((LM_DEBUG, "..%N:%l Resetting Typecode dynamic any from original any\n")); + dany->from_any (myAny); + analyzer.analyze (dany.in ()); + + ACE_DEBUG ((LM_DEBUG, "..%N:%l Testing for equality with original dyanamic any\n")); + if (!(dany->equal (dany_trunc.in ()))) + { + ACE_DEBUG ((LM_DEBUG, "..%N:%l FAILED they test unequal!\n")); + return 1; + } + + ACE_DEBUG ((LM_DEBUG, "..%N:%l Converting from dynamic any back to any\n")); + myAny_var = dany_trunc->to_any (); + + ACE_DEBUG ((LM_DEBUG, "..%N:%l Attempting to extract from this any (without factory)\n")); + myTruncExtracted= reinterpret_cast<DynValue_Test::Trunc::_ptr_type> (9); + if (myAny_var.in () >>= myTruncExtracted) + { + ACE_DEBUG ((LM_DEBUG, "..%N:%l FAILED the extraction occured without factory\n")); + return 1; + } + + ACE_DEBUG ((LM_DEBUG, "..%N:%l Attempting to get_val from dynamic any (without factory)\n")); + try + { + myTruncExtracted= dynamic_cast<DynValue_Test::Trunc *> (dany_trunc->get_val ()); + if (myTruncExtracted) + { + ACE_DEBUG ((LM_DEBUG, "..%N:%l FAILED get_val successful without factory\n")); + return 1; + } + } + catch (const CORBA::MARSHAL &) + { + // Expected with no factory registered + } + + ACE_NEW_THROW_EX (vf, Trunc_Factory, CORBA::NO_MEMORY ()); + analyzer.register_factory (vf); + + ACE_DEBUG ((LM_DEBUG, "..%N:%l Extracting from this any (now with factory)\n")); + if (!(myAny_var.in () >>= myTruncExtracted)) + { + ACE_DEBUG ((LM_DEBUG, "..%N:%l FAILED extraction\n")); + return 1; + } + if (!myTruncExtracted) + { + ACE_DEBUG ((LM_DEBUG, "..%N:%l FAILED Null pointer extracted\n")); + return 1; + } + if (reinterpret_cast<DynValue_Test::Trunc::_ptr_type> (9) == myTruncExtracted) + { + ACE_DEBUG ((LM_DEBUG, "..%N:%l FAILED pointer NOT extracted\n")); + return 1; + } + ACE_DEBUG ((LM_DEBUG, "..%N:%l checking embedded values, ")); + myTruncExtracted->print (); + if (us1 != myTruncExtracted->Base_us1 () || + us2 != myTruncExtracted->Base_us2 () || + l1 != myTruncExtracted->Trunc_bl()->_value () || + s1 != myTruncExtracted->Trunc_nested()->Nested_s1 () || + s2 != myTruncExtracted->Trunc_nested()->Nested_s2 () ) + { + ACE_DEBUG ((LM_DEBUG, "..%N:%l FAILED should have been %u, %u, %d and %d, %d\n", us1, us2, l1, s1, s2)); + return 1; + } + + ACE_DEBUG ((LM_DEBUG, "..%N:%l Attempting to get_val from dynamic any (now with factory)\n")); + myTruncExtracted= dynamic_cast<DynValue_Test::Trunc*> (dany_trunc->get_val ()); + if (!myTruncExtracted) + { + ACE_DEBUG ((LM_DEBUG, "..%N:%l FAILED get_val unsuccessful even with factory\n")); + return 1; + } + ACE_DEBUG ((LM_DEBUG, "..%N:%l checking embedded values, ")); + myTruncExtracted->print (); + if (us1 != myTruncExtracted->Base_us1 () || + us2 != myTruncExtracted->Base_us2 () || + l1 != myTruncExtracted->Trunc_bl()->_value () || + s1 != myTruncExtracted->Trunc_nested()->Nested_s1 () || + s2 != myTruncExtracted->Trunc_nested()->Nested_s2 () ) + { + ACE_DEBUG ((LM_DEBUG, "..%N:%l FAILED should have been %u, %u, %d and %d, %d\n", us1, us2, l1, s1, s2)); + return 1; + } + myTruncExtracted->_remove_ref (); + + /////////////////////////////////////////////////// + // DynValue_Test::Trunc -> DynValue_Test::BaseValue + /////////////////////////////////////////////////// + + ACE_DEBUG ((LM_DEBUG, "\n%N:%l Placing DynValue_Test::Trunc into DynValue_Test::BaseValue\n")); + DynValue_Test::BaseValue::_ptr_type p_myBaseValue = myTrunc.in (); + + ACE_DEBUG ((LM_DEBUG, "..%N:%l checking values, ")); + p_myBaseValue->print (); + if (us1 != p_myBaseValue->Base_us1 () || + us2 != p_myBaseValue->Base_us2 () ) + { + ACE_DEBUG ((LM_DEBUG, "..%N:%l FAILED should have been %u and %u\n", us1, us2)); + return 1; + } + + ACE_DEBUG ((LM_DEBUG, "..%N:%l Inserting into an any\n")); + CORBA::Any myAny_trunc; + myAny_trunc <<= p_myBaseValue; + ACE_DEBUG ((LM_DEBUG, "..%N:%l any reports type %C\n", myAny_trunc._tao_get_typecode ()->id ())); + myAny_trunc.type (DynValue_Test::_tc_BaseValue); + ACE_DEBUG ((LM_DEBUG, "..%N:%l any NOW reports type %C\n", myAny_trunc._tao_get_typecode ()->id ())); + + ACE_DEBUG ((LM_DEBUG, "..%N:%l Extracting BaseValue from an any\n")); + DynValue_Test::BaseValue::_ptr_type myBaseExtracted= + reinterpret_cast<DynValue_Test::BaseValue::_ptr_type> (9); + if (!(myAny_trunc >>= myBaseExtracted)) + { + ACE_DEBUG ((LM_DEBUG, "..%N:%l FAILED extraction\n")); + return 1; + } + if (!myBaseExtracted) + { + ACE_DEBUG ((LM_DEBUG, "..%N:%l FAILED Null pointer extracted\n")); + return 1; + } + ACE_DEBUG ((LM_DEBUG, "..%N:%l checking embedded values, ")); + myBaseExtracted->print (); + if (us1 != myBaseExtracted->Base_us1 () || + us2 != myBaseExtracted->Base_us2 () ) + { + ACE_DEBUG ((LM_DEBUG, "..%N:%l FAILED should have been %u and %u\n", us1, us2)); + return 1; + } + + ACE_DEBUG ((LM_DEBUG, "..%N:%l Creating dynamic any from any\n")); + DynamicAny::DynAny_var dany_base (analyzer.DynAny (myAny_trunc)); + analyzer.analyze (dany_base.in ()); + + ACE_DEBUG ((LM_DEBUG, "..%N:%l Testing dynamic any for non-null\n")); + dvc= dynamic_cast<DynamicAny::DynValueCommon *> (dany_base.in ()); + if (!dvc) + { + ACE_DEBUG ((LM_DEBUG, "..%N:%l FAILURE can not obtain DynamicAny::DynValueCommon *\n")); + return 1; + } + if (dvc->is_null ()) + { + ACE_DEBUG ((LM_DEBUG, "..%N:%l FAILED this dynamic any is NULL!\n")); + return 1; + } + + ACE_DEBUG ((LM_DEBUG, "..%N:%l Converting from dynamic any back to any\n")); + myAny_var = dany_base->to_any (); + + + ACE_DEBUG ((LM_DEBUG, "..%N:%l Attempting to extract from this any (without factory)\n")); + myBaseExtracted= reinterpret_cast<DynValue_Test::BaseValue::_ptr_type> (9); + if (myAny_var.in () >>= myBaseExtracted) + { + ACE_DEBUG ((LM_DEBUG, "..%N:%l FAILED the extraction occured without factory\n")); + return 1; + } + + ACE_NEW_THROW_EX (vf, BaseValue_Factory, CORBA::NO_MEMORY ()); + analyzer.register_factory (vf); + + ACE_DEBUG ((LM_DEBUG, "..%N:%l Extracting from this any (now with factory)\n")); + if (!(myAny_var.in () >>= myBaseExtracted)) + { + ACE_DEBUG ((LM_DEBUG, "..%N:%l FAILED extraction\n")); + return 1; + } + if (!myBaseExtracted) + { + ACE_DEBUG ((LM_DEBUG, "..%N:%l FAILED Null pointer extracted\n")); + return 1; + } + if (reinterpret_cast<DynValue_Test::BaseValue::_ptr_type> (9) == myBaseExtracted) + { + ACE_DEBUG ((LM_DEBUG, "..%N:%l FAILED pointer NOT extracted\n")); + return 1; + } + ACE_DEBUG ((LM_DEBUG, "..%N:%l checking embedded values, ")); + myBaseExtracted->print (); + if (us1 != myBaseExtracted->Base_us1 () || + us2 != myBaseExtracted->Base_us2 () ) + { + ACE_DEBUG ((LM_DEBUG, "..%N:%l FAILED should have been %u, and %u\n", us1, us2)); + return 1; + } + + ACE_DEBUG ((LM_DEBUG, "..%N:%l Creating dynamic any from truncted any (no truncation allowed)\n")); + try + { + DynamicAny::DynAny_var dany_base (analyzer.DynAny_NoTrunc (myAny_trunc)); + ACE_DEBUG ((LM_DEBUG, "..%N:%l FAILED, obtained Dynamic any\n")); + analyzer.analyze (dany_base.in ()); + return 1; + } + catch (const DynamicAny::MustTruncate &) + { + ACE_DEBUG ((LM_DEBUG, "..%N:%l obtained MustTruncate as expected\n")); + } + + ACE_DEBUG ((LM_DEBUG, "\nAll tests passed\n")); + } + catch (const CORBA::TRANSIENT &) + { + ACE_DEBUG ((LM_INFO, "Transient\n")); + } + catch (const CORBA::COMM_FAILURE &) + { + ACE_DEBUG ((LM_INFO, "COMM_FAILURE\n")); + } + catch (const CORBA::Exception & ex) + { + ex._tao_print_exception ("Tests failed with CORBA exception:"); + return 1; + } + catch (...) + { + ACE_ERROR_RETURN ((LM_ERROR, "Test failed with NON-CORBA exception\n"), 1); + } + + return 0; +} diff --git a/TAO/tests/DynValue_Test/run_test.pl b/TAO/tests/DynValue_Test/run_test.pl new file mode 100755 index 00000000000..a678f06b12b --- /dev/null +++ b/TAO/tests/DynValue_Test/run_test.pl @@ -0,0 +1,22 @@ +eval '(exit $?0)' && eval 'exec perl -S $0 ${1+"$@"}' + & eval 'exec perl -S $0 $argv:q' + if 0; + +# $Id$ +# -*- perl -*- + +use lib "$ENV{ACE_ROOT}/bin"; +use PerlACE::TestTarget; + +my $server = PerlACE::TestTarget::create_target (1) || die "Create target 1 failed\n"; + +$SV = $server->CreateProcess ("DynValue_Test"); + +$test = $SV->SpawnWaitKill ($server->ProcessStartWaitInterval()+30); + +if ($test != 0) { + print STDERR "ERROR: test returned $test\n"; + exit 1; +} + +exit 0; |