summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorkolpackov <kolpackov@ae88bc3d-4319-0410-8dbf-d08b4c9d3795>2002-01-18 19:06:50 +0000
committerkolpackov <kolpackov@ae88bc3d-4319-0410-8dbf-d08b4c9d3795>2002-01-18 19:06:50 +0000
commitc961ae6f4f05d493b3a827d679419b93210dec84 (patch)
treec1c4e6979bb26d5bd88b91d73f1afd57de34a342
parent82e7d92dd2a04b64a6accd8684b3a093e6f73ce8 (diff)
downloadATCD-c961ae6f4f05d493b3a827d679419b93210dec84.tar.gz
*** empty log message ***
-rw-r--r--TAO/TAO_IDL/be/be_valuetype.cpp128
-rw-r--r--TAO/TAO_IDL/be/be_visitor_valuetype.cpp3
-rw-r--r--TAO/TAO_IDL/be/be_visitor_valuetype/any_op_ch.cpp23
-rw-r--r--TAO/TAO_IDL/be/be_visitor_valuetype/any_op_cs.cpp86
-rw-r--r--TAO/TAO_IDL/be/be_visitor_valuetype/valuetype_ch.cpp23
-rw-r--r--TAO/TAO_IDL/be/be_visitor_valuetype/valuetype_cs.cpp30
-rw-r--r--TAO/tao/Typecode.cpp305
-rw-r--r--TAO/tao/Typecode.h20
-rw-r--r--TAO/tao/ValueBase.cpp15
-rw-r--r--TAO/tao/append.cpp95
-rw-r--r--TAO/tao/skip.cpp86
11 files changed, 804 insertions, 10 deletions
diff --git a/TAO/TAO_IDL/be/be_valuetype.cpp b/TAO/TAO_IDL/be/be_valuetype.cpp
index 7b4a241ca63..8391baa5784 100644
--- a/TAO/TAO_IDL/be/be_valuetype.cpp
+++ b/TAO/TAO_IDL/be/be_valuetype.cpp
@@ -748,6 +748,134 @@ be_valuetype::accept (be_visitor *visitor)
return visitor->visit_valuetype (this);
}
+ACE_CDR::ULong
+be_valuetype::data_members_count (AST_Field::Visibility vis)
+{
+ ACE_CDR::ULong count = 0;
+
+ // proceed if the number of members in our scope is greater than 0
+ if (this->nmembers () > 0)
+ {
+ // initialize an iterator to iterate thru our scope
+ UTL_ScopeActiveIterator *si;
+ ACE_NEW_RETURN (si,
+ UTL_ScopeActiveIterator (this,
+ UTL_Scope::IK_decls),
+ 0);
+
+ // continue until each element is visited
+ for (;!si->is_done ();si->next())
+ {
+ AST_Decl *d = si->item ();
+
+ if (!d)
+ {
+ delete si;
+ ACE_ERROR_RETURN ((
+ LM_ERROR,
+ "(%N:%l) be_valuetype::data_members_count - "
+ "bad node in this scope\n"), 0);
+ }
+
+ AST_Field *field = AST_Field::narrow_from_decl (d);
+
+ if (!field)
+ {
+ continue;
+ }
+
+ if (vis != AST_Field::vis_NA)
+ {
+ if (vis == field->visibility ()) ++count;
+ }
+ else
+ {
+ ++count;
+ }
+
+ } // end of for loop
+
+ delete si;
+ }
+ return count;
+}
+
+idl_bool
+be_valuetype::in_recursion (AST_Type *node)
+{
+ if (node == 0)
+ {
+ node = this;
+ }
+
+ // proceed if the number of members in our scope is greater than 0
+ if (this->nmembers () > 0)
+ {
+ // initialize an iterator to iterate thru our scope
+ UTL_ScopeActiveIterator *si;
+ ACE_NEW_RETURN (si,
+ UTL_ScopeActiveIterator (this,
+ UTL_Scope::IK_decls),
+ 0);
+
+ // continue until each element is visited
+ for (;!si->is_done ();si->next())
+ {
+ AST_Decl *d = si->item ();
+
+ if (!d)
+ {
+ delete si;
+ ACE_ERROR_RETURN ((
+ LM_ERROR,
+ "(%N:%l) be_valuetype::in_recursion - "
+ "bad node in this scope\n"), 0);
+ }
+
+ AST_Field *field = AST_Field::narrow_from_decl (d);
+
+ if (!field)
+ {
+ continue;
+ }
+
+ // IDL doesn't have such a feature as name reuse so
+ // just compare fully qualified names
+
+ AST_Type *type = AST_Type::narrow_from_decl (field->field_type ());
+
+ if (!type)
+ {
+ delete si;
+ ACE_ERROR_RETURN ((
+ LM_ERROR,
+ "(%N:%l) be_valuetype::in_recursion - "
+ "bad base type\n"), 0);
+ }
+
+ if (!ACE_OS::strcmp (node->full_name (),
+ type->full_name ()))
+ {
+ delete si;
+ return 1;
+ }
+
+ // Now hand over to our field type
+ if (type->in_recursion (node))
+ {
+ delete si;
+ return 1;
+ }
+
+ } // end of for loop
+
+ delete si;
+ }
+
+ return 0;
+}
+
+
// Narrowing.
IMPL_NARROW_METHODS1 (be_valuetype, be_interface)
IMPL_NARROW_FROM_DECL (be_valuetype)
diff --git a/TAO/TAO_IDL/be/be_visitor_valuetype.cpp b/TAO/TAO_IDL/be/be_visitor_valuetype.cpp
index 53c530e207b..21eb2c2c90b 100644
--- a/TAO/TAO_IDL/be/be_visitor_valuetype.cpp
+++ b/TAO/TAO_IDL/be/be_visitor_valuetype.cpp
@@ -53,5 +53,6 @@
#include "be_visitor_valuetype/valuetype_init_ci.cpp"
#include "be_visitor_valuetype/valuetype_init_cs.cpp"
#include "be_visitor_valuetype/valuetype_init_arglist_ch.cpp"
-
+#include "be_visitor_valuetype/any_op_ch.cpp"
+#include "be_visitor_valuetype/any_op_cs.cpp"
diff --git a/TAO/TAO_IDL/be/be_visitor_valuetype/any_op_ch.cpp b/TAO/TAO_IDL/be/be_visitor_valuetype/any_op_ch.cpp
index 0b760f96ee1..b461d181ca6 100644
--- a/TAO/TAO_IDL/be/be_visitor_valuetype/any_op_ch.cpp
+++ b/TAO/TAO_IDL/be/be_visitor_valuetype/any_op_ch.cpp
@@ -16,6 +16,7 @@
//
// = AUTHOR
// Jeff Parsons <parsons@cs.wustl.edu>
+// Boris Kolpackov <bosk@ipmce.ru>
//
// ============================================================================
@@ -46,12 +47,30 @@ be_visitor_valuetype_any_op_ch::~be_visitor_valuetype_any_op_ch (void)
int
be_visitor_valuetype_any_op_ch::visit_valuetype (be_valuetype *node)
{
- if (node->cli_hdr_any_op_gen () || node->imported () || node->is_local ())
+ if (node->cli_hdr_any_op_gen ()
+ || node->imported ()
+ || node->is_local ())
{
return 0;
}
- // TODO
+ TAO_OutStream *os = this->ctx_->stream ();
+
+ // Generate the Any <<= and >>= operator declarations.
+ os->indent ();
+ *os << "// Any operators for valuetype " << node->name () << be_nl;
+
+ *os << be_global->stub_export_macro () << "void"
+ << " operator<<= (CORBA::Any &, " << node->name ()
+ << " *); // copying" << be_nl;
+
+ *os << be_global->stub_export_macro () << "void"
+ << " operator<<= (CORBA::Any &, " << node->name ()
+ << " **); // non-copying" << be_nl;
+
+ *os << be_global->stub_export_macro () << "CORBA::Boolean"
+ << " operator>>= (const CORBA::Any &, "
+ << node->name () << " *&);\n";
node->cli_hdr_any_op_gen (1);
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 0af1db9391d..404d08ec99c 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
@@ -14,6 +14,7 @@
//
// = AUTHOR
// Jeff Parsons <parsons@cs.wustl.edu>
+// Boris Kolpackov <bosk@ipmce.ru>
//
// ============================================================================
@@ -53,9 +54,88 @@ be_visitor_valuetype_any_op_cs::visit_valuetype (be_valuetype *node)
os->indent ();
- // TODO
-
- *os << be_nl;
+ // Generate the Any <<= and >>= operator declarations
+
+ *os << be_global->stub_export_macro () << "void" << be_nl
+ << "operator<<= (CORBA::Any &any, " << node->name ()
+ << " *value) // copying" << be_nl
+ << "{" << be_idt_nl
+ << "TAO_OutputCDR stream;" << be_nl
+ << "if (stream << value)" << be_nl
+ << "{" << be_idt_nl
+ << "any._tao_replace (" << be_idt << be_idt_nl
+ << node->tc_name () << ", " << be_nl
+ << "TAO_ENCAP_BYTE_ORDER," << be_nl
+ << "stream.begin ());" << be_uidt << be_uidt << be_uidt_nl
+ << "}" << be_uidt_nl
+ << "}" << be_nl << be_nl;
+
+ *os << be_global->stub_export_macro () << "void" << be_nl
+ << "operator<<= (CORBA::Any &any, " << node->name ()
+ << " **value) // non-copying" << be_nl
+ << "{" << be_idt_nl
+ << "TAO_OutputCDR stream;" << be_nl
+ << "if (stream << *value)" << be_nl
+ << "{" << be_idt_nl
+ << "any._tao_replace (" << be_idt << be_idt_nl
+ << node->tc_name () << ", " << be_nl
+ << "TAO_ENCAP_BYTE_ORDER," << be_nl
+ << "stream.begin ()," << be_nl
+ << "1," << be_nl
+ << "*value," << be_nl
+ << node->name () << "::_tao_any_destructor);"
+ << be_uidt << be_uidt << be_uidt_nl
+ << "}" << be_uidt_nl
+ << "}" << be_nl << be_nl;
+
+
+ *os << be_global->stub_export_macro () << "CORBA::Boolean" << be_nl
+ << "operator>>= (const CORBA::Any &any, "
+ << node->name () << " *&value)" << be_nl
+ << "{" << be_idt_nl
+ << "ACE_TRY_NEW_ENV" << be_nl
+ << "{" << be_idt_nl
+ << "value = 0;" << be_nl
+ << "CORBA::TypeCode_var type = any.type ();" << be_nl << be_nl
+ << "CORBA::Boolean result = type->equivalent (" << node->tc_name ()
+ << " TAO_ENV_ARG_PARAMETER);" << be_nl
+ << "ACE_TRY_CHECK;" << be_nl << be_nl
+ << "if (!result)" << be_nl
+ << "{" << be_idt_nl
+ << "return 0; // not equivalent" << be_uidt_nl
+ << "}" << be_nl
+ << "if (any.any_owns_data ())" << be_nl
+ << "{" << be_idt_nl
+ << "value = ACE_static_cast(" << be_idt << be_idt_nl
+ << node->name () << "*," << be_nl
+ << "any.value ());" << be_uidt << be_uidt_nl
+ << "return 1;" << be_uidt_nl
+ << "}" << be_nl
+ << "else" << be_nl // else any does not own the data
+ << "{" << be_idt_nl
+ << node->name () << " *tmp;" << be_nl
+ << "TAO_InputCDR stream (" << be_idt << be_idt_nl
+ << "any._tao_get_cdr ()," << be_nl
+ << "any._tao_byte_order ());" << be_uidt << be_uidt_nl
+ << "if (stream >> tmp)" << be_nl
+ << "{" << be_idt_nl
+ << "((CORBA::Any *)&any)->_tao_replace (" << be_idt << be_idt_nl
+ << node->tc_name () << "," << be_nl
+ << "1," << be_nl
+ << "ACE_static_cast (void *, tmp)," << be_nl
+ << node->name () << "::_tao_any_destructor);" << be_uidt << be_uidt_nl
+ << "value = tmp;" << be_nl
+ << "return 1;" << be_uidt_nl
+ << "}" << be_nl
+ << be_uidt_nl
+ << "}" << be_uidt_nl
+ << "}" << be_nl
+ << "ACE_CATCHANY" << be_nl
+ << "{" << be_nl
+ << "}" << be_nl
+ << "ACE_ENDTRY;" << be_nl
+ << "return 0;" << be_uidt_nl
+ << "}" << be_nl << be_nl;
*os << "#if defined (ACE_HAS_EXPLICIT_TEMPLATE_INSTANTIATION) || \\"
<< be_idt_nl
diff --git a/TAO/TAO_IDL/be/be_visitor_valuetype/valuetype_ch.cpp b/TAO/TAO_IDL/be/be_visitor_valuetype/valuetype_ch.cpp
index a530996d54a..92fa9608d7b 100644
--- a/TAO/TAO_IDL/be/be_visitor_valuetype/valuetype_ch.cpp
+++ b/TAO/TAO_IDL/be/be_visitor_valuetype/valuetype_ch.cpp
@@ -216,6 +216,11 @@ be_visitor_valuetype_ch::visit_valuetype (be_valuetype *node)
<< "static const char* "
<< "_tao_obv_static_repository_id ();" << be_nl << be_nl;
+ // Ugly TAO any support routine
+ *os << "static void _tao_any_destructor (void *);"
+ << be_nl << be_nl;
+
+
// Generate code for the valuetype definition.
if (this->visit_valuetype_scope (node) == -1)
{
@@ -315,6 +320,24 @@ be_visitor_valuetype_ch::visit_valuetype (be_valuetype *node)
delete visitor;
+ // Step last: generate typecode declaration
+ {
+ be_visitor *visitor;
+ be_visitor_context ctx (*this->ctx_);
+ ctx.state (TAO_CodeGen::TAO_TYPECODE_DECL);
+ visitor = tao_cg->make_visitor (&ctx);
+
+ if (!visitor || (node->accept (visitor) == -1))
+ {
+ ACE_ERROR_RETURN ((LM_ERROR,
+ "(%N:%l) be_visitor_valuetype_ch::"
+ "visit_structure - "
+ "TypeCode declaration failed\n"
+ ),
+ -1);
+ }
+ }
+
node->cli_hdr_gen (I_TRUE);
return 0;
diff --git a/TAO/TAO_IDL/be/be_visitor_valuetype/valuetype_cs.cpp b/TAO/TAO_IDL/be/be_visitor_valuetype/valuetype_cs.cpp
index 417e2c58ea4..fa658ecdffb 100644
--- a/TAO/TAO_IDL/be/be_visitor_valuetype/valuetype_cs.cpp
+++ b/TAO/TAO_IDL/be/be_visitor_valuetype/valuetype_cs.cpp
@@ -51,6 +51,25 @@ be_visitor_valuetype_cs::visit_valuetype (be_valuetype *node)
return 0;
}
+ // by using a visitor to declare and define the TypeCode, we have the
+ // added advantage to conditionally not generate any code. This will be
+ // based on the command line options. This is still TO-DO
+ {
+ be_visitor *visitor;
+ be_visitor_context ctx (*this->ctx_);
+ ctx.state (TAO_CodeGen::TAO_TYPECODE_DEFN);
+ ctx.sub_state (TAO_CodeGen::TAO_TC_DEFN_TYPECODE);
+ visitor = tao_cg->make_visitor (&ctx);
+ if (!visitor || (node->accept (visitor) == -1))
+ {
+ ACE_ERROR_RETURN ((LM_ERROR,
+ "(%N:%l) be_visitor_valuetype_cs::"
+ "visit_valuetype - "
+ "TypeCode definition failed\n"
+ ), -1);
+ }
+ }
+
os = this->ctx_->stream ();
os->indent (); // start with whatever indentation level we are at
@@ -132,6 +151,17 @@ be_visitor_valuetype_cs::visit_valuetype (be_valuetype *node)
*os << "return rval;" << be_uidt_nl
<< "}\n\n";
+ // Ugly TAO any support routine
+ *os << "void" << be_nl
+ << node->name ()
+ << "::_tao_any_destructor (void *_tao_void_pointer)" << be_nl
+ << "{" << be_idt_nl
+ << node->local_name () << " *tmp = ACE_static_cast ("
+ << node->local_name () << "*, _tao_void_pointer);" << be_nl
+ << "delete tmp;" << be_uidt_nl
+ << "}" << be_nl << be_nl;
+
+
// Nothing to marshal if abstract valuetype.
if (!node->is_abstract_valuetype ())
{
diff --git a/TAO/tao/Typecode.cpp b/TAO/tao/Typecode.cpp
index 471b73b195d..254bfb5eb31 100644
--- a/TAO/tao/Typecode.cpp
+++ b/TAO/tao/Typecode.cpp
@@ -427,6 +427,25 @@ CORBA_TypeCode::content_type (TAO_ENV_SINGLE_ARG_DECL) const
}
+CORBA::TypeCode_ptr
+CORBA_TypeCode::concrete_base_type (TAO_ENV_SINGLE_ARG_DECL) const
+{
+ if (this->private_state_->tc_concrete_base_type_known_)
+ {
+ return CORBA_TypeCode::_duplicate (
+ this->private_state_->tc_concrete_base_type_
+ );
+ }
+ else
+ {
+ CORBA::TypeCode_ptr tmp =
+ this->private_concrete_base_type (TAO_ENV_SINGLE_ARG_PARAMETER);
+ ACE_CHECK_RETURN (CORBA::TypeCode::_nil ());
+
+ return CORBA_TypeCode::_duplicate (tmp);
+ }
+}
+
// skip a typecode encoding in a given CDR stream
// This is just a helper function
CORBA::Boolean
@@ -462,6 +481,7 @@ CORBA_TypeCode::skip_typecode (TAO_InputCDR &stream)
case CORBA::tk_array:
case CORBA::tk_alias:
case CORBA::tk_except:
+ case CORBA::tk_value:
return (stream.read_ulong (temp) != 0
&& stream.skip_bytes (temp) != 0);
}
@@ -485,6 +505,8 @@ TC_Private_State::TC_Private_State (CORBA::TCKind kind)
tc_default_index_used_known_ (0),
tc_length_known_ (0),
tc_content_type_known_ (0),
+ tc_discrim_pad_size_known_ (0),
+ tc_concrete_base_type_known_ (0),
tc_id_ (0),
tc_name_ (0),
tc_member_count_ (0),
@@ -494,7 +516,8 @@ TC_Private_State::TC_Private_State (CORBA::TCKind kind)
tc_discriminator_type_ (0),
tc_default_index_used_ (0),
tc_length_ (0),
- tc_content_type_ (0)
+ tc_content_type_ (0),
+ tc_concrete_base_type_ (0)
{
}
@@ -631,6 +654,49 @@ TC_Private_State::~TC_Private_State (void)
}
break;
+ case CORBA::tk_value:
+ {
+ // free up the member name list
+ if (this->tc_member_name_list_known_)
+ {
+ for (CORBA::ULong i = 0;
+ i < this->tc_member_count_;
+ i++)
+ {
+ CORBA::string_free (this->tc_member_name_list_ [i]);
+ this->tc_member_name_list_ [i] = 0;
+ }
+
+ delete [] this->tc_member_name_list_;
+ this->tc_member_name_list_ = 0;
+ }
+
+ // free up member type list
+ if (this->tc_member_type_list_known_)
+ {
+ for (CORBA::ULong i = 0;
+ i < this->tc_member_count_;
+ i++)
+ {
+ CORBA::release (this->tc_member_type_list_[i]);
+ }
+
+ // Now free up the array.
+ delete [] this->tc_member_type_list_;
+ this->tc_member_type_list_ = 0;
+ }
+ this->tc_member_count_ = 0;
+
+ // free up concrete base value typecode
+ if (this->tc_concrete_base_type_known_)
+ {
+ CORBA::release (this->tc_concrete_base_type_);
+ this->tc_concrete_base_type_ = 0;
+ this->tc_concrete_base_type_known_ = 0;
+ }
+ break;
+ }
+
default:
// nothing to do
break;
@@ -792,6 +858,11 @@ CORBA_TypeCode::private_equal (CORBA::TypeCode_ptr tc,
return this->private_equal_except (tc,
equiv_only
TAO_ENV_ARG_PARAMETER);
+ case CORBA::tk_value:
+ return this->private_equal_valuetype (tc,
+ equiv_only
+ TAO_ENV_ARG_PARAMETER);
+
case ~0u: // indirection
{
// indirection offset must be same
@@ -1415,6 +1486,56 @@ CORBA_TypeCode::private_equal_except (CORBA::TypeCode_ptr tc,
return 1; // success
}
+
+//@@ boris: This version is incomplete...
+CORBA::Boolean
+CORBA_TypeCode::private_equal_valuetype (
+ CORBA::TypeCode_ptr tc,
+ CORBA::Boolean equiv_only
+ TAO_ENV_ARG_DECL
+ ) const
+{
+ // compare the repoID and name, of which the name is optional as per GIOP
+ // spec. However, the repoID is mandatory.
+ const char *my_id = this->id (TAO_ENV_SINGLE_ARG_PARAMETER);
+ ACE_CHECK_RETURN (0);
+
+ const char *tc_id = tc->id (TAO_ENV_SINGLE_ARG_PARAMETER);
+ ACE_CHECK_RETURN (0);
+
+ if (!ACE_OS::strcmp (my_id, tc_id))
+ {
+ // Equality of repoIDs is sufficient for equivalence.
+ if (equiv_only)
+ {
+ return 1;
+ }
+ // Name check is skipped by equivalent().
+ else
+ {
+ // same repository IDs. Now check their names
+ const char *myname = this->name (TAO_ENV_SINGLE_ARG_PARAMETER);
+ ACE_CHECK_RETURN (0);
+
+ const char *tcname = tc->name (TAO_ENV_SINGLE_ARG_PARAMETER);
+ ACE_CHECK_RETURN (0);
+
+ if ((ACE_OS::strlen (myname) > 1) &&
+ (ACE_OS::strlen (tcname) > 1))
+ {
+ // both of them specify names, compare them
+ if (!ACE_OS::strcmp (myname, tcname))
+ return 1; // success
+ else
+ return 0; // failed
+ }
+ return 1; // success
+ }
+ }
+ return 0; // failed
+}
+
+
// Return the type ID (RepositoryId) for the TypeCode; it may be empty.
//
// NOTE the string returned here is owned by the typecode!!
@@ -1437,6 +1558,7 @@ CORBA_TypeCode::private_id (TAO_ENV_SINGLE_ARG_DECL) const
case CORBA::tk_enum:
case CORBA::tk_alias:
case CORBA::tk_except:
+ case CORBA::tk_value:
{
// Double checked locking...
ACE_GUARD_RETURN (TAO_SYNCH_MUTEX, guard,
@@ -1476,6 +1598,7 @@ CORBA_TypeCode::private_name (TAO_ENV_SINGLE_ARG_DECL) const
case CORBA::tk_enum:
case CORBA::tk_alias:
case CORBA::tk_except:
+ case CORBA::tk_value:
{
// Double checked locking...
ACE_GUARD_RETURN (TAO_SYNCH_MUTEX, guard,
@@ -1573,6 +1696,55 @@ CORBA_TypeCode::private_member_count (TAO_ENV_SINGLE_ARG_DECL) const
this->private_state_->tc_member_count_ = members;
return this->private_state_->tc_member_count_;
}
+ case CORBA::tk_value:
+ {
+ // Double checked locking...
+ ACE_GUARD_RETURN (TAO_SYNCH_MUTEX, guard,
+ this->private_state_->mutex_, 0);
+ if (this->private_state_->tc_member_count_known_)
+ return this->private_state_->tc_member_count_;
+
+ CORBA::ULong members;
+ // setup an encapsulation
+ TAO_InputCDR stream (this->buffer_+4, this->length_-4,
+ this->byte_order_);
+
+ // skip rest of header (type ID, name, etc) and collect the
+ // number of value members
+ CORBA::ULong tc_kind_holder;
+ CORBA::TCKind tc_kind;
+ if (!stream.skip_string () // ID
+ || !stream.skip_string () // Name
+ || !stream.skip_ulong () // ValueModifier
+ || !stream.read_ulong(tc_kind_holder)) // Base's TCKind
+ ACE_THROW_RETURN (CORBA::BAD_TYPECODE (), 0);
+ tc_kind = ACE_static_cast(CORBA::TCKind, tc_kind_holder);
+
+
+ // The tc_kind can be either tk_null or tk_value.
+ // In the latter case we should skip encapsulation or
+ // indirection - whatever comes in.
+ CORBA::ULong encap_length;
+ if (tc_kind != CORBA::tk_null)
+ {
+ if (!stream.read_ulong(encap_length))
+ ACE_THROW_RETURN (CORBA::BAD_TYPECODE (), 0);
+
+ if (encap_length != 0xffffffff) // check for indirection
+ {
+ if (!stream.skip_bytes (encap_length))
+ ACE_THROW_RETURN (CORBA::BAD_TYPECODE (), 0);
+ }
+ }
+
+ // Now read member count.
+ if (!stream.read_ulong (members))
+ ACE_THROW_RETURN (CORBA::BAD_TYPECODE (), 0);
+
+ this->private_state_->tc_member_count_known_ = 1;
+ this->private_state_->tc_member_count_ = members;
+ return this->private_state_->tc_member_count_;
+ }
default:
ACE_THROW_RETURN (CORBA::BAD_TYPECODE (), 0);
}
@@ -1723,6 +1895,97 @@ CORBA_TypeCode::private_member_type (CORBA::ULong slot
}
ACE_NOTREACHED (break);
+ case CORBA::tk_value:
+ mcount = this->member_count (TAO_ENV_SINGLE_ARG_PARAMETER);
+ ACE_CHECK_RETURN ((CORBA::TypeCode_ptr)0);
+
+ {
+ // Double checked locking...
+ ACE_GUARD_RETURN (TAO_SYNCH_MUTEX, guard,
+ this->private_state_->mutex_, 0);
+ if (this->private_state_->tc_member_type_list_known_)
+ if (slot < mcount)
+ return this->private_state_->tc_member_type_list_[slot];
+ else
+ ACE_THROW_RETURN (CORBA::TypeCode::Bounds (),
+ CORBA::TypeCode::_nil ());
+
+ // the first time in. Precompute and store types of all members
+
+ // Allocate a list to hold the member typecodes
+ ACE_NEW_THROW_EX (this->private_state_->tc_member_type_list_,
+ CORBA::TypeCode_ptr [mcount],
+ CORBA::NO_MEMORY ());
+
+ ACE_CHECK_RETURN (CORBA::TypeCode::_nil ());
+
+ // skip rest of header (type ID, name, etc) and collect the
+ // number of value members
+ CORBA::ULong tc_kind_holder;
+ CORBA::TCKind tc_kind;
+ if (!stream.skip_string () // ID
+ || !stream.skip_string () // Name
+ || !stream.skip_ulong () // ValueModifier
+ || !stream.read_ulong(tc_kind_holder)) // Base's TCKind
+ ACE_THROW_RETURN (CORBA::BAD_TYPECODE (),
+ CORBA::TypeCode::_nil ());
+ tc_kind = ACE_static_cast (CORBA::TCKind, tc_kind_holder);
+
+ // The tc_kind can be either tk_null or tk_value.
+ // In the latter case we should skip encapsulation or
+ // indirection - whatever comes in.
+ CORBA::ULong encap_length;
+ if (tc_kind != CORBA::tk_null)
+ {
+ if (!stream.read_ulong(encap_length))
+ ACE_THROW_RETURN (CORBA::BAD_TYPECODE (),
+ CORBA::TypeCode::_nil ());
+
+ if (encap_length != 0xffffffff) // check for indirection
+ {
+ if (!stream.skip_bytes (encap_length))
+ ACE_THROW_RETURN (CORBA::BAD_TYPECODE (),
+ CORBA::TypeCode::_nil ());
+ }
+ }
+
+ // Now skip member count.
+ if (!stream.skip_ulong ())
+ ACE_THROW_RETURN (CORBA::BAD_TYPECODE (),
+ CORBA::TypeCode::_nil ());
+
+ // compute the typecodes for all the members and
+ // return the required one.
+ for (CORBA::ULong i = 0; i < mcount; i++)
+ // the ith entry will have the typecode of the ith guy
+ {
+ if (!stream.skip_string ()) // skip the name
+ ACE_THROW_RETURN (CORBA::BAD_TYPECODE (),
+ CORBA::TypeCode::_nil ());
+
+ CORBA::TypeCode_ptr& member_type =
+ this->private_state_->tc_member_type_list_[i];
+ CORBA_TypeCode::_tao_decode (this,
+ stream,
+ member_type
+ TAO_ENV_ARG_PARAMETER);
+ ACE_CHECK_RETURN (CORBA::TypeCode::_nil ());
+
+ if (!stream.skip_ulong ()) // skip member visibility
+ ACE_THROW_RETURN (CORBA::BAD_TYPECODE (),
+ CORBA::TypeCode::_nil ());
+ }
+
+ this->private_state_->tc_member_type_list_known_ = 1;
+
+ if (slot < mcount)
+ return this->private_state_->tc_member_type_list_[slot];
+ else
+ ACE_THROW_RETURN (CORBA::TypeCode::Bounds (),
+ CORBA::TypeCode::_nil ());
+ }
+ ACE_NOTREACHED (break;)
+
default:
// bad kind
ACE_THROW_RETURN (CORBA::TypeCode::BadKind (),
@@ -2238,6 +2501,40 @@ CORBA_TypeCode::private_content_type (TAO_ENV_SINGLE_ARG_DECL) const
ACE_NOTREACHED (return 0);
}
+CORBA::TypeCode_ptr
+CORBA_TypeCode::private_concrete_base_type (TAO_ENV_SINGLE_ARG_DECL) const
+{
+ if (kind_ != CORBA::tk_value)
+ ACE_THROW_RETURN (CORBA::TypeCode::BadKind (), 0);
+
+ // Double checked locking...
+ ACE_GUARD_RETURN (TAO_SYNCH_MUTEX, guard,
+ this->private_state_->mutex_, 0);
+ if (this->private_state_->tc_concrete_base_type_known_)
+ return this->private_state_->tc_concrete_base_type_;
+
+ // setup an encapsulation
+ TAO_InputCDR stream (this->buffer_+4, this->length_-4,
+ this->byte_order_);
+
+ // skip rest of header (type ID, name, etc) and collect the
+ // number of value members
+ if (!stream.skip_string () // ID
+ || !stream.skip_string () // Name
+ || !stream.skip_ulong ()) // ValueModifier
+ ACE_THROW_RETURN (CORBA::BAD_TYPECODE (), 0);
+
+ // retrieve the concrete base typecode
+ CORBA_TypeCode::_tao_decode (this,
+ stream,
+ this->private_state_->tc_concrete_base_type_
+ TAO_ENV_ARG_PARAMETER);
+ ACE_CHECK_RETURN (0);
+
+ this->private_state_->tc_concrete_base_type_known_ = 1;
+ return this->private_state_->tc_concrete_base_type_;
+}
+
// ****************************************************************
void
@@ -2285,7 +2582,9 @@ CORBA_TypeCode::_tao_decode (const CORBA_TypeCode *parent,
CORBA::_tc_ulonglong,
CORBA::_tc_longdouble,
CORBA::_tc_wchar,
- 0 // CORBA::_tc_wstring ... unbounded
+ 0, // CORBA::_tc_wstring ... unbounded
+ 0, // CORBA_tk_fixed @@ boris: This is unsupported but I need next value
+ 0, // CORBA_tk_value
};
if (kind < CORBA::TC_KIND_COUNT && tc_consts [kind] != 0)
@@ -2451,6 +2750,7 @@ CORBA_TypeCode::_tao_decode (const CORBA_TypeCode *parent,
case CORBA::tk_array:
case CORBA::tk_alias:
case CORBA::tk_except:
+ case CORBA::tk_value:
{
CORBA::ULong length;
@@ -2638,6 +2938,7 @@ operator<< (TAO_OutputCDR& cdr, const CORBA::TypeCode *x)
case CORBA::tk_array:
case CORBA::tk_alias:
case CORBA::tk_except:
+ case CORBA::tk_value:
{
if (!cdr.write_ulong (x->length_)
|| !cdr.write_octet_array ((CORBA::Octet*)x->buffer_,
diff --git a/TAO/tao/Typecode.h b/TAO/tao/Typecode.h
index 99610b73f20..747bc19547a 100644
--- a/TAO/tao/Typecode.h
+++ b/TAO/tao/Typecode.h
@@ -154,6 +154,13 @@ public:
/// for tk_sequence, tk_array, and tk_alias.
CORBA::TypeCode_ptr content_type (TAO_ENV_SINGLE_ARG_DECL_WITH_DEFAULTS) const;
+
+ /// Returns the concrete base type. Raises (BadKind); Useful
+ /// for tk_value only.
+ CORBA::TypeCode_ptr concrete_base_type (
+ TAO_ENV_SINGLE_ARG_DECL_WITH_DEFAULTS
+ ) const;
+
// = Creation/refcounting
// These aren't really public APIs, but an IDL compiler will need to
@@ -348,6 +355,10 @@ private:
TAO_ENV_SINGLE_ARG_DECL_WITH_DEFAULTS
) const;
+ CORBA::TypeCode_ptr private_concrete_base_type (
+ TAO_ENV_SINGLE_ARG_DECL_WITH_DEFAULTS
+ ) const;
+
// = All the private helpers testing for equality of typecodes
/// test equality for typecodes of objrefs
@@ -400,6 +411,13 @@ private:
CORBA::Boolean equiv_only
TAO_ENV_ARG_DECL_WITH_DEFAULTS) const;
+ /// test equality for typecodes of exceptions
+ CORBA::Boolean private_equal_valuetype (CORBA::TypeCode_ptr tc,
+ CORBA::Boolean equiv_only
+ TAO_ENV_ARG_DECL_WITH_DEFAULTS)
+ const;
+
+
/// if refcount reaches 0, free this typecode
CORBA::ULong refcount_;
@@ -475,6 +493,7 @@ public:
CORBA::Boolean tc_length_known_;
CORBA::Boolean tc_content_type_known_;
CORBA::Boolean tc_discrim_pad_size_known_;
+ CORBA::Boolean tc_concrete_base_type_known_;
// = These data members store the precomputed values
char * tc_id_;
@@ -487,6 +506,7 @@ public:
CORBA::Long tc_default_index_used_;
CORBA::ULong tc_length_;
CORBA::TypeCode_ptr tc_content_type_;
+ CORBA::TypeCode_ptr tc_concrete_base_type_;
};
/**
diff --git a/TAO/tao/ValueBase.cpp b/TAO/tao/ValueBase.cpp
index 1505f62ce21..dfbc4170e70 100644
--- a/TAO/tao/ValueBase.cpp
+++ b/TAO/tao/ValueBase.cpp
@@ -196,8 +196,19 @@ CORBA_ValueBase::_tao_unmarshal_pre (TAO_InputCDR &strm,
return 0;
}
- factory = strm.orb_core ()->orb ()
- ->lookup_value_factory (repo_id_stream.in());
+ TAO_ORB_Core *orb_core = strm.orb_core ();
+ if (orb_core == 0)
+ {
+ orb_core = TAO_ORB_Core_instance ();
+ if (TAO_debug_level > 0)
+ {
+ ACE_DEBUG ((LM_WARNING,
+ "TAO (%P|%t) WARNING: extracting valuetype using "
+ "default ORB_Core\n"));
+ }
+ }
+
+ factory = orb_core->orb ()->lookup_value_factory (repo_id_stream.in());
if (factory == 0) // %! except.!
{
ACE_DEBUG ((LM_ERROR, ACE_TEXT ("(%N:%l) OBV factory is null !!!\n")));
diff --git a/TAO/tao/append.cpp b/TAO/tao/append.cpp
index 2df57c58492..e6ea5de14ac 100644
--- a/TAO/tao/append.cpp
+++ b/TAO/tao/append.cpp
@@ -23,6 +23,7 @@
#include "tao/CDR.h"
#include "tao/Environment.h"
#include "tao/Any.h"
+#include "tao/ValueBase.h"
#include "tao/debug.h"
ACE_RCSID(tao, append, "$Id$")
@@ -206,6 +207,7 @@ TAO_Marshal_TypeCode::append (CORBA::TypeCode_ptr,
case CORBA::tk_array:
case CORBA::tk_alias:
case CORBA::tk_except:
+ case CORBA::tk_value:
{
// write the encapsulation i.e., octet sequence
retval =
@@ -1156,3 +1158,96 @@ TAO_Marshal_WString::append (CORBA::TypeCode_ptr,
CORBA::COMPLETED_MAYBE),
CORBA::TypeCode::TRAVERSE_STOP);
}
+
+CORBA::TypeCode::traverse_status
+TAO_Marshal_Value::append (CORBA::TypeCode_ptr tc,
+ TAO_InputCDR *src,
+ TAO_OutputCDR *dest
+ TAO_ENV_ARG_DECL)
+{
+ CORBA::TypeCode::traverse_status retval =
+ CORBA::TypeCode::TRAVERSE_CONTINUE;
+ CORBA::TypeCode_var param;
+
+ // Use the same method to append our base valuetype.
+ // To achive this we'll need to distinguish between
+ // first-time/nested appends so that we won't attempt to
+ // append rep_id several times.
+ //
+ if (nested_processing_ == 0)
+ {
+ nested_processing_ = 1;
+
+ CORBA::ULong value_tag;
+
+ if (!src->read_ulong (value_tag) ||
+ !dest->write_ulong (value_tag))
+ {
+ return CORBA::TypeCode::TRAVERSE_STOP;
+ }
+
+ if (value_tag == 0) // Null value type pointer.
+ {
+ //We are done.
+ return retval;
+ }
+ else if (value_tag & TAO_OBV_GIOP_Flags::Type_info_single)
+ {
+ // Append repository id which is of type string.
+ dest->append_string (*src);
+ }
+ else
+ {
+ //@@ boris: VT CDR
+ return CORBA::TypeCode::TRAVERSE_STOP;
+ }
+ }
+
+ // Handle our base valuetype if any.
+ param = tc->concrete_base_type (TAO_ENV_SINGLE_ARG_PARAMETER);
+ ACE_CHECK_RETURN (CORBA::TypeCode::TRAVERSE_STOP);
+ if (param->kind () != CORBA::tk_null)
+ {
+ retval = this->append (param.in (),
+ src,
+ dest
+ TAO_ENV_ARG_PARAMETER);
+ ACE_CHECK_RETURN (CORBA::TypeCode::TRAVERSE_STOP);
+
+ if (retval != CORBA::TypeCode::TRAVERSE_CONTINUE)
+ {
+ return retval;
+ }
+ }
+
+ // Number of fields in the struct.
+ int member_count = tc->member_count (TAO_ENV_SINGLE_ARG_PARAMETER);
+ ACE_CHECK_RETURN (CORBA::TypeCode::TRAVERSE_STOP);
+
+ for (int i = 0;
+ i < member_count && retval == CORBA::TypeCode::TRAVERSE_CONTINUE;
+ i++)
+ {
+ // get member type
+ param = tc->member_type (i TAO_ENV_ARG_PARAMETER);
+ ACE_CHECK_RETURN (CORBA::TypeCode::TRAVERSE_STOP);
+
+ retval =
+ TAO_Marshal_Object::perform_append (param.in (),
+ src,
+ dest
+ TAO_ENV_ARG_PARAMETER);
+ ACE_CHECK_RETURN (CORBA::TypeCode::TRAVERSE_STOP);
+ }
+
+ if (retval == CORBA::TypeCode::TRAVERSE_CONTINUE)
+ return CORBA::TypeCode::TRAVERSE_CONTINUE;
+
+ if (TAO_debug_level > 0)
+ ACE_DEBUG ((LM_DEBUG,
+ ACE_TEXT ("TAO_Marshal_Value::append detected error\n")));
+
+ ACE_THROW_RETURN (CORBA::MARSHAL (TAO_DEFAULT_MINOR_CODE,
+ CORBA::COMPLETED_MAYBE),
+ CORBA::TypeCode::TRAVERSE_STOP);
+}
diff --git a/TAO/tao/skip.cpp b/TAO/tao/skip.cpp
index 7790558531e..65ffe868d3f 100644
--- a/TAO/tao/skip.cpp
+++ b/TAO/tao/skip.cpp
@@ -23,6 +23,7 @@
#include "tao/CDR.h"
#include "tao/Any.h"
#include "tao/Environment.h"
+#include "tao/ValueBase.h"
#include "tao/debug.h"
ACE_RCSID(tao, skip, "$Id$")
@@ -163,6 +164,7 @@ TAO_Marshal_TypeCode::skip (CORBA::TypeCode_ptr,
case CORBA::tk_array:
case CORBA::tk_alias:
case CORBA::tk_except:
+ case CORBA::tk_value:
{
CORBA::ULong length;
@@ -896,3 +898,87 @@ TAO_Marshal_WString::skip (CORBA::TypeCode_ptr,
CORBA::COMPLETED_MAYBE),
CORBA::TypeCode::TRAVERSE_STOP);
}
+
+CORBA::TypeCode::traverse_status
+TAO_Marshal_Value::skip (CORBA::TypeCode_ptr tc,
+ TAO_InputCDR *stream
+ TAO_ENV_ARG_DECL)
+{
+ CORBA::TypeCode::traverse_status retval =
+ CORBA::TypeCode::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
+ // first-time/nested skips so that we won't attempt to
+ // skip rep_id several times.
+ //
+ if (nested_processing_ == 0)
+ {
+ nested_processing_ = 1;
+
+ CORBA::ULong value_tag;
+
+ if (!stream->read_ulong (value_tag))
+ {
+ return CORBA::TypeCode::TRAVERSE_STOP;
+ }
+
+ if (value_tag == 0) // Null value type pointer.
+ {
+ //We are done.
+ return retval;
+ }
+ else if (value_tag & TAO_OBV_GIOP_Flags::Type_info_single)
+ {
+ // Skip a single repository id which is of type string.
+ stream->skip_string ();
+ }
+ else
+ {
+ //@@ boris: VT CDR
+ return CORBA::TypeCode::TRAVERSE_STOP;
+ }
+ }
+
+ // Handle our base valuetype if any.
+ param = tc->concrete_base_type (TAO_ENV_SINGLE_ARG_PARAMETER);
+ ACE_CHECK_RETURN (CORBA::TypeCode::TRAVERSE_STOP);
+ if (param->kind () != CORBA::tk_null)
+ {
+ retval = this->skip (param.in (), stream TAO_ENV_ARG_PARAMETER);
+ ACE_CHECK_RETURN (CORBA::TypeCode::TRAVERSE_STOP);
+
+ if (retval != CORBA::TypeCode::TRAVERSE_CONTINUE)
+ {
+ return retval;
+ }
+ }
+
+ // Number of fields in the valuetype.
+ int member_count = tc->member_count (TAO_ENV_SINGLE_ARG_PARAMETER);
+ ACE_CHECK_RETURN (CORBA::TypeCode::TRAVERSE_STOP);
+
+ for (int i = 0; i < member_count
+ && retval == CORBA::TypeCode::TRAVERSE_CONTINUE;
+ i++)
+ {
+ param = tc->member_type (i TAO_ENV_ARG_PARAMETER);
+ ACE_CHECK_RETURN (CORBA::TypeCode::TRAVERSE_STOP);
+
+ retval = TAO_Marshal_Object::perform_skip (param.in (),
+ stream
+ TAO_ENV_ARG_PARAMETER);
+ ACE_CHECK_RETURN (CORBA::TypeCode::TRAVERSE_STOP);
+ }
+
+ if (retval == CORBA::TypeCode::TRAVERSE_CONTINUE)
+ return CORBA::TypeCode::TRAVERSE_CONTINUE;
+
+ if (TAO_debug_level > 0)
+ ACE_DEBUG ((LM_DEBUG,
+ ACE_TEXT ("TAO_Marshal_Value::skip detected error\n")));
+ ACE_THROW_RETURN (CORBA::MARSHAL (TAO_DEFAULT_MINOR_CODE,
+ CORBA::COMPLETED_MAYBE),
+ CORBA::TypeCode::TRAVERSE_STOP);
+}