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