[omniORB] Possible bug in handling of enum discriminator labels

Michael omniorb at bindone.de
Tue Jun 5 19:40:20 BST 2007


Hello,

while developing an Any serializer I found the following behaviour when handling labels in
unions. It seems liek (in case of enums as discriminators) CORBA::TypeCode::member_label
returns an ULong containing the value of DynEnumImpl::get_as_ulong instead the actual
enumeration value (so the any returned has a kind() of tk_ulong instead of tk_enum).

// example IDL
enum DataType {
 DT_LONG_LONG,
 DT_STRING
};

struct Tag {
  string tagName;
  union TagData switch (DataType) {
    case DT_LONG_LONG:
      long long longValue;
    case DT_STRING:
      string stringValue;
  } data;
};


// example C++

Tag t;
t.tagName = "Test";
t.data.stringValue("test");
CORBA::Any any;
any <<= t;
CORBA::TypeCode_var tcStruct = any.type();
assert(tcStruct->kind() == CORBA::tk_struct); // kind of Tag is struct - ok
		
CORBA::TypeCode_var tcUnion = tcStruct->member_type(1);
assert(tcUnion->kind() == CORBA::tk_union); // type of Tag.data is union = ok

CORBA::TypeCode_var tcEnum = tcUnion->discriminator_type();
assert(tcEnum->kind() == CORBA::tk_enum);
// type of Tag.Tagdata's dicriminator is enum - ok

std::cout << "Fist union member name: " << tcUnion->member_name(0) << std::endl;
// outputs longValue - ok

CORBA::TypeCode_var memberTc = tcUnion->member_type(0);
assert(memberTc->kind() == CORBA::tk_longlong);
// Tag.TagData.longValue is a long long - ok
		
CORBA::Any_var label = tcUnion->member_label(0); // get label for first member (longValue)
CORBA::TypeCode_var labelTc = label->type();
CORBA::ULong ulongLabelValue;
if (labelTc->kind() == CORBA::tk_ulong)
{
  label >>= ulongLabelValue;
  std::cout << "!!!!Found type tk_ulong in labelTypeCode" << std::endl;
  std::cout << "!!!!Label value is " << ulongLabelValue << std::endl;
}
assert(labelTc->kind() == CORBA::tk_enum || labelTc->kind() == CORBA::tk_octet); // oops

Output:
Fist union member name: longValue
!!!!Found type tk_ulong in labelTypeCode
!!!!Label value is 0
Assertion failed: (labelTc->kind() == CORBA::tk_enum || labelTc->kind() ==
CORBA::tk_octet), function main, file ...

-
I'm not certain if this is standard compliant (I would expect the get the same types from
discriminator_type and member_label(x).type()). Tt seems like omniORBs behaviour is
symmetric with constructing unions typecodes using ORB::create_union_tc. For me it was
easy to do a workaround in deserialization (pseudo code):
if (discriminatortype == tk_enum)
{
  members[x].label <<= (CORBA::ULong) labelReadFromDisc.to_ulong();
}
else
{
  ..more serious construction
}

thanks & regards
michael



More information about the omniORB-list mailing list