### Navigation

- index
- next |
- previous |
- IDL PreProcessor Guide »

# 7. Keys

## 7.1. Defining Keys

The Vortex OpenSplice IDL Pre-processor also provides a mechanism to define a list of keys (space- or comma-separated) with a specific data type. The syntax for that definition is:

    #pragma keylist <data-type-name> <key>*

The identifier `<data-type-name>` is the identification of a struct or a union definition.

The identifier `<key>` is the member of a struct. For a struct either no key list is defined, in which case no specialized interfaces (`TypeSupport`, `DataReader` and `DataWriter`) are generated for the struct, or a key list with or without keys is defined, in which case the specialized interfaces are generated for the struct. For a union either no key list is defined, in which case no specialized interfaces are generated for the union, or a key list without keys is defined, in which case the specialized interfaces are generated for the union. It is not possible to define keys for a union because a union case may only be addressed when the discriminant is set accordingly, nor is it possible to address the discriminant of a union. The keylist must be defined in the same name scope or module as the referred struct or union.

### 7.1.1. Supported types for keys

Vortex OpenSplice supports following types as keys:

- short
- long
- long long
- unsigned short
- unsigned long
- unsigned long long
- float
- double
- char
- boolean
- octet
- string
- bounded string
- enum
- char array (provided that `#pragma cats` is specified; see Character arrays as Keys below)

Vortex OpenSplice also supports typedef for these types.

### 7.1.2. Character arrays as Keys

By default Vortex OpenSplice does not support using a character array as a key. Using an (character) array as a key field is not desirable or supported, because:

1. Every index in the array must be considered a separate key in this situation. This is the only way that arrays can be compared to each other in a correct manner. An array of ten characters would have to be treated as a ten-dimensional storage structure, leading to poor performance compared with the processing of a (bounded) string of ten characters.
2. An array always has a fixed length and therefore the whole array is sent over the wire even if only a small part of it is needed. When using a (bounded) string, only the actual string is sent and not the maximum length.

However, in certain scenarios a character array is the logical key for a topic, either from an information modeling perspective or simply due to a legacy data model. To facilitate such scenarios Vortex OpenSplice introduces the following pragma which allows for character arrays to be used as a key.

    #pragma cats <data-type-name> <char-array-field-name>*

The identifier `<data-type-name>` is the identification of a struct definition. The identifier `<char-array-field-name>` is the member of a struct with the type character array. The `cats` pragma must be defined in the same name scope or module as the referred struct.

This pragma ensures that each character array listed for the specified struct definition is treated as a string type internally within Vortex OpenSplice and operates exactly like a regular string. This allows the character array to be used as a key for the data type, because as far as Vortex OpenSplice is concerned the character array is in fact a string. On the API level (e.g., generated code) the character array is maintained so that applications will be able to use the field as a regular character array as normal. Be aware that listing a character array here does not promote the character array to a key of the data type; the regular keylist pragma must still be used for that. In effect this pragma can be used to let any character array be treated as a string internally, although that is not by definition desirable.

When a character array is mapped to a string internally by using the cats pragma, the product behaves as follows:

1. If the character array does not have a ‘0’ terminator, the middleware will add a `\0` terminator internally and then remove it again in the character array that is presented to a subscribing application. In other words, a character array used in combination with the cats pragma does not need to define a `\0` terminator as one of its elements.
2. If the character array does have a `\0` terminator, the middleware will only process the characters up to the first element containing the `\0` character; all other characters are ignored. The middleware will present the character array with the same `\0` terminator to a subscribing application and any array elements following that `\0` terminator will contain `\0` terminators as well; i.e., any array elements following a `\0` element are ignored.

The following table shows some examples using the cats pragma for a character array with a size of `4`.

Character array written | Internal string representation | Character array read
--- | --- | ---
(by publishing application) | (Internal OpenSplice data) | (By subscribing application)
`['a','b','c','d']` | `"abcd"` | `['a','b','c','d']`
`['a','b','c','\0']` | `"abc"` | `['a','b','c','\0']`
`['a','b','\0','d']` | `"ab"` | `['a','b','\0','\0']`

## 7.2. Bounded strings as character arrays

In some use cases a large number of (relatively small) strings may be used in the data model, and because each string is a reference type, it means that it is not stored inline in the data model but instead as a pointer. This will result in separate allocations for each string (and thus a performance penalty when writing data) and a slight increase in memory usage due to pointers and (memory storage) headers for each string.

The Vortex OpenSplice IDL Pre-Processor features a special pragma called `stac` which can be utilized in such use cases. This pragma enables you to indicate that Vortex OpenSplice should store strings internally as character arrays (but on the API level they are still bounded strings). Because a character array has a fixed size, the pragma `stac` only affects bounded strings. By storing the strings internally as a character array the number of allocations is reduced and less memory is used. This is most effective in a scenario where a typical string has a relatively small size, i.e. fewer than 100 characters.

> Using the pragma `stac` on bounded strings results in the limitation that those strings can no longer be utilized in queries. It also results in the maximum size of the bounded string to be used each time, therefore the pragma `stac` is less suitable when the string has a large bound and does not always use up the maximum space when filled with data. A bounded string that is also mentioned in the pragma `keylist` can not be listed for pragma `stac`, as transforming those strings to an array would violate the rule that an array can not be a keyfield.

    #pragma stac <data-type-name> [[!]bounded-string-fieldname]\*

The identifier <data-type-name> is the identification of a struct definition. The identifier [[!]bounded-string-field-name] is the member of a struct with the type bounded string. The `stac` pragma must be defined in the same name scope or module as the referred struct. If no field names are listed, then all bounded strings will be treated as character arrays internally. If only a subset of the struct members is targeted for transformation then these members can be listed explicitly one by one. Preceeding a field name with a `!` character indicates that the listed member should not be considered for transformation from bounded string to character array.

> Member names with and without the `!` character may not be mixed within a `stac` pragma for a specific struct as this has no relevant meaning. This pragma ensures that each bounded string listed for the specified struct definition is treated as a character array type internally within Vortex OpenSplice and operates exactly like a regular bounded string. On the API level ( i.e. , generated code) the bounded string is maintained so that applications will be able to use the field as a regular bounded string.

### Navigation

- index
- next |
- previous |
- IDL PreProcessor Guide »