From 3fd4fed886f7ac410ed9e99318a520bf6ddd1207 Mon Sep 17 00:00:00 2001 From: Michael Zillgith Date: Sat, 7 Mar 2020 10:40:42 +0100 Subject: [PATCH] - .NET API: fixed memory management issue in MmsValue.SetElement (see #213) --- dotnet/IEC61850forCSharp/MmsValue.cs | 77 +++++++++++++++++----------- dotnet/tests/Test.cs | 44 ++++++++++++++-- 2 files changed, 87 insertions(+), 34 deletions(-) diff --git a/dotnet/IEC61850forCSharp/MmsValue.cs b/dotnet/IEC61850forCSharp/MmsValue.cs index 4e883fa5..5d6a90c7 100644 --- a/dotnet/IEC61850forCSharp/MmsValue.cs +++ b/dotnet/IEC61850forCSharp/MmsValue.cs @@ -533,43 +533,60 @@ namespace IEC61850 throw new MmsValueException ("Value is of wrong type"); } - /// - /// Sets the element of an array of structure - /// - /// index of the element starting with 0 - /// MmsValue instance that will be used as element value - /// This exception is thrown if the value has the wrong type. - /// This exception is thrown if the index is out of range. - public void SetElement(int index, MmsValue elementValue) - { - MmsType elementType = GetType (); + /// + /// Sets the element of an array or structure + /// + /// + /// After calling this function the native memory of the element will be managed by the array or structure. + /// Therefore an element can only be used in a single array or structure. + /// When the value is required in multiple arrays or structures + /// a clone has to be created before using this function! + /// To be save, always use a clone for setting the element. + /// + /// index of the element starting with 0 + /// MmsValue instance that will be used as element value + /// This exception is thrown if the value has the wrong type. + /// This exception is thrown if the index is out of range. + public void SetElement(int index, MmsValue elementValue) + { + MmsType elementType = GetType(); + + if ((elementType == MmsType.MMS_ARRAY) || (elementType == MmsType.MMS_STRUCTURE)) + { + + if ((index >= 0) && (index < Size())) + { - if ((elementType == MmsType.MMS_ARRAY) || (elementType == MmsType.MMS_STRUCTURE)) { - - if ((index >= 0) && (index < Size ())) { if (elementValue != null) - MmsValue_setElement (valueReference, index, elementValue.valueReference); + { + MmsValue_setElement(valueReference, index, elementValue.valueReference); + + /* will be deleted by structure */ + elementValue.responsableForDeletion = false; + } else - MmsValue_setElement (valueReference, index, IntPtr.Zero); + MmsValue_setElement(valueReference, index, IntPtr.Zero); - } else - throw new MmsValueException ("Index out of bounds"); - - } else - throw new MmsValueException ("Value is of wrong type"); + } + else + throw new MmsValueException("Index out of bounds"); - } + } + else + throw new MmsValueException("Value is of wrong type"); + } - public MmsDataAccessError GetDataAccessError () - { - if (GetType () == MmsType.MMS_DATA_ACCESS_ERROR) { - int errorCode = MmsValue_getDataAccessError (valueReference); + public MmsDataAccessError GetDataAccessError() + { + if (GetType() == MmsType.MMS_DATA_ACCESS_ERROR) + { + int errorCode = MmsValue_getDataAccessError(valueReference); - return (MmsDataAccessError)errorCode; - } - else - throw new MmsValueException ("Value is of wrong type"); - } + return (MmsDataAccessError)errorCode; + } + else + throw new MmsValueException("Value is of wrong type"); + } /// /// Gets the timestamp value as UTC time in s (UNIX time stamp). diff --git a/dotnet/tests/Test.cs b/dotnet/tests/Test.cs index a835d92b..8b945f7d 100644 --- a/dotnet/tests/Test.cs +++ b/dotnet/tests/Test.cs @@ -294,9 +294,6 @@ namespace tests { IedModel iedModel = ConfigFileParser.CreateModelFromConfigFile("../../model.cfg"); - - - ModelNode ind1 = iedModel.GetModelNodeByShortObjectReference ("GenericIO/GGIO1.Ind1.stVal"); Assert.IsTrue (ind1.GetType ().Equals (typeof(IEC61850.Server.DataAttribute))); @@ -556,6 +553,45 @@ namespace tests Assert.AreEqual (Validity.QUESTIONABLE, q.Validity); } - } + + [Test()] + public void MmsValaueCreateStructureAndAddElement() + { + MmsValue structure1 = MmsValue.NewEmptyStructure(1); + MmsValue structure2 = MmsValue.NewEmptyStructure(1); + MmsValue element = MmsValue.NewEmptyStructure(1); + + structure1.SetElement(0, element); + + /* Clone is required when adding the value to another structure or element */ + MmsValue elementClone = element.Clone(); + structure2.SetElement(0, elementClone); + + element.Dispose(); + + structure1.Dispose(); + structure2.Dispose(); + + Assert.AreEqual(true, true); + } + + [Test()] + public void MmsValueClone() + { + MmsValue boolValue = new MmsValue(true); + + MmsValue boolClone = boolValue.Clone(); + + boolValue.Dispose(); + boolClone.Dispose(); + + MmsValue structure = MmsValue.NewEmptyStructure(1); + MmsValue structureClone = structure.Clone(); + + structure.Dispose(); + structureClone.Dispose(); + } + + } }