This commit is contained in:
luosheng
2023-07-12 06:42:28 +08:00
parent 25555cad18
commit db591e0367
188 changed files with 56088 additions and 9 deletions

View File

@@ -0,0 +1,715 @@
#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.Collections;
using System.Xml;
using System.IO;
using Technosoftware.DaAeHdaClient.Da;
#endregion
namespace Technosoftware.DaAeHdaClient.Cpx
{
/// <summary>
/// A class that contains complex data related properties for an item.
/// </summary>
public class TsCCpxComplexItem : OpcItem
{
///////////////////////////////////////////////////////////////////////
#region Constants
/// <summary>
/// The reserved name for complex data branch in the server namespace.
/// </summary>
public const string CPX_BRANCH = "CPX";
/// <summary>
/// The reserved name for the data filters branch in the CPX namespace.
/// </summary>
public const string CPX_DATA_FILTERS = "DataFilters";
/// <summary>
/// The set of all complex data item properties.
/// </summary>
public static readonly TsDaPropertyID[] CPX_PROPERTIES = new TsDaPropertyID[]
{
TsDaProperty.TYPE_SYSTEM_ID,
TsDaProperty.DICTIONARY_ID,
TsDaProperty.TYPE_ID,
TsDaProperty.UNCONVERTED_ITEM_ID,
TsDaProperty.UNFILTERED_ITEM_ID,
TsDaProperty.DATA_FILTER_VALUE
};
#endregion
///////////////////////////////////////////////////////////////////////
#region Fields
private string _typeSystemID;
private string _dictionaryID;
private string _typeID;
private OpcItem _dictionaryItemID;
private OpcItem _typeItemID;
private OpcItem _unconvertedItemID;
private OpcItem _unfilteredItemID;
private OpcItem _filterItem;
#endregion
///////////////////////////////////////////////////////////////////////
#region Constructors, Destructor, Initialization
/// <summary>
/// Initializes the object with the default values.
/// </summary>
public TsCCpxComplexItem() { }
/// <summary>
/// Initializes the object from an item identifier.
/// </summary>
/// <param name="itemID">The item id.</param>
public TsCCpxComplexItem(OpcItem itemID)
{
ItemPath = itemID.ItemPath;
ItemName = itemID.ItemName;
}
#endregion
///////////////////////////////////////////////////////////////////////
#region Properties
/// <summary>
/// The name of the item in the server address space.
/// </summary>
public string Name { get; private set; }
/// <summary>
/// The type system id for the complex item.
/// </summary>
public string TypeSystemID => _typeSystemID;
/// <summary>
/// The dictionary id for the complex item.
/// </summary>
public string DictionaryID => _dictionaryID;
/// <summary>
/// The type id for the complex item.
/// </summary>
public string TypeID => _typeID;
/// <summary>
/// The id of the item containing the dictionary for the item.
/// </summary>
public OpcItem DictionaryItemID => _dictionaryItemID;
/// <summary>
/// The id of the item containing the type description for the item.
/// </summary>
public OpcItem TypeItemID => _typeItemID;
/// <summary>
/// The id of the unconverted version of the item. Only valid for items which apply type conversions to the item.
/// </summary>
public OpcItem UnconvertedItemID => _unconvertedItemID;
/// <summary>
/// The id of the unfiltered version of the item. Only valid for items apply data filters to the item.
/// </summary>
public OpcItem UnfilteredItemID => _unfilteredItemID;
/// <summary>
/// The item used to create new data filters for the complex data item (null is item does not support it).
/// </summary>
public OpcItem DataFilterItem => _filterItem;
/// <summary>
/// The current data filter value. Only valid for items apply data filters to the item.
/// </summary>
public string DataFilterValue { get; set; }
#endregion
///////////////////////////////////////////////////////////////////////
#region Public Methods
/// <summary>
/// Returns an appropriate string representation of the object.
/// </summary>
public override string ToString()
{
if (Name != null || Name.Length != 0)
{
return Name;
}
return ItemName;
}
/// <summary>
/// Returns the root complex data item for the object.
/// </summary>
public TsCCpxComplexItem GetRootItem()
{
if (_unconvertedItemID != null)
{
return TsCCpxComplexTypeCache.GetComplexItem(_unconvertedItemID);
}
if (_unfilteredItemID != null)
{
return TsCCpxComplexTypeCache.GetComplexItem(_unfilteredItemID);
}
return this;
}
/// <summary>
/// Reads the current complex data item properties from the server.
/// </summary>
/// <param name="server">The server object</param>
public void Update(TsCDaServer server)
{
// clear the existing state.
Clear();
// check if the item supports any of the complex data properties.
var results = server.GetProperties(
new OpcItem[] { this },
CPX_PROPERTIES,
true);
// unexpected return value.
if (results == null || results.Length != 1)
{
throw new OpcResultException(new OpcResult((int)OpcResult.E_FAIL.Code, OpcResult.FuncCallType.SysFuncCall, null), "Unexpected results returned from server.");
}
// update object.
if (!Init((TsCDaItemProperty[])results[0].ToArray(typeof(TsCDaItemProperty))))
{
throw new OpcResultException(new OpcResult((int)OpcResult.E_INVALIDARG.Code, OpcResult.FuncCallType.SysFuncCall, null), "Not a valid complex item.");
}
// check if data filters are suppported for the item.
GetDataFilterItem(server);
}
/// <summary>
/// Fetches the set of type conversions from the server.
/// </summary>
/// <param name="server">The server object</param>
public TsCCpxComplexItem[] GetTypeConversions(TsCDaServer server)
{
// only the root item can have type conversions.
if (_unconvertedItemID != null || _unfilteredItemID != null)
{
return null;
}
TsCDaBrowsePosition position = null;
try
{
// look for the 'CPX' branch.
var filters = new TsCDaBrowseFilters { ElementNameFilter = CPX_BRANCH, BrowseFilter = TsCDaBrowseFilter.Branch, ReturnAllProperties = false, PropertyIDs = null, ReturnPropertyValues = false };
var elements = server.Browse(this, filters, out position);
// nothing found.
if (elements == null || elements.Length == 0)
{
return null;
}
// release the browse position object.
if (position != null)
{
position.Dispose();
position = null;
}
// browse for type conversions.
var itemID = new OpcItem(elements[0].ItemPath, elements[0].ItemName);
filters.ElementNameFilter = null;
filters.BrowseFilter = TsCDaBrowseFilter.Item;
filters.ReturnAllProperties = false;
filters.PropertyIDs = CPX_PROPERTIES;
filters.ReturnPropertyValues = true;
elements = server.Browse(itemID, filters, out position);
// nothing found.
if (elements == null || elements.Length == 0)
{
return new TsCCpxComplexItem[0];
}
// contruct an array of complex data items for each available conversion.
var conversions = new ArrayList(elements.Length);
Array.ForEach(elements, element =>
{
if (element.Name != CPX_DATA_FILTERS)
{
var item = new TsCCpxComplexItem();
if (item.Init(element))
{
// check if data filters supported for type conversion.
item.GetDataFilterItem(server);
conversions.Add(item);
}
}
});
// return the set of available conversions.
return (TsCCpxComplexItem[])conversions.ToArray(typeof(TsCCpxComplexItem));
}
finally
{
if (position != null)
{
position.Dispose();
position = null;
}
}
}
/// <summary>
/// Fetches the set of data filters from the server.
/// </summary>
/// <param name="server">The server object</param>
public TsCCpxComplexItem[] GetDataFilters(TsCDaServer server)
{
// not a valid operation for data filter items.
if (_unfilteredItemID != null)
{
return null;
}
// data filters not supported by the item.
if (_filterItem == null)
{
return null;
}
TsCDaBrowsePosition position = null;
try
{
// browse any existing filter instances.
var filters = new TsCDaBrowseFilters { ElementNameFilter = null, BrowseFilter = TsCDaBrowseFilter.Item, ReturnAllProperties = false, PropertyIDs = CPX_PROPERTIES, ReturnPropertyValues = true };
var elements = server.Browse(_filterItem, filters, out position);
// nothing found.
if (elements == null || elements.Length == 0)
{
return new TsCCpxComplexItem[0];
}
// contruct an array of complex data items for each available data filter.
var dataFilters = new ArrayList(elements.Length);
Array.ForEach(elements, element =>
{
var item = new TsCCpxComplexItem();
if (item.Init(element))
dataFilters.Add(item);
});
// return the set of available data filters.
return (TsCCpxComplexItem[])dataFilters.ToArray(typeof(TsCCpxComplexItem));
}
finally
{
if (position != null)
{
position.Dispose();
position = null;
}
}
}
/// <summary>
/// Creates a new data filter.
/// </summary>
/// <param name="server">The server object</param>
/// <param name="filterName">The name of the filter</param>
/// <param name="filterValue">The value of the filter</param>
public TsCCpxComplexItem CreateDataFilter(TsCDaServer server, string filterName, string filterValue)
{
// not a valid operation for data filter items.
if (_unfilteredItemID != null)
{
return null;
}
// data filters not supported by the item.
if (_filterItem == null)
{
return null;
}
TsCDaBrowsePosition position = null;
try
{
// write the desired filter to the server.
var item = new TsCDaItemValue(_filterItem);
// create the filter parameters document.
using (var ostrm = new StringWriter())
{
using (var writer = new XmlTextWriter(ostrm))
{
writer.WriteStartElement("DataFilters");
writer.WriteAttributeString("Name", filterName);
writer.WriteString(filterValue);
writer.WriteEndElement();
writer.Close();
}
// create the value to write.
item.Value = ostrm.ToString();
}
item.Quality = TsCDaQuality.Bad;
item.QualitySpecified = false;
item.Timestamp = DateTime.MinValue;
item.TimestampSpecified = false;
// write the value.
var result = server.Write(new TsCDaItemValue[] { item });
if (result == null || result.Length == 0)
{
throw new OpcResultException(new OpcResult((int)OpcResult.E_FAIL.Code, OpcResult.FuncCallType.SysFuncCall, null), "Unexpected results returned from server.");
}
if (result[0].Result.Failed())
{
throw new OpcResultException(new OpcResult((int)OpcResult.Cpx.E_FILTER_ERROR.Code, OpcResult.FuncCallType.SysFuncCall, null), "Could not create new data filter.");
}
// browse for new data filter item.
var filters = new TsCDaBrowseFilters { ElementNameFilter = filterName, BrowseFilter = TsCDaBrowseFilter.Item, ReturnAllProperties = false, PropertyIDs = CPX_PROPERTIES, ReturnPropertyValues = true };
var elements = server.Browse(_filterItem, filters, out position);
// nothing found.
if (elements == null || elements.Length == 0)
{
throw new OpcResultException(new OpcResult((int)OpcResult.Cpx.E_FILTER_ERROR.Code, OpcResult.FuncCallType.SysFuncCall, null), "Could not browse to new data filter.");
}
var filterItem = new TsCCpxComplexItem();
if (!filterItem.Init(elements[0]))
{
throw new OpcResultException(new OpcResult((int)OpcResult.Cpx.E_FILTER_ERROR.Code, OpcResult.FuncCallType.SysFuncCall, null), "Could not initialize to new data filter.");
}
// return the new data filter.
return filterItem;
}
finally
{
if (position != null)
{
position.Dispose();
}
}
}
/// <summary>
/// Updates a data filter.
/// </summary>
/// <param name="server">The server object</param>
/// <param name="filterValue">The value of the filter</param>
public void UpdateDataFilter(TsCDaServer server, string filterValue)
{
// not a valid operation for non data filter items.
if (_unfilteredItemID == null)
{
throw new OpcResultException(new OpcResult((int)OpcResult.Cpx.E_FILTER_ERROR.Code, OpcResult.FuncCallType.SysFuncCall, null), "Cannot update the data filter for this item.");
}
// create the value to write.
var item = new TsCDaItemValue(this) { Value = filterValue, Quality = TsCDaQuality.Bad, QualitySpecified = false, Timestamp = DateTime.MinValue, TimestampSpecified = false };
// write the value.
var result = server.Write(new TsCDaItemValue[] { item });
if (result == null || result.Length == 0)
{
throw new OpcResultException(new OpcResult((int)OpcResult.E_FAIL.Code, OpcResult.FuncCallType.SysFuncCall, null), "Unexpected results returned from server.");
}
if (result[0].Result.Failed())
{
throw new OpcResultException(new OpcResult((int)OpcResult.Cpx.E_FILTER_ERROR.Code, OpcResult.FuncCallType.SysFuncCall, null), "Could not update data filter.");
}
// update locale copy of the filter value.
DataFilterValue = filterValue;
}
/// <summary>
/// Fetches the type dictionary for the item.
/// </summary>
/// <param name="server">The server object</param>
public string GetTypeDictionary(TsCDaServer server)
{
var results = server.GetProperties(
new OpcItem[] { _dictionaryItemID },
new TsDaPropertyID[] { TsDaProperty.DICTIONARY },
true);
if (results == null || results.Length == 0 || results[0].Count == 0)
{
return null;
}
var property = results[0][0];
if (!property.Result.Succeeded())
{
return null;
}
return (string)property.Value;
}
/// <summary>
/// Fetches the type description for the item.
/// </summary>
/// <param name="server">The server object</param>
public string GetTypeDescription(TsCDaServer server)
{
var results = server.GetProperties(
new OpcItem[] { _typeItemID },
new TsDaPropertyID[] { TsDaProperty.TYPE_DESCRIPTION },
true);
if (results == null || results.Length == 0 || results[0].Count == 0)
{
return null;
}
var property = results[0][0];
if (!property.Result.Succeeded())
{
return null;
}
return (string)property.Value;
}
/// <summary>
/// Fetches the item id for the data filters items and stores it in the internal cache.
/// </summary>
/// <param name="server">The server object</param>
public void GetDataFilterItem(TsCDaServer server)
{
_filterItem = null;
// not a valid operation for data filter items.
if (_unfilteredItemID != null)
{
return;
}
TsCDaBrowsePosition position = null;
try
{
var itemID = new OpcItem(this);
// browse any existing filter instances.
var filters = new TsCDaBrowseFilters { ElementNameFilter = CPX_DATA_FILTERS, BrowseFilter = TsCDaBrowseFilter.All, ReturnAllProperties = false, PropertyIDs = null, ReturnPropertyValues = false };
TsCDaBrowseElement[] elements = null;
// browse for the 'CPX' branch first.
if (_unconvertedItemID == null)
{
filters.ElementNameFilter = CPX_BRANCH;
elements = server.Browse(itemID, filters, out position);
// nothing found.
if (elements == null || elements.Length == 0)
{
return;
}
// release the position object.
if (position != null)
{
position.Dispose();
position = null;
}
// update the item for the next browse operation.
itemID = new OpcItem(elements[0].ItemPath, elements[0].ItemName);
filters.ElementNameFilter = CPX_DATA_FILTERS;
}
// browse for the 'DataFilters' branch.
elements = server.Browse(itemID, filters, out position);
// nothing found.
if (elements == null || elements.Length == 0)
{
return;
}
_filterItem = new OpcItem(elements[0].ItemPath, elements[0].ItemName);
}
finally
{
if (position != null)
{
position.Dispose();
}
}
}
#endregion
///////////////////////////////////////////////////////////////////////
#region Private Methods
/// <summary>
/// Sets all object properties to their default values.
/// </summary>
private void Clear()
{
_typeSystemID = null;
_dictionaryID = null;
_typeID = null;
_dictionaryItemID = null;
_typeItemID = null;
_unconvertedItemID = null;
_unfilteredItemID = null;
_filterItem = null;
DataFilterValue = null;
}
/// <summary>
/// Initializes the object from a browse element.
/// </summary>
private bool Init(TsCDaBrowseElement element)
{
// update the item id.
ItemPath = element.ItemPath;
ItemName = element.ItemName;
Name = element.Name;
return Init(element.Properties);
}
/// <summary>
/// Initializes the object from a list of properties.
/// </summary>
private bool Init(TsCDaItemProperty[] properties)
{
// put the object into default state.
Clear();
// must have at least three properties defined.
if (properties == null || properties.Length < 3)
{
return false;
}
foreach (var property in properties)
{
// continue - ignore invalid properties.
if (!property.Result.Succeeded())
{
continue;
}
// type system id.
if (property.ID == TsDaProperty.TYPE_SYSTEM_ID)
{
_typeSystemID = (string)property.Value;
continue;
}
// dictionary id
if (property.ID == TsDaProperty.DICTIONARY_ID)
{
_dictionaryID = (string)property.Value;
_dictionaryItemID = new OpcItem(property.ItemPath, property.ItemName);
continue;
}
// type id
if (property.ID == TsDaProperty.TYPE_ID)
{
_typeID = (string)property.Value;
_typeItemID = new OpcItem(property.ItemPath, property.ItemName);
continue;
}
// unconverted item id
if (property.ID == TsDaProperty.UNCONVERTED_ITEM_ID)
{
_unconvertedItemID = new OpcItem(ItemPath, (string)property.Value);
continue;
}
// unfiltered item id
if (property.ID == TsDaProperty.UNFILTERED_ITEM_ID)
{
_unfilteredItemID = new OpcItem(ItemPath, (string)property.Value);
continue;
}
// data filter value.
if (property.ID == TsDaProperty.DATA_FILTER_VALUE)
{
DataFilterValue = (string)property.Value;
continue;
}
}
// validate object.
if (_typeSystemID == null || _dictionaryID == null || _typeID == null)
{
return false;
}
return true;
}
#endregion
}
}

