diff --git a/Opc.Ua.ModelCompiler/ModelGenerator2.cs b/Opc.Ua.ModelCompiler/ModelGenerator2.cs index f838c1d..9ad00cc 100644 --- a/Opc.Ua.ModelCompiler/ModelGenerator2.cs +++ b/Opc.Ua.ModelCompiler/ModelGenerator2.cs @@ -3916,6 +3916,14 @@ private bool WriteTemplate_ListOfTypes(Template template, Context context) new LoadTemplateEventHandler(LoadTemplate_ListOfEncodingMaskFields), null); + AddTemplate( + template, + "// EncodingMaskProperty", + TemplatePath + "Version2.EncodingMaskProperty.cs", + new DataTypeDesign[] { dataType }, + new LoadTemplateEventHandler(LoadTemplate_EncodingMaskProperty), + new WriteTemplateEventHandler(WriteTemplate_EncodingMaskProperty)); + AddTemplate( template, "// ListOfEncodedFields", @@ -4701,7 +4709,7 @@ private string LoadTemplate_ListOfEncodedFields(Template template, Context conte if (field.IsOptional) { - template.Write($"if ((EncodingMask & (uint){dataType.ClassName}Fields.{field.Name}) != 0) "); + template.Write($"if ((EncodingMask & {dataType.ClassName}Fields.{field.Name}) != 0) "); } string functionName = field.DataTypeNode.BasicDataType.ToString(); @@ -4872,7 +4880,7 @@ private string LoadTemplate_ListOfDecodedFields(Template template, Context conte if (field.IsOptional) { - template.Write($"if ((EncodingMask & (uint){dataType.ClassName}Fields.{field.Name}) != 0) "); + template.Write($"if ((EncodingMask & {dataType.ClassName}Fields.{field.Name}) != 0) "); } string functionName = field.DataTypeNode.BasicDataType.ToString(); @@ -5030,7 +5038,7 @@ private string LoadTemplate_ListOfComparedFields(Template template, Context cont if (field.IsOptional) { - template.Write($"if ((EncodingMask & (uint){dataType.ClassName}Fields.{field.Name}) != 0) "); + template.Write($"if ((EncodingMask & {dataType.ClassName}Fields.{field.Name}) != 0) "); } template.Write("if (!Utils.IsEqual({0}, value.{0})) return false;", GetChildFieldName(field)); @@ -5065,7 +5073,7 @@ private string LoadTemplate_ListOfClonedFields(Template template, Context contex if (field.IsOptional) { - template.Write($"if ((EncodingMask & (uint){dataType.ClassName}Fields.{field.Name}) != 0) "); + template.Write($"if ((EncodingMask & {dataType.ClassName}Fields.{field.Name}) != 0) "); } template.Write("clone.{0} = ({1})Utils.Clone(this.{0});", GetChildFieldName(field), GetSystemTypeName(field.DataTypeNode, field.ValueRank)); @@ -5483,6 +5491,54 @@ private bool WriteTemplate_InitializeOptionalChildren(Template template, Context } #endregion + #region "// EncodingMaskProperty" + + private string LoadTemplate_EncodingMaskProperty(Template template, Context context) + { + if (context.Target is not DataTypeDesign _) + { + return null; + } + + return TemplatePath + "Version2.DataTypes.EncodingMaskProperty.cs"; + } + + private bool WriteTemplate_EncodingMaskProperty(Template template, Context context) + { + if (context.Target is not DataTypeDesign dataType) + { + return false; + } + + template.AddReplacement("_hide_by_new_", IsFirstDataTypeWithOptionalFields(dataType) ? string.Empty : "new "); + template.AddReplacement("_ClassName_", dataType.ClassName); + + var result = template.WriteTemplate(context); + template.WriteLine(string.Empty); + + return result; + } + + private static bool HasOptionalFields(DataTypeDesign dataType) + { + return dataType.Fields?.Any(field => field.IsOptional) ?? false; + } + + private static bool HasOptionalFieldsInherited(DataTypeDesign dataType) + { + return dataType.BaseTypeNode is DataTypeDesign baseDataType + && (HasOptionalFields(baseDataType) || HasOptionalFieldsInherited(baseDataType)); + } + + private static bool IsFirstDataTypeWithOptionalFields(DataTypeDesign dataType) + { + return dataType.IsStructure + && HasOptionalFields(dataType) + && !HasOptionalFieldsInherited(dataType); + } + + #endregion + #region "// ListOfPropertiesForType and // ListOfProperties" private string LoadTemplate_ListOfPropertiesForType(Template template, Context context) { diff --git a/Opc.Ua.ModelCompiler/Opc.Ua.ModelCompiler.csproj b/Opc.Ua.ModelCompiler/Opc.Ua.ModelCompiler.csproj index 26e89da..74cbaf7 100644 --- a/Opc.Ua.ModelCompiler/Opc.Ua.ModelCompiler.csproj +++ b/Opc.Ua.ModelCompiler/Opc.Ua.ModelCompiler.csproj @@ -128,6 +128,7 @@ + @@ -437,6 +438,7 @@ + diff --git a/Opc.Ua.ModelCompiler/Templates/Version2/ConstantsFile.cs b/Opc.Ua.ModelCompiler/Templates/Version2/ConstantsFile.cs index f6402cc..958afac 100644 --- a/Opc.Ua.ModelCompiler/Templates/Version2/ConstantsFile.cs +++ b/Opc.Ua.ModelCompiler/Templates/Version2/ConstantsFile.cs @@ -26,6 +26,7 @@ * * The complete license agreement can be found here: * http://opcfoundation.org/License/MIT/1.00/ + * * ======================================================================*/ using System; diff --git a/Opc.Ua.ModelCompiler/Templates/Version2/DataTypes/Class.cs b/Opc.Ua.ModelCompiler/Templates/Version2/DataTypes/Class.cs index 5bdc39e..03e3fbf 100644 --- a/Opc.Ua.ModelCompiler/Templates/Version2/DataTypes/Class.cs +++ b/Opc.Ua.ModelCompiler/Templates/Version2/DataTypes/Class.cs @@ -8,10 +8,33 @@ namespace X { [DataContract(Namespace = _XmlNamespaceUri_)] public _IsAbstract_partial class _BrowseName_ : IEncodeable, IJsonEncodeable { + #region Fields + + private readonly ExpandedNodeId _typeId; + private readonly ExpandedNodeId _binaryEncodingId; + private readonly ExpandedNodeId _xmlEncodingId; + private readonly ExpandedNodeId _jsonEncodingId; + + #endregion + #region Constructors /// - public _BrowseName_() + public _BrowseName_() : this( + DataTypeIds._BrowseName_, + ObjectIds._BrowseName__Encoding_DefaultBinary, + ObjectIds._BrowseName__Encoding_DefaultXml, + ObjectIds._BrowseName__Encoding_DefaultJson) { + } + + /// + protected _BrowseName_(ExpandedNodeId typeId, ExpandedNodeId binaryEncodingId, ExpandedNodeId xmlEncodingId, ExpandedNodeId jsonEncodingId) + { + _typeId = typeId; + _binaryEncodingId = binaryEncodingId; + _xmlEncodingId = xmlEncodingId; + _jsonEncodingId = jsonEncodingId; + Initialize(); } @@ -33,37 +56,53 @@ private void Initialize() #region IEncodeable Members /// - public virtual ExpandedNodeId TypeId => DataTypeIds._BrowseName_; + ExpandedNodeId IEncodeable.TypeId => _typeId; /// - public virtual ExpandedNodeId BinaryEncodingId => ObjectIds._BrowseName__Encoding_DefaultBinary; + ExpandedNodeId IEncodeable.BinaryEncodingId => _binaryEncodingId; /// - public virtual ExpandedNodeId XmlEncodingId => ObjectIds._BrowseName__Encoding_DefaultXml; + ExpandedNodeId IEncodeable.XmlEncodingId => _xmlEncodingId; /// - public virtual ExpandedNodeId JsonEncodingId => ObjectIds._BrowseName__Encoding_DefaultJson; + ExpandedNodeId IJsonEncodeable.JsonEncodingId => _jsonEncodingId; /// - public virtual void Encode(IEncoder encoder) + void IEncodeable.Encode(IEncoder encoder) { encoder.PushNamespace(_XmlNamespaceUri_); - // ListOfEncodedFields + OnWriteEncodingMask(encoder); + OnEncodeFields(encoder); encoder.PopNamespace(); } + protected virtual void OnWriteEncodingMask(IEncoder encoder) { } + + protected virtual void OnEncodeFields(IEncoder encoder) + { + // ListOfEncodedFields + } + /// - public virtual void Decode(IDecoder decoder) + void IEncodeable.Decode(IDecoder decoder) { decoder.PushNamespace(_XmlNamespaceUri_); - // ListOfDecodedFields + OnReadEncodingMask(decoder); + OnDecodeFields(decoder); decoder.PopNamespace(); } + protected virtual void OnReadEncodingMask(IDecoder decoder) { } + + protected virtual void OnDecodeFields(IDecoder decoder) + { + // ListOfDecodedFields + } + /// public virtual bool IsEqual(IEncodeable encodeable) { diff --git a/Opc.Ua.ModelCompiler/Templates/Version2/DataTypes/ClassWithOptionalFields.cs b/Opc.Ua.ModelCompiler/Templates/Version2/DataTypes/ClassWithOptionalFields.cs index 92b8997..6f6b3f9 100644 --- a/Opc.Ua.ModelCompiler/Templates/Version2/DataTypes/ClassWithOptionalFields.cs +++ b/Opc.Ua.ModelCompiler/Templates/Version2/DataTypes/ClassWithOptionalFields.cs @@ -21,10 +21,33 @@ public enum _ClassName_Fields : uint [DataContract(Namespace = _XmlNamespaceUri_)] public partial class _BrowseName_ : IEncodeable, IJsonEncodeable { + #region Fields + + private readonly ExpandedNodeId _typeId; + private readonly ExpandedNodeId _binaryEncodingId; + private readonly ExpandedNodeId _xmlEncodingId; + private readonly ExpandedNodeId _jsonEncodingId; + + #endregion + #region Constructors /// - public _BrowseName_() + public _BrowseName_() : this( + DataTypeIds._BrowseName_, + ObjectIds._BrowseName__Encoding_DefaultBinary, + ObjectIds._BrowseName__Encoding_DefaultXml, + ObjectIds._BrowseName__Encoding_DefaultJson) + { + } + + /// + protected _BrowseName_(ExpandedNodeId typeId, ExpandedNodeId binaryEncodingId, ExpandedNodeId xmlEncodingId, ExpandedNodeId jsonEncodingId) { + _typeId = typeId; + _binaryEncodingId = binaryEncodingId; + _xmlEncodingId = xmlEncodingId; + _jsonEncodingId = jsonEncodingId; + Initialize(); } @@ -36,7 +59,7 @@ private void Initialize(StreamingContext context) private void Initialize() { - EncodingMask = (uint)_ClassName_Fields.None; + EncodingMask = _ClassName_Fields.None; // ListOfFieldInitializers } #endregion @@ -44,47 +67,67 @@ private void Initialize() #region Public Properties /// [DataMember(Name = "EncodingMask", IsRequired = true, Order = 0)] - public virtual uint EncodingMask { get; set; } + public _ClassName_Fields EncodingMask { get; set; } // ListOfProperties #endregion #region IEncodeable Members /// - public virtual ExpandedNodeId TypeId => DataTypeIds._BrowseName_; + ExpandedNodeId IEncodeable.TypeId => _typeId; /// - public virtual ExpandedNodeId BinaryEncodingId => ObjectIds._BrowseName__Encoding_DefaultBinary; + ExpandedNodeId IEncodeable.BinaryEncodingId => _binaryEncodingId; /// - public virtual ExpandedNodeId XmlEncodingId => ObjectIds._BrowseName__Encoding_DefaultXml; + ExpandedNodeId IEncodeable.XmlEncodingId => _xmlEncodingId; /// - public virtual ExpandedNodeId JsonEncodingId => ObjectIds._BrowseName__Encoding_DefaultJson; + ExpandedNodeId IJsonEncodeable.JsonEncodingId => _jsonEncodingId; /// - public virtual void Encode(IEncoder encoder) + void IEncodeable.Encode(IEncoder encoder) { encoder.PushNamespace(_XmlNamespaceUri_); - encoder.WriteEncodingMask((uint)EncodingMask); - // ListOfEncodedFields + OnWriteEncodingMask(encoder); + OnEncodeFields(encoder); encoder.PopNamespace(); } + protected virtual void OnWriteEncodingMask(IEncoder encoder) + { + encoder.WriteEncodingMask((uint)EncodingMask); + } + + protected virtual void OnEncodeFields(IEncoder encoder) + { + // ListOfEncodedFields + } + + /// - public virtual void Decode(IDecoder decoder) + void IEncodeable.Decode(IDecoder decoder) { decoder.PushNamespace(_XmlNamespaceUri_); - EncodingMask = decoder.ReadEncodingMask(m_FieldNames); - - // ListOfDecodedFields + OnReadEncodingMask(decoder); + OnDecodeFields(decoder); decoder.PopNamespace(); } + protected virtual void OnReadEncodingMask(IDecoder decoder) + { + EncodingMask = (_ClassName_Fields)decoder.ReadEncodingMask(m_FieldNames); + } + + protected virtual void OnDecodeFields(IDecoder decoder) + { + // ListOfDecodedFields + } + /// public virtual bool IsEqual(IEncodeable encodeable) { diff --git a/Opc.Ua.ModelCompiler/Templates/Version2/DataTypes/DerivedClass.cs b/Opc.Ua.ModelCompiler/Templates/Version2/DataTypes/DerivedClass.cs index 3c2e147..f03bf31 100644 --- a/Opc.Ua.ModelCompiler/Templates/Version2/DataTypes/DerivedClass.cs +++ b/Opc.Ua.ModelCompiler/Templates/Version2/DataTypes/DerivedClass.cs @@ -9,8 +9,19 @@ namespace X { public partial class _BrowseName_ : _BaseType_ { #region Constructors + /// - public _BrowseName_() + public _BrowseName_() : this( + DataTypeIds._BrowseName_, + ObjectIds._BrowseName__Encoding_DefaultBinary, + ObjectIds._BrowseName__Encoding_DefaultXml, + ObjectIds._BrowseName__Encoding_DefaultJson) + { + } + + /// + protected _BrowseName_(ExpandedNodeId typeId, ExpandedNodeId binaryEncodingId, ExpandedNodeId xmlEncodingId, ExpandedNodeId jsonEncodingId) + : base(typeId, binaryEncodingId, xmlEncodingId, jsonEncodingId) { Initialize(); } @@ -31,41 +42,19 @@ private void Initialize() // ListOfProperties #endregion - #region IEncodeable Members - /// - public override ExpandedNodeId TypeId => DataTypeIds._BrowseName_; - - /// - public override ExpandedNodeId BinaryEncodingId => ObjectIds._BrowseName__Encoding_DefaultBinary; - - /// - public override ExpandedNodeId XmlEncodingId => ObjectIds._BrowseName__Encoding_DefaultXml; + #region Overridden Members - /// - public override ExpandedNodeId JsonEncodingId => ObjectIds._BrowseName__Encoding_DefaultJson; - - /// - public override void Encode(IEncoder encoder) + /// + protected override void OnEncodeFields(IEncoder encoder) { - base.Encode(encoder); - - encoder.PushNamespace(_XmlNamespaceUri_); - + base.OnEncodeFields(encoder); // ListOfEncodedFields - - encoder.PopNamespace(); } - /// - public override void Decode(IDecoder decoder) + protected override void OnDecodeFields(IDecoder decoder) { - base.Decode(decoder); - - decoder.PushNamespace(_XmlNamespaceUri_); - + base.OnDecodeFields(decoder); // ListOfDecodedFields - - decoder.PopNamespace(); } /// diff --git a/Opc.Ua.ModelCompiler/Templates/Version2/DataTypes/DerivedClassWithOptionalFields.cs b/Opc.Ua.ModelCompiler/Templates/Version2/DataTypes/DerivedClassWithOptionalFields.cs index 6712b5e..6ac7adb 100644 --- a/Opc.Ua.ModelCompiler/Templates/Version2/DataTypes/DerivedClassWithOptionalFields.cs +++ b/Opc.Ua.ModelCompiler/Templates/Version2/DataTypes/DerivedClassWithOptionalFields.cs @@ -22,8 +22,18 @@ public enum _ClassName_Fields : uint public partial class _BrowseName_ : _BaseType_ { #region Constructors + + public _BrowseName_() : this( + DataTypeIds._BrowseName_, + ObjectIds._BrowseName__Encoding_DefaultBinary, + ObjectIds._BrowseName__Encoding_DefaultXml, + ObjectIds._BrowseName__Encoding_DefaultJson) + { + } + /// - public _BrowseName_() + protected _BrowseName_(ExpandedNodeId typeId, ExpandedNodeId binaryEncodingId, ExpandedNodeId xmlEncodingId, ExpandedNodeId jsonEncodingId) + : base(typeId, binaryEncodingId, xmlEncodingId, jsonEncodingId) { Initialize(); } @@ -41,44 +51,34 @@ private void Initialize() #endregion #region Public Properties + // EncodingMaskProperty // ListOfProperties #endregion - #region IEncodeable Members - /// - public override ExpandedNodeId TypeId => DataTypeIds._BrowseName_; - - /// - public override ExpandedNodeId BinaryEncodingId => ObjectIds._BrowseName__Encoding_DefaultBinary; + #region Overridden Members - /// - public override ExpandedNodeId XmlEncodingId => ObjectIds._BrowseName__Encoding_DefaultXml; + /// + protected override void OnWriteEncodingMask(IEncoder encoder) + { + encoder.WriteEncodingMask((uint)EncodingMask); + } - /// - public override ExpandedNodeId JsonEncodingId => ObjectIds._BrowseName__Encoding_DefaultJson; - - /// - public override void Encode(IEncoder encoder) + /// + protected override void OnEncodeFields(IEncoder encoder) { - base.Encode(encoder); - - encoder.PushNamespace(_XmlNamespaceUri_); - + base.OnEncodeFields(encoder); // ListOfEncodedFields - - encoder.PopNamespace(); } - /// - public override void Decode(IDecoder decoder) + protected override void OnReadEncodingMask(IDecoder decoder) { - base.Decode(decoder); - - decoder.PushNamespace(_XmlNamespaceUri_); + EncodingMask = (_ClassName_Fields)decoder.ReadEncodingMask(m_FieldNames); + } + protected override void OnDecodeFields(IDecoder decoder) + { + base.OnDecodeFields(decoder); // ListOfDecodedFields - - decoder.PopNamespace(); } /// diff --git a/Opc.Ua.ModelCompiler/Templates/Version2/DataTypes/EncodingMaskProperty.cs b/Opc.Ua.ModelCompiler/Templates/Version2/DataTypes/EncodingMaskProperty.cs new file mode 100644 index 0000000..da232c1 --- /dev/null +++ b/Opc.Ua.ModelCompiler/Templates/Version2/DataTypes/EncodingMaskProperty.cs @@ -0,0 +1,7 @@ +class _Name_{ +// ***START*** +/// +[DataMember(Name = "EncodingMask", IsRequired = true, Order = 0)] +public _hide_by_new__ClassName_Fields EncodingMask { get; set; } +// ***END*** +} \ No newline at end of file diff --git a/Opc.Ua.ModelCompiler/Templates/Version2/TypesFile.cs b/Opc.Ua.ModelCompiler/Templates/Version2/TypesFile.cs index fdb6c23..d6391b2 100644 --- a/Opc.Ua.ModelCompiler/Templates/Version2/TypesFile.cs +++ b/Opc.Ua.ModelCompiler/Templates/Version2/TypesFile.cs @@ -26,6 +26,7 @@ * * The complete license agreement can be found here: * http://opcfoundation.org/License/MIT/1.00/ + * * ======================================================================*/ using System;