mirror of
https://github.com/OPCFoundation/UA-.NETStandard.git
synced 2026-10-24 11:01:55 +08:00
Merge pull request #197 from AlinMoldovean/master
Merged changes from UA-.NET
This commit is contained in:
@@ -642,6 +642,12 @@ namespace Opc.Ua.Client
|
||||
// create a placeholder for the node if it does not already exist.
|
||||
if (!m_nodes.Exists(reference.NodeId))
|
||||
{
|
||||
// transform absolute identifiers.
|
||||
if (reference.NodeId != null && reference.NodeId.IsAbsolute)
|
||||
{
|
||||
reference.NodeId = ExpandedNodeId.ToNodeId(reference.NodeId, NamespaceUris);
|
||||
}
|
||||
|
||||
Node target = new Node(reference);
|
||||
m_nodes.Attach(target);
|
||||
}
|
||||
|
||||
@@ -128,36 +128,36 @@ namespace Opc.Ua.Server
|
||||
/// </summary>
|
||||
/// <param name="session">The session to use.</param>
|
||||
/// <returns>
|
||||
/// A copy of the system context that references the new operation context.
|
||||
/// A copy of the system context that references the new session.
|
||||
/// </returns>
|
||||
public ServerSystemContext Copy(Session session)
|
||||
{
|
||||
ServerSystemContext copy = (ServerSystemContext)MemberwiseClone();
|
||||
|
||||
OperationContext = null;
|
||||
copy.OperationContext = null;
|
||||
|
||||
if (session != null)
|
||||
{
|
||||
SessionId = session.Id;
|
||||
UserIdentity = session.Identity;
|
||||
PreferredLocales = session.PreferredLocales;
|
||||
copy.SessionId = session.Id;
|
||||
copy.UserIdentity = session.Identity;
|
||||
copy.PreferredLocales = session.PreferredLocales;
|
||||
}
|
||||
else
|
||||
{
|
||||
SessionId = null;
|
||||
UserIdentity = null;
|
||||
PreferredLocales = null;
|
||||
copy.SessionId = null;
|
||||
copy.UserIdentity = null;
|
||||
copy.PreferredLocales = null;
|
||||
}
|
||||
|
||||
return copy;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Creates a copy of the context that can be used with the specified session.
|
||||
/// Creates a copy of the context that can be used with the specified server context.
|
||||
/// </summary>
|
||||
/// <param name="context">The session to use.</param>
|
||||
/// <param name="context">The server context to use.</param>
|
||||
/// <returns>
|
||||
/// A copy of the system context that references the new operation context.
|
||||
/// A copy of the system context that references the new server context.
|
||||
/// </returns>
|
||||
public ServerSystemContext Copy(ServerSystemContext context)
|
||||
{
|
||||
@@ -165,14 +165,14 @@ namespace Opc.Ua.Server
|
||||
|
||||
if (context != null)
|
||||
{
|
||||
OperationContext = context.OperationContext;
|
||||
SessionId = context.SessionId;
|
||||
UserIdentity = context.UserIdentity;
|
||||
PreferredLocales = context.PreferredLocales;
|
||||
NamespaceUris = context.NamespaceUris;
|
||||
ServerUris = context.ServerUris;
|
||||
TypeTable = context.TypeTable;
|
||||
EncodeableFactory = context.EncodeableFactory;
|
||||
copy.OperationContext = context.OperationContext;
|
||||
copy.SessionId = context.SessionId;
|
||||
copy.UserIdentity = context.UserIdentity;
|
||||
copy.PreferredLocales = context.PreferredLocales;
|
||||
copy.NamespaceUris = context.NamespaceUris;
|
||||
copy.ServerUris = context.ServerUris;
|
||||
copy.TypeTable = context.TypeTable;
|
||||
copy.EncodeableFactory = context.EncodeableFactory;
|
||||
}
|
||||
|
||||
return copy;
|
||||
|
||||
@@ -335,8 +335,11 @@ namespace Opc.Ua.Server
|
||||
public void Delete(OperationContext context)
|
||||
{
|
||||
// delete the diagnostics.
|
||||
ServerSystemContext systemContext = m_server.DefaultSystemContext.Copy(m_session);
|
||||
m_server.DiagnosticsNodeManager.DeleteSubscriptionDiagnostics(systemContext, m_diagnosticsId);
|
||||
if (m_diagnosticsId != null && !m_diagnosticsId.IsNullNodeId)
|
||||
{
|
||||
ServerSystemContext systemContext = m_server.DefaultSystemContext.Copy(m_session);
|
||||
m_server.DiagnosticsNodeManager.DeleteSubscriptionDiagnostics(systemContext, m_diagnosticsId);
|
||||
}
|
||||
|
||||
lock (m_lock)
|
||||
{
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -33,6 +33,7 @@ namespace Opc.Ua
|
||||
m_ostrm = new MemoryStream();
|
||||
m_writer = new BinaryWriter(m_ostrm);
|
||||
m_context = context;
|
||||
m_nestingLevel = 0;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@@ -45,6 +46,7 @@ namespace Opc.Ua
|
||||
m_ostrm = new MemoryStream(buffer, start, count);
|
||||
m_writer = new BinaryWriter(m_ostrm);
|
||||
m_context = context;
|
||||
m_nestingLevel = 0;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@@ -57,6 +59,7 @@ namespace Opc.Ua
|
||||
m_ostrm = stream;
|
||||
m_writer = new BinaryWriter(m_ostrm);
|
||||
m_context = context;
|
||||
m_nestingLevel = 0;
|
||||
}
|
||||
#endregion
|
||||
|
||||
@@ -644,6 +647,15 @@ namespace Opc.Ua
|
||||
/// </summary>
|
||||
public void WriteDiagnosticInfo(string fieldName, DiagnosticInfo value)
|
||||
{
|
||||
// check the nesting level for avoiding a stack overflow.
|
||||
if (m_nestingLevel > m_context.MaxEncodingNestingLevels)
|
||||
{
|
||||
throw ServiceResultException.Create(
|
||||
StatusCodes.BadEncodingLimitsExceeded,
|
||||
"Maximum nesting level of {0} was exceeded",
|
||||
m_context.MaxEncodingNestingLevels);
|
||||
}
|
||||
|
||||
// check for null.
|
||||
if (value == null)
|
||||
{
|
||||
@@ -651,6 +663,8 @@ namespace Opc.Ua
|
||||
return;
|
||||
}
|
||||
|
||||
m_nestingLevel++;
|
||||
|
||||
// calculate the encoding.
|
||||
byte encoding = 0;
|
||||
|
||||
@@ -727,6 +741,8 @@ namespace Opc.Ua
|
||||
{
|
||||
WriteDiagnosticInfo(null, value.InnerDiagnosticInfo);
|
||||
}
|
||||
|
||||
m_nestingLevel--;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@@ -792,160 +808,24 @@ namespace Opc.Ua
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Writes an Variant array to the stream.
|
||||
/// Writes an Variant to the stream.
|
||||
/// </summary>
|
||||
[System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Maintainability", "CA1506:AvoidExcessiveClassCoupling"), System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Maintainability", "CA1502:AvoidExcessiveComplexity")]
|
||||
public void WriteVariant(string fieldName, Variant value)
|
||||
{
|
||||
// check for null.
|
||||
if (value.Value == null || value.TypeInfo == null || value.TypeInfo.BuiltInType == BuiltInType.Null)
|
||||
// check the nesting level for avoiding a stack overflow.
|
||||
if (m_nestingLevel > m_context.MaxEncodingNestingLevels)
|
||||
{
|
||||
WriteByte(null, 0);
|
||||
return;
|
||||
}
|
||||
|
||||
// encode enums as int32.
|
||||
byte encodingByte = (byte)value.TypeInfo.BuiltInType;
|
||||
|
||||
if (value.TypeInfo.BuiltInType == BuiltInType.Enumeration)
|
||||
{
|
||||
encodingByte = (byte)BuiltInType.Int32;
|
||||
}
|
||||
|
||||
object valueToEncode = value.Value;
|
||||
|
||||
if (value.TypeInfo.ValueRank < 0)
|
||||
{
|
||||
WriteByte(null, encodingByte);
|
||||
|
||||
switch (value.TypeInfo.BuiltInType)
|
||||
{
|
||||
case BuiltInType.Boolean: { WriteBoolean(null, (bool)valueToEncode); return; }
|
||||
case BuiltInType.SByte: { WriteSByte(null, (sbyte)valueToEncode); return; }
|
||||
case BuiltInType.Byte: { WriteByte(null, (byte)valueToEncode); return; }
|
||||
case BuiltInType.Int16: { WriteInt16(null, (short)valueToEncode); return; }
|
||||
case BuiltInType.UInt16: { WriteUInt16(null, (ushort)valueToEncode); return; }
|
||||
case BuiltInType.Int32: { WriteInt32(null, (int)valueToEncode); return; }
|
||||
case BuiltInType.UInt32: { WriteUInt32(null, (uint)valueToEncode); return; }
|
||||
case BuiltInType.Int64: { WriteInt64(null, (long)valueToEncode); return; }
|
||||
case BuiltInType.UInt64: { WriteUInt64(null, (ulong)valueToEncode); return; }
|
||||
case BuiltInType.Float: { WriteFloat(null, (float)valueToEncode); return; }
|
||||
case BuiltInType.Double: { WriteDouble(null, (double)valueToEncode); return; }
|
||||
case BuiltInType.String: { WriteString(null, (string)valueToEncode); return; }
|
||||
case BuiltInType.DateTime: { WriteDateTime(null, (DateTime)valueToEncode); return; }
|
||||
case BuiltInType.Guid: { WriteGuid(null, (Uuid)valueToEncode); return; }
|
||||
case BuiltInType.ByteString: { WriteByteString(null, (byte[])valueToEncode); return; }
|
||||
case BuiltInType.XmlElement: { WriteXmlElement(null, (XmlElement)valueToEncode); return; }
|
||||
case BuiltInType.NodeId: { WriteNodeId(null, (NodeId)valueToEncode); return; }
|
||||
case BuiltInType.ExpandedNodeId: { WriteExpandedNodeId(null, (ExpandedNodeId)valueToEncode); return; }
|
||||
case BuiltInType.StatusCode: { WriteStatusCode(null, (StatusCode)valueToEncode); return; }
|
||||
case BuiltInType.QualifiedName: { WriteQualifiedName(null, (QualifiedName)valueToEncode); return; }
|
||||
case BuiltInType.LocalizedText: { WriteLocalizedText(null, (LocalizedText)valueToEncode); return; }
|
||||
case BuiltInType.ExtensionObject: { WriteExtensionObject(null, (ExtensionObject)valueToEncode); return; }
|
||||
case BuiltInType.DataValue: { WriteDataValue(null, (DataValue)valueToEncode); return; }
|
||||
case BuiltInType.Enumeration: { WriteInt32(null, (int)valueToEncode); return; }
|
||||
}
|
||||
|
||||
throw ServiceResultException.Create(
|
||||
StatusCodes.BadEncodingError,
|
||||
"Unexpected type encountered while encoding a Variant: {0}",
|
||||
value.TypeInfo.BuiltInType);
|
||||
StatusCodes.BadEncodingLimitsExceeded,
|
||||
"Maximum nesting level of {0} was exceeded",
|
||||
m_context.MaxEncodingNestingLevels);
|
||||
}
|
||||
|
||||
if (value.TypeInfo.ValueRank >= 0)
|
||||
{
|
||||
Matrix matrix = null;
|
||||
m_nestingLevel++;
|
||||
|
||||
encodingByte |= (byte)VariantArrayEncodingBits.Array;
|
||||
WriteVariantValue(fieldName, value);
|
||||
|
||||
if (value.TypeInfo.ValueRank > 1)
|
||||
{
|
||||
encodingByte |= (byte)VariantArrayEncodingBits.ArrayDimensions;
|
||||
matrix = (Matrix)valueToEncode;
|
||||
valueToEncode = matrix.Elements;
|
||||
}
|
||||
|
||||
WriteByte(null, encodingByte);
|
||||
|
||||
switch (value.TypeInfo.BuiltInType)
|
||||
{
|
||||
case BuiltInType.Boolean: { WriteBooleanArray(null, (bool[])valueToEncode); break; }
|
||||
case BuiltInType.SByte: { WriteSByteArray(null, (sbyte[])valueToEncode); break; }
|
||||
case BuiltInType.Byte: { WriteByteArray(null, (byte[])valueToEncode); break; }
|
||||
case BuiltInType.Int16: { WriteInt16Array(null, (short[])valueToEncode); break; }
|
||||
case BuiltInType.UInt16: { WriteUInt16Array(null, (ushort[])valueToEncode); break; }
|
||||
case BuiltInType.Int32: { WriteInt32Array(null, (int[])valueToEncode); break; }
|
||||
case BuiltInType.UInt32: { WriteUInt32Array(null, (uint[])valueToEncode); break; }
|
||||
case BuiltInType.Int64: { WriteInt64Array(null, (long[])valueToEncode); break; }
|
||||
case BuiltInType.UInt64: { WriteUInt64Array(null, (ulong[])valueToEncode); break; }
|
||||
case BuiltInType.Float: { WriteFloatArray(null, (float[])valueToEncode); break; }
|
||||
case BuiltInType.Double: { WriteDoubleArray(null, (double[])valueToEncode); break; }
|
||||
case BuiltInType.String: { WriteStringArray(null, (string[])valueToEncode); break; }
|
||||
case BuiltInType.DateTime: { WriteDateTimeArray(null, (DateTime[])valueToEncode); break; }
|
||||
case BuiltInType.Guid: { WriteGuidArray(null, (Uuid[])valueToEncode); break; }
|
||||
case BuiltInType.ByteString: { WriteByteStringArray(null, (byte[][])valueToEncode); break; }
|
||||
case BuiltInType.XmlElement: { WriteXmlElementArray(null, (XmlElement[])valueToEncode); break; }
|
||||
case BuiltInType.NodeId: { WriteNodeIdArray(null, (NodeId[])valueToEncode); break; }
|
||||
case BuiltInType.ExpandedNodeId: { WriteExpandedNodeIdArray(null, (ExpandedNodeId[])valueToEncode); break; }
|
||||
case BuiltInType.StatusCode: { WriteStatusCodeArray(null, (StatusCode[])valueToEncode); break; }
|
||||
case BuiltInType.QualifiedName: { WriteQualifiedNameArray(null, (QualifiedName[])valueToEncode); break; }
|
||||
case BuiltInType.LocalizedText: { WriteLocalizedTextArray(null, (LocalizedText[])valueToEncode); break; }
|
||||
case BuiltInType.ExtensionObject: { WriteExtensionObjectArray(null, (ExtensionObject[])valueToEncode); break; }
|
||||
case BuiltInType.DataValue: { WriteDataValueArray(null, (DataValue[])valueToEncode); break; }
|
||||
|
||||
case BuiltInType.Enumeration:
|
||||
{
|
||||
Enum[] enums = valueToEncode as Enum[];
|
||||
int[] ints = new int[enums.Length];
|
||||
|
||||
for (int ii = 0; ii < enums.Length; ii++)
|
||||
{
|
||||
ints[ii] = (int)(object)enums[ii];
|
||||
}
|
||||
|
||||
WriteInt32Array(null, ints);
|
||||
return;
|
||||
}
|
||||
|
||||
case BuiltInType.Variant:
|
||||
{
|
||||
Variant[] variants = valueToEncode as Variant[];
|
||||
|
||||
if (variants != null)
|
||||
{
|
||||
WriteVariantArray(null, variants);
|
||||
break;
|
||||
}
|
||||
|
||||
object[] objects = valueToEncode as object[];
|
||||
|
||||
if (objects != null)
|
||||
{
|
||||
WriteObjectArray(null, objects);
|
||||
break;
|
||||
}
|
||||
|
||||
throw ServiceResultException.Create(
|
||||
StatusCodes.BadEncodingError,
|
||||
"Unexpected type encountered while encoding a Matrix: {0}",
|
||||
valueToEncode.GetType());
|
||||
}
|
||||
|
||||
default:
|
||||
{
|
||||
throw ServiceResultException.Create(
|
||||
StatusCodes.BadEncodingError,
|
||||
"Unexpected type encountered while encoding a Variant: {0}",
|
||||
value.TypeInfo.BuiltInType);
|
||||
}
|
||||
}
|
||||
|
||||
// write the dimensions.
|
||||
if (value.TypeInfo.ValueRank > 1)
|
||||
{
|
||||
WriteInt32Array(null, (int[])matrix.Dimensions);
|
||||
}
|
||||
}
|
||||
m_nestingLevel--;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@@ -1158,6 +1038,15 @@ namespace Opc.Ua
|
||||
/// </summary>
|
||||
public void WriteEncodeable(string fieldName, IEncodeable value, System.Type systemType)
|
||||
{
|
||||
// check the nesting level for avoiding a stack overflow.
|
||||
if (m_nestingLevel > m_context.MaxEncodingNestingLevels)
|
||||
{
|
||||
throw ServiceResultException.Create(
|
||||
StatusCodes.BadEncodingLimitsExceeded,
|
||||
"Maximum nesting level of {0} was exceeded",
|
||||
m_context.MaxEncodingNestingLevels);
|
||||
}
|
||||
|
||||
// create a default object if a null object specified.
|
||||
if (value == null)
|
||||
{
|
||||
@@ -1165,11 +1054,15 @@ namespace Opc.Ua
|
||||
value = Activator.CreateInstance(systemType) as IEncodeable;
|
||||
}
|
||||
|
||||
m_nestingLevel++;
|
||||
|
||||
// encode the object.
|
||||
if (value != null)
|
||||
{
|
||||
value.Encode(this);
|
||||
}
|
||||
|
||||
m_nestingLevel--;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@@ -1866,6 +1759,163 @@ namespace Opc.Ua
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Writes an Variant to the stream.
|
||||
/// </summary>
|
||||
[System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Maintainability", "CA1506:AvoidExcessiveClassCoupling"), System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Maintainability", "CA1502:AvoidExcessiveComplexity")]
|
||||
private void WriteVariantValue(string fieldName, Variant value)
|
||||
{
|
||||
// check for null.
|
||||
if (value.Value == null || value.TypeInfo == null || value.TypeInfo.BuiltInType == BuiltInType.Null)
|
||||
{
|
||||
WriteByte(null, 0);
|
||||
return;
|
||||
}
|
||||
|
||||
// encode enums as int32.
|
||||
byte encodingByte = (byte)value.TypeInfo.BuiltInType;
|
||||
|
||||
if (value.TypeInfo.BuiltInType == BuiltInType.Enumeration)
|
||||
{
|
||||
encodingByte = (byte)BuiltInType.Int32;
|
||||
}
|
||||
|
||||
object valueToEncode = value.Value;
|
||||
|
||||
if (value.TypeInfo.ValueRank < 0)
|
||||
{
|
||||
WriteByte(null, encodingByte);
|
||||
|
||||
switch (value.TypeInfo.BuiltInType)
|
||||
{
|
||||
case BuiltInType.Boolean: { WriteBoolean(null, (bool)valueToEncode); return; }
|
||||
case BuiltInType.SByte: { WriteSByte(null, (sbyte)valueToEncode); return; }
|
||||
case BuiltInType.Byte: { WriteByte(null, (byte)valueToEncode); return; }
|
||||
case BuiltInType.Int16: { WriteInt16(null, (short)valueToEncode); return; }
|
||||
case BuiltInType.UInt16: { WriteUInt16(null, (ushort)valueToEncode); return; }
|
||||
case BuiltInType.Int32: { WriteInt32(null, (int)valueToEncode); return; }
|
||||
case BuiltInType.UInt32: { WriteUInt32(null, (uint)valueToEncode); return; }
|
||||
case BuiltInType.Int64: { WriteInt64(null, (long)valueToEncode); return; }
|
||||
case BuiltInType.UInt64: { WriteUInt64(null, (ulong)valueToEncode); return; }
|
||||
case BuiltInType.Float: { WriteFloat(null, (float)valueToEncode); return; }
|
||||
case BuiltInType.Double: { WriteDouble(null, (double)valueToEncode); return; }
|
||||
case BuiltInType.String: { WriteString(null, (string)valueToEncode); return; }
|
||||
case BuiltInType.DateTime: { WriteDateTime(null, (DateTime)valueToEncode); return; }
|
||||
case BuiltInType.Guid: { WriteGuid(null, (Uuid)valueToEncode); return; }
|
||||
case BuiltInType.ByteString: { WriteByteString(null, (byte[])valueToEncode); return; }
|
||||
case BuiltInType.XmlElement: { WriteXmlElement(null, (XmlElement)valueToEncode); return; }
|
||||
case BuiltInType.NodeId: { WriteNodeId(null, (NodeId)valueToEncode); return; }
|
||||
case BuiltInType.ExpandedNodeId: { WriteExpandedNodeId(null, (ExpandedNodeId)valueToEncode); return; }
|
||||
case BuiltInType.StatusCode: { WriteStatusCode(null, (StatusCode)valueToEncode); return; }
|
||||
case BuiltInType.QualifiedName: { WriteQualifiedName(null, (QualifiedName)valueToEncode); return; }
|
||||
case BuiltInType.LocalizedText: { WriteLocalizedText(null, (LocalizedText)valueToEncode); return; }
|
||||
case BuiltInType.ExtensionObject: { WriteExtensionObject(null, (ExtensionObject)valueToEncode); return; }
|
||||
case BuiltInType.DataValue: { WriteDataValue(null, (DataValue)valueToEncode); return; }
|
||||
case BuiltInType.Enumeration: { WriteInt32(null, (int)valueToEncode); return; }
|
||||
}
|
||||
|
||||
throw ServiceResultException.Create(
|
||||
StatusCodes.BadEncodingError,
|
||||
"Unexpected type encountered while encoding a Variant: {0}",
|
||||
value.TypeInfo.BuiltInType);
|
||||
}
|
||||
|
||||
if (value.TypeInfo.ValueRank >= 0)
|
||||
{
|
||||
Matrix matrix = null;
|
||||
|
||||
encodingByte |= (byte)VariantArrayEncodingBits.Array;
|
||||
|
||||
if (value.TypeInfo.ValueRank > 1)
|
||||
{
|
||||
encodingByte |= (byte)VariantArrayEncodingBits.ArrayDimensions;
|
||||
matrix = (Matrix)valueToEncode;
|
||||
valueToEncode = matrix.Elements;
|
||||
}
|
||||
|
||||
WriteByte(null, encodingByte);
|
||||
|
||||
switch (value.TypeInfo.BuiltInType)
|
||||
{
|
||||
case BuiltInType.Boolean: { WriteBooleanArray(null, (bool[])valueToEncode); break; }
|
||||
case BuiltInType.SByte: { WriteSByteArray(null, (sbyte[])valueToEncode); break; }
|
||||
case BuiltInType.Byte: { WriteByteArray(null, (byte[])valueToEncode); break; }
|
||||
case BuiltInType.Int16: { WriteInt16Array(null, (short[])valueToEncode); break; }
|
||||
case BuiltInType.UInt16: { WriteUInt16Array(null, (ushort[])valueToEncode); break; }
|
||||
case BuiltInType.Int32: { WriteInt32Array(null, (int[])valueToEncode); break; }
|
||||
case BuiltInType.UInt32: { WriteUInt32Array(null, (uint[])valueToEncode); break; }
|
||||
case BuiltInType.Int64: { WriteInt64Array(null, (long[])valueToEncode); break; }
|
||||
case BuiltInType.UInt64: { WriteUInt64Array(null, (ulong[])valueToEncode); break; }
|
||||
case BuiltInType.Float: { WriteFloatArray(null, (float[])valueToEncode); break; }
|
||||
case BuiltInType.Double: { WriteDoubleArray(null, (double[])valueToEncode); break; }
|
||||
case BuiltInType.String: { WriteStringArray(null, (string[])valueToEncode); break; }
|
||||
case BuiltInType.DateTime: { WriteDateTimeArray(null, (DateTime[])valueToEncode); break; }
|
||||
case BuiltInType.Guid: { WriteGuidArray(null, (Uuid[])valueToEncode); break; }
|
||||
case BuiltInType.ByteString: { WriteByteStringArray(null, (byte[][])valueToEncode); break; }
|
||||
case BuiltInType.XmlElement: { WriteXmlElementArray(null, (XmlElement[])valueToEncode); break; }
|
||||
case BuiltInType.NodeId: { WriteNodeIdArray(null, (NodeId[])valueToEncode); break; }
|
||||
case BuiltInType.ExpandedNodeId: { WriteExpandedNodeIdArray(null, (ExpandedNodeId[])valueToEncode); break; }
|
||||
case BuiltInType.StatusCode: { WriteStatusCodeArray(null, (StatusCode[])valueToEncode); break; }
|
||||
case BuiltInType.QualifiedName: { WriteQualifiedNameArray(null, (QualifiedName[])valueToEncode); break; }
|
||||
case BuiltInType.LocalizedText: { WriteLocalizedTextArray(null, (LocalizedText[])valueToEncode); break; }
|
||||
case BuiltInType.ExtensionObject: { WriteExtensionObjectArray(null, (ExtensionObject[])valueToEncode); break; }
|
||||
case BuiltInType.DataValue: { WriteDataValueArray(null, (DataValue[])valueToEncode); break; }
|
||||
|
||||
case BuiltInType.Enumeration:
|
||||
{
|
||||
Enum[] enums = valueToEncode as Enum[];
|
||||
int[] ints = new int[enums.Length];
|
||||
|
||||
for (int ii = 0; ii < enums.Length; ii++)
|
||||
{
|
||||
ints[ii] = (int)(object)enums[ii];
|
||||
}
|
||||
|
||||
WriteInt32Array(null, ints);
|
||||
return;
|
||||
}
|
||||
|
||||
case BuiltInType.Variant:
|
||||
{
|
||||
Variant[] variants = valueToEncode as Variant[];
|
||||
|
||||
if (variants != null)
|
||||
{
|
||||
WriteVariantArray(null, variants);
|
||||
break;
|
||||
}
|
||||
|
||||
object[] objects = valueToEncode as object[];
|
||||
|
||||
if (objects != null)
|
||||
{
|
||||
WriteObjectArray(null, objects);
|
||||
break;
|
||||
}
|
||||
|
||||
throw ServiceResultException.Create(
|
||||
StatusCodes.BadEncodingError,
|
||||
"Unexpected type encountered while encoding a Matrix: {0}",
|
||||
valueToEncode.GetType());
|
||||
}
|
||||
|
||||
default:
|
||||
{
|
||||
throw ServiceResultException.Create(
|
||||
StatusCodes.BadEncodingError,
|
||||
"Unexpected type encountered while encoding a Variant: {0}",
|
||||
value.TypeInfo.BuiltInType);
|
||||
}
|
||||
}
|
||||
|
||||
// write the dimensions.
|
||||
if (value.TypeInfo.ValueRank > 1)
|
||||
{
|
||||
WriteInt32Array(null, (int[])matrix.Dimensions);
|
||||
}
|
||||
}
|
||||
}
|
||||
#endregion
|
||||
|
||||
#region Private Fields
|
||||
@@ -1874,6 +1924,7 @@ namespace Opc.Ua
|
||||
private ServiceMessageContext m_context;
|
||||
private ushort[] m_namespaceMappings;
|
||||
private ushort[] m_serverMappings;
|
||||
private uint m_nestingLevel;
|
||||
#endregion
|
||||
}
|
||||
|
||||
|
||||
@@ -32,6 +32,7 @@ namespace Opc.Ua
|
||||
private ServiceMessageContext m_context;
|
||||
private ushort[] m_namespaceMappings;
|
||||
private ushort[] m_serverMappings;
|
||||
private uint m_nestingLevel;
|
||||
#endregion
|
||||
|
||||
#region Constructors
|
||||
@@ -40,8 +41,8 @@ namespace Opc.Ua
|
||||
if (context == null) throw new ArgumentNullException("context");
|
||||
Initialize();
|
||||
|
||||
|
||||
m_context = context;
|
||||
m_nestingLevel = 0;
|
||||
m_reader = new JsonTextReader(new StringReader(json));
|
||||
m_root = ReadObject();
|
||||
m_stack = new Stack<object>();
|
||||
@@ -53,6 +54,7 @@ namespace Opc.Ua
|
||||
Initialize();
|
||||
|
||||
m_context = context;
|
||||
m_nestingLevel = 0;
|
||||
m_reader = reader;
|
||||
m_root = ReadObject();
|
||||
m_stack = new Stack<object>();
|
||||
@@ -942,6 +944,16 @@ namespace Opc.Ua
|
||||
|
||||
try
|
||||
{
|
||||
// check the nesting level for avoiding a stack overflow.
|
||||
if (m_nestingLevel > m_context.MaxEncodingNestingLevels)
|
||||
{
|
||||
throw ServiceResultException.Create(
|
||||
StatusCodes.BadEncodingLimitsExceeded,
|
||||
"Maximum nesting level of {0} was exceeded",
|
||||
m_context.MaxEncodingNestingLevels);
|
||||
}
|
||||
|
||||
m_nestingLevel++;
|
||||
m_stack.Push(value);
|
||||
|
||||
DiagnosticInfo di = new DiagnosticInfo();
|
||||
@@ -985,6 +997,7 @@ namespace Opc.Ua
|
||||
}
|
||||
finally
|
||||
{
|
||||
m_nestingLevel--;
|
||||
m_stack.Pop();
|
||||
}
|
||||
}
|
||||
@@ -1150,6 +1163,16 @@ namespace Opc.Ua
|
||||
|
||||
try
|
||||
{
|
||||
// check the nesting level for avoiding a stack overflow.
|
||||
if (m_nestingLevel > m_context.MaxEncodingNestingLevels)
|
||||
{
|
||||
throw ServiceResultException.Create(
|
||||
StatusCodes.BadEncodingLimitsExceeded,
|
||||
"Maximum nesting level of {0} was exceeded",
|
||||
m_context.MaxEncodingNestingLevels);
|
||||
}
|
||||
|
||||
m_nestingLevel++;
|
||||
m_stack.Push(value);
|
||||
|
||||
BuiltInType type = (BuiltInType)ReadByte("Type");
|
||||
@@ -1180,6 +1203,7 @@ namespace Opc.Ua
|
||||
}
|
||||
finally
|
||||
{
|
||||
m_nestingLevel--;
|
||||
m_stack.Pop();
|
||||
}
|
||||
}
|
||||
@@ -1357,6 +1381,17 @@ namespace Opc.Ua
|
||||
throw new ServiceResultException(StatusCodes.BadDecodingError, Utils.Format("Type does not support IEncodeable interface: '{0}'", systemType.FullName));
|
||||
}
|
||||
|
||||
// check the nesting level for avoiding a stack overflow.
|
||||
if (m_nestingLevel > m_context.MaxEncodingNestingLevels)
|
||||
{
|
||||
throw ServiceResultException.Create(
|
||||
StatusCodes.BadEncodingLimitsExceeded,
|
||||
"Maximum nesting level of {0} was exceeded",
|
||||
m_context.MaxEncodingNestingLevels);
|
||||
}
|
||||
|
||||
m_nestingLevel++;
|
||||
|
||||
try
|
||||
{
|
||||
m_stack.Push(token);
|
||||
@@ -1368,6 +1403,8 @@ namespace Opc.Ua
|
||||
m_stack.Pop();
|
||||
}
|
||||
|
||||
m_nestingLevel--;
|
||||
|
||||
return value;
|
||||
}
|
||||
|
||||
|
||||
@@ -32,6 +32,7 @@ namespace Opc.Ua
|
||||
private ServiceMessageContext m_context;
|
||||
private ushort[] m_namespaceMappings;
|
||||
private ushort[] m_serverMappings;
|
||||
private uint m_nestingLevel;
|
||||
#endregion
|
||||
|
||||
public bool UseReversibleEncoding { get; private set; }
|
||||
@@ -45,6 +46,7 @@ namespace Opc.Ua
|
||||
Initialize();
|
||||
|
||||
m_context = context;
|
||||
m_nestingLevel = 0;
|
||||
m_writer = writer;
|
||||
UseReversibleEncoding = useReversibleEncoding;
|
||||
|
||||
@@ -729,6 +731,17 @@ namespace Opc.Ua
|
||||
/// </summary>
|
||||
public void WriteDiagnosticInfo(string fieldName, DiagnosticInfo value)
|
||||
{
|
||||
// check the nesting level for avoiding a stack overflow.
|
||||
if (m_nestingLevel > m_context.MaxEncodingNestingLevels)
|
||||
{
|
||||
throw ServiceResultException.Create(
|
||||
StatusCodes.BadEncodingLimitsExceeded,
|
||||
"Maximum nesting level of {0} was exceeded",
|
||||
m_context.MaxEncodingNestingLevels);
|
||||
}
|
||||
|
||||
m_nestingLevel++;
|
||||
|
||||
if (value == null)
|
||||
{
|
||||
WriteSimpleField(fieldName, null, false);
|
||||
@@ -773,6 +786,8 @@ namespace Opc.Ua
|
||||
}
|
||||
|
||||
PopStructure();
|
||||
|
||||
m_nestingLevel--;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@@ -837,10 +852,21 @@ namespace Opc.Ua
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Writes an Variant array to the stream.
|
||||
/// Writes an Variant to the stream.
|
||||
/// </summary>
|
||||
public void WriteVariant(string fieldName, Variant value)
|
||||
{
|
||||
// check the nesting level for avoiding a stack overflow.
|
||||
if (m_nestingLevel > m_context.MaxEncodingNestingLevels)
|
||||
{
|
||||
throw ServiceResultException.Create(
|
||||
StatusCodes.BadEncodingLimitsExceeded,
|
||||
"Maximum nesting level of {0} was exceeded",
|
||||
m_context.MaxEncodingNestingLevels);
|
||||
}
|
||||
|
||||
m_nestingLevel++;
|
||||
|
||||
if (Variant.Null == value)
|
||||
{
|
||||
WriteSimpleField(fieldName, null, false);
|
||||
@@ -881,6 +907,8 @@ namespace Opc.Ua
|
||||
|
||||
PopStructure();
|
||||
}
|
||||
|
||||
m_nestingLevel--;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@@ -987,6 +1015,17 @@ namespace Opc.Ua
|
||||
/// </summary>
|
||||
public void WriteEncodeable(string fieldName, IEncodeable value, System.Type systemType)
|
||||
{
|
||||
// check the nesting level for avoiding a stack overflow.
|
||||
if (m_nestingLevel > m_context.MaxEncodingNestingLevels)
|
||||
{
|
||||
throw ServiceResultException.Create(
|
||||
StatusCodes.BadEncodingLimitsExceeded,
|
||||
"Maximum nesting level of {0} was exceeded",
|
||||
m_context.MaxEncodingNestingLevels);
|
||||
}
|
||||
|
||||
m_nestingLevel++;
|
||||
|
||||
if (value == null)
|
||||
{
|
||||
WriteSimpleField(fieldName, null, false);
|
||||
@@ -1001,6 +1040,8 @@ namespace Opc.Ua
|
||||
}
|
||||
|
||||
PopStructure();
|
||||
|
||||
m_nestingLevel--;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
|
||||
@@ -33,8 +33,9 @@ namespace Opc.Ua
|
||||
if (context == null) throw new ArgumentNullException("context");
|
||||
Initialize();
|
||||
m_context = context;
|
||||
}
|
||||
|
||||
m_nestingLevel = 0;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Initializes the object with an XML element to parse.
|
||||
/// </summary>
|
||||
@@ -44,6 +45,7 @@ namespace Opc.Ua
|
||||
Initialize();
|
||||
m_reader = XmlReader.Create(new StringReader(element.OuterXml));
|
||||
m_context = context;
|
||||
m_nestingLevel = 0;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@@ -55,6 +57,7 @@ namespace Opc.Ua
|
||||
|
||||
m_reader = reader;
|
||||
m_context = context;
|
||||
m_nestingLevel = 0;
|
||||
|
||||
string ns = null;
|
||||
string name = null;
|
||||
@@ -82,11 +85,11 @@ namespace Opc.Ua
|
||||
|
||||
PushNamespace(ns);
|
||||
BeginField(name, false);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Sets private members to default values.
|
||||
/// </summary>
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Sets private members to default values.
|
||||
/// </summary>
|
||||
private void Initialize()
|
||||
{
|
||||
m_reader = null;
|
||||
@@ -1190,6 +1193,17 @@ namespace Opc.Ua
|
||||
/// </summary>
|
||||
public DiagnosticInfo ReadDiagnosticInfo()
|
||||
{
|
||||
// check the nesting level for avoiding a stack overflow.
|
||||
if (m_nestingLevel > m_context.MaxEncodingNestingLevels)
|
||||
{
|
||||
throw ServiceResultException.Create(
|
||||
StatusCodes.BadEncodingLimitsExceeded,
|
||||
"Maximum nesting level of {0} was exceeded",
|
||||
m_context.MaxEncodingNestingLevels);
|
||||
}
|
||||
|
||||
m_nestingLevel++;
|
||||
|
||||
DiagnosticInfo value = new DiagnosticInfo();
|
||||
|
||||
if (BeginField("SymbolicId", true))
|
||||
@@ -1225,6 +1239,8 @@ namespace Opc.Ua
|
||||
EndField("InnerDiagnosticInfo");
|
||||
}
|
||||
|
||||
m_nestingLevel--;
|
||||
|
||||
return value;
|
||||
}
|
||||
|
||||
@@ -1321,6 +1337,17 @@ namespace Opc.Ua
|
||||
/// </summary>
|
||||
public Variant ReadVariant(string fieldName)
|
||||
{
|
||||
// check the nesting level for avoiding a stack overflow.
|
||||
if (m_nestingLevel > m_context.MaxEncodingNestingLevels)
|
||||
{
|
||||
throw ServiceResultException.Create(
|
||||
StatusCodes.BadEncodingLimitsExceeded,
|
||||
"Maximum nesting level of {0} was exceeded",
|
||||
m_context.MaxEncodingNestingLevels);
|
||||
}
|
||||
|
||||
m_nestingLevel++;
|
||||
|
||||
Variant value = new Variant();
|
||||
|
||||
if (BeginField(fieldName, true))
|
||||
@@ -1348,6 +1375,8 @@ namespace Opc.Ua
|
||||
EndField(fieldName);
|
||||
}
|
||||
|
||||
m_nestingLevel--;
|
||||
|
||||
return value;
|
||||
}
|
||||
|
||||
@@ -1443,6 +1472,17 @@ namespace Opc.Ua
|
||||
Utils.Format("Type does not support IEncodeable interface: '{0}'", systemType.FullName));
|
||||
}
|
||||
|
||||
// check the nesting level for avoiding a stack overflow.
|
||||
if (m_nestingLevel > m_context.MaxEncodingNestingLevels)
|
||||
{
|
||||
throw ServiceResultException.Create(
|
||||
StatusCodes.BadEncodingLimitsExceeded,
|
||||
"Maximum nesting level of {0} was exceeded",
|
||||
m_context.MaxEncodingNestingLevels);
|
||||
}
|
||||
|
||||
m_nestingLevel++;
|
||||
|
||||
if (BeginField(fieldName, true))
|
||||
{
|
||||
XmlQualifiedName xmlName = EncodeableFactory.GetXmlName(systemType);
|
||||
@@ -1466,10 +1506,12 @@ namespace Opc.Ua
|
||||
m_reader.Skip();
|
||||
m_reader.MoveToContent();
|
||||
}
|
||||
|
||||
|
||||
EndField(fieldName);
|
||||
}
|
||||
|
||||
|
||||
m_nestingLevel--;
|
||||
|
||||
return value;
|
||||
}
|
||||
|
||||
@@ -2742,6 +2784,7 @@ namespace Opc.Ua
|
||||
private ServiceMessageContext m_context;
|
||||
private ushort[] m_namespaceMappings;
|
||||
private ushort[] m_serverMappings;
|
||||
private uint m_nestingLevel;
|
||||
#endregion
|
||||
}
|
||||
}
|
||||
|
||||
@@ -35,6 +35,7 @@ namespace Opc.Ua
|
||||
|
||||
m_destination = new StringBuilder();
|
||||
m_context = context;
|
||||
m_nestingLevel = 0;
|
||||
|
||||
XmlWriterSettings settings = new XmlWriterSettings();
|
||||
settings.CheckCharacters = false;
|
||||
@@ -72,6 +73,7 @@ namespace Opc.Ua
|
||||
|
||||
Initialize(root.Name, root.Namespace);
|
||||
m_context = context;
|
||||
m_nestingLevel = 0;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@@ -612,10 +614,21 @@ namespace Opc.Ua
|
||||
/// </summary>
|
||||
public void WriteDiagnosticInfo(string fieldName, DiagnosticInfo value)
|
||||
{
|
||||
// check the nesting level for avoiding a stack overflow.
|
||||
if (m_nestingLevel > m_context.MaxEncodingNestingLevels)
|
||||
{
|
||||
throw ServiceResultException.Create(
|
||||
StatusCodes.BadEncodingLimitsExceeded,
|
||||
"Maximum nesting level of {0} was exceeded",
|
||||
m_context.MaxEncodingNestingLevels);
|
||||
}
|
||||
|
||||
m_nestingLevel++;
|
||||
|
||||
if (BeginField(fieldName, value == null, true))
|
||||
{
|
||||
PushNamespace(Namespaces.OpcUaXsd);
|
||||
|
||||
|
||||
if (value != null)
|
||||
{
|
||||
WriteInt32("SymbolicId", value.SymbolicId);
|
||||
@@ -628,9 +641,11 @@ namespace Opc.Ua
|
||||
}
|
||||
|
||||
PopNamespace();
|
||||
|
||||
|
||||
EndField(fieldName);
|
||||
}
|
||||
|
||||
m_nestingLevel--;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@@ -687,18 +702,31 @@ namespace Opc.Ua
|
||||
/// </summary>
|
||||
public void WriteVariant(string fieldName, Variant value)
|
||||
{
|
||||
// check the nesting level for avoiding a stack overflow.
|
||||
if (m_nestingLevel > m_context.MaxEncodingNestingLevels)
|
||||
{
|
||||
throw ServiceResultException.Create(
|
||||
StatusCodes.BadEncodingLimitsExceeded,
|
||||
"Maximum nesting level of {0} was exceeded",
|
||||
m_context.MaxEncodingNestingLevels);
|
||||
}
|
||||
|
||||
m_nestingLevel++;
|
||||
|
||||
if (BeginField(fieldName, false, false))
|
||||
{
|
||||
PushNamespace(Namespaces.OpcUaXsd);
|
||||
|
||||
m_writer.WriteStartElement("Value", Namespaces.OpcUaXsd);
|
||||
WriteVariantContents(value.Value, value.TypeInfo);
|
||||
|
||||
m_writer.WriteStartElement("Value", Namespaces.OpcUaXsd);
|
||||
WriteVariantContents(value.Value, value.TypeInfo);
|
||||
m_writer.WriteEndElement();
|
||||
|
||||
|
||||
PopNamespace();
|
||||
|
||||
|
||||
EndField(fieldName);
|
||||
}
|
||||
|
||||
m_nestingLevel--;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@@ -804,7 +832,18 @@ namespace Opc.Ua
|
||||
/// Writes an encodeable object to the stream.
|
||||
/// </summary>
|
||||
public void WriteEncodeable(string fieldName, IEncodeable value, System.Type systemType)
|
||||
{
|
||||
{
|
||||
// check the nesting level for avoiding a stack overflow.
|
||||
if (m_nestingLevel > m_context.MaxEncodingNestingLevels)
|
||||
{
|
||||
throw ServiceResultException.Create(
|
||||
StatusCodes.BadEncodingLimitsExceeded,
|
||||
"Maximum nesting level of {0} was exceeded",
|
||||
m_context.MaxEncodingNestingLevels);
|
||||
}
|
||||
|
||||
m_nestingLevel++;
|
||||
|
||||
if (BeginField(fieldName, value == null, true))
|
||||
{
|
||||
if (value != null)
|
||||
@@ -814,7 +853,9 @@ namespace Opc.Ua
|
||||
|
||||
EndField(fieldName);
|
||||
}
|
||||
}
|
||||
|
||||
m_nestingLevel--;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Writes an enumerated value array to the stream.
|
||||
@@ -1959,6 +2000,7 @@ namespace Opc.Ua
|
||||
private ServiceMessageContext m_context;
|
||||
private ushort[] m_namespaceMappings;
|
||||
private ushort[] m_serverMappings;
|
||||
private uint m_nestingLevel;
|
||||
#endregion
|
||||
}
|
||||
}
|
||||
|
||||
@@ -31,24 +31,26 @@ namespace Opc.Ua
|
||||
/// </summary>
|
||||
public ServiceMessageContext()
|
||||
{
|
||||
m_maxStringLength = UInt16.MaxValue;
|
||||
m_maxByteStringLength = UInt16.MaxValue*16;
|
||||
m_maxArrayLength = UInt16.MaxValue;
|
||||
m_maxMessageSize = UInt16.MaxValue*32;
|
||||
m_namespaceUris = new NamespaceTable();
|
||||
m_serverUris = new StringTable();
|
||||
m_factory = EncodeableFactory.GlobalFactory;
|
||||
m_maxStringLength = UInt16.MaxValue;
|
||||
m_maxByteStringLength = UInt16.MaxValue*16;
|
||||
m_maxArrayLength = UInt16.MaxValue;
|
||||
m_maxMessageSize = UInt16.MaxValue*32;
|
||||
m_namespaceUris = new NamespaceTable();
|
||||
m_serverUris = new StringTable();
|
||||
m_factory = EncodeableFactory.GlobalFactory;
|
||||
m_maxEncodingNestingLevels = 200;
|
||||
}
|
||||
|
||||
private ServiceMessageContext(bool shared) : this()
|
||||
{
|
||||
m_maxStringLength = UInt16.MaxValue;
|
||||
m_maxByteStringLength = UInt16.MaxValue*16;
|
||||
m_maxArrayLength = UInt16.MaxValue;
|
||||
m_maxMessageSize = UInt16.MaxValue*32;
|
||||
m_namespaceUris = new NamespaceTable(shared);
|
||||
m_serverUris = new StringTable(shared);
|
||||
m_factory = EncodeableFactory.GlobalFactory;
|
||||
m_maxStringLength = UInt16.MaxValue;
|
||||
m_maxByteStringLength = UInt16.MaxValue*16;
|
||||
m_maxArrayLength = UInt16.MaxValue;
|
||||
m_maxMessageSize = UInt16.MaxValue*32;
|
||||
m_namespaceUris = new NamespaceTable(shared);
|
||||
m_serverUris = new StringTable(shared);
|
||||
m_factory = EncodeableFactory.GlobalFactory;
|
||||
m_maxEncodingNestingLevels = 200;
|
||||
}
|
||||
#endregion
|
||||
|
||||
@@ -123,6 +125,14 @@ namespace Opc.Ua
|
||||
set { lock (m_lock) { m_maxMessageSize = value; } }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// The maximum nesting level accepted while encoding or decoding objects.
|
||||
/// </summary>
|
||||
public uint MaxEncodingNestingLevels
|
||||
{
|
||||
get { lock (m_lock) { return m_maxEncodingNestingLevels; } }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// The table of namespaces used by the server.
|
||||
/// </summary>
|
||||
@@ -205,6 +215,7 @@ namespace Opc.Ua
|
||||
private int m_maxByteStringLength;
|
||||
private int m_maxArrayLength;
|
||||
private int m_maxMessageSize;
|
||||
private uint m_maxEncodingNestingLevels;
|
||||
private NamespaceTable m_namespaceUris;
|
||||
private StringTable m_serverUris;
|
||||
private EncodeableFactory m_factory;
|
||||
|
||||
Reference in New Issue
Block a user