dynunion_i.cpp
来自「这是广泛使用的通信开源项目,对于大容量,高并发的通讯要求完全能够胜任,他广泛可用」· C++ 代码 · 共 1,121 行 · 第 1/3 页
CPP
1,121 行
/* -*- C++ -*- */
// DynUnion_i.cpp,v 1.34 2003/11/19 20:04:20 parsons Exp
#include "DynUnion_i.h"
#include "DynAnyFactory.h"
#include "tao/Marshal.h"
#include "tao/Any_Unknown_IDL_Type.h"
ACE_RCSID (DynamicAny,
DynUnion_i,
"DynUnion_i.cpp,v 1.34 2003/11/19 20:04:20 parsons Exp")
TAO_DynUnion_i::TAO_DynUnion_i (void)
{
}
TAO_DynUnion_i::~TAO_DynUnion_i (void)
{
}
void
TAO_DynUnion_i::init_common (void)
{
this->ref_to_component_ = 0;
this->container_is_destroying_ = 0;
this->has_components_ = 1;
this->destroyed_ = 0;
this->component_count_ = 2;
this->current_position_ = 0;
this->member_slot_ = 0;
}
void
TAO_DynUnion_i::init (const CORBA::Any& any
ACE_ENV_ARG_DECL)
{
CORBA::TypeCode_var tc = any.type ();
CORBA::TCKind kind = TAO_DynAnyFactory::unalias (tc.in ()
ACE_ENV_ARG_PARAMETER);
ACE_CHECK;
if (kind != CORBA::tk_union)
{
ACE_THROW (DynamicAny::DynAnyFactory::InconsistentTypeCode ());
}
// Initialize the typecode holder.
this->type_ = tc;
this->init_common ();
// Set the from_factory arg to TRUE, so any problems will throw
// InconsistentTypeCode.
this->set_from_any (any,
1
ACE_ENV_ARG_PARAMETER);
ACE_CHECK;
}
void
TAO_DynUnion_i::init (CORBA::TypeCode_ptr tc
ACE_ENV_ARG_DECL)
{
CORBA::TCKind kind = TAO_DynAnyFactory::unalias (tc
ACE_ENV_ARG_PARAMETER);
ACE_CHECK;
if (kind != CORBA::tk_union)
{
ACE_THROW (DynamicAny::DynAnyFactory::InconsistentTypeCode ());
}
// Initialize the typecode holder and current index.
this->type_ = CORBA::TypeCode::_duplicate (tc);
this->init_common ();
// member_type()/member_label() do not work with aliased type codes.
CORBA::TypeCode_var unaliased_tc =
TAO_DynAnyFactory::strip_alias (this->type_.in ()
ACE_ENV_ARG_PARAMETER);
CORBA::Any_var first_label =
unaliased_tc->member_label (this->current_position_
ACE_ENV_ARG_PARAMETER);
ACE_CHECK;
// Initialize the discriminator to the label value of the first member.
this->discriminator_ =
TAO_DynAnyFactory::make_dyn_any (first_label.in ()
ACE_ENV_ARG_PARAMETER);
ACE_CHECK;
CORBA::TypeCode_var first_type =
unaliased_tc->member_type (this->current_position_
ACE_ENV_ARG_PARAMETER);
ACE_CHECK;
// Recursively initialize the member to its default value.
this->member_ = TAO_DynAnyFactory::make_dyn_any (first_type.in ()
ACE_ENV_ARG_PARAMETER);
ACE_CHECK;
}
// ****************************************************************
TAO_DynUnion_i *
TAO_DynUnion_i::_narrow (CORBA::Object_ptr _tao_objref
ACE_ENV_ARG_DECL_NOT_USED)
{
if (CORBA::is_nil (_tao_objref))
{
return 0;
}
return dynamic_cast<TAO_DynUnion_i *> (_tao_objref);
}
// This code is common to from_any() and the init() overload that takes
// an Any argument.
void
TAO_DynUnion_i::set_from_any (const CORBA::Any & any,
CORBA::Boolean /* from_factory */
ACE_ENV_ARG_DECL)
ACE_THROW_SPEC ((
CORBA::SystemException,
DynamicAny::DynAny::TypeMismatch,
DynamicAny::DynAnyFactory::InconsistentTypeCode
))
{
// discriminator_type () does not work with aliased type codes,
// only on unions, so strip the alias out of the type code
//
CORBA::TypeCode_var tc =
TAO_DynAnyFactory::strip_alias (any.type ()
ACE_ENV_ARG_PARAMETER);
ACE_CHECK;
// Get the CDR stream of the argument.
ACE_Message_Block* mb = any._tao_get_cdr ();
bool type_known = false;
if (mb == 0)
{
ACE_NEW (mb,
ACE_Message_Block);
TAO_OutputCDR out;
any.impl ()->marshal_value (out);
ACE_CDR::consolidate (mb, out.begin ());
type_known = true;
}
TAO_InputCDR cdr (mb,
any._tao_byte_order ());
if (type_known)
{
mb->release ();
}
CORBA::TypeCode_var disc_tc =
tc->discriminator_type (ACE_ENV_SINGLE_ARG_PARAMETER);
ACE_CHECK;
CORBA::Any disc_any;
TAO::Unknown_IDL_Type *unk = 0;
ACE_NEW (unk,
TAO::Unknown_IDL_Type (disc_tc.in (),
cdr.start (),
cdr.byte_order ()));
disc_any.replace (unk);
// Need this here because we might have been called from init().
if (!CORBA::is_nil (this->discriminator_.in ()))
{
this->discriminator_->destroy (ACE_ENV_SINGLE_ARG_PARAMETER);
ACE_CHECK;
}
// Set the discriminator.
this->discriminator_ =
TAO_DynAnyFactory::make_dyn_any (disc_any
ACE_ENV_ARG_PARAMETER);
ACE_CHECK;
// Move to the next field in the CDR stream.
(void) TAO_Marshal_Object::perform_skip (disc_tc.in (),
&cdr
ACE_ENV_ARG_PARAMETER);
ACE_CHECK;
CORBA::TypeCode_var unaliased =
TAO_DynAnyFactory::strip_alias (tc.in ()
ACE_ENV_ARG_PARAMETER);
ACE_CHECK;
CORBA::ULong count =
unaliased->member_count (ACE_ENV_SINGLE_ARG_PARAMETER);
ACE_CHECK;
CORBA::Boolean match = 0;
CORBA::ULong i;
// Get the index.
for (i = 0; i < count; ++i)
{
CORBA::Any_var label_any = tc->member_label (i
ACE_ENV_ARG_PARAMETER);
ACE_CHECK;
match = this->label_match (label_any.in (),
disc_any
ACE_ENV_ARG_PARAMETER);
ACE_CHECK;
if (match)
{
break;
}
}
// Need this here because we might have been called from init().
if (!CORBA::is_nil (this->member_.in ()))
{
this->member_->destroy (ACE_ENV_SINGLE_ARG_PARAMETER);
ACE_CHECK;
}
if (match)
{
CORBA::TypeCode_var member_tc =
tc->member_type (i
ACE_ENV_ARG_PARAMETER);
ACE_CHECK;
CORBA::Any member_any;
TAO::Unknown_IDL_Type *unk = 0;
ACE_NEW (unk,
TAO::Unknown_IDL_Type (member_tc.in (),
cdr.start (),
cdr.byte_order ()));
member_any.replace (unk);
this->member_ =
TAO_DynAnyFactory::make_dyn_any (member_any
ACE_ENV_ARG_PARAMETER);
ACE_CHECK;
this->member_slot_ = i;
}
else
{
// If no match, either the Any contains the default member or the
// type code was bad.
// default_index() does not work with aliased type codes.
CORBA::TypeCode_var unaliased_tc =
TAO_DynAnyFactory::strip_alias (this->type_.in ()
ACE_ENV_ARG_PARAMETER);
ACE_CHECK;
CORBA::Long default_index =
unaliased_tc->default_index (ACE_ENV_SINGLE_ARG_PARAMETER);
ACE_CHECK;
if (default_index == -1)
{
set_to_no_active_member (ACE_ENV_SINGLE_ARG_PARAMETER);
}
else
{
CORBA::ULong index = ACE_static_cast (CORBA::ULong,
default_index);
CORBA::TypeCode_var default_tc =
tc->member_type (index
ACE_ENV_ARG_PARAMETER);
ACE_CHECK;
CORBA::Any default_any;
TAO::Unknown_IDL_Type *unk = 0;
ACE_NEW (unk,
TAO::Unknown_IDL_Type (default_tc.in (),
cdr.start (),
cdr.byte_order ()));
default_any.replace (unk);
this->member_ =
TAO_DynAnyFactory::make_dyn_any (default_any
ACE_ENV_ARG_PARAMETER);
ACE_CHECK;
this->member_slot_ = index;
}
}
}
// ****************************************************************
DynamicAny::DynAny_ptr
TAO_DynUnion_i::get_discriminator (ACE_ENV_SINGLE_ARG_DECL)
ACE_THROW_SPEC ((
CORBA::SystemException
))
{
if (this->destroyed_)
{
ACE_THROW_RETURN (CORBA::OBJECT_NOT_EXIST (),
DynamicAny::DynAny::_nil ());
}
// 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->discriminator_.in (),
0
ACE_ENV_ARG_PARAMETER);
return DynamicAny::DynAny::_duplicate (this->discriminator_.in ());
}
void
TAO_DynUnion_i::set_discriminator (DynamicAny::DynAny_ptr value
ACE_ENV_ARG_DECL)
ACE_THROW_SPEC ((
CORBA::SystemException,
DynamicAny::DynAny::TypeMismatch
))
{
if (this->destroyed_)
{
ACE_THROW (CORBA::OBJECT_NOT_EXIST ());
}
CORBA::TypeCode_var tc = value->type (ACE_ENV_SINGLE_ARG_PARAMETER);
ACE_CHECK;
CORBA::TypeCode_var disc_tc =
this->discriminator_->type (ACE_ENV_SINGLE_ARG_PARAMETER);
ACE_CHECK;
CORBA::Boolean equivalent = disc_tc->equivalent (tc.in ()
ACE_ENV_ARG_PARAMETER);
ACE_CHECK;
if (!equivalent)
{
ACE_THROW (DynamicAny::DynAny::TypeMismatch ());
}
CORBA::Any_var value_any = value->to_any (ACE_ENV_SINGLE_ARG_PARAMETER);
ACE_CHECK;
CORBA::ULong length =
this->type_->member_count (ACE_ENV_SINGLE_ARG_PARAMETER);
ACE_CHECK;
CORBA::Any_var label_any;
CORBA::ULong i;
// member_label() does not work with aliased type codes.
CORBA::TypeCode_var unaliased_tc =
TAO_DynAnyFactory::strip_alias (this->type_.in ()
ACE_ENV_ARG_PARAMETER);
ACE_CHECK;
CORBA::Boolean match = 0;
for (i = 0; i < length; ++i)
{
label_any = unaliased_tc->member_label (i
ACE_ENV_ARG_PARAMETER);
ACE_CHECK;
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?