4. Data Representation

The data representation specifies the ways in which a data sample of a given type are communicated over the network.

The OMG 'Extensible and Dynamic Topic Types for DDS' specification, version 1.3 defines three different data representations:

  • Extended Common Data Representation (CDR) encoding version 1 (XCDR)
  • Extended CDR encoding version 2 (XCDR2)
  • XML data representation

Connext 6.0.0 and above implements both XCDR and XCDR2. Connext 5.3.1 and below implements only XCDR. XML data representation is not supported.

4.1 Configuring the CDR

You may use the DataRepresentationQosPolicy in the DataWriterQos to configure which version of Extended CDR, version 1 or version 2, the DataWriter will use to serialize its data. The same QosPolicy exists in the DataReaderQos to configure which version(s) the DataReader will accept from DataWriters. DataWriters can offer only one data representation, while DataReaders can request multiple data representations.

For more information, see "DATA_REPRESENTATION QosPolicy" in the RTI Connext Core Libraries User's Manual.

4.1.1 @allowed_data_representation annotation

The data representations that you are allowed to configure in the DataRepresentationQosPolicy for a type ‘T’ are limited to the allowed data representations for the type.

The @allowed_data_representation annotation lets you restrict the data representations that may be used to encode a data object of a specific type. (You can select from this restricted set when setting the DataRepresentationQosPolicy.) The IDL definition of the @allowed_data_representation annotation is as follows:

// Positions are defined to match the values of the DataRepresentationId_t
// XCDR_DATA_REPRESENTATION, XML_DATA_REPRESENTATION, and
// XCDR2_DATA_REPRESENTATION
@bit_bound(32)
bitmask DataRepresentationMask {
   @position(0) XCDR,
   @position(1) XML,
   @posiiton(2) XCDR2
}
 
@annotation allowed_data_representation {
   DataRepresentationMask value;
};

For example:

@allowed_data_representation(XCDR2)
struct Position
{
    int32 x;
    int32 y;
};

DataWriters and DataReaders using the previous type can publish and subscribe to only an XCDR2 representation, regardless of the value set in the DataRepresentationQosPolicy. (If a DataWriter or DataReader in this case sets its DataRepresentationQosPolicy to XCDR, Connext will automatically change it to XCDR2 and print a log message indicating this change.)

If the @allowed_data_representation annotation is not present, Connext interprets the data representation as if the DataRepresentationMask value was set to XCDR|XCDR2 for PLAIN language binding and XCDR2 for FLAT_DATA language binding. For information about the RTI FlatData™ language binding, see the "Sending Large Data" chapter in the RTI Connext Core Libraries User's Manual.

4.2 Extended CDR (encoding version 1)

The "traditional" OMG CDR (PLAIN_CDR) is used for final and extensible types. It is also used for primitive, string, and sequence types.

Mutable types and optional members use parameterized CDR (PL_CDR), in which each member is preceded by a member header that consists of the member ID and member serialized length.

The member header can be 4 bytes (2 bytes for the member ID and 2 bytes for the serialized length) or 12 bytes (where 8 bytes are used for the member ID and 4 bytes are used for the length).

Member IDs greater than 16,128 require a 12-byte header. Therefore, to reduce network bandwidth, the recommendation is to use member IDs less than or equal to 16,128.

Also, members with a serialized size greater than 65,535 bytes require a 12-byte header.

Notice that for members with a member ID less than 16,129 and a serialized size less than 65,536 bytes, it is up to the implementation to decide whether or not to use a 12-byte header. For this version of Connext, the header selection rules are as follows:

  • If the member ID is greater than 16,128, use a 12-byte header.
  • Otherwise, if the member is a primitive type (int16, uint16, int32, uint32, int64, uint64, float, double, long double, boolean, octet, char), use a 4-byte header.
  • Otherwise, if the member is an enumeration, use a 4-byte header.
  • Otherwise, if the maximum serialized size of the type is less than 65,536 bytes, use a 4-byte header.
  • Otherwise, use a 12-byte header.

4.3 Extended CDR (encoding version 2)

From the ‘Extensible and Dynamic Topic Types for DDS’ specification:

The specification defines three encoding formats used with encoding version 2: PLAIN_CDR2, DELIMITED_CDR, and PL_CDR2.

  • PLAIN_CDR2 shall be used for all primitive, string, and enumerated types. It is also used for any type with an extensibility kind of FINAL. The encoding is similar to PLAIN_CDR except that INT64, UINT64, FLOAT64, and FLOAT128 are serialized into the CDR buffer at offsets that are aligned to 4 [bytes] instead of 8 ....
  • DELIMITED_CDR shall be used for types with an extensibility kind of APPENDABLE. It serializes a UINT32 delimiter header (DHEADER) before serializing the object using PLAIN_CDR2. The delimiter encodes the endianness and the length of the serialized object that follows.
  • PL_CDR2 shall be used for aggregated types with an extensibility kind of MUTABLE. Similar to DELIMITED_CDR, it also serializes a DHEADER before serializing the object. In addition, it serializes a member header (EMHEADER) ahead of each serialized member. The member header encodes the member ID, the must-understand flag, and the length of the serialized member that follows.

In Extended CDR encoding version 2, wchar sizes changed from 4 bytes (Char32) to 2 bytes (Char16).

For more information about encoding version 2, please see the OMG 'Extensible and Dynamic Topic Types for DDS' specification, version 1.3.

4.4 Choosing the Right Data Representation

Extended CDR encoding 2 (XCDR2) is more efficient on the wire than Extended CDR encoding 1 (XCDR). For new applications, Extended CDR encoding 2 is the recommended data representation; however, if you need to keep compatibility and interoperability with old Connext applications (5.3.1 and below), you may have to continue using Extended CDR encoding 1.

DataReaders can be configured to receive data using both XCDR2 and XCDR. This way, a DataReader can still interoperate and receive data from old Connext DataWriters using XCDR, while receiving data from new DataWriters using XCDR2.

The opposite is not true. DataWriters can publish only one data representation. Therefore, if there is a requirement to receive data for a topic 'T' with old Connext DataReaders, you will have to continue to publish data for topic 'T' with XCDR representation on the new DataWriters or use a bridge such as Routing Service to translate between XCDR and XCDR2.