Built-in Types |
This topic contains the following sections:
A Boolean value shall be encoded as a single byte where a value of 0 (zero) is false and any non-zero value is true.
Encoders shall use the value of 1 to indicate a true value; however, decoders shall treat any non-zero value as true.
All integer types shall be encoded as little endian values where the least significant byte appears first in the stream.
The Figure 1 illustrates how the value 1,000,000,000 (Hex: 3B9ACA00) should be encoded as a 32 bit integer in the stream.
All floating point values shall be encoded with the appropriate IEEE-754binary representation which has three basic components: the sign, the exponent, and the fraction. The bit ranges assigned to each component depend on the width of the type. Figure 2 lists the bit ranges for the supported floating point types.
In addition, the order of bytes in the stream is significant. All floating point values shall be encoded with the least significant byte appearing first (i.e. little endian).
The Figure 3 illustrates how the value -6.5 (Hex: C0D00000) should be encoded as a Float.
All String values are encoded as a sequence of UTF8characters without a null terminator and preceded by the length in bytes..
The length in bytes is encoded as Int32. A value of -1 is used to indicate a ‘null’ string.
Figure 4 illustrates how the multilingual string “水Boy” should be encoded in a byte stream.
A DateTime value shall be encoded as a 64-bit signed integer (see Integer ) which represents the number of 100 nanosecond intervals since January 1, 1601 (UTC)..
Not all platforms will be able to represent the full range of dates and times that can be represented with this encoding. For example, the UNIX time_t structure only has a 1 second resolution and cannot represent dates prior to 1970. For this reason, a number of rules shall be applied when dealing with date/time values that exceed the dynamic range of a platform. These rules are:
A date/time value is encoded as 0 if either:
The value equal to or earlier than 1601-01-01 12:00AM
The value is the earliest date that can be represented with the platform’s encoding.
A date/time is encoded as the maximum value for an Int64 if either:
The value is equal to or greater than 9999-01-01 11:59:59PM
The value is the latest date that can be represented with the platform’s encoding
A date/time is decoded as the earliest time that can be represented on the platform if either:
The encoded value is 0
The encoded value represents a time earlier than the earliest time that can be represented with the platform’s encoding.
A date/time is decoded as the latest time that can be represented on the platform if either:
The encoded value is the maximum value for an Int64
The encoded value represents a time later than the latest time that can be represented with the platform’s encoding.
These rules imply that the earliest and latest times that can be represented on a given platform are invalid date/time values and should be treated that way by applications.
A decoder shall truncate the value if a decoder encounters a DateTime value with a resolution that is greater than the resolution supported on the platform.
A Guid is encoded a the structure shown in section Overview topic GUID . The fields are encode sequentially according to the data type for field.
Figure 5 illustrates how the Guid “72962B91-FA75-4ae6-8D28-B404DC7DAF63” should be encoded in a byte stream.
A ByteString is encoded as sequence of bytes preceded by its length in bytes. The length is encoded as a 32-bit signed integer as described above.
If the length of the byte string is -1 then the byte string is ‘null’.
An XmlElement is an XML fragment serialized as UTF-8 string and then encoded as ByteString
Figure 6 illustrates how the XmlElement “Hot水” should be encoded in a byte stream.
The components of a NodeId are described the Figure 7.
The encoding of a NodeId varies according to the contents of the instance. For that reason the first byte of the encoded form indicates the format of the rest of the encoded NodeId. The possible encoding formats are shown on Figure 8. The tables that follow describe the structure of the each possible format (they exclude the byte which indicates the format).
The standard NodeId encoding has the structure shown on Figure 9. The standard encoding is used for all formats that do not have an explicit format defined.
An example of a String NodeId with Namespace = 1 and Identifier = “Hot水” is shown in Figure 10.
The Two Byte NodeId encoding has the structure shown on Figure 11.
An example of a Two Byte NodeId with Identifier = 72 is shown in Figure 12.
The Four Byte NodeId encoding has the structure shown in Figure 13.
An example of a Four Byte NodeId with Namespace = 5 and Identifier = 1025 is shown in Figure 14.
An ExpandedNodeId extends the NodeId structure by allowing the NamespaceUri to be explicitly specified instead of using the NamespaceIndex. The NamespaceUri is optional. If it is specified then the NamespaceIndex inside the NodeId shall be ignored.
The ExpandedNodeId is encoded by first encoding a NodeId as described in NodeId and then encoding NamespaceUri as a String.
An instance of an ExpandedNodeId may still use the NamespaceIndex instead of the NamespaceUri. In this case, the NamespaceUri is not encoded in the stream. The presence of the NamespaceUri in the stream is indicated by setting the NamespaceUri flag in the encoding format byte for the NodeId.
If the NamespaceUri is present then the encoder shall encode the NamespaceIndex as 0 in the stream when the NodeId portion is encoded. The unused NamespaceIndex is included in the stream for consistency,
An ExpandedNodeId may also have a ServerIndex which is encoded as a UInt32 after the NamespaceUri. The ServerIndex flag in the NodeId encoding byte indicates whether the ServerIndex is present in the stream. The ServerIndex is omitted if it is equal to zero.
The ExpandedNodeId encoding has the structure shown in Figure 15.
A StatusCode is encoded as a UInt32
A DiagnosticInfo structure is described in Services. It specifies a number of fields that could be missing. For that reason, the encoding uses a bit mask to indicate which fields are actually present in the encoded form.
As described in Services, the SymbolicId, NamespaceUri, LocalizedText and Locale fields are indexes in a string table which is returned in the response header. Only the index of the string in this table is encoded. An index of -1 indicates that there is no value for the string.
A QualifiedName structure is encoded as shown in Figure 17.
The abstract QualifiedName structure is defined in Standard Data Types .
A LocalizedText structure contains two fields that could be missing. For that reason, the encoding uses a bit mask to indicate which fields are actually present in the encoded form.
The abstract LocalizedText structure is defined in Standard Data Types.
An ExtensionObject is encoded as sequence of bytes prefixed by the NodeId of its DataTypeEncoding and the number of bytes encoded.
An ExtensionObject may be encoded by the application which means it is passed as a ByteString or an XmlElement to the encoder. In this case, the encoder will be able to write the number of bytes in the object before it encodes the bytes. However, an ExtensionObject may know how to encode/decode itself which means the encoder shall calculate the number of bytes before it encodes the object or it shall be able seek backwards in the stream and update the length after encoding the body
When a decoder encounters an ExtensionObject it shall check if it recognizes the DataTypeEncoding identifier. If it does then it can call the appropriate function to decode the object body. If the decoder does not recognize the type it shall use the EncodingMask to determine if the body is a ByteString or an XmlElement and then decode the object body.
The serialized form of a ExtensionObject is shown in Figure 19.
ExtensionObjects are used in two contexts: as values contained in Variant structures or as parameters in OPC UA messages.
An Variant is a union of the built-in types.
The structure of an Variant is shown in Figure 20
The possible types and their identifiers that can be encoded in an Variant are shown in Built-in Types
A DataValue is always preceded by a mask that indicates which fields are present in the stream.
The fields of a DataValue are described in Figure 21.
The Picoseconds fields store the difference between a high resolution timestamp with a resolution of 10ps and the Timestamp field value which only has a 100ns resolution. The Picoseconds fields shall contain values less than 10000. The decoder shall treat values greater than or equal to 10000 as the value ‘9999’.