Unions are encoded as a switch field preceding one of the possible fields. The encoding for the selected field is determined by the data type for the field.
The switch field is encoded as a UInt32.
The switch field is the index of the available union fields starting with 1. If the switch field is 0 then no field is present. For any value greater than the number of defined union fields the encoders or decoders shall report an error.
A Union with no fields present has the same meaning as a NULL value. A Union with any field present is not a NULL value even if the value of the field itself is NULL.
The following is an example of a union using C/C++ syntax:
struct Type2
{
Int32 A;
Int32 B;
};
struct Type1
{
Byte Selector;
union
{
Int32Field1;
Type2Field2;
}
Value;
};
In the C/C++ example above, the Selector, Field1 and Field2 are semantically coupled to form a union.
An instance of Type1 would be encoded as byte sequence. The length of the byte sequence depends on the selected field.
An instance of Type1 where field Field1 is available would be encoded as 8-byte sequence. If the instance of Type 1 was encoded in an ExtensionObject it would have the encoded form shown in Table 27 and it would have a total length of 17 bytes. The TypeId, Encoding and the Length are fields defined by the ExtensionObject.
Table 27 – Sample OPC UA Binary Encoded Structure
Field |
Bytes |
Value |
Type Id |
4 |
The identifier for Type1 |
Encoding |
1 |
0x1 for ByteString |
Length |
4 |
8 |
SwitchValue |
4 |
1 for Field1 |
Field1 |
4 |
The value of Field1 |
The Value of the DataTypeDefinition Attribute for a DataType Node describing Type1 is:
Name |
Type |
Description |
defaultEncodingId |
NodeId |
NodeId of the “Type1_Encoding_DefaultBinary” Node. |
baseDataType |
NodeId |
“i=22” [Union] |
structureType |
StructureType |
Union_2 [Union] |
fields [0] |
StructureField |
|
name |
String |
“Field1” |
description |
LocalizedText |
Description of Field1 |
dataType |
NodeId |
“i=6” [Int32] |
valueRank |
Int32 |
-1 (Scalar) |
arrayDimensions |
UInt32[] |
null |
maxStringLength |
UInt32 |
0 |
isOptional |
Boolean |
true |
fields [1] |
StructureField |
|
name |
String |
“Field2“ |
description |
LocalizedText |
Description of Field2 |
dataType |
NodeId |
NodeId of the Type2 DataType Node (e.g. “ns=3; s=MyType2”) |
valueRank |
Int32 |
-1 (Scalar) |
arrayDimensions |
UInt32[] |
null |
maxStringLength |
UInt32 |
0 |
isOptional |
Boolean |
true |
The Value of the DataTypeDefinition Attribute for a DataType Node describing Type2 is:
Name |
Type |
Description |
defaultEncodingId |
NodeId |
NodeId of the “Type2_Encoding_DefaultBinary” Node. |
baseDataType |
NodeId |
“i=22” [Structure] |
structureType |
StructureType |
Structure_0 [Structure without optional fields] |
fields [0] |
StructureField |
|
name |
String |
“A“ |
description |
LocalizedText |
Description of A |
dataType |
NodeId |
“i=6” [Int32] |
valueRank |
Int32 |
-1 (Scalar) |
arrayDimensions |
UInt32[] |
null |
maxStringLength |
UInt32 |
0 |
isOptional |
Boolean |
false |
fields [1] |
StructureField |
|
name |
String |
“B“ |
description |
LocalizedText |
Description of B |
dataType |
NodeId |
“i=6” [Int32] |
valueRank |
Int32 |
-1 (Scalar) |
arrayDimensions |
UInt32[] |
null |
maxStringLength |
UInt32 |
0 |
isOptional |
Boolean |
false |