View File

@@ -0,0 +1,207 @@
#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.Collections;
using Technosoftware.DaAeHdaClient.Da;
#endregion
namespace Technosoftware.DaAeHdaClient.Cpx
{
/// <summary>
/// A class that caches properties of complex data items.
/// </summary>
public class TsCCpxComplexTypeCache
{
///////////////////////////////////////////////////////////////////////
#region Fields
/// <summary>
/// The active server for the application.
/// </summary>
private static TsCDaServer _server;
/// <summary>
/// A cache of item properties fetched from the active server.
/// </summary>
private static Hashtable _items = new Hashtable();
/// <summary>
/// A cache of type dictionaries fetched from the active server.
/// </summary>
private static Hashtable _dictionaries = new Hashtable();
/// <summary>
/// A cache of type descriptions fetched from the active server.
/// </summary>
private static Hashtable _descriptions = new Hashtable();
#endregion
///////////////////////////////////////////////////////////////////////
#region Constructors, Destructor, Initialization
/// <summary>
/// Initializes the complex type cache with defaults.
/// </summary>
public TsCCpxComplexTypeCache() { }
#endregion
///////////////////////////////////////////////////////////////////////
#region Properties
/// <summary>
/// Get or sets the server to use for the cache.
/// </summary>
public static TsCDaServer Server
{
get
{
lock (typeof(TsCCpxComplexTypeCache))
{
return _server;
}
}
set
{
lock (typeof(TsCCpxComplexTypeCache))
{
_server = value;
_items.Clear();
_dictionaries.Clear();
_descriptions.Clear();
}
}
}
#endregion
///////////////////////////////////////////////////////////////////////
#region Public Methods
/// <summary>
/// Returns the complex item for the specified item id.
/// </summary>
/// <param name="itemID">The item id.</param>
public static TsCCpxComplexItem GetComplexItem(OpcItem itemID)
{
if (itemID == null) return null;
lock (typeof(TsCCpxComplexTypeCache))
{
var item = new TsCCpxComplexItem(itemID);
try
{
item.Update(_server);
}
catch
{
// item is not a valid complex data item.
item = null;
}
_items[itemID.Key] = item;
return item;
}
}
/// <summary>
/// Returns the complex item for the specified item browse element.
/// </summary>
/// <param name="element">The item browse element.</param>
public static TsCCpxComplexItem GetComplexItem(TsCDaBrowseElement element)
{
if (element == null) return null;
lock (typeof(TsCCpxComplexTypeCache))
{
return GetComplexItem(new OpcItem(element.ItemPath, element.ItemName));
}
}
/// <summary>
/// Fetches the type dictionary for the item.
/// </summary>
/// <param name="itemID">The item id.</param>
public static string GetTypeDictionary(OpcItem itemID)
{
if (itemID == null) return null;
lock (typeof(TsCCpxComplexTypeCache))
{
var dictionary = (string)_dictionaries[itemID.Key];
if (dictionary != null)
{
return dictionary;
}
var item = GetComplexItem(itemID);
if (item != null)
{
dictionary = item.GetTypeDictionary(_server);
}
return dictionary;
}
}
/// <summary>
/// Fetches the type description for the item.
/// </summary>
/// <param name="itemID">The item id.</param>
public static string GetTypeDescription(OpcItem itemID)
{
if (itemID == null) return null;
lock (typeof(TsCCpxComplexTypeCache))
{
string description = null;
var item = GetComplexItem(itemID);
if (item != null)
{
description = (string)_descriptions[item.TypeItemID.Key];
if (description != null)
{
return description;
}
_descriptions[item.TypeItemID.Key] = description = item.GetTypeDescription(_server);
}
return description;
}
}
#endregion
}
}

