DynamicData Serialization
Following method allows to serialize and deserialize data of arbitrary type (type definition must be known) and store it's representation. It can be useful in many scenarios, e.g:
- save sample to file for a later use.
- forward data received via DDS to an application with no access to DDS network
TypeCode Serialization is already covered in following example: http://community.rti.com/filedepot?cid=5&fid=28
To serialize and deserialize DDS_DynamicData you have to specify type definition via type code. Type code can be either generated with rtiddsgen or created manually
DDS_TypeCode *createTypeCode()
{
DDS_TypeCodeFactory * factory = NULL;
DDS_TypeCode * structTc = NULL;
DDS_ExceptionCode_t ex = DDS_NO_EXCEPTION_CODE;
DDS_StructMemberSeq structMembers;
factory = DDS_TypeCodeFactory::get_instance();
structTc = factory->create_struct_tc("test_type", structMembers, ex);
structTc->add_member("bool_1", DDS_TYPECODE_MEMBER_ID_INVALID, factory->get_primitive_tc(DDS_TK_BOOLEAN),
DDS_TYPECODE_NONKEY_REQUIRED_MEMBER, ex);
structTc->add_member("bool_2", DDS_TYPECODE_MEMBER_ID_INVALID, factory->get_primitive_tc(DDS_TK_BOOLEAN),
DDS_TYPECODE_NONKEY_REQUIRED_MEMBER, ex);
structTc->add_member("bool_3", DDS_TYPECODE_MEMBER_ID_INVALID, factory->get_primitive_tc(DDS_TK_BOOLEAN),
DDS_TYPECODE_NONKEY_REQUIRED_MEMBER, ex);
structTc->add_member("double_1", DDS_TYPECODE_MEMBER_ID_INVALID, factory->get_primitive_tc(DDS_TK_DOUBLE),
DDS_TYPECODE_NONKEY_REQUIRED_MEMBER, ex);
structTc->add_member("ulong_1", DDS_TYPECODE_MEMBER_ID_INVALID, factory->get_primitive_tc(DDS_TK_ULONG),
DDS_TYPECODE_NONKEY_REQUIRED_MEMBER, ex);
structTc->add_member("string_1", DDS_TYPECODE_MEMBER_ID_INVALID, factory->create_string_tc(60, ex),
DDS_TYPECODE_NONKEY_REQUIRED_MEMBER, ex);
return structTc;
}After you have DDS_TypeCode you will need DDSDynamicDataTypeSupport to create DDS_DynamicData objects of this type
DDS_TypeCode* typeCode = createTypeCode(); DDSDynamicDataTypeSupport* typeSupport = new DDSDynamicDataTypeSupport(typeCode, DDS_DYNAMIC_DATA_TYPE_PROPERTY_DEFAULT); DDS_DynamicData* dynamicData = typeSupport->create_data();
To serialize DDS data RTICdrStream is used. It's possible to provide external buffer to get access to serialized data representation.
Important: You have to define RTI_ENDIAN_LITTLE macro for you compiler if you platform uses little-endian representation (and it's most common case since x86 and x86-64 machines are little-endian) in order to correctly serialize and deserialize data. This define is used in RTICdrStream_init to set correct native endianness of your platform.
With following code buffer is assigned to RtiCdrStream :
char buffer[1000]; int bufferLen = 1000; RTICdrStream serializationStream; RTICdrStream_init(&serializationStream); RTICdrStream_set(&serializationStream, buffer, bufferLen);
Afterwards it's easy to serialize DDS_DynamicData to buffer using to_stream method:
dynamicData->to_stream(serializationStream);
There is internal current position offset in RtiCdrStream so you should always set buffer with RTICdrStream_set before serialization to reset offset. Size of serialized representation can be determined via current offset
int serializedSize = RTICdrStream_getCurrentPositionOffset(&serializationStream);
Deserialization is performed in similar way. First prepare stream by providing it buffer with serialized data:
RTICdrStream deserializationStream; RTICdrStream_init(&deserializationStream); RTICdrStream_set(&deserializationStream, buffer, bufferLen);
Next you can deserialize data. You should prepare DynamicData object before deserialization.
DDS_DynamicData* deserializedData = typeSupport->create_data(); deserializedData->from_stream(deserializationStream);
Comments
Gerardo Pardo
Tue, 05/10/2016 - 00:52
Permalink
This has been simplified in Connext DDS 5.2
Connext DDS 5.2 introduced a new operation DDS_DynamicData::to_cdr_buffer that simplifies serialization of dynamic data so you no longer need to deal with the underlying RTICdrStream object.
For example, the dynamicData object can be serialized with:
Likewise to deserialize a dynamic data from a CDR buffer there is a new function DDS_DynamicData::from_cdr_buffer as in:
Gerardo