/// <summary> /// Set DataSetFieldContentMask /// </summary> /// <param name="fieldContentMask">The new <see cref="DataSetFieldContentMask"/> for this dataset</param> public override void SetFieldContentMask(DataSetFieldContentMask fieldContentMask) { FieldContentMask = fieldContentMask; #region DataSetFlags1: Bit range 1-2: Field Encoding DataSetFlags1 &= kDataSetFlags1UsedBits; FieldTypeEncodingMask fieldType = FieldTypeEncodingMask.Reserved; if (FieldContentMask == DataSetFieldContentMask.None) { // 00 Variant Field Encoding fieldType = FieldTypeEncodingMask.Variant; } else if ((FieldContentMask & DataSetFieldContentMask.RawData) != 0) { // 01 RawData Field Encoding fieldType = FieldTypeEncodingMask.RawData; } else if ((FieldContentMask & (DataSetFieldContentMask.StatusCode | DataSetFieldContentMask.SourceTimestamp | DataSetFieldContentMask.ServerTimestamp | DataSetFieldContentMask.SourcePicoSeconds | DataSetFieldContentMask.ServerPicoSeconds)) != 0) { // 10 DataValue Field Encoding fieldType = FieldTypeEncodingMask.DataValue; } DataSetFlags1 |= (DataSetFlags1EncodingMask)((byte)fieldType << 1); #endregion }
/// <summary> /// Set DataSetFieldContentMask /// </summary> /// <param name="fieldContentMask">The new <see cref="DataSetFieldContentMask"/> for this dataset</param> public override void SetFieldContentMask(DataSetFieldContentMask fieldContentMask) { FieldContentMask = fieldContentMask; if (FieldContentMask == DataSetFieldContentMask.None) { // 00 Variant Field Encoding m_fieldTypeEncoding = FieldTypeEncodingMask.Variant; } else if ((FieldContentMask & DataSetFieldContentMask.RawData) != 0) { // If the RawData flag is set, all other bits are ignored. // 01 RawData Field Encoding m_fieldTypeEncoding = FieldTypeEncodingMask.RawData; } else if ((FieldContentMask & (DataSetFieldContentMask.StatusCode | DataSetFieldContentMask.SourceTimestamp | DataSetFieldContentMask.ServerTimestamp | DataSetFieldContentMask.SourcePicoSeconds | DataSetFieldContentMask.ServerPicoSeconds)) != 0) { // 10 DataValue Field Encoding m_fieldTypeEncoding = FieldTypeEncodingMask.DataValue; } }
/// <summary> /// Encode payload data delta frame /// </summary> /// <param name="binaryEncoder"></param> private void EncodeMessageDataDeltaFrame(BinaryEncoder binaryEncoder) { // calculate the number of fields that will be written int fieldCount = DataSet.Fields.Count(f => f != null); // The field count is written for RadData encoding too unlike for KeyFrame message binaryEncoder.WriteUInt16("FieldCount", (UInt16)fieldCount); FieldTypeEncodingMask fieldType = (FieldTypeEncodingMask)(((byte)DataSetFlags1 & kFieldTypeUsedBits) >> 1); for (int i = 0; i < DataSet.Fields.Length; i++) { Field field = DataSet.Fields[i]; if (field == null) { continue; // ignore null fields } // write field index binaryEncoder.WriteUInt16("FieldIndex", (UInt16)i); switch (fieldType) { case FieldTypeEncodingMask.Variant: // 00 Variant type binaryEncoder.WriteVariant("FieldValue", field.Value.WrappedValue); break; case FieldTypeEncodingMask.DataValue: // 10 DataValue type binaryEncoder.WriteDataValue("FieldValue", field.Value); break; case FieldTypeEncodingMask.RawData: EncodeFieldAsRawData(binaryEncoder, field); break; case FieldTypeEncodingMask.Reserved: // ignore break; } } }
/// <summary> /// Encode payload data /// </summary> /// <param name="binaryEncoder"></param> private void EncodeMessageDataKeyFrame(BinaryEncoder binaryEncoder) { FieldTypeEncodingMask fieldType = (FieldTypeEncodingMask)(((byte)DataSetFlags1 & kFieldTypeUsedBits) >> 1); switch (fieldType) { case FieldTypeEncodingMask.Variant: binaryEncoder.WriteUInt16("DataSetFieldCount", (UInt16)DataSet.Fields.Length); foreach (Field field in DataSet.Fields) { // 00 Variant type binaryEncoder.WriteVariant("Variant", field.Value.WrappedValue); } break; case FieldTypeEncodingMask.DataValue: binaryEncoder.WriteUInt16("DataSetFieldCount", (UInt16)DataSet.Fields.Length); foreach (Field field in DataSet.Fields) { // 10 DataValue type binaryEncoder.WriteDataValue("DataValue", field.Value); } break; case FieldTypeEncodingMask.RawData: // DataSetFieldCount is not persisted for RawData foreach (Field field in DataSet.Fields) { EncodeFieldAsRawData(binaryEncoder, field); } break; case FieldTypeEncodingMask.Reserved: // ignore break; } }
/// <summary> /// Decode field message data delta frame from decoder and using a DataSetReader /// </summary> /// <param name="binaryDecoder"></param> /// <param name="dataSetReader"></param> /// <returns></returns> private DataSet DecodeMessageDataDeltaFrame(BinaryDecoder binaryDecoder, DataSetReaderDataType dataSetReader) { DataSetMetaDataType dataSetMetaData = dataSetReader.DataSetMetaData; try { FieldTypeEncodingMask fieldType = (FieldTypeEncodingMask)(((byte)DataSetFlags1 & kFieldTypeUsedBits) >> 1); if (dataSetMetaData != null) { TargetVariablesDataType targetVariablesData = ExtensionObject.ToEncodeable(dataSetReader.SubscribedDataSet) as TargetVariablesDataType; // create dataFields collection List <Field> dataFields = new List <Field>(); for (int i = 0; i < dataSetMetaData.Fields.Count; i++) { Field dataField = new Field(); dataField.FieldMetaData = dataSetMetaData?.Fields[i]; if (targetVariablesData != null && targetVariablesData.TargetVariables != null && i < targetVariablesData.TargetVariables.Count) { // remember the target Attribute and target nodeId dataField.TargetAttribute = targetVariablesData.TargetVariables[i].AttributeId; dataField.TargetNodeId = targetVariablesData.TargetVariables[i].TargetNodeId; } dataFields.Add(dataField); } // read number of fields encoded in this delta frame message ushort fieldCount = fieldCount = binaryDecoder.ReadUInt16("FieldCount"); for (int i = 0; i < fieldCount; i++) { ushort fieldIndex = binaryDecoder.ReadUInt16("FieldIndex"); // update value in dataFields switch (fieldType) { case FieldTypeEncodingMask.Variant: dataFields[fieldIndex].Value = new DataValue(binaryDecoder.ReadVariant("FieldValue")); break; case FieldTypeEncodingMask.DataValue: dataFields[fieldIndex].Value = binaryDecoder.ReadDataValue("FieldValue"); break; case FieldTypeEncodingMask.RawData: FieldMetaData fieldMetaData = dataSetMetaData.Fields[fieldIndex]; if (fieldMetaData != null) { var decodedValue = DecodeRawData(binaryDecoder, fieldMetaData); dataFields[fieldIndex].Value = new DataValue(new Variant(decodedValue)); } break; case FieldTypeEncodingMask.Reserved: // ignore break; } } DataSet dataSet = new DataSet(dataSetMetaData?.Name); dataSet.DataSetMetaData = dataSetMetaData; dataSet.Fields = dataFields.ToArray(); dataSet.IsDeltaFrame = true; dataSet.DataSetWriterId = DataSetWriterId; dataSet.SequenceNumber = SequenceNumber; return(dataSet); } } catch (Exception ex) { Utils.Trace(ex, "UadpDataSetMessage.DecodeMessageDataDeltaFrame"); } return(null); }
/// <summary> /// Decode field message data key frame from decoder and using a DataSetReader /// </summary> /// <param name="binaryDecoder"></param> /// <param name="dataSetReader"></param> /// <returns></returns> private DataSet DecodeMessageDataKeyFrame(BinaryDecoder binaryDecoder, DataSetReaderDataType dataSetReader) { DataSetMetaDataType dataSetMetaData = dataSetReader.DataSetMetaData; try { ushort fieldCount = 0; FieldTypeEncodingMask fieldType = (FieldTypeEncodingMask)(((byte)DataSetFlags1 & kFieldTypeUsedBits) >> 1); if (fieldType == FieldTypeEncodingMask.RawData) { if (dataSetMetaData != null) { // metadata should provide field count fieldCount = (ushort)dataSetMetaData.Fields.Count; } } else { fieldCount = binaryDecoder.ReadUInt16("DataSetFieldCount"); } TargetVariablesDataType targetVariablesData = ExtensionObject.ToEncodeable(dataSetReader.SubscribedDataSet) as TargetVariablesDataType; // check configuration version List <DataValue> dataValues = new List <DataValue>(); switch (fieldType) { case FieldTypeEncodingMask.Variant: for (int i = 0; i < fieldCount; i++) { dataValues.Add(new DataValue(binaryDecoder.ReadVariant("Variant"))); } break; case FieldTypeEncodingMask.DataValue: for (int i = 0; i < fieldCount; i++) { dataValues.Add(binaryDecoder.ReadDataValue("DataValue")); } break; case FieldTypeEncodingMask.RawData: if (dataSetMetaData != null) { for (int i = 0; i < fieldCount; i++) { FieldMetaData fieldMetaData = dataSetMetaData.Fields[i]; if (fieldMetaData != null) { var decodedValue = DecodeRawData(binaryDecoder, fieldMetaData); dataValues.Add(new DataValue(new Variant(decodedValue))); } } } // else the decoding is compromised for RawData type break; case FieldTypeEncodingMask.Reserved: // ignore break; } List <Field> dataFields = new List <Field>(); for (int i = 0; i < dataValues.Count; i++) { Field dataField = new Field(); dataField.FieldMetaData = dataSetMetaData?.Fields[i]; dataField.Value = dataValues[i]; if (targetVariablesData != null && targetVariablesData.TargetVariables != null && i < targetVariablesData.TargetVariables.Count) { // remember the target Attribute and target nodeId dataField.TargetAttribute = targetVariablesData.TargetVariables[i].AttributeId; dataField.TargetNodeId = targetVariablesData.TargetVariables[i].TargetNodeId; } dataFields.Add(dataField); } if (dataFields.Count == 0) { return(null); //the dataset cannot be decoded } DataSet dataSet = new DataSet(dataSetMetaData?.Name); dataSet.DataSetMetaData = dataSetMetaData; dataSet.Fields = dataFields.ToArray(); dataSet.DataSetWriterId = DataSetWriterId; dataSet.SequenceNumber = SequenceNumber; return(dataSet); } catch (Exception ex) { Utils.Trace(ex, "UadpDataSetMessage.DecodeMessageDataKeyFrame"); return(null); } }