RTI Connext Modern C++ API  Version 6.1.0

Offsets provide access to the members of a FlatData Sample. More...

Classes

class  MyFlatFinalOffset
 Represents the Offset to an arbitrary user-defined FlatData final IDL struct. More...
 
class  MyFlatMutableOffset
 Represents the Offset to an arbitrary user-defined FlatData mutable IDL struct. More...
 
class  MyFlatUnionOffset
 Represents the Offset to an arbitrary user-defined FlatData mutable IDL union. More...
 
class  rti::flat::OffsetBase
 Base class of all Offset types. More...
 
class  rti::flat::FinalOffset< T >
 The base class of all Offsets to a final struct type. More...
 
class  rti::flat::MutableOffset
 The base class of all Offsets to a final struct type. More...
 
struct  rti::flat::PrimitiveConstOffset< T >
 A const Offset to an optional primitive member. More...
 
struct  rti::flat::PrimitiveOffset< T >
 An Offset to an optional primitive member. More...
 
class  rti::flat::SequenceIterator< E, OffsetKind >
 Iterator for collections of Offsets. More...
 
class  rti::flat::AbstractPrimitiveList< T >
 Base class for Offsets to sequences and arrays of primitive types. More...
 
class  rti::flat::PrimitiveSequenceOffset< T >
 Offset to a sequence of primitive elements. More...
 
class  rti::flat::PrimitiveArrayOffset< T, N >
 Offset to an array of primitive elements. More...
 
class  rti::flat::StringOffset
 Offset to a string. More...
 
class  rti::flat::AbstractAlignedList< ElementOffset >
 Base class of Offsets to sequences and arrays of non-primitive members. More...
 
class  rti::flat::SequenceOffset< ElementOffset >
 Offset to a sequence of non-primitive elements. More...
 
class  rti::flat::MutableArrayOffset< ElementOffset, N >
 Offset to an array of variable-size elements. More...
 
class  rti::flat::FinalArrayOffset< ElementOffset, N >
 Offset to an array of final elements. More...
 
class  rti::flat::FinalAlignedArrayOffset< ElementOffset, N >
 Offset to an array of final elements. More...
 

Functions

template<typename OffsetType >
flat_type_traits< OffsetType >::plain_type * rti::flat::plain_cast (OffsetType &offset)
 Casts into an equivalent plain C++ type. More...
 
template<typename OffsetType >
const flat_type_traits< OffsetType >::plain_type * rti::flat::plain_cast (const OffsetType &offset)
 Const version of plain_cast. More...
 

Detailed Description

Offsets provide access to the members of a FlatData Sample.

An Offset represents a position within a FlatData Sample that allows accessing a member of that Sample, or the Sample's root.

Offsets can be described as iterators. They represent a position in a buffer, not the value itself. As such, they're lightweight objects that can be copied to point to the same data.

There are the following Offset types to access the different IDL types:

Category Offset type
User types For example:
Arrays
Sequences
Primitive types

Offsets for user types are generated by rtiddsgen and provide methods to access the type's members by their names. Offsets for arrays and sequences provide methods to access each element.

Some offsets allow accessing the data through a pointer to the equivalent plain C++ type, which generally provides better performance. See rti::flat::plain_cast().

Offset Error Management

Functions that return an Offset may return a "null" Offset (one such that is_null() returns true).

An Offset may be null if a member doesn't exist in the Sample. For example, if the member 'my_final' in MyFlatMutable doesn't exist (because it wasn't added while building the Sample, or because it wasn't received in the subscribing application), MyFlatMutableOffset::my_final() returns an null Offset. Note that a member in a final type (for example, MyFlatFinalOffset::my_complex()) always exists, except in the case of an error.

Other than that, any error condition will cause one of the following exceptions, not a null Offset:

Function Documentation

◆ plain_cast() [1/2]

template<typename OffsetType >
flat_type_traits<OffsetType>::plain_type* rti::flat::plain_cast ( OffsetType &  offset)

Casts into an equivalent plain C++ type.

Some FlatData types can be cast to their equivalent plain definition as a regular non-FlatData C++ type. This is a more efficient way to access the data. This function casts, if possible, the member pointed to by the offset argument to an equivalent plain C++ type. Any changes made through the plain type are reflected in the FlatData sample.

Template Parameters
OffsetTypeThe Offset type
Precondition
plain_cast requires the type to meet the following restrictions:
  • The type must be a final struct, or an array or sequence of members of a type that meets these restrictions (including primitive types)
  • The type must be defined in a way such that the packing of the plain C++ type doesn't differ from the padding in XCDR2.
  • The type may not inherit from another type.
  • In addition, the sample must be serialized in the native endianness. For example, if a subscribing application on a little-endian platform receives a sample published from a big-endian system, it is not possible to plain_cast the sample or any of its members, except if the member is a primitive array or sequence of 1-byte elements.

offset.is_cpp_compatible() indicates if the member meets the requirements. If the type doesn't, this function throws dds::core::PreconditionNotMetError.

Parameters
offsetThe offset to the member to cast.
Returns
The data that offset referred to, cast as a plain C++ type with the same definition. If offset is an array or sequence member, the returned pointer represents a C++ array with the same number of elements.

The following table summarizes the possible parameters to this function (assuming that they meet the previous requirements), and the return type in each case:

OffsetType return type
Offset to a final struct, such as MyFlatFinalOffset MyFlatFinalPlainHelper* (pointer to a single element). This is a type with the same IDL definition, but without @language_binding(FLAT_DATA).
Offset to an array of final structs, such as FinalArrayOffset<MyFlatFinalOffset, N> MyFlatFinalPlainHelper* (array of N elements)
Offset to a sequence of final structs, such as SequenceOffset<MyFlatFinalOffset> MyFlatFinalPlainHelper* (array of offset.element_count() elements)
Offset to an array of primitive types, such as PrimitiveArrayOffset<int32_t, N> int32_t* (array of N elements)
Offset to a sequence of primitive types, such as PrimitiveSequenceOffset<int32_t> int32_t* (array of offset.element_count() elements)

Due to the performance advantages that plain_cast offers, it is recommended to define FlatData types in a way that their largest member(s) can be plain_cast.

The following example shows how to use plain_cast to cast a MyFlatFinalOffset into the type with the same IDL definition as MyFlatFinal, but without the @language_binding(FLAT_DATA) annotation:

MyFlatMutable *my_sample = ...;
auto my_root = my_sample->root();
auto my_final = my_root.my_final();
// Get the plain C++ type and modify an array
auto my_final_plain = rti::flat::plain_cast(my_final);
my_final_plain->my_primitive(3); // this is using the plain C++ setter
my_final_plain->my_complex_array()[1].x(20); // this is a std::array
// The change to my_complex_array is reflected in the FlatData sample
std::cout << my_final.my_primitive() << std::endl; // 3
std::cout << my_final.my_complex_array().get_element(1).x() << std::endl; // 20

This example shows how to use plain_cast to efficiently build a sequence of final elements and a sequence of integers, both members of a mutable type:

// 1)
//
// Build a sequence of 5 elements with add_n() instead of 5 calls to
// add_next()
builder.build_my_final_seq();
seq_builder.add_n(5);
// Finish the member, getting the offset to the member
// Cast it to an array of plain C++ type and initialize it.
// This way to initialize it is more efficient than add_next().
auto seq_elements = rti::flat::plain_cast(seq_offset);
for (int i = 0; i < 5; i++) {
seq_elements[i].my_primitive(i);
// ...
}
// 2)
//
// Build a sequence of 1000 integers
auto seq_builder = builder.build_my_primitive_seq();
// make space for 1000 elements, but leave them uninitialized
seq_builder.add_n(1000);
auto seq_offset = seq_builder.finish();
// Initialize the elements:
int32_t *elements = rti::flat::plain_cast(seq_offset);
for (int i = 0; i < 1000; i++) {
elements[i] = ...;
}
// ... continue building the sample using 'builder'

◆ plain_cast() [2/2]

template<typename OffsetType >
const flat_type_traits<OffsetType>::plain_type* rti::flat::plain_cast ( const OffsetType &  offset)

Const version of plain_cast.