in src/Azure.IIoT.OpcUa/src/Encoders/PubSub/JsonDataSetMessage.cs [160:316]
internal virtual bool TryDecode(JsonDecoderEx jsonDecoder, string? property, ref bool withHeader,
ref string? publisherId)
{
if (TryReadDataSetMessageHeader(jsonDecoder, out var dataSetMessageContentMask))
{
withHeader |= true;
DataSetMessageContentMask = dataSetMessageContentMask;
var payload = jsonDecoder.ReadDataSet(nameof(Payload));
if (payload != null)
{
Payload = payload;
}
return true;
}
else if (withHeader)
{
// Previously we found a header, not now, we fail here
return false;
}
else
{
// Reset content
DataSetMessageContentMask = 0;
MessageType = MessageType.KeyFrame;
DataSetWriterId = 0;
DataSetWriterName = null;
SequenceNumber = 0;
MetaDataVersion = null;
Timestamp = DateTimeOffset.MinValue;
var payload = property != null && jsonDecoder.HasField(property) ?
// Read payload off of the property name
jsonDecoder.ReadDataSet(property) :
// Read the current object as dataset
jsonDecoder.ReadDataSet(null);
if (payload != null)
{
Payload = payload;
}
return true;
}
// Read the data set message header
bool TryReadDataSetMessageHeader(JsonDecoderEx jsonDecoder, out DataSetMessageContentFlags dataSetMessageContentMask)
{
dataSetMessageContentMask = 0;
if (jsonDecoder.HasField(nameof(DataSetWriterId)))
{
DataSetWriterId = jsonDecoder.ReadUInt16(nameof(DataSetWriterId));
if (DataSetWriterId == 0)
{
// Up to version 2.8 we wrote the string id as id which is not per standard
DataSetWriterName = jsonDecoder.ReadString(nameof(DataSetWriterId));
if (DataSetWriterName != null)
{
UseCompatibilityMode = true;
dataSetMessageContentMask |= DataSetMessageContentFlags.DataSetWriterId;
dataSetMessageContentMask |= DataSetMessageContentFlags.DataSetWriterName;
}
else
{
// Continue and treat all of this as payload.
return false;
}
}
else
{
dataSetMessageContentMask |= DataSetMessageContentFlags.DataSetWriterId;
}
}
if (jsonDecoder.HasField(nameof(MetaDataVersion)))
{
MetaDataVersion = (Opc.Ua.ConfigurationVersionDataType?)jsonDecoder.ReadEncodeable(
nameof(MetaDataVersion), typeof(Opc.Ua.ConfigurationVersionDataType));
if (MetaDataVersion != null)
{
dataSetMessageContentMask |= DataSetMessageContentFlags.MetaDataVersion;
}
else
{
// Continue and treat all of this as payload.
return false;
}
}
if (jsonDecoder.HasField(nameof(SequenceNumber)))
{
SequenceNumber = jsonDecoder.ReadUInt32(nameof(SequenceNumber));
dataSetMessageContentMask |= DataSetMessageContentFlags.SequenceNumber;
}
if (jsonDecoder.HasField(nameof(Timestamp)))
{
Timestamp = jsonDecoder.ReadDateTime(nameof(Timestamp));
dataSetMessageContentMask |= DataSetMessageContentFlags.Timestamp;
}
if (jsonDecoder.HasField(nameof(Status)))
{
UseCompatibilityMode = jsonDecoder.IsObject(nameof(Status));
dataSetMessageContentMask |= DataSetMessageContentFlags.Status;
if (!UseCompatibilityMode)
{
Status = jsonDecoder.ReadUInt32(nameof(Status));
}
else
{
// Up to version 2.8 we wrote the string id as id which is not per standard
Status = jsonDecoder.ReadStatusCode(nameof(Status));
}
}
if (jsonDecoder.HasField(nameof(MessageType)))
{
var messageType = jsonDecoder.ReadString(nameof(MessageType));
dataSetMessageContentMask |= DataSetMessageContentFlags.MessageType;
if (messageType != null)
{
if (messageType.Equals("ua-deltaframe", StringComparison.Ordinal))
{
MessageType = MessageType.DeltaFrame;
}
else if (messageType.Equals("ua-event", StringComparison.Ordinal))
{
MessageType = MessageType.Event;
}
else if (messageType.Equals("ua-keepalive", StringComparison.Ordinal))
{
MessageType = MessageType.KeepAlive;
}
else if (messageType.Equals("ua-condition", StringComparison.Ordinal))
{
MessageType = MessageType.Condition;
}
else if (messageType.Equals("ua-keyframe", StringComparison.Ordinal))
{
MessageType = MessageType.KeyFrame;
}
else
{
// Continue and treat this as payload.
return false;
}
}
}
if (jsonDecoder.HasField(nameof(DataSetWriterName)))
{
DataSetWriterName = jsonDecoder.ReadString(nameof(DataSetWriterName));
dataSetMessageContentMask |= DataSetMessageContentFlags.DataSetWriterName;
}
return jsonDecoder.HasField(nameof(Payload));
}
}