View File

@@ -0,0 +1,49 @@
#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
#endregion
namespace Technosoftware.DaAeHdaClient.Cpx
{
/// <summary>
/// Stores a value with an associated name and/or type.
/// </summary>
public class TsCCpxComplexValue
{
/// <summary>
/// The name of the value.
/// </summary>
public string Name;
/// <summary>
/// The complex or simple data type of the value.
/// </summary>
public string Type;
/// <summary>
/// The actual value.
/// </summary>
public object Value;
}
}

View File

@@ -0,0 +1,71 @@
#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
#endregion
namespace Technosoftware.DaAeHdaClient.Cpx
{
/// <summary>
/// Stores the current serialization context.
/// </summary>
internal struct TsCCpxContext
{
///////////////////////////////////////////////////////////////////////
#region Constructors, Destructor, Initialization
public TsCCpxContext(byte[] buffer)
{
Buffer = buffer;
Index = 0;
Dictionary = null;
Type = null;
BigEndian = false;
CharWidth = 2;
StringEncoding = STRING_ENCODING_UCS2;
FloatFormat = FLOAT_FORMAT_IEEE754;
}
#endregion
///////////////////////////////////////////////////////////////////////
#region Public Fields
public byte[] Buffer;
public int Index;
public TypeDictionary Dictionary;
public TypeDescription Type;
public bool BigEndian;
public int CharWidth;
public string StringEncoding;
public string FloatFormat;
public const string STRING_ENCODING_ACSII = "ASCII";
public const string STRING_ENCODING_UCS2 = "UCS-2";
public const string FLOAT_FORMAT_IEEE754 = "IEEE-754";
#endregion
}
}

View File

@@ -0,0 +1,48 @@
#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.Serialization;
#endregion
namespace Technosoftware.DaAeHdaClient.Cpx
{
/// <summary>
/// Raised if the data in buffer is not consistent with the schema.
/// </summary>
[Serializable]
public class TsCCpxInvalidDataInBufferException : ApplicationException
{
private const string Default = "The data in the buffer cannot be read because it is not consistent with the schema.";
/// <remarks/>
public TsCCpxInvalidDataInBufferException() : base(Default) { }
/// <remarks/>
public TsCCpxInvalidDataInBufferException(string message) : base(Default + Environment.NewLine + message) { }
/// <remarks/>
public TsCCpxInvalidDataInBufferException(Exception e) : base(Default, e) { }
/// <remarks/>
public TsCCpxInvalidDataInBufferException(string message, Exception innerException) : base(Default + Environment.NewLine + message, innerException) { }
/// <remarks/>
protected TsCCpxInvalidDataInBufferException(SerializationInfo info, StreamingContext context) : base(info, context) { }
}
}

View File

@@ -0,0 +1,48 @@
#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.Serialization;
#endregion
namespace Technosoftware.DaAeHdaClient.Cpx
{
/// <summary>
/// Raised if the data in buffer is not consistent with the schema.
/// </summary>
[Serializable]
public class TsCCpxInvalidDataToWriteException : ApplicationException
{
private const string Default = "The object cannot be written because it is not consistent with the schema.";
/// <remarks/>
public TsCCpxInvalidDataToWriteException() : base(Default) { }
/// <remarks/>
public TsCCpxInvalidDataToWriteException(string message) : base(Default + Environment.NewLine + message) { }
/// <remarks/>
public TsCCpxInvalidDataToWriteException(Exception e) : base(Default, e) { }
/// <remarks/>
public TsCCpxInvalidDataToWriteException(string message, Exception innerException) : base(Default + Environment.NewLine + message, innerException) { }
/// <remarks/>
protected TsCCpxInvalidDataToWriteException(SerializationInfo info, StreamingContext context) : base(info, context) { }
}
}

View File

@@ -0,0 +1,48 @@
#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.Serialization;
#endregion
namespace Technosoftware.DaAeHdaClient.Cpx
{
/// <summary>
/// Raised if the schema contains errors or inconsistencies.
/// </summary>
[Serializable]
public class TsCCpxInvalidSchemaException : ApplicationException
{
private const string Default = "The schema cannot be used because it contains errors or inconsitencies.";
/// <remarks/>
public TsCCpxInvalidSchemaException() : base(Default) { }
/// <remarks/>
public TsCCpxInvalidSchemaException(string message) : base(Default + Environment.NewLine + message) { }
/// <remarks/>
public TsCCpxInvalidSchemaException(Exception e) : base(Default, e) { }
/// <remarks/>
public TsCCpxInvalidSchemaException(string message, Exception innerException) : base(Default + Environment.NewLine + message, innerException) { }
/// <remarks/>
protected TsCCpxInvalidSchemaException(SerializationInfo info, StreamingContext context) : base(info, context) { }
}
}

View File

@@ -0,0 +1,269 @@
//------------------------------------------------------------------------------
// <autogenerated>
// This code was generated by a tool.
// Runtime Version: 1.1.4322.573
//
// Changes to this file may cause incorrect behavior and will be lost if
// the code is regenerated.
// </autogenerated>
//------------------------------------------------------------------------------
//
// This source code was auto-generated by xsd, Version=1.1.4322.573.
//
namespace Technosoftware.DaAeHdaClient.Cpx
{
using System.Xml.Serialization;
/// <remarks/>
[XmlTypeAttribute(Namespace="http://opcfoundation.org/OPCBinary/1.0/")]
[XmlRootAttribute(Namespace="http://opcfoundation.org/OPCBinary/1.0/", IsNullable=false)]
public class TypeDictionary {
/// <remarks/>
[XmlElementAttribute("TypeDescription")]
public TypeDescription[] TypeDescription;
/// <remarks/>
[XmlAttributeAttribute()]
public string DictionaryName;
/// <remarks/>
[XmlAttributeAttribute()]
[System.ComponentModel.DefaultValueAttribute(true)]
public bool DefaultBigEndian = true;
/// <remarks/>
[XmlAttributeAttribute()]
[System.ComponentModel.DefaultValueAttribute("UCS-2")]
public string DefaultStringEncoding = "UCS-2";
/// <remarks/>
[XmlAttributeAttribute()]
[System.ComponentModel.DefaultValueAttribute(2)]
public int DefaultCharWidth = 2;
/// <remarks/>
[XmlAttributeAttribute()]
[System.ComponentModel.DefaultValueAttribute("IEEE-754")]
public string DefaultFloatFormat = "IEEE-754";
}
/// <remarks/>
[XmlTypeAttribute(Namespace="http://opcfoundation.org/OPCBinary/1.0/")]
public class TypeDescription {
/// <remarks/>
[XmlElementAttribute("Field")]
public FieldType[] Field;
/// <remarks/>
[XmlAttributeAttribute()]
public string TypeID;
/// <remarks/>
[XmlAttributeAttribute()]
public bool DefaultBigEndian;
/// <remarks/>
[XmlIgnoreAttribute()]
public bool DefaultBigEndianSpecified;
/// <remarks/>
[XmlAttributeAttribute()]
public string DefaultStringEncoding;
/// <remarks/>
[XmlAttributeAttribute()]
public int DefaultCharWidth;
/// <remarks/>
[XmlIgnoreAttribute()]
public bool DefaultCharWidthSpecified;
/// <remarks/>
[XmlAttributeAttribute()]
public string DefaultFloatFormat;
}
/// <remarks/>
[XmlTypeAttribute(Namespace="http://opcfoundation.org/OPCBinary/1.0/")]
[XmlIncludeAttribute(typeof(TypeReference))]
[XmlIncludeAttribute(typeof(CharString))]
[XmlIncludeAttribute(typeof(Unicode))]
[XmlIncludeAttribute(typeof(Ascii))]
[XmlIncludeAttribute(typeof(FloatingPoint))]
[XmlIncludeAttribute(typeof(Double))]
[XmlIncludeAttribute(typeof(Single))]
[XmlIncludeAttribute(typeof(Integer))]
[XmlIncludeAttribute(typeof(UInt64))]
[XmlIncludeAttribute(typeof(UInt32))]
[XmlIncludeAttribute(typeof(UInt16))]
[XmlIncludeAttribute(typeof(UInt8))]
[XmlIncludeAttribute(typeof(Int64))]
[XmlIncludeAttribute(typeof(Int32))]
[XmlIncludeAttribute(typeof(Int16))]
[XmlIncludeAttribute(typeof(Int8))]
[XmlIncludeAttribute(typeof(BitString))]
public class FieldType {
/// <remarks/>
[XmlAttributeAttribute()]
public string Name;
/// <remarks/>
[XmlAttributeAttribute()]
public string Format;
/// <remarks/>
[XmlAttributeAttribute()]
public int Length;
/// <remarks/>
[XmlIgnoreAttribute()]
public bool LengthSpecified;
/// <remarks/>
[XmlAttributeAttribute()]
public int ElementCount;
/// <remarks/>
[XmlIgnoreAttribute()]
public bool ElementCountSpecified;
/// <remarks/>
[XmlAttributeAttribute()]
public string ElementCountRef;
/// <remarks/>
[XmlAttributeAttribute()]
public string FieldTerminator;
}
/// <remarks/>
[XmlTypeAttribute(Namespace="http://opcfoundation.org/OPCBinary/1.0/")]
public class TypeReference : FieldType {
/// <remarks/>
[XmlAttributeAttribute()]
public string TypeID;
}
/// <remarks/>
[XmlTypeAttribute(Namespace="http://opcfoundation.org/OPCBinary/1.0/")]
[XmlIncludeAttribute(typeof(Unicode))]
[XmlIncludeAttribute(typeof(Ascii))]
public class CharString : FieldType {
/// <remarks/>
[XmlAttributeAttribute()]
public int CharWidth;
/// <remarks/>
[XmlIgnoreAttribute()]
public bool CharWidthSpecified;
/// <remarks/>
[XmlAttributeAttribute()]
public string StringEncoding;
/// <remarks/>
[XmlAttributeAttribute()]
public string CharCountRef;
}
/// <remarks/>
[XmlTypeAttribute(Namespace="http://opcfoundation.org/OPCBinary/1.0/")]
public class Unicode : CharString {
}
/// <remarks/>
[XmlTypeAttribute(Namespace="http://opcfoundation.org/OPCBinary/1.0/")]
public class Ascii : CharString {
}
/// <remarks/>
[XmlTypeAttribute(Namespace="http://opcfoundation.org/OPCBinary/1.0/")]
[XmlIncludeAttribute(typeof(Double))]
[XmlIncludeAttribute(typeof(Single))]
public class FloatingPoint : FieldType {
/// <remarks/>
[XmlAttributeAttribute()]
public string FloatFormat;
}
/// <remarks/>
[XmlTypeAttribute(Namespace="http://opcfoundation.org/OPCBinary/1.0/")]
public class Double : FloatingPoint {
}
/// <remarks/>
[XmlTypeAttribute(Namespace="http://opcfoundation.org/OPCBinary/1.0/")]
public class Single : FloatingPoint {
}
/// <remarks/>
[XmlTypeAttribute(Namespace="http://opcfoundation.org/OPCBinary/1.0/")]
[XmlIncludeAttribute(typeof(UInt64))]
[XmlIncludeAttribute(typeof(UInt32))]
[XmlIncludeAttribute(typeof(UInt16))]
[XmlIncludeAttribute(typeof(UInt8))]
[XmlIncludeAttribute(typeof(Int64))]
[XmlIncludeAttribute(typeof(Int32))]
[XmlIncludeAttribute(typeof(Int16))]
[XmlIncludeAttribute(typeof(Int8))]
public class Integer : FieldType {
/// <remarks/>
[XmlAttributeAttribute()]
[System.ComponentModel.DefaultValueAttribute(true)]
public bool Signed = true;
}
/// <remarks/>
[XmlTypeAttribute(Namespace="http://opcfoundation.org/OPCBinary/1.0/")]
public class UInt64 : Integer {
}
/// <remarks/>
[XmlTypeAttribute(Namespace="http://opcfoundation.org/OPCBinary/1.0/")]
public class UInt32 : Integer {
}
/// <remarks/>
[XmlTypeAttribute(Namespace="http://opcfoundation.org/OPCBinary/1.0/")]
public class UInt16 : Integer {
}
/// <remarks/>
[XmlTypeAttribute(Namespace="http://opcfoundation.org/OPCBinary/1.0/")]
public class UInt8 : Integer {
}
/// <remarks/>
[XmlTypeAttribute(Namespace="http://opcfoundation.org/OPCBinary/1.0/")]
public class Int64 : Integer {
}
/// <remarks/>
[XmlTypeAttribute(Namespace="http://opcfoundation.org/OPCBinary/1.0/")]
public class Int32 : Integer {
}
/// <remarks/>
[XmlTypeAttribute(Namespace="http://opcfoundation.org/OPCBinary/1.0/")]
public class Int16 : Integer {
}
/// <remarks/>
[XmlTypeAttribute(Namespace="http://opcfoundation.org/OPCBinary/1.0/")]
public class Int8 : Integer {
}
/// <remarks/>
[XmlTypeAttribute(Namespace="http://opcfoundation.org/OPCBinary/1.0/")]
public class BitString : FieldType {
}
}

View File

@@ -0,0 +1,165 @@
<?xml version="1.0" encoding="utf-8" ?>
<xs:schema id="OPCBinary" targetNamespace="http://opcfoundation.org/OPCBinary/1.0/" elementFormDefault="qualified"
xmlns="http://opcfoundation.org/OPCBinary/1.0/" xmlns:xs="http://www.w3.org/2001/XMLSchema">
<xs:element name="TypeDictionary">
<xs:complexType>
<xs:sequence>
<xs:element name="TypeDescription" type="TypeDescription" minOccurs="1" maxOccurs="unbounded" />
</xs:sequence>
<xs:attribute name="DictionaryName" type="xs:string" use="required" />
<xs:attribute name="DefaultBigEndian" type="xs:boolean" default="true" />
<xs:attribute name="DefaultStringEncoding" type="xs:string" default="UCS-2" />
<xs:attribute name="DefaultCharWidth" type="xs:int" default="2" />
<xs:attribute name="DefaultFloatFormat" type="xs:string" default="IEEE-754" />
</xs:complexType>
</xs:element>
<xs:complexType name="TypeDescription">
<xs:sequence>
<xs:element name="Field" type="FieldType" minOccurs="1" maxOccurs="unbounded" />
</xs:sequence>
<xs:attribute name="TypeID" type="xs:string" use="required" />
<xs:attribute name="DefaultBigEndian" type="xs:boolean" use="optional" />
<xs:attribute name="DefaultStringEncoding" type="xs:string" use="optional" />
<xs:attribute name="DefaultCharWidth" type="xs:int" use="optional" />
<xs:attribute name="DefaultFloatFormat" type="xs:string" use="optional" />
</xs:complexType>
<xs:complexType name="FieldType">
<xs:attribute name="Name" type="xs:string" use="optional" />
<xs:attribute name="Format" type="xs:string" use="optional" />
<xs:attribute name="Length" type="xs:int" use="optional" />
<xs:attribute name="ElementCount" type="xs:int" use="optional" />
<xs:attribute name="ElementCountRef" type="xs:string" use="optional" />
<xs:attribute name="FieldTerminator" type="xs:string" use="optional" />
</xs:complexType>
<xs:complexType name="BitString">
<xs:complexContent>
<xs:extension base="FieldType"></xs:extension>
</xs:complexContent>
</xs:complexType>
<xs:complexType name="Integer">
<xs:complexContent>
<xs:extension base="FieldType">
<xs:attribute name="Signed" type="xs:boolean" default="true" />
</xs:extension>
</xs:complexContent>
</xs:complexType>
<xs:complexType name="FloatingPoint">
<xs:complexContent>
<xs:extension base="FieldType">
<xs:attribute name="FloatFormat" type="xs:string" />
</xs:extension>
</xs:complexContent>
</xs:complexType>
<xs:complexType name="CharString">
<xs:complexContent>
<xs:extension base="FieldType">
<xs:attribute name="CharWidth" type="xs:int" />
<xs:attribute name="StringEncoding" type="xs:string" />
<xs:attribute name="CharCountRef" type="xs:string" />
</xs:extension>
</xs:complexContent>
</xs:complexType>
<xs:complexType name="TypeReference">
<xs:complexContent>
<xs:extension base="FieldType">
<xs:attribute name="TypeID" type="xs:string" />
</xs:extension>
</xs:complexContent>
</xs:complexType>
<xs:complexType name="Int8">
<xs:complexContent>
<xs:restriction base="Integer">
<xs:attribute name="Length" type="xs:int" fixed="1" />
<xs:attribute name="Signed" type="xs:boolean" fixed="true" />
</xs:restriction>
</xs:complexContent>
</xs:complexType>
<xs:complexType name="Int16">
<xs:complexContent>
<xs:restriction base="Integer">
<xs:attribute name="Length" type="xs:int" fixed="2" />
<xs:attribute name="Signed" type="xs:boolean" fixed="true" />
</xs:restriction>
</xs:complexContent>
</xs:complexType>
<xs:complexType name="Int32">
<xs:complexContent>
<xs:restriction base="Integer">
<xs:attribute name="Length" type="xs:int" fixed="4" />
<xs:attribute name="Signed" type="xs:boolean" fixed="true" />
</xs:restriction>
</xs:complexContent>
</xs:complexType>
<xs:complexType name="Int64">
<xs:complexContent>
<xs:restriction base="Integer">
<xs:attribute name="Length" type="xs:int" fixed="8" />
<xs:attribute name="Signed" type="xs:boolean" fixed="true" />
</xs:restriction>
</xs:complexContent>
</xs:complexType>
<xs:complexType name="UInt8">
<xs:complexContent>
<xs:restriction base="Integer">
<xs:attribute name="Length" type="xs:int" fixed="1" />
<xs:attribute name="Signed" type="xs:boolean" fixed="false" />
</xs:restriction>
</xs:complexContent>
</xs:complexType>
<xs:complexType name="UInt16">
<xs:complexContent>
<xs:restriction base="Integer">
<xs:attribute name="Length" type="xs:int" fixed="2" />
<xs:attribute name="Signed" type="xs:boolean" fixed="false" />
</xs:restriction>
</xs:complexContent>
</xs:complexType>
<xs:complexType name="UInt32">
<xs:complexContent>
<xs:restriction base="Integer">
<xs:attribute name="Length" type="xs:int" fixed="4" />
<xs:attribute name="Signed" type="xs:boolean" fixed="false" />
</xs:restriction>
</xs:complexContent>
</xs:complexType>
<xs:complexType name="UInt64">
<xs:complexContent>
<xs:restriction base="Integer">
<xs:attribute name="Length" type="xs:int" fixed="8" />
<xs:attribute name="Signed" type="xs:boolean" fixed="false" />
</xs:restriction>
</xs:complexContent>
</xs:complexType>
<xs:complexType name="Single">
<xs:complexContent>
<xs:restriction base="FloatingPoint">
<xs:attribute name="Length" type="xs:int" fixed="4" />
<xs:attribute name="FloatFormat" type="xs:string" fixed="IEEE-754" />
</xs:restriction>
</xs:complexContent>
</xs:complexType>
<xs:complexType name="Double">
<xs:complexContent>
<xs:restriction base="FloatingPoint">
<xs:attribute name="Length" type="xs:int" fixed="8" />
<xs:attribute name="FloatFormat" type="xs:string" fixed="IEEE-754" />
</xs:restriction>
</xs:complexContent>
</xs:complexType>
<xs:complexType name="Ascii">
<xs:complexContent>
<xs:restriction base="CharString">
<xs:attribute name="CharWidth" type="xs:int" fixed="1" />
<xs:attribute name="StringEncoding" type="xs:string" fixed="ASCII" />
</xs:restriction>
</xs:complexContent>
</xs:complexType>
<xs:complexType name="Unicode">
<xs:complexContent>
<xs:restriction base="CharString">
<xs:attribute name="CharWidth" type="xs:int" fixed="2" />
<xs:attribute name="StringEncoding" type="xs:string" fixed="UCS-2" />
</xs:restriction>
</xs:complexContent>
</xs:complexType>
</xs:schema>