#region Copyright (c) 2011-2023 Technosoftware GmbH. All rights reserved //----------------------------------------------------------------------------- // Copyright (c) 2011-2023 Technosoftware GmbH. All rights reserved // Web: https://www.technosoftware.com // // The source code in this file is covered under a dual-license scenario: // - Owner of a purchased license: SCLA 1.0 // - GPL V3: everybody else // // SCLA license terms accompanied with this source code. // See SCLA 1.0: https://technosoftware.com/license/Source_Code_License_Agreement.pdf // // GNU General Public License as published by the Free Software Foundation; // version 3 of the License are accompanied with this source code. // See https://technosoftware.com/license/GPLv3License.txt // // This source code is distributed in the hope that it will be useful, but // WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY // or FITNESS FOR A PARTICULAR PURPOSE. //----------------------------------------------------------------------------- #endregion Copyright (c) 2011-2023 Technosoftware GmbH. All rights reserved #region Using Directives using System; using System.Runtime.InteropServices; using Technosoftware.DaAeHdaClient.Da; using Technosoftware.DaAeHdaClient.Hda; #endregion #pragma warning disable 0618 namespace Technosoftware.DaAeHdaClient.Com.Hda { /// /// Contains state information for a single asynchronous Technosoftware.DaAeHdaClient.Com.Hda.Interop. /// internal class Interop { /// /// Converts a standard FILETIME to an OpcRcw.Da.FILETIME structure. /// internal static OpcRcw.Hda.OPCHDA_FILETIME Convert(FILETIME input) { var output = new OpcRcw.Hda.OPCHDA_FILETIME(); output.dwLowDateTime = input.dwLowDateTime; output.dwHighDateTime = input.dwHighDateTime; return output; } /// /// Converts an OpcRcw.Da.FILETIME to a standard FILETIME structure. /// internal static FILETIME Convert(OpcRcw.Hda.OPCHDA_FILETIME input) { var output = new FILETIME(); output.dwLowDateTime = input.dwLowDateTime; output.dwHighDateTime = input.dwHighDateTime; return output; } /// /// Converts a decimal value to a OpcRcw.Hda.OPCHDA_TIME structure. /// internal static OpcRcw.Hda.OPCHDA_FILETIME GetFILETIME(decimal input) { var output = new OpcRcw.Hda.OPCHDA_FILETIME(); output.dwHighDateTime = (int)((((ulong)(input*10000000)) & 0xFFFFFFFF00000000)>>32); output.dwLowDateTime = (int)((((ulong)(input*10000000)) & 0x00000000FFFFFFFF)); return output; } /// /// Returns an array of FILETIMEs. /// internal static OpcRcw.Hda.OPCHDA_FILETIME[] GetFILETIMEs(DateTime[] input) { OpcRcw.Hda.OPCHDA_FILETIME[] output = null; if (input != null) { output = new OpcRcw.Hda.OPCHDA_FILETIME[input.Length]; for (var ii = 0; ii < input.Length; ii++) { output[ii] = Convert(Technosoftware.DaAeHdaClient.Com.Interop.GetFILETIME(input[ii])); } } return output; } /// /// Converts a Technosoftware.DaAeHdaClient.Time object to a Technosoftware.DaAeHdaClient.Com.Hda.OPCHDA_TIME structure. /// internal static OpcRcw.Hda.OPCHDA_TIME GetTime(TsCHdaTime input) { var output = new OpcRcw.Hda.OPCHDA_TIME(); if (input != null) { output.ftTime = Convert(Technosoftware.DaAeHdaClient.Com.Interop.GetFILETIME(input.AbsoluteTime)); output.szTime = (input.IsRelative)?input.ToString():""; output.bString = (input.IsRelative)?1:0; } // create a null value for a time structure. else { output.ftTime = Convert(Technosoftware.DaAeHdaClient.Com.Interop.GetFILETIME(DateTime.MinValue)); output.szTime = ""; output.bString = 1; } return output; } /// /// Unmarshals and deallocates an array of OPCHDA_ITEM structures. /// internal static TsCHdaItemValueCollection[] GetItemValueCollections(ref IntPtr pInput, int count, bool deallocate) { TsCHdaItemValueCollection[] output = null; if (pInput != IntPtr.Zero && count > 0) { output = new TsCHdaItemValueCollection[count]; var pos = pInput; for (var ii = 0; ii < count; ii++) { output[ii] = GetItemValueCollection(pos, deallocate); pos = (IntPtr)(pos.ToInt64() + Marshal.SizeOf(typeof(OpcRcw.Hda.OPCHDA_ITEM))); } if (deallocate) { Marshal.FreeCoTaskMem(pInput); pInput = IntPtr.Zero; } } return output; } /// /// Unmarshals and deallocates an OPCHDA_ITEM structure. /// internal static TsCHdaItemValueCollection GetItemValueCollection(IntPtr pInput, bool deallocate) { TsCHdaItemValueCollection output = null; if (pInput != IntPtr.Zero) { var item = Marshal.PtrToStructure(pInput, typeof(OpcRcw.Hda.OPCHDA_ITEM)); output = GetItemValueCollection((OpcRcw.Hda.OPCHDA_ITEM)item, deallocate); if (deallocate) { Marshal.DestroyStructure(pInput, typeof(OpcRcw.Hda.OPCHDA_ITEM)); } } return output; } /// /// Unmarshals and deallocates an OPCHDA_ITEM structure. /// internal static TsCHdaItemValueCollection GetItemValueCollection(OpcRcw.Hda.OPCHDA_ITEM input, bool deallocate) { var output = new TsCHdaItemValueCollection(); output.ClientHandle = input.hClient; output.Aggregate = input.haAggregate; var values = Com.Interop.GetVARIANTs(ref input.pvDataValues, input.dwCount, deallocate); var timestamps = Utilities.Interop.GetDateTimes(ref input.pftTimeStamps, input.dwCount, deallocate); var qualities = Utilities.Interop.GetInt32s(ref input.pdwQualities, input.dwCount, deallocate); for (var ii = 0; ii < input.dwCount; ii++) { var value = new TsCHdaItemValue(); value.Value = values[ii]; value.Timestamp = timestamps[ii]; value.Quality = new TsCDaQuality((short)(qualities[ii] & 0x0000FFFF)); value.HistorianQuality = (TsCHdaQuality)((int)(qualities[ii] & 0xFFFF0000)); output.Add(value); } return output; } /// /// Unmarshals and deallocates an array of OPCHDA_MODIFIEDITEM structures. /// internal static TsCHdaModifiedValueCollection[] GetModifiedValueCollections(ref IntPtr pInput, int count, bool deallocate) { TsCHdaModifiedValueCollection[] output = null; if (pInput != IntPtr.Zero && count > 0) { output = new TsCHdaModifiedValueCollection[count]; var pos = pInput; for (var ii = 0; ii < count; ii++) { output[ii] = GetModifiedValueCollection(pos, deallocate); pos = (IntPtr)(pos.ToInt64() + Marshal.SizeOf(typeof(OpcRcw.Hda.OPCHDA_MODIFIEDITEM))); } if (deallocate) { Marshal.FreeCoTaskMem(pInput); pInput = IntPtr.Zero; } } return output; } /// /// Unmarshals and deallocates an OPCHDA_MODIFIEDITEM structure. /// internal static TsCHdaModifiedValueCollection GetModifiedValueCollection(IntPtr pInput, bool deallocate) { TsCHdaModifiedValueCollection output = null; if (pInput != IntPtr.Zero) { var item = Marshal.PtrToStructure(pInput, typeof(OpcRcw.Hda.OPCHDA_MODIFIEDITEM)); output = GetModifiedValueCollection((OpcRcw.Hda.OPCHDA_MODIFIEDITEM)item, deallocate); if (deallocate) { Marshal.DestroyStructure(pInput, typeof(OpcRcw.Hda.OPCHDA_MODIFIEDITEM)); } } return output; } /// /// Unmarshals and deallocates an OPCHDA_MODIFIEDITEM structure. /// internal static TsCHdaModifiedValueCollection GetModifiedValueCollection(OpcRcw.Hda.OPCHDA_MODIFIEDITEM input, bool deallocate) { var output = new TsCHdaModifiedValueCollection(); output.ClientHandle = input.hClient; var values = Com.Interop.GetVARIANTs(ref input.pvDataValues, input.dwCount, deallocate); var timestamps = Utilities.Interop.GetDateTimes(ref input.pftTimeStamps, input.dwCount, deallocate); var qualities = Utilities.Interop.GetInt32s(ref input.pdwQualities, input.dwCount, deallocate); var modificationTimes = Utilities.Interop.GetDateTimes(ref input.pftModificationTime, input.dwCount, deallocate); var editTypes = Utilities.Interop.GetInt32s(ref input.pEditType, input.dwCount, deallocate); var users = Utilities.Interop.GetUnicodeStrings(ref input.szUser, input.dwCount, deallocate); for (var ii = 0; ii < input.dwCount; ii++) { var value = new TsCHdaModifiedValue(); value.Value = values[ii]; value.Timestamp = timestamps[ii]; value.Quality = new TsCDaQuality((short)(qualities[ii] & 0x0000FFFF)); value.HistorianQuality = (TsCHdaQuality)((int)(qualities[ii] & 0xFFFF0000)); value.ModificationTime = modificationTimes[ii]; value.EditType = (TsCHdaEditType)editTypes[ii]; value.User = users[ii]; output.Add(value); } return output; } /// /// Unmarshals and deallocates an array of OPCHDA_ATTRIBUTE structures. /// internal static TsCHdaAttributeValueCollection[] GetAttributeValueCollections(ref IntPtr pInput, int count, bool deallocate) { TsCHdaAttributeValueCollection[] output = null; if (pInput != IntPtr.Zero && count > 0) { output = new TsCHdaAttributeValueCollection[count]; var pos = pInput; for (var ii = 0; ii < count; ii++) { output[ii] = GetAttributeValueCollection(pos, deallocate); pos = (IntPtr)(pos.ToInt64() + Marshal.SizeOf(typeof(OpcRcw.Hda.OPCHDA_ATTRIBUTE))); } if (deallocate) { Marshal.FreeCoTaskMem(pInput); pInput = IntPtr.Zero; } } return output; } /// /// Unmarshals and deallocates an OPCHDA_ATTRIBUTE structure. /// internal static TsCHdaAttributeValueCollection GetAttributeValueCollection(IntPtr pInput, bool deallocate) { TsCHdaAttributeValueCollection output = null; if (pInput != IntPtr.Zero) { var item = Marshal.PtrToStructure(pInput, typeof(OpcRcw.Hda.OPCHDA_ATTRIBUTE)); output = GetAttributeValueCollection((OpcRcw.Hda.OPCHDA_ATTRIBUTE)item, deallocate); if (deallocate) { Marshal.DestroyStructure(pInput, typeof(OpcRcw.Hda.OPCHDA_ATTRIBUTE)); } } return output; } /// /// Unmarshals and deallocates an OPCHDA_ATTRIBUTE structure. /// internal static TsCHdaAttributeValueCollection GetAttributeValueCollection(OpcRcw.Hda.OPCHDA_ATTRIBUTE input, bool deallocate) { var output = new TsCHdaAttributeValueCollection(); output.AttributeID = input.dwAttributeID; var values = Com.Interop.GetVARIANTs(ref input.vAttributeValues, input.dwNumValues, deallocate); var timestamps = Utilities.Interop.GetDateTimes(ref input.ftTimeStamps, input.dwNumValues, deallocate); for (var ii = 0; ii < input.dwNumValues; ii++) { var value = new TsCHdaAttributeValue(); value.Value = values[ii]; value.Timestamp = timestamps[ii]; output.Add(value); } return output; } /// /// Unmarshals and deallocates an array of OPCHDA_ANNOTATION structures. /// internal static TsCHdaAnnotationValueCollection[] GetAnnotationValueCollections(ref IntPtr pInput, int count, bool deallocate) { TsCHdaAnnotationValueCollection[] output = null; if (pInput != IntPtr.Zero && count > 0) { output = new TsCHdaAnnotationValueCollection[count]; var pos = pInput; for (var ii = 0; ii < count; ii++) { output[ii] = GetAnnotationValueCollection(pos, deallocate); pos = (IntPtr)(pos.ToInt64() + Marshal.SizeOf(typeof(OpcRcw.Hda.OPCHDA_ANNOTATION))); } if (deallocate) { Marshal.FreeCoTaskMem(pInput); pInput = IntPtr.Zero; } } return output; } /// /// Unmarshals and deallocates an OPCHDA_ANNOTATION structure. /// internal static TsCHdaAnnotationValueCollection GetAnnotationValueCollection(IntPtr pInput, bool deallocate) { TsCHdaAnnotationValueCollection output = null; if (pInput != IntPtr.Zero) { var item = Marshal.PtrToStructure(pInput, typeof(OpcRcw.Hda.OPCHDA_ANNOTATION)); output = GetAnnotationValueCollection((OpcRcw.Hda.OPCHDA_ANNOTATION)item, deallocate); if (deallocate) { Marshal.DestroyStructure(pInput, typeof(OpcRcw.Hda.OPCHDA_ANNOTATION)); } } return output; } /// /// Unmarshals and deallocates an OPCHDA_ANNOTATION structure. /// internal static TsCHdaAnnotationValueCollection GetAnnotationValueCollection(OpcRcw.Hda.OPCHDA_ANNOTATION input, bool deallocate) { var output = new TsCHdaAnnotationValueCollection(); output.ClientHandle = input.hClient; var timestamps = Utilities.Interop.GetDateTimes(ref input.ftTimeStamps, input.dwNumValues, deallocate); var annotations = Utilities.Interop.GetUnicodeStrings(ref input.szAnnotation, input.dwNumValues, deallocate); var creationTimes = Utilities.Interop.GetDateTimes(ref input.ftAnnotationTime, input.dwNumValues, deallocate); var users = Utilities.Interop.GetUnicodeStrings(ref input.szUser, input.dwNumValues, deallocate); for (var ii = 0; ii < input.dwNumValues; ii++) { var value = new TsCHdaAnnotationValue(); value.Timestamp = timestamps[ii]; value.Annotation = annotations[ii]; value.CreationTime = creationTimes[ii]; value.User = users[ii]; output.Add(value); } return output; } } }