Writing a type plugin from a C structure

Updated: April 19, 2023

The process for creating a PiPS data type from an existing C structure is largely the same as that when starting from an IDL definition. But in the C structure scenario, a suitable IDL must be derived for the structure. In this second programming tutorial, we enhance the DataBuffer type to allow for keyed data exchanges. The fastrtps_databuffer structure will be re-used for this purpose.

We can support point-to-point and client-server communication for our new data type in PiPS, by specifying a key value. In our case, we can enhance the DataBuffer IDL structure to implement the KeyedDataBuffer_s data type:
struct KeyedDataBuffer_s {
    @Key string           id;
    string                name;
    sequence<octet>       buffer;

We name our file KeyedDataBuffer.idl. Its content is identical to DataBuffer.idl, with an additional id field that is tagged with @Key. Using our new IDL file, we can follow the same steps as in the first tutorial to write the type plugin. The type implementation class is named KeyedDataBufferType and in the encoder and decoder routines (e.g., encodePPS(), decodePPS()), the id field doesn't get serialized or deserialized. This is because the ID is used strictly for subscribers to determine whether an update is directed to them, and doesn't convey any sample data.

To support point-to-point and client-server communication, we must override the setKey() function. This involves translating a 128-bit GUID into an appropriate key value and storing it in the given sample. For KeyedDataBufferType, we can convert the GUID to a string and assign it to the id field:
void KeyedDataBufferType::setKey( void* data, const pips_guid_t& guid ) const
    pips_guid_str_t key;
    KeyedDataBuffer* sample = ( KeyedDataBuffer* )data;

    assert( sample );
    pips_guid_tostring( &guid, &key );
    sample.id( ( char* )key.str );

This guarantees the uniqueness of the GUID-to-key mapping.