TypeCode serialization

1 post / 0 new
Offline
Last seen: 6 years 8 months ago
Joined: 04/04/2014
Posts: 27
TypeCode serialization

Hello!

We extensively use DynamicData with deserialized typecodes and I've met following problem - it's not possible (serialized representation is much shorter than expected and invalid) to serialize dynamically created struct typecode containg deserialized typecode members:

deserializedTypeCode = deserializeTypeCode(...);

DDS_TypeCodeFactory* factory = DDS_TypeCodeFactory_get_instance();
DDS_TypeCode* tc = DDS_TypeCodeFactory_create_struct_tc(factory, "test_tc", NULL, &ex);
tc->add_member("data", DDS_TYPECODE_MEMBER_ID_INVALID, deserializedTypeCode, DDS_TYPECODE_NONKEY_REQUIRED_MEMBER, ex);

 I've investigated this problem in sources and found that it actually shouldn't be possible to add serialized typecode members:

/* Double-check to make sure we don't have serialized form */
if ((self->_data._kind & ~RTI_CDR_TK_FLAGS_ALL) != kind) {
    DDS_SET_EXCEPTION_CODE(DDS_IMMUTABLE_TYPECODE_SYSTEM_EXCEPTION_CODE);
    return DDS_TYPECODE_INDEX_INVALID;
}

But  RTI_CDR_TK_FLAGS_ALL is defined as short  0xff00 and  kind is long so it doesn't check serialized flag  0x80000000 and allows to add serialized members. Since serializing and deserializing data with such dynamic nested typecode was possible I've check typecode serialization internals and found the critical point -  RTICdrTypeCode_serialize itself would work with the nested serialized types, but  RTICdrTypeCode_get_serialized_size is returning 0 size for the serialized typecode representation. Adding following to the RTICdrTypeCode_get_serialized_size was sufficient:

if (RTICdrTypeCode_CDR_REPRESENTATION(typeCode->_kind)) {
    return RTICdrTypeCode_get_stream_length((RTICdrTypeCode *) typeCode)
                    + (RTICdrType_get4ByteMaxSizeSerialized(currentPos) - 4) - 8;
}

It looks a little bit strange because serialized representation contains  kind (long) and  size (short) fields and RTICdrTypeCode_get_serialized_size returns size without them.  RTICdrType_get4ByteMaxSizeSerialized(currentPos) is necessary to correctly align serialized typecode. It works for the structs and another typecode kinds probably need to be aligned in another way, but could work so as well, because as far as I can see they all start with 4 byte field and will be aligned in the same way.

Is it a known problem and is it supposed to work? I didn't test publishing data with such so may be it will crash there, but this change allows to generate the same serialized representation of the dynamic nested typecode as it would be generated for the IDL nested typecode.