Skip to content

Latest commit

 

History

History
321 lines (244 loc) · 12.2 KB

supported_types.rst

File metadata and controls

321 lines (244 loc) · 12.2 KB

Supported Types

In order to provide maximum flexibility and capability to the defined dynamic types, eProsima Fast DDS supports several member types, ranging from simple primitives to nested structures.

This section describes the basic (not nested) supported types. For more complex structures and examples, please, refer to :ref:`dynamictypes_complextypes`.

Primitive Types

This section includes every simple kind:

BOOLEAN INT64
BYTE UINT16
CHAR8 UINT32
CHAR16 UINT64
INT16 FLOAT32
INT32 FLOAT64
FLOAT128  

By definition, primitive types are self-described and can be created without configuration parameters. Therefore, |DynamicTypeBuilderFactory| exposes several functions to allow users create the dynamic type avoiding the |DynamicTypeBuilder| step. The DynamicTypeBuilder can still be used to create dynamic data of primitive types, as shown on the example below. The DynamicData class has a specific :func:`get` and :func:`set` functions for each primitive type of the list.

.. literalinclude:: /../code/CodeTester.cpp
   :language: c++
   :start-after: //DYNAMIC_TYPES_CREATE_PRIMITIVES
   :end-before: //!--
   :dedent: 8

String and WString

Strings are pretty similar to primitive types, the main difference being that they need to set the size of the buffer that they can manage. By default this size is set to 255 characters.

DynamicTypeBuilderFactory exposes the functions :func:`create_string_type` and :func:`create_wstring_type` to allow users create the DynamicTypes avoiding the DynamicTypeBuilder step. The DynamicTypeBuilder can still be used to create String type dynamic data, as shown on the example below.

.. literalinclude:: /../code/CodeTester.cpp
   :language: c++
   :start-after: //DYNAMIC_TYPES_CREATE_STRINGS
   :end-before: //!--
   :dedent: 8

Alias

Alias types provide an alternative name to an already existing type. Once the DynamicData is created, users can access its information as if they were working with the base type.

DynamicTypeBuilderFactory exposes the function :func:`create_alias_type` to allow users create the Alias types avoiding the DynamicTypeBuilder step. The DynamicTypeBuilder can still be used to create Alias, as shown on the example below.

.. literalinclude:: /../code/CodeTester.cpp
   :language: c++
   :start-after: //DYNAMIC_TYPES_CREATE_ALIAS
   :end-before: //!--
   :dedent: 8

Enumeration

An enumeration contains a set of supported values and a selected value among those supported. The supported values must be configured using the DynamicTypeBuilder, using the :func:`add_member` function for each supported value. The input to this function is the index and the name of the value we want to add.

The DynamicData class has functions :func:`get_enum_value` and :func:`set_enum_value` to work with value index or value name name strings.

.. literalinclude:: /../code/CodeTester.cpp
   :language: c++
   :start-after: //DYNAMIC_TYPES_CREATE_ENUMERATIONS
   :end-before: //!--
   :dedent: 8

Bitmask

Bitmasks are similar to enumeration types, but their members work as bit flags that can be individually turned on and off. Bit operations can be applied when testing or setting a bitmask value. DynamicData has the special functions :func:`get_bitmask_value` and :func:`set_bitmask_value` which allow to retrieve or modify the full value instead of accessing each bit.

Bitmasks can be bound to any number of bits up to 64.

.. literalinclude:: /../code/CodeTester.cpp
   :language: c++
   :start-after: //DYNAMIC_TYPES_CREATE_BITMASKS
   :end-before: //!--
   :dedent: 8

Structure

Structures are the common complex types, they allow to add any kind of members inside them. They do not have any value, they are only used to contain other types.

To manage the types inside the structure, users can call the :func:`get` and :func:`set` functions according to the kind of the type inside the structure using their ids. If the structure contains a complex value, it should be used with loan_value to access to it and return_loaned_value to release that pointer. DynamicData manages the counter of loaned values and users can not loan a value that has been loaned previously without calling return_loaned_value before.

The ids must be consecutive starting by zero, and the DynamicType will change that Id if it doesn't match with the next value. If two members have the same Id, after adding the second one, the previous will change its Id to the next value. To get the Id of a member by name, DynamicData exposes the function :func:`get_member_id_by_name`.

.. literalinclude:: /../code/CodeTester.cpp
   :language: c++
   :start-after: //DYNAMIC_TYPES_CREATE_STRUCTS
   :end-before: //!--
   :dedent: 8

Structures allow inheritance, exactly with the same OOP meaning. To inherit from another structure, we must create the structure calling the :func:`create_child_struct_builder` of the factory. This function is shared with bitsets and will deduce our type depending on the parent's type.

.. literalinclude:: /../code/CodeTester.cpp
   :language: c++
   :start-after: //DYNAMIC_TYPES_CREATE_STRUCTS-INHERIT
   :end-before: //!--
   :dedent: 8

Bitset

Bitset types are similar to structure types, but their members are merely bitfields, which are stored optimally. In the static version of bitsets, each bit uses just one bit in memory (with platform limitations) without alignment considerations. A bitfield can be anonymous (cannot be addressed) to skip unused bits within a bitset.

Each bitfield in a bitset can be modified through their minimal needed primitive representation.

Number of bits Primitive
1 BOOLEAN
2-8 UINT8
9-16 UINT16
17-32 UINT32
33-64 UINT64

Each bitfield (or member) works like its primitive type with the only difference that the internal storage only modifies the involved bits instead of the full primitive value.

Bit_bound and position of the bitfield can be set using annotations (useful when converting between static and dynamic bitsets).

.. literalinclude:: /../code/CodeTester.cpp
   :language: c++
   :start-after: //DYNAMIC_TYPES_CREATE_BITSETS
   :end-before: //!--
   :dedent: 8

Bitsets allows inheritance, exactly with the same OOP meaning. To inherit from another bitset, we must create the bitset calling the create_child_struct_builder of the factory. This function is shared with structures and will deduce our type depending on the parent's type.

.. literalinclude:: /../code/CodeTester.cpp
   :language: c++
   :start-after: //DYNAMIC_TYPES_CREATE_BITSETS-INHERIT
   :end-before: //!--
   :dedent: 8

Union

Unions are a special kind of structures where only one of the members is active at the same time. To control these members, users must set the discriminator type that is going to be used to select the current member calling the create_union_builder function. The discriminator itself is a DynamicType of any primitive type, string type or union type.

Every member that is going to be added needs at least one union_case_index to set how it is going to be selected and, optionally, if it is the default value of the union.

.. literalinclude:: /../code/CodeTester.cpp
   :language: c++
   :start-after: //DYNAMIC_TYPES_CREATE_UNIONS
   :end-before: //!--
   :dedent: 8

Sequence

A complex type that manages its members as a list of items allowing users to insert, remove or access to a member of the list. To create this type users need to specify the type that it is going to store and optionally the size limit of the list.

To ease the memory management of this type, DynamicData has these functions:

.. literalinclude:: /../code/CodeTester.cpp
   :language: c++
   :start-after: //DYNAMIC_TYPES_CREATE_SEQUENCES
   :end-before: //!--
   :dedent: 8

Array

Arrays are pretty similar to sequences with two main differences: they can have multiple dimensions and they do not need their elements to be stored consecutively.

An array needs to know the number of dimensions it is managing. For that, users must provide a vector with as many elements as dimensions in the array. Each element in the vector represents the size of the given dimension. If the value of an element is set to zero, the default value applies (100).

Id values on the :func:`set` and :func:`get` functions of DynamicData correspond to the array index. To ease the management of array elements, every :func:`set` function in DynamicData class creates the item if the given index is empty.

To ease the memory management of this type, DynamicData has these functions:

.. literalinclude:: /../code/CodeTester.cpp
   :language: c++
   :start-after: //DYNAMIC_TYPES_CREATE_ARRAYS
   :end-before: //!--
   :dedent: 8

Map

Maps contain a list of 'key-value' pair types, allowing users to insert, remove or modify the element types of the map. The main difference with sequences is that the map works with pairs of elements and creates copies of the key element to block the access to these elements.

To create a map, users must set the types of the key and the value elements, and, optionally, the size limit of the map.

To ease the memory management of this type, DynamicData has these functions:

.. literalinclude:: /../code/CodeTester.cpp
   :language: c++
   :start-after: //DYNAMIC_TYPES_CREATE_MAPS
   :end-before: //!--
   :dedent: 8