Errata exists for this version of the document.
Structures with optional fields are encoded with an encoding mask preceding a sequence of fields in the order that they appear in the definition. The encoding for each field is determined by the data type for the field.
The EncodingMask is a 32-bit unsigned integer. Each optional field is assigned exactly one bit. The first optional field is assigned bit ‘0’, the second optional field is assigned bit ‘1’ and so until all optional fields are assigned bits. A maximum of 32 optional fields can appear within a single Structure. Unassigned bits are set to 0 by encoders. Decoders shall report an error if unassigned bits are not 0.
The following is an example of a structure with optional fields using C++ syntax:
struct TypeA
{
Int32 X;
Int32* O1;
SByte Y;
Int32* O2;
};
O1 and O2 are optional fields which are NULL if not present
An instance of TypeA which contains two mandatory (X and Y) and two optional (O1 and O2) fields would be encoded as a byte sequence. The length of the byte sequence is depending on the available optional fields. An encoding mask field determines the available optional fields.
An instance of TypeA where field O2 is available and field O1 is not available would be encoded as a 13-byte sequence. If the instance of TypeA was encoded in an ExtensionObject it would have the encoded form shown in Table 17 and have a total length of 20 bytes. The length of the TypeId, Encoding and the Length are fields defined by the ExtensionObject.
Table 17 – Sample OPC UA Binary Encoded Structure with optional fields
Field |
Bytes |
Value |
Type Id |
4 |
The identifier for TypeA |
Encoding |
1 |
0x1 for ByteString |
Length |
4 |
13 |
EncodingMask |
4 |
0x02 for O2 |
X |
4 |
The value of X |
Y |
1 |
The value of Y |
O2 |
4 |
The value of *O2 |
If a Structure with optional fields is subtyped, the subtypes extend the EncodingMask defined for the the parent.
The Value of the DataTypeDefinition Attribute for a DataType Node describing TypeA is:
Name |
Type |
Description |
defaultEncodingId |
NodeId |
NodeId of the “TypeA_Encoding_DefaultBinary” Node. |
baseDataType |
NodeId |
“i=22” [Structure] |
structureType |
StructureType |
StructureWithOptionalFields_1 [Structure without optional fields] |
fields [0] |
StructureField |
|
name |
String |
“X” |
description |
LocalizedText |
Description of X |
dataType |
NodeId |
“i=6” [Int32] |
valueRank |
Int32 |
-1 (Scalar) |
isOptional |
Boolean |
false |
fields [1] |
StructureField |
|
name |
String |
“O1“ |
description |
LocalizedText |
Description of O1 |
dataType |
NodeId |
“i=6” [Int32] |
valueRank |
Int32 |
-1 (Scalar) |
isOptional |
Boolean |
true |
fields [2] |
StructureField |
|
name |
String |
“Y“ |
description |
LocalizedText |
Description of Z |
dataType |
NodeId |
“i=2” [SByte] |
valueRank |
Int32 |
-1 (Scalar) |
isOptional |
Boolean |
false |
fields [3] |
StructureField |
|
name |
String |
“O2“ |
description |
LocalizedText |
Description of O2 |
dataType |
NodeId |
“i=6” [Int32] |
valueRank |
Int32 |
-1 (Scalar) |
isOptional |
Boolean |
true |