Hi,
I am looking to define a topic which ideally would have, say following attributes:
struct topic {
sequence<octet, 1000> data1;
sequence<octet, 2000> data2;
sequence<octet, 3000> data3;
}
But, some instance of this topic will not have any value for data3, say. And some instance will not have to occupy the entire length of data, say length of topic.data2 = 1000 (instead of 2000).
What is the best way (or best ways) to deal with such a scenario?
Thanks,
Uday
Hi Uday,
Sequences are variable length structures that allow you to change the size from one publish to the next. When publishing, RTI Connext does not send the maximum but rather the current length of the sequence. For example, say you only wanted to send 1000 bytes in the data structure you've defined above (in c++):
topic dataItem;
dataItem.data2.ensure_length(1000,2000); // this allocates space for up to 2000 elements, but sets the logical length to 1000 elements
When the DataReader receives the above, the length() of the data2 sequence will indicate the actual length - 1000 elements. And only 1000 elements will be sent on the wire. In the same vein, you can set a sequence to have 0 elements:
dataItem.data3.length(0);
When
dataItem
is published, data3 will have 0 elements present (length()==0).So sequences are variable length by definition. If you wanted fixed length fields, then use an array rather than a sequence. There is also another option called 'optional' fields, but I'm not sure if that's what you need given your data type.
Question for you - why does your data type have 3 opaque sequences? Are you sending opaque bytes, or is there some structure that you cannot describe in IDL?
Also, if I may ask - which GE Healthcare group are you with?
-sumeet
Hi Sumeet,
Thanks a lot for the reply.
I came across some examples, which follow the idea you mentioned - ensuring that the length of data is set to only what is populated so that only that amount is sent on wire. I am OK with setting to the actual length, but I am not OK with the case of setting to 0. I would rather avoid that attribute/field completely. Basically I am trying to define a topic which may or may not have some associated data depending on the logic of publisher.
To answer your question on why I am using 3 opaque bytes - I just used it for the sake of simplicity. Some of them could as well be sequence<unsigned long, 1000>, but some could just be opaque bytes as I cannot define in IDL.
What did you mean by 'optional fields'? It sounds like that is what I want, but dont know. Does it mean I can have 'data3' field optional?
I will have to explore a bit more on the arrays.
I work with CT group (Greg / Kevin).
Thanks.
Uday
BTW, I just came across this link - https://community.rti.com/content/forum-topic/using-union-idl
Looks like this would help me. But I need to evaluate.
Hi Uday,
Unions carry consequences with resources. A union gets generated as a structure/class that contains a field of every possible type within the union definition; that is, the generated definition is not an actual C/C++ union, but an RTI specific type. However, only the type identified by the discriminant is actually published on the wire. I mention this because the memory size of the generated union type will be the sum total of all possible fields.
You may be more interested in the optional field functionality. You can identify a field as optional in your IDL:
struct type {
sequence<octet, 100=""> data1; //@Optional
The above marks data1 as an optional field, which means it may or may not be present from one publish to the next. The field will be generated as a pointer for C/C++, and a reference for Java. If the field is present, you will be able to access the value. If the field is not present, data1 will be null.
This may be a better option for what you want, but bear in mind each optional field will use dynamic memory allocation to hold data rather than our usual strategy of pre-allocation. This may not be a concern for you, but I wanted to make sure you were aware. You can find more info about optional fields (and type extensibility in general) in the XTypes addendum (link here: http://community.rti.com/rti-doc/510/ndds.5.1.0/doc/pdf/RTI_CoreLibrariesAndUtilities_GettingStarted_ExtensibleTypesAddendum.pdf).
-sumeet
Hi Sumeet,
I am looking into the option of discriminated unions, currently, though the approach of 'Optional fields' is in pipeline. I understand from IDL_CPP mapping that a union of the following type:
union U switch (char) {
case 'L':
long long_mem;
case 'c':
case 'C':
char char_mem;
default:
string string_mem;
};
would end up providing apis like 'short_mem()' and 'long_mem()' etc. These functions would eventually take care of setting the discriminator. But, I dont see that in my generated code. Not sure if that is expected. In other words, I am looking into use cases of setting and accessing the instances with fields coming from discriminated unions. Is there a place I can find end-to-end example(s) for such scenario?
Thanks.
Uday
With a little bit of exploring the examples, I see that the short_mem() etc. functions are not from the generated code, but from the DDS_DynamicData api. This is what I came across - https://community.rti.com/examples/dynamic-data-access-union-discriminators.
Can I get an end-to-end example of the discriminated union usage with the idl definition, setting of the union fields by publisher, accessing them by the subscriber etc.?
Uday
Hi Uday,
Here's a simple example using the Union type you provided. The logic would be similar for Java or C as the 'Union' type in IDL is mapped to a structure (or Java class) that contains all possible types rather than a native language union. Note that you have to inspect the discriminant to identify which field has the relevant value.
-sumeet
Thanks Sumeet for the example.