Files
ThingsGateway/framework/Foundation/ThingsGateway.Foundation.Adapter.OPCUA/Utils/JsonEncoder.cs
2023-09-30 23:05:53 +08:00

2050 lines
72 KiB
C#
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

#region copyright
//------------------------------------------------------------------------------
// 此代码版权声明为全文件覆盖,如有原作者特别声明,会在下方手动补充
// 此代码版权除特别声明外的代码归作者本人Diego所有
// 源代码使用协议遵循本仓库的开源协议及附加协议
// Gitee源代码仓库https://gitee.com/diego2098/ThingsGateway
// Github源代码仓库https://github.com/kimdiego2098/ThingsGateway
// 使用文档https://diego2098.gitee.io/thingsgateway-docs/
// QQ群605534569
//------------------------------------------------------------------------------
#endregion
using System.Globalization;
using System.IO;
using System.Text;
using System.Xml;
#pragma warning disable CS1591 // 缺少对公共可见类型或成员的 XML 注释
namespace Opc.Ua
{
public class OPCUAJsonEncoder : IJsonEncoder, IEncoder, IDisposable
{
private const int kStreamWriterBufferSize = 1024;
private Stream m_stream;
private MemoryStream m_memoryStream;
private StreamWriter m_writer;
private Stack<string> m_namespaces;
private bool m_commaRequired;
private bool m_inVariantWithEncoding;
private IServiceMessageContext m_context;
private ushort[] m_namespaceMappings;
private ushort[] m_serverMappings;
private uint m_nestingLevel;
private bool m_topLevelIsArray;
private bool m_levelOneSkipped;
private bool m_dontWriteClosing;
private bool m_leaveOpen;
private static readonly char[] m_specialChars = new char[7] { '"', '\\', '\n', '\r', '\t', '\b', '\f' };
private static readonly char[] m_substitution = new char[7] { '"', '\\', 'n', 'r', 't', 'b', 'f' };
public EncodingType EncodingType => EncodingType.Json;
public IServiceMessageContext Context => m_context;
public bool UseReversibleEncoding { get; private set; }
public bool ForceNamespaceUri { get; set; }
public bool ForceNamespaceUriForIndex1 { get; set; }
public bool IncludeDefaultValues { get; set; }
public bool IncludeDefaultNumberValues { get; set; }
public OPCUAJsonEncoder(IServiceMessageContext context, bool useReversibleEncoding)
: this(context, useReversibleEncoding, topLevelIsArray: false, null, leaveOpen: false, 1024)
{
}
public OPCUAJsonEncoder(IServiceMessageContext context, bool useReversibleEncoding, bool topLevelIsArray = false, Stream stream = null, bool leaveOpen = false, int streamSize = 1024)
{
Initialize();
m_context = context;
m_stream = stream;
m_leaveOpen = leaveOpen;
UseReversibleEncoding = useReversibleEncoding;
m_topLevelIsArray = topLevelIsArray;
if (m_stream == null)
{
m_memoryStream = new MemoryStream();
m_writer = new StreamWriter(m_memoryStream, new UTF8Encoding(encoderShouldEmitUTF8Identifier: false), streamSize, leaveOpen: false);
m_leaveOpen = false;
}
else
{
m_writer = new StreamWriter(m_stream, new UTF8Encoding(encoderShouldEmitUTF8Identifier: false), streamSize, m_leaveOpen);
}
InitializeWriter();
}
public OPCUAJsonEncoder(IServiceMessageContext context, bool useReversibleEncoding, StreamWriter writer, bool topLevelIsArray = false)
{
Initialize();
m_context = context;
m_writer = writer;
UseReversibleEncoding = useReversibleEncoding;
m_topLevelIsArray = topLevelIsArray;
if (m_writer == null)
{
m_stream = new MemoryStream();
m_writer = new StreamWriter(m_stream, new UTF8Encoding(encoderShouldEmitUTF8Identifier: false), 1024);
}
InitializeWriter();
}
private void Initialize()
{
m_stream = null;
m_writer = null;
m_namespaces = new Stack<string>();
m_commaRequired = false;
m_leaveOpen = false;
m_nestingLevel = 0u;
m_levelOneSkipped = false;
ForceNamespaceUri = false;
IncludeDefaultValues = false;
IncludeDefaultNumberValues = true;
}
private void InitializeWriter()
{
if (m_topLevelIsArray)
{
m_writer.Write("[");
}
else
{
m_writer.Write("{");
}
}
public static void EncodeSessionLessMessage(IEncodeable message, Stream stream, IServiceMessageContext context, bool leaveOpen)
{
if (message == null)
{
throw new ArgumentNullException("message");
}
if (context == null)
{
throw new ArgumentNullException("context");
}
OPCUAJsonEncoder jsonEncoder = new OPCUAJsonEncoder(context, useReversibleEncoding: true, topLevelIsArray: false, stream, leaveOpen);
try
{
long position = stream.Position;
SessionLessServiceMessage sessionLessServiceMessage = new SessionLessServiceMessage();
sessionLessServiceMessage.NamespaceUris = context.NamespaceUris;
sessionLessServiceMessage.ServerUris = context.ServerUris;
sessionLessServiceMessage.Message = message;
sessionLessServiceMessage.Encode(jsonEncoder);
if (context.MaxMessageSize > 0 && context.MaxMessageSize < (int)(stream.Position - position))
{
throw ServiceResultException.Create(2148007936u, "MaxMessageSize {0} < {1}", context.MaxMessageSize, (int)(stream.Position - position));
}
jsonEncoder.Close();
}
finally
{
if (leaveOpen)
{
stream.Position = 0L;
}
jsonEncoder.Dispose();
}
}
public static ArraySegment<byte> EncodeMessage(IEncodeable message, byte[] buffer, IServiceMessageContext context)
{
if (message == null)
{
throw new ArgumentNullException("message");
}
if (buffer == null)
{
throw new ArgumentNullException("buffer");
}
if (context == null)
{
throw new ArgumentNullException("context");
}
using MemoryStream stream = new MemoryStream(buffer, writable: true);
using OPCUAJsonEncoder jsonEncoder = new OPCUAJsonEncoder(context, useReversibleEncoding: true, topLevelIsArray: false, stream);
jsonEncoder.EncodeMessage(message);
int count = jsonEncoder.Close();
return new ArraySegment<byte>(buffer, 0, count);
}
public void EncodeMessage(IEncodeable message)
{
if (message == null)
{
throw new ArgumentNullException("message");
}
NodeId value = ExpandedNodeId.ToNodeId(message.TypeId, m_context.NamespaceUris);
WriteNodeId("TypeId", value);
WriteEncodeable("Body", message, message.GetType());
}
public void SetMappingTables(NamespaceTable namespaceUris, StringTable serverUris)
{
m_namespaceMappings = null;
if (namespaceUris != null && m_context.NamespaceUris != null)
{
m_namespaceMappings = namespaceUris.CreateMapping(m_context.NamespaceUris, updateTable: false);
}
m_serverMappings = null;
if (serverUris != null && m_context.ServerUris != null)
{
m_serverMappings = serverUris.CreateMapping(m_context.ServerUris, updateTable: false);
}
}
public string CloseAndReturnText()
{
Close();
if (m_memoryStream == null)
{
MemoryStream memoryStream = m_stream as MemoryStream;
if (memoryStream != null)
{
return Encoding.UTF8.GetString(memoryStream.ToArray());
}
throw new NotSupportedException("Cannot get text from external stream. Use Close or MemoryStream instead.");
}
return Encoding.UTF8.GetString(m_memoryStream.ToArray());
}
public int Close()
{
if (!m_dontWriteClosing)
{
if (m_topLevelIsArray)
{
m_writer.Write("]");
}
else
{
m_writer.Write("}");
}
}
m_writer.Flush();
int result = (int)m_writer.BaseStream.Position;
m_writer.Dispose();
m_writer = null;
return result;
}
public void Dispose()
{
Dispose(disposing: true);
GC.SuppressFinalize(this);
}
protected virtual void Dispose(bool disposing)
{
if (disposing)
{
if (m_writer != null)
{
Close();
}
if (!m_leaveOpen)
{
Utils.SilentDispose(m_memoryStream);
Utils.SilentDispose(m_stream);
m_memoryStream = null;
m_stream = null;
}
}
}
public void PushStructure(string fieldName)
{
m_nestingLevel++;
if (m_commaRequired)
{
m_writer.Write(",");
}
if (!string.IsNullOrEmpty(fieldName))
{
m_writer.Write("\"");
EscapeString(fieldName);
m_writer.Write("\":");
}
else if (!m_commaRequired && m_nestingLevel == 1 && !m_topLevelIsArray)
{
m_levelOneSkipped = true;
return;
}
m_commaRequired = false;
m_writer.Write("{");
}
public void PushArray(string fieldName)
{
m_nestingLevel++;
if (m_commaRequired)
{
m_writer.Write(",");
}
if (!string.IsNullOrEmpty(fieldName))
{
m_writer.Write("\"");
EscapeString(fieldName);
m_writer.Write("\":");
}
else if (!m_commaRequired && m_nestingLevel == 1 && !m_topLevelIsArray)
{
m_levelOneSkipped = true;
return;
}
m_commaRequired = false;
m_writer.Write("[");
}
public void PopStructure()
{
if (m_nestingLevel > 1 || m_topLevelIsArray || (m_nestingLevel == 1 && !m_levelOneSkipped))
{
m_writer.Write("}");
m_commaRequired = true;
}
m_nestingLevel--;
}
public void PopArray()
{
if (m_nestingLevel > 1 || m_topLevelIsArray || (m_nestingLevel == 1 && !m_levelOneSkipped))
{
m_writer.Write("]");
m_commaRequired = true;
}
m_nestingLevel--;
}
public void UsingReversibleEncoding<T>(Action<string, T> action, string fieldName, T value, bool useReversibleEncoding)
{
bool useReversibleEncoding2 = UseReversibleEncoding;
try
{
UseReversibleEncoding = useReversibleEncoding;
action(fieldName, value);
}
finally
{
UseReversibleEncoding = useReversibleEncoding2;
}
}
public void PushNamespace(string namespaceUri)
{
m_namespaces.Push(namespaceUri);
}
public void PopNamespace()
{
m_namespaces.Pop();
}
private void EscapeString(string value)
{
foreach (char c in value)
{
bool flag = false;
for (int j = 0; j < m_specialChars.Length; j++)
{
if (m_specialChars[j] == c)
{
m_writer.Write('\\');
m_writer.Write(m_substitution[j]);
flag = true;
break;
}
}
if (!flag)
{
if (c < ' ')
{
m_writer.Write("\\u");
m_writer.Write("{0:X4}", (int)c);
}
else
{
m_writer.Write(c);
}
}
}
}
private void WriteSimpleField(string fieldName, string value, bool quotes)
{
if (!string.IsNullOrEmpty(fieldName))
{
if (value == null)
{
return;
}
if (m_commaRequired)
{
m_writer.Write(",");
}
m_writer.Write("\"");
EscapeString(fieldName);
m_writer.Write("\":");
}
else if (m_commaRequired)
{
m_writer.Write(",");
}
if (value != null)
{
if (quotes)
{
m_writer.Write("\"");
EscapeString(value);
m_writer.Write("\"");
}
else
{
m_writer.Write(value);
}
}
else
{
m_writer.Write("null");
}
m_commaRequired = true;
}
public void WriteBoolean(string fieldName, bool value)
{
if (fieldName != null && !IncludeDefaultNumberValues && !value)
{
WriteSimpleField(fieldName, null, quotes: false);
}
else if (value)
{
WriteSimpleField(fieldName, "true", quotes: false);
}
else
{
WriteSimpleField(fieldName, "false", quotes: false);
}
}
public void WriteSByte(string fieldName, sbyte value)
{
if (fieldName != null && !IncludeDefaultNumberValues && value == 0)
{
WriteSimpleField(fieldName, null, quotes: false);
}
else
{
WriteSimpleField(fieldName, value.ToString(CultureInfo.InvariantCulture), quotes: false);
}
}
public void WriteByte(string fieldName, byte value)
{
if (fieldName != null && !IncludeDefaultNumberValues && value == 0)
{
WriteSimpleField(fieldName, null, quotes: false);
}
else
{
WriteSimpleField(fieldName, value.ToString(CultureInfo.InvariantCulture), quotes: false);
}
}
public void WriteInt16(string fieldName, short value)
{
if (fieldName != null && !IncludeDefaultNumberValues && value == 0)
{
WriteSimpleField(fieldName, null, quotes: false);
}
else
{
WriteSimpleField(fieldName, value.ToString(CultureInfo.InvariantCulture), quotes: false);
}
}
public void WriteUInt16(string fieldName, ushort value)
{
if (fieldName != null && !IncludeDefaultNumberValues && value == 0)
{
WriteSimpleField(fieldName, null, quotes: false);
}
else
{
WriteSimpleField(fieldName, value.ToString(CultureInfo.InvariantCulture), quotes: false);
}
}
public void WriteInt32(string fieldName, int value)
{
if (fieldName != null && !IncludeDefaultNumberValues && value == 0)
{
WriteSimpleField(fieldName, null, quotes: false);
}
else
{
WriteSimpleField(fieldName, value.ToString(CultureInfo.InvariantCulture), quotes: false);
}
}
public void WriteUInt32(string fieldName, uint value)
{
if (fieldName != null && !IncludeDefaultNumberValues && value == 0)
{
WriteSimpleField(fieldName, null, quotes: false);
}
else
{
WriteSimpleField(fieldName, value.ToString(CultureInfo.InvariantCulture), quotes: false);
}
}
public void WriteInt64(string fieldName, long value)
{
if (fieldName != null && !IncludeDefaultNumberValues && value == 0L)
{
WriteSimpleField(fieldName, null, quotes: false);
}
else
{
WriteSimpleField(fieldName, value.ToString(CultureInfo.InvariantCulture), quotes: true);
}
}
public void WriteUInt64(string fieldName, ulong value)
{
if (fieldName != null && !IncludeDefaultNumberValues && value == 0L)
{
WriteSimpleField(fieldName, null, quotes: false);
}
else
{
WriteSimpleField(fieldName, value.ToString(CultureInfo.InvariantCulture), quotes: true);
}
}
public void WriteFloat(string fieldName, float value)
{
if (fieldName != null && !IncludeDefaultNumberValues && value > -1.401298E-45f && value < float.Epsilon)
{
WriteSimpleField(fieldName, null, quotes: false);
}
else if (float.IsNaN(value))
{
WriteSimpleField(fieldName, "NaN", quotes: true);
}
else if (float.IsPositiveInfinity(value))
{
WriteSimpleField(fieldName, "Infinity", quotes: true);
}
else if (float.IsNegativeInfinity(value))
{
WriteSimpleField(fieldName, "-Infinity", quotes: true);
}
else
{
WriteSimpleField(fieldName, value.ToString("R", CultureInfo.InvariantCulture), quotes: false);
}
}
public void WriteDouble(string fieldName, double value)
{
if (fieldName != null && !IncludeDefaultNumberValues && value > -4.94065645841247E-324 && value < double.Epsilon)
{
WriteSimpleField(fieldName, null, quotes: false);
}
else if (double.IsNaN(value))
{
WriteSimpleField(fieldName, "NaN", quotes: true);
}
else if (double.IsPositiveInfinity(value))
{
WriteSimpleField(fieldName, "Infinity", quotes: true);
}
else if (double.IsNegativeInfinity(value))
{
WriteSimpleField(fieldName, "-Infinity", quotes: true);
}
else
{
WriteSimpleField(fieldName, value.ToString("R", CultureInfo.InvariantCulture), quotes: false);
}
}
public void WriteString(string fieldName, string value)
{
if (fieldName != null && !IncludeDefaultValues && value == null)
{
WriteSimpleField(fieldName, null, quotes: false);
}
else
{
WriteSimpleField(fieldName, value, quotes: true);
}
}
public void WriteDateTime(string fieldName, DateTime value)
{
if (fieldName != null && !IncludeDefaultValues && value == DateTime.MinValue)
{
WriteSimpleField(fieldName, null, quotes: false);
}
else if (value <= DateTime.MinValue)
{
WriteSimpleField(fieldName, "0001-01-01T00:00:00Z", quotes: true);
}
else if (value >= DateTime.MaxValue)
{
WriteSimpleField(fieldName, "9999-12-31T23:59:59Z", quotes: true);
}
else
{
WriteSimpleField(fieldName, value.ToUniversalTime().ToString("yyyy-MM-dd'T'HH:mm:ss.FFFFFFFK", CultureInfo.InvariantCulture), quotes: true);
}
}
public void WriteGuid(string fieldName, Uuid value)
{
if (fieldName != null && !IncludeDefaultValues && value == Uuid.Empty)
{
WriteSimpleField(fieldName, null, quotes: false);
}
else
{
WriteSimpleField(fieldName, value.ToString(), quotes: true);
}
}
public void WriteGuid(string fieldName, Guid value)
{
if (fieldName != null && !IncludeDefaultValues && value == Guid.Empty)
{
WriteSimpleField(fieldName, null, quotes: false);
}
else
{
WriteSimpleField(fieldName, value.ToString(), quotes: true);
}
}
public void WriteByteString(string fieldName, byte[] value)
{
if (value == null)
{
WriteSimpleField(fieldName, null, quotes: false);
return;
}
if (m_context.MaxByteStringLength > 0 && m_context.MaxByteStringLength < value.Length)
{
throw new ServiceResultException(2148007936u);
}
WriteSimpleField(fieldName, Convert.ToBase64String(value), quotes: true);
}
public void WriteXmlElement(string fieldName, XmlElement value)
{
if (value == null)
{
WriteSimpleField(fieldName, null, quotes: false);
return;
}
string outerXml = value.OuterXml;
byte[] bytes = Encoding.UTF8.GetBytes(outerXml);
WriteSimpleField(fieldName, Convert.ToBase64String(bytes), quotes: true);
}
private void WriteNamespaceIndex(string fieldName, ushort namespaceIndex)
{
if (namespaceIndex == 0)
{
return;
}
if ((!UseReversibleEncoding || ForceNamespaceUri) && namespaceIndex > ((!ForceNamespaceUriForIndex1) ? 1 : 0))
{
string @string = m_context.NamespaceUris.GetString(namespaceIndex);
if (!string.IsNullOrEmpty(@string))
{
WriteSimpleField(fieldName, @string, quotes: true);
return;
}
}
if (m_namespaceMappings != null && m_namespaceMappings.Length > namespaceIndex)
{
namespaceIndex = m_namespaceMappings[namespaceIndex];
}
if (namespaceIndex != 0)
{
WriteUInt16(fieldName, namespaceIndex);
}
}
private void WriteNodeIdContents(NodeId value, string namespaceUri = null)
{
if (value.IdType > IdType.Numeric)
{
WriteInt32("IdType", (int)value.IdType);
}
switch (value.IdType)
{
case IdType.Numeric:
WriteUInt32("Id", (uint)value.Identifier);
break;
case IdType.String:
WriteString("Id", (string)value.Identifier);
break;
case IdType.Guid:
WriteGuid("Id", (Guid)value.Identifier);
break;
case IdType.Opaque:
WriteByteString("Id", (byte[])value.Identifier);
break;
}
if (namespaceUri != null)
{
WriteString("Namespace", namespaceUri);
}
else
{
WriteNamespaceIndex("Namespace", value.NamespaceIndex);
}
}
public void WriteNodeId(string fieldName, NodeId value)
{
if (value == null || (NodeId.IsNull(value) && value.IdType == IdType.Numeric))
{
WriteSimpleField(fieldName, null, quotes: false);
return;
}
PushStructure(fieldName);
ushort namespaceIndex = value.NamespaceIndex;
if (ForceNamespaceUri && namespaceIndex > ((!ForceNamespaceUriForIndex1) ? 1 : 0))
{
string @string = Context.NamespaceUris.GetString(namespaceIndex);
WriteNodeIdContents(value, @string);
}
else
{
WriteNodeIdContents(value);
}
PopStructure();
}
public void WriteExpandedNodeId(string fieldName, ExpandedNodeId value)
{
var nodeid = (((NodeId)value));
if (value == null || nodeid == null || (!UseReversibleEncoding && NodeId.IsNull(value)))
{
WriteSimpleField(fieldName, null, quotes: false);
return;
}
PushStructure(fieldName);
string text = value.NamespaceUri;
ushort namespaceIndex = value.NamespaceIndex;
if (ForceNamespaceUri && text == null && namespaceIndex > ((!ForceNamespaceUriForIndex1) ? 1 : 0))
{
text = Context.NamespaceUris.GetString(namespaceIndex);
}
WriteNodeIdContents(nodeid, text);
uint num = value.ServerIndex;
if (num >= 1)
{
string @string = m_context.ServerUris.GetString(num);
if (!string.IsNullOrEmpty(@string))
{
WriteSimpleField("ServerUri", @string, quotes: true);
PopStructure();
return;
}
if (m_serverMappings != null && m_serverMappings.Length > num)
{
num = m_serverMappings[num];
}
if (num != 0)
{
WriteUInt32("ServerUri", num);
}
}
PopStructure();
}
public void WriteStatusCode(string fieldName, StatusCode value)
{
if (fieldName != null && !IncludeDefaultValues && value == 0u)
{
WriteSimpleField(fieldName, null, quotes: false);
}
else if (UseReversibleEncoding)
{
WriteUInt32(fieldName, value.Code);
}
else if (value != 0u)
{
PushStructure(fieldName);
WriteSimpleField("Code", value.Code.ToString(CultureInfo.InvariantCulture), quotes: false);
WriteSimpleField("Symbol", StatusCode.LookupSymbolicId(value.CodeBits), quotes: true);
PopStructure();
}
}
public void WriteDiagnosticInfo(string fieldName, DiagnosticInfo value)
{
WriteDiagnosticInfo(fieldName, value, 0);
}
public void WriteQualifiedName(string fieldName, QualifiedName value)
{
if (QualifiedName.IsNull(value))
{
WriteSimpleField(fieldName, null, quotes: false);
return;
}
PushStructure(fieldName);
WriteString("Name", value.Name);
WriteNamespaceIndex("Uri", value.NamespaceIndex);
PopStructure();
}
public void WriteLocalizedText(string fieldName, LocalizedText value)
{
if (LocalizedText.IsNullOrEmpty(value))
{
WriteSimpleField(fieldName, null, quotes: false);
}
else if (UseReversibleEncoding)
{
PushStructure(fieldName);
WriteSimpleField("Text", value.Text, quotes: true);
if (!string.IsNullOrEmpty(value.Locale))
{
WriteSimpleField("Locale", value.Locale, quotes: true);
}
PopStructure();
}
else
{
WriteSimpleField(fieldName, value.Text, quotes: true);
}
}
public void WriteVariant(string fieldName, Variant value)
{
if (Variant.Null == value)
{
WriteSimpleField(fieldName, null, quotes: false);
return;
}
CheckAndIncrementNestingLevel();
try
{
bool flag = value.TypeInfo == null || value.TypeInfo.BuiltInType == BuiltInType.Null || value.Value == null;
if (UseReversibleEncoding && !flag)
{
PushStructure(fieldName);
byte value2 = (byte)value.TypeInfo.BuiltInType;
if (value.TypeInfo.BuiltInType == BuiltInType.Enumeration)
{
value2 = 6;
}
WriteByte("Type", value2);
fieldName = "Body";
}
if (m_commaRequired)
{
m_writer.Write(",");
}
if (!string.IsNullOrEmpty(fieldName))
{
m_writer.Write("\"");
EscapeString(fieldName);
m_writer.Write("\":");
}
WriteVariantContents(value.Value, value.TypeInfo);
if (UseReversibleEncoding && !flag)
{
Matrix matrix = value.Value as Matrix;
if (matrix != null)
{
WriteInt32Array("Dimensions", matrix.Dimensions);
}
PopStructure();
}
}
finally
{
m_nestingLevel--;
}
}
public void WriteDataValue(string fieldName, DataValue value)
{
if (value == null)
{
WriteSimpleField(fieldName, null, quotes: false);
return;
}
PushStructure(fieldName);
if (value != null)
{
if (value.WrappedValue.TypeInfo != null && value.WrappedValue.TypeInfo.BuiltInType != 0)
{
WriteVariant("Value", value.WrappedValue);
}
if (value.StatusCode != 0u)
{
WriteStatusCode("StatusCode", value.StatusCode);
}
if (value.SourceTimestamp != DateTime.MinValue)
{
WriteDateTime("SourceTimestamp", value.SourceTimestamp);
if (value.SourcePicoseconds != 0)
{
WriteUInt16("SourcePicoseconds", value.SourcePicoseconds);
}
}
if (value.ServerTimestamp != DateTime.MinValue)
{
WriteDateTime("ServerTimestamp", value.ServerTimestamp);
if (value.ServerPicoseconds != 0)
{
WriteUInt16("ServerPicoseconds", value.ServerPicoseconds);
}
}
}
PopStructure();
}
public void WriteExtensionObject(string fieldName, ExtensionObject value)
{
if (value == null || value.Encoding == ExtensionObjectEncoding.None)
{
WriteSimpleField(fieldName, null, quotes: false);
return;
}
IEncodeable encodeable = value.Body as IEncodeable;
if (!UseReversibleEncoding && encodeable != null)
{
IStructureTypeInfo structureTypeInfo = value.Body as IStructureTypeInfo;
if (structureTypeInfo != null && structureTypeInfo.StructureType == StructureType.Union)
{
encodeable.Encode(this);
return;
}
PushStructure(fieldName);
encodeable.Encode(this);
PopStructure();
return;
}
PushStructure(fieldName);
ExpandedNodeId expandedNodeId = value.TypeId;
if (encodeable != null)
{
expandedNodeId = value.Encoding switch
{
ExtensionObjectEncoding.Binary => encodeable.BinaryEncodingId,
ExtensionObjectEncoding.Xml => encodeable.XmlEncodingId,
_ => encodeable.TypeId,
};
}
NodeId value2 = ExpandedNodeId.ToNodeId(expandedNodeId, Context.NamespaceUris);
if (UseReversibleEncoding)
{
WriteNodeId("TypeId", value2);
}
else
{
WriteExpandedNodeId("TypeId", expandedNodeId);
}
if (encodeable != null)
{
WriteEncodeable("Body", encodeable, null);
}
else if (value.Body != null)
{
if (value.Encoding == ExtensionObjectEncoding.Json)
{
WriteSimpleField("Body", value.Body as string, quotes: true);
}
else
{
WriteByte("Encoding", (byte)value.Encoding);
if (value.Encoding == ExtensionObjectEncoding.Binary)
{
WriteByteString("Body", value.Body as byte[]);
}
else if (value.Encoding == ExtensionObjectEncoding.Xml)
{
WriteXmlElement("Body", value.Body as XmlElement);
}
}
}
PopStructure();
}
public void WriteEncodeable(string fieldName, IEncodeable value, Type systemType)
{
if (value == null)
{
WriteSimpleField(fieldName, null, quotes: false);
return;
}
if (m_nestingLevel == 0 && (m_commaRequired || m_topLevelIsArray) && (string.IsNullOrWhiteSpace(fieldName) ^ m_topLevelIsArray))
{
throw ServiceResultException.Create(2147876864u, "With Array as top level, encodeables with fieldname will create invalid json");
}
if (m_nestingLevel == 0 && !m_commaRequired && string.IsNullOrWhiteSpace(fieldName) && !m_topLevelIsArray)
{
m_writer.Flush();
if (m_writer.BaseStream.Length == 1)
{
m_writer.BaseStream.Seek(0L, SeekOrigin.Begin);
}
m_dontWriteClosing = true;
}
CheckAndIncrementNestingLevel();
try
{
PushStructure(fieldName);
value?.Encode(this);
PopStructure();
}
finally
{
m_nestingLevel--;
}
}
public void WriteEnumerated(string fieldName, Enum value)
{
int num = Convert.ToInt32(value, CultureInfo.InvariantCulture);
string text = num.ToString();
if (UseReversibleEncoding)
{
WriteSimpleField(fieldName, text, quotes: false);
return;
}
if (value.ToString() == text)
{
WriteSimpleField(fieldName, text, quotes: true);
return;
}
WriteSimpleField(fieldName, Utils.Format("{0}_{1}", value.ToString(), num), quotes: true);
}
public void WriteEnumerated(string fieldName, int numeric)
{
string value = numeric.ToString(CultureInfo.InvariantCulture);
WriteSimpleField(fieldName, value, !UseReversibleEncoding);
}
public void WriteBooleanArray(string fieldName, IList<bool> values)
{
if (values == null)
{
WriteSimpleField(fieldName, null, quotes: false);
return;
}
PushArray(fieldName);
if (m_context.MaxArrayLength > 0 && m_context.MaxArrayLength < values.Count)
{
throw new ServiceResultException(2148007936u);
}
for (int i = 0; i < values.Count; i++)
{
WriteBoolean(null, values[i]);
}
PopArray();
}
public void WriteSByteArray(string fieldName, IList<sbyte> values)
{
if (values == null)
{
WriteSimpleField(fieldName, null, quotes: false);
return;
}
PushArray(fieldName);
if (m_context.MaxArrayLength > 0 && m_context.MaxArrayLength < values.Count)
{
throw new ServiceResultException(2148007936u);
}
for (int i = 0; i < values.Count; i++)
{
WriteSByte(null, values[i]);
}
PopArray();
}
public void WriteByteArray(string fieldName, IList<byte> values)
{
if (values == null)
{
WriteSimpleField(fieldName, null, quotes: false);
return;
}
PushArray(fieldName);
if (m_context.MaxArrayLength > 0 && m_context.MaxArrayLength < values.Count)
{
throw new ServiceResultException(2148007936u);
}
for (int i = 0; i < values.Count; i++)
{
WriteByte(null, values[i]);
}
PopArray();
}
public void WriteInt16Array(string fieldName, IList<short> values)
{
if (values == null)
{
WriteSimpleField(fieldName, null, quotes: false);
return;
}
PushArray(fieldName);
if (m_context.MaxArrayLength > 0 && m_context.MaxArrayLength < values.Count)
{
throw new ServiceResultException(2148007936u);
}
for (int i = 0; i < values.Count; i++)
{
WriteInt16(null, values[i]);
}
PopArray();
}
public void WriteUInt16Array(string fieldName, IList<ushort> values)
{
if (values == null)
{
WriteSimpleField(fieldName, null, quotes: false);
return;
}
PushArray(fieldName);
if (m_context.MaxArrayLength > 0 && m_context.MaxArrayLength < values.Count)
{
throw new ServiceResultException(2148007936u);
}
for (int i = 0; i < values.Count; i++)
{
WriteUInt16(null, values[i]);
}
PopArray();
}
public void WriteInt32Array(string fieldName, IList<int> values)
{
if (values == null)
{
WriteSimpleField(fieldName, null, quotes: false);
return;
}
PushArray(fieldName);
if (m_context.MaxArrayLength > 0 && m_context.MaxArrayLength < values.Count)
{
throw new ServiceResultException(2148007936u);
}
for (int i = 0; i < values.Count; i++)
{
WriteInt32(null, values[i]);
}
PopArray();
}
public void WriteUInt32Array(string fieldName, IList<uint> values)
{
if (values == null)
{
WriteSimpleField(fieldName, null, quotes: false);
return;
}
PushArray(fieldName);
if (m_context.MaxArrayLength > 0 && m_context.MaxArrayLength < values.Count)
{
throw new ServiceResultException(2148007936u);
}
for (int i = 0; i < values.Count; i++)
{
WriteUInt32(null, values[i]);
}
PopArray();
}
public void WriteInt64Array(string fieldName, IList<long> values)
{
if (values == null)
{
WriteSimpleField(fieldName, null, quotes: false);
return;
}
PushArray(fieldName);
if (m_context.MaxArrayLength > 0 && m_context.MaxArrayLength < values.Count)
{
throw new ServiceResultException(2148007936u);
}
for (int i = 0; i < values.Count; i++)
{
WriteInt64(null, values[i]);
}
PopArray();
}
public void WriteUInt64Array(string fieldName, IList<ulong> values)
{
if (values == null)
{
WriteSimpleField(fieldName, null, quotes: false);
return;
}
PushArray(fieldName);
if (m_context.MaxArrayLength > 0 && m_context.MaxArrayLength < values.Count)
{
throw new ServiceResultException(2148007936u);
}
for (int i = 0; i < values.Count; i++)
{
WriteUInt64(null, values[i]);
}
PopArray();
}
public void WriteFloatArray(string fieldName, IList<float> values)
{
if (values == null)
{
WriteSimpleField(fieldName, null, quotes: false);
return;
}
PushArray(fieldName);
if (m_context.MaxArrayLength > 0 && m_context.MaxArrayLength < values.Count)
{
throw new ServiceResultException(2148007936u);
}
for (int i = 0; i < values.Count; i++)
{
WriteFloat(null, values[i]);
}
PopArray();
}
public void WriteDoubleArray(string fieldName, IList<double> values)
{
if (values == null)
{
WriteSimpleField(fieldName, null, quotes: false);
return;
}
PushArray(fieldName);
if (m_context.MaxArrayLength > 0 && m_context.MaxArrayLength < values.Count)
{
throw new ServiceResultException(2148007936u);
}
for (int i = 0; i < values.Count; i++)
{
WriteDouble(null, values[i]);
}
PopArray();
}
public void WriteStringArray(string fieldName, IList<string> values)
{
if (values == null)
{
WriteSimpleField(fieldName, null, quotes: false);
return;
}
PushArray(fieldName);
if (m_context.MaxArrayLength > 0 && m_context.MaxArrayLength < values.Count)
{
throw new ServiceResultException(2148007936u);
}
for (int i = 0; i < values.Count; i++)
{
WriteString(null, values[i]);
}
PopArray();
}
public void WriteDateTimeArray(string fieldName, IList<DateTime> values)
{
if (values == null)
{
WriteSimpleField(fieldName, null, quotes: false);
return;
}
PushArray(fieldName);
if (m_context.MaxArrayLength > 0 && m_context.MaxArrayLength < values.Count)
{
throw new ServiceResultException(2148007936u);
}
for (int i = 0; i < values.Count; i++)
{
if (values[i] <= DateTime.MinValue)
{
WriteSimpleField(null, null, quotes: false);
}
else
{
WriteDateTime(null, values[i]);
}
}
PopArray();
}
public void WriteGuidArray(string fieldName, IList<Uuid> values)
{
if (values == null)
{
WriteSimpleField(fieldName, null, quotes: false);
return;
}
PushArray(fieldName);
if (m_context.MaxArrayLength > 0 && m_context.MaxArrayLength < values.Count)
{
throw new ServiceResultException(2148007936u);
}
for (int i = 0; i < values.Count; i++)
{
WriteGuid(null, values[i]);
}
PopArray();
}
public void WriteGuidArray(string fieldName, IList<Guid> values)
{
if (values == null)
{
WriteSimpleField(fieldName, null, quotes: false);
return;
}
PushArray(fieldName);
if (m_context.MaxArrayLength > 0 && m_context.MaxArrayLength < values.Count)
{
throw new ServiceResultException(2148007936u);
}
for (int i = 0; i < values.Count; i++)
{
WriteGuid(null, values[i]);
}
PopArray();
}
public void WriteByteStringArray(string fieldName, IList<byte[]> values)
{
if (values == null)
{
WriteSimpleField(fieldName, null, quotes: false);
return;
}
PushArray(fieldName);
if (m_context.MaxArrayLength > 0 && m_context.MaxArrayLength < values.Count)
{
throw new ServiceResultException(2148007936u);
}
for (int i = 0; i < values.Count; i++)
{
WriteByteString(null, values[i]);
}
PopArray();
}
public void WriteXmlElementArray(string fieldName, IList<XmlElement> values)
{
if (values == null)
{
WriteSimpleField(fieldName, null, quotes: false);
return;
}
PushArray(fieldName);
if (m_context.MaxArrayLength > 0 && m_context.MaxArrayLength < values.Count)
{
throw new ServiceResultException(2148007936u);
}
for (int i = 0; i < values.Count; i++)
{
WriteXmlElement(null, values[i]);
}
PopArray();
}
public void WriteNodeIdArray(string fieldName, IList<NodeId> values)
{
if (values == null)
{
WriteSimpleField(fieldName, null, quotes: false);
return;
}
PushArray(fieldName);
if (m_context.MaxArrayLength > 0 && m_context.MaxArrayLength < values.Count)
{
throw new ServiceResultException(2148007936u);
}
for (int i = 0; i < values.Count; i++)
{
WriteNodeId(null, values[i]);
}
PopArray();
}
public void WriteExpandedNodeIdArray(string fieldName, IList<ExpandedNodeId> values)
{
if (values == null)
{
WriteSimpleField(fieldName, null, quotes: false);
return;
}
PushArray(fieldName);
if (m_context.MaxArrayLength > 0 && m_context.MaxArrayLength < values.Count)
{
throw new ServiceResultException(2148007936u);
}
for (int i = 0; i < values.Count; i++)
{
WriteExpandedNodeId(null, values[i]);
}
PopArray();
}
public void WriteStatusCodeArray(string fieldName, IList<StatusCode> values)
{
if (values == null)
{
WriteSimpleField(fieldName, null, quotes: false);
return;
}
PushArray(fieldName);
if (m_context.MaxArrayLength > 0 && m_context.MaxArrayLength < values.Count)
{
throw new ServiceResultException(2148007936u);
}
for (int i = 0; i < values.Count; i++)
{
if (!UseReversibleEncoding && values[i] == 0u)
{
WriteSimpleField(null, null, quotes: false);
}
else
{
WriteStatusCode(null, values[i]);
}
}
PopArray();
}
public void WriteDiagnosticInfoArray(string fieldName, IList<DiagnosticInfo> values)
{
if (values == null)
{
WriteSimpleField(fieldName, null, quotes: false);
return;
}
PushArray(fieldName);
if (m_context.MaxArrayLength > 0 && m_context.MaxArrayLength < values.Count)
{
throw new ServiceResultException(2148007936u);
}
for (int i = 0; i < values.Count; i++)
{
WriteDiagnosticInfo(null, values[i]);
}
PopArray();
}
public void WriteQualifiedNameArray(string fieldName, IList<QualifiedName> values)
{
if (values == null)
{
WriteSimpleField(fieldName, null, quotes: false);
return;
}
PushArray(fieldName);
if (m_context.MaxArrayLength > 0 && m_context.MaxArrayLength < values.Count)
{
throw new ServiceResultException(2148007936u);
}
for (int i = 0; i < values.Count; i++)
{
WriteQualifiedName(null, values[i]);
}
PopArray();
}
public void WriteLocalizedTextArray(string fieldName, IList<LocalizedText> values)
{
if (values == null)
{
WriteSimpleField(fieldName, null, quotes: false);
return;
}
PushArray(fieldName);
if (m_context.MaxArrayLength > 0 && m_context.MaxArrayLength < values.Count)
{
throw new ServiceResultException(2148007936u);
}
for (int i = 0; i < values.Count; i++)
{
WriteLocalizedText(null, values[i]);
}
PopArray();
}
public void WriteVariantArray(string fieldName, IList<Variant> values)
{
if (values == null)
{
WriteSimpleField(fieldName, null, quotes: false);
return;
}
PushArray(fieldName);
if (m_context.MaxArrayLength > 0 && m_context.MaxArrayLength < values.Count)
{
throw new ServiceResultException(2148007936u);
}
for (int i = 0; i < values.Count; i++)
{
if (values[i] == Variant.Null)
{
WriteSimpleField(null, null, quotes: false);
}
else
{
WriteVariant(null, values[i]);
}
}
PopArray();
}
public void WriteDataValueArray(string fieldName, IList<DataValue> values)
{
if (values == null)
{
WriteSimpleField(fieldName, null, quotes: false);
return;
}
PushArray(fieldName);
if (m_context.MaxArrayLength > 0 && m_context.MaxArrayLength < values.Count)
{
throw new ServiceResultException(2148007936u);
}
for (int i = 0; i < values.Count; i++)
{
WriteDataValue(null, values[i]);
}
PopArray();
}
public void WriteExtensionObjectArray(string fieldName, IList<ExtensionObject> values)
{
if (values == null)
{
WriteSimpleField(fieldName, null, quotes: false);
return;
}
PushArray(fieldName);
if (m_context.MaxArrayLength > 0 && m_context.MaxArrayLength < values.Count)
{
throw new ServiceResultException(2148007936u);
}
for (int i = 0; i < values.Count; i++)
{
WriteExtensionObject(null, values[i]);
}
PopArray();
}
public void WriteEncodeableArray(string fieldName, IList<IEncodeable> values, Type systemType)
{
if (values == null)
{
WriteSimpleField(fieldName, null, quotes: false);
}
else if (string.IsNullOrWhiteSpace(fieldName) && m_nestingLevel == 0 && !m_topLevelIsArray)
{
m_writer.Flush();
if (m_writer.BaseStream.Length == 1)
{
m_writer.BaseStream.Seek(0L, SeekOrigin.Begin);
}
m_nestingLevel++;
PushArray(fieldName);
for (int i = 0; i < values.Count; i++)
{
WriteEncodeable(null, values[i], systemType);
}
PopArray();
m_dontWriteClosing = true;
m_nestingLevel--;
}
else
{
if (!string.IsNullOrWhiteSpace(fieldName) && m_nestingLevel == 0 && m_topLevelIsArray)
{
throw ServiceResultException.Create(2147876864u, "With Array as top level, encodeables array with filename will create invalid json");
}
PushArray(fieldName);
if (m_context.MaxArrayLength > 0 && m_context.MaxArrayLength < values.Count)
{
throw new ServiceResultException(2148007936u);
}
for (int j = 0; j < values.Count; j++)
{
WriteEncodeable(null, values[j], systemType);
}
PopArray();
}
}
public void WriteEnumeratedArray(string fieldName, Array values, Type systemType)
{
if (values == null || values.Length == 0)
{
WriteSimpleField(fieldName, null, quotes: false);
return;
}
PushArray(fieldName);
if (m_context.MaxArrayLength > 0 && m_context.MaxArrayLength < values.Length)
{
throw new ServiceResultException(2148007936u);
}
Type elementType = values.GetType().GetElementType();
if (elementType.IsEnum)
{
foreach (Enum value in values)
{
WriteEnumerated(null, value);
}
}
else
{
if (elementType != typeof(int))
{
throw new ServiceResultException(2147876864u, Utils.Format("Type '{0}' is not allowed in an Enumeration.", elementType.FullName));
}
foreach (int value2 in values)
{
WriteEnumerated(null, value2);
}
}
PopArray();
}
public void WriteVariantContents(object value, TypeInfo typeInfo)
{
try
{
m_inVariantWithEncoding = UseReversibleEncoding;
if (value == null)
{
return;
}
m_commaRequired = false;
if (typeInfo.ValueRank < 0)
{
switch (typeInfo.BuiltInType)
{
case BuiltInType.Boolean:
WriteBoolean(null, (bool)value);
break;
case BuiltInType.SByte:
WriteSByte(null, (sbyte)value);
break;
case BuiltInType.Byte:
WriteByte(null, (byte)value);
break;
case BuiltInType.Int16:
WriteInt16(null, (short)value);
break;
case BuiltInType.UInt16:
WriteUInt16(null, (ushort)value);
break;
case BuiltInType.Int32:
WriteInt32(null, (int)value);
break;
case BuiltInType.UInt32:
WriteUInt32(null, (uint)value);
break;
case BuiltInType.Int64:
WriteInt64(null, (long)value);
break;
case BuiltInType.UInt64:
WriteUInt64(null, (ulong)value);
break;
case BuiltInType.Float:
WriteFloat(null, (float)value);
break;
case BuiltInType.Double:
WriteDouble(null, (double)value);
break;
case BuiltInType.String:
WriteString(null, (string)value);
break;
case BuiltInType.DateTime:
WriteDateTime(null, (DateTime)value);
break;
case BuiltInType.Guid:
WriteGuid(null, (Uuid)value);
break;
case BuiltInType.ByteString:
WriteByteString(null, (byte[])value);
break;
case BuiltInType.XmlElement:
WriteXmlElement(null, (XmlElement)value);
break;
case BuiltInType.NodeId:
WriteNodeId(null, (NodeId)value);
break;
case BuiltInType.ExpandedNodeId:
WriteExpandedNodeId(null, (ExpandedNodeId)value);
break;
case BuiltInType.StatusCode:
WriteStatusCode(null, (StatusCode)value);
break;
case BuiltInType.QualifiedName:
WriteQualifiedName(null, (QualifiedName)value);
break;
case BuiltInType.LocalizedText:
WriteLocalizedText(null, (LocalizedText)value);
break;
case BuiltInType.ExtensionObject:
WriteExtensionObject(null, (ExtensionObject)value);
break;
case BuiltInType.DataValue:
WriteDataValue(null, (DataValue)value);
break;
case BuiltInType.Enumeration:
WriteEnumerated(null, (Enum)value);
break;
case BuiltInType.DiagnosticInfo:
WriteDiagnosticInfo(null, (DiagnosticInfo)value);
break;
case BuiltInType.Variant:
case BuiltInType.Number:
case BuiltInType.Integer:
case BuiltInType.UInteger:
break;
}
}
else
{
if (typeInfo.ValueRank < 1)
{
return;
}
int valueRank = typeInfo.ValueRank;
if (UseReversibleEncoding)
{
Matrix matrix = value as Matrix;
if (matrix != null)
{
value = matrix.Elements;
valueRank = 1;
}
}
WriteArray(null, value, valueRank, typeInfo.BuiltInType);
return;
}
}
finally
{
m_inVariantWithEncoding = false;
}
}
public void WriteObjectArray(string fieldName, IList<object> values)
{
if (values == null)
{
WriteSimpleField(fieldName, null, quotes: false);
return;
}
PushArray(fieldName);
if (values != null && m_context.MaxArrayLength > 0 && m_context.MaxArrayLength < values.Count)
{
throw new ServiceResultException(2148007936u);
}
if (values != null)
{
for (int i = 0; i < values.Count; i++)
{
WriteVariant("Variant", new Variant(values[i]));
}
}
PopArray();
}
public void WriteArray(string fieldName, object array, int valueRank, BuiltInType builtInType)
{
if (valueRank == 1)
{
switch (builtInType)
{
case BuiltInType.Boolean:
WriteBooleanArray(fieldName, (bool[])array);
break;
case BuiltInType.SByte:
WriteSByteArray(fieldName, (sbyte[])array);
break;
case BuiltInType.Byte:
WriteByteArray(fieldName, (byte[])array);
break;
case BuiltInType.Int16:
WriteInt16Array(fieldName, (short[])array);
break;
case BuiltInType.UInt16:
WriteUInt16Array(fieldName, (ushort[])array);
break;
case BuiltInType.Int32:
WriteInt32Array(fieldName, (int[])array);
break;
case BuiltInType.UInt32:
WriteUInt32Array(fieldName, (uint[])array);
break;
case BuiltInType.Int64:
WriteInt64Array(fieldName, (long[])array);
break;
case BuiltInType.UInt64:
WriteUInt64Array(fieldName, (ulong[])array);
break;
case BuiltInType.Float:
WriteFloatArray(fieldName, (float[])array);
break;
case BuiltInType.Double:
WriteDoubleArray(fieldName, (double[])array);
break;
case BuiltInType.String:
WriteStringArray(fieldName, (string[])array);
break;
case BuiltInType.DateTime:
WriteDateTimeArray(fieldName, (DateTime[])array);
break;
case BuiltInType.Guid:
WriteGuidArray(fieldName, (Uuid[])array);
break;
case BuiltInType.ByteString:
WriteByteStringArray(fieldName, (byte[][])array);
break;
case BuiltInType.XmlElement:
WriteXmlElementArray(fieldName, (XmlElement[])array);
break;
case BuiltInType.NodeId:
WriteNodeIdArray(fieldName, (NodeId[])array);
break;
case BuiltInType.ExpandedNodeId:
WriteExpandedNodeIdArray(fieldName, (ExpandedNodeId[])array);
break;
case BuiltInType.StatusCode:
WriteStatusCodeArray(fieldName, (StatusCode[])array);
break;
case BuiltInType.QualifiedName:
WriteQualifiedNameArray(fieldName, (QualifiedName[])array);
break;
case BuiltInType.LocalizedText:
WriteLocalizedTextArray(fieldName, (LocalizedText[])array);
break;
case BuiltInType.ExtensionObject:
WriteExtensionObjectArray(fieldName, (ExtensionObject[])array);
break;
case BuiltInType.DataValue:
WriteDataValueArray(fieldName, (DataValue[])array);
break;
case BuiltInType.DiagnosticInfo:
WriteDiagnosticInfoArray(fieldName, (DiagnosticInfo[])array);
break;
case BuiltInType.Enumeration:
{
Array array6 = array as Array;
if (array6 == null)
{
throw ServiceResultException.Create(2147876864u, "Unexpected non Array type encountered while encoding an array of enumeration.");
}
WriteEnumeratedArray(fieldName, array6, array6.GetType().GetElementType());
break;
}
case BuiltInType.Variant:
{
Variant[] array3 = array as Variant[];
if (array3 != null)
{
WriteVariantArray(fieldName, array3);
break;
}
IEncodeable[] array4 = array as IEncodeable[];
if (array4 != null)
{
WriteEncodeableArray(fieldName, array4, array.GetType().GetElementType());
break;
}
object[] array5 = array as object[];
if (array5 != null)
{
WriteObjectArray(fieldName, array5);
break;
}
throw ServiceResultException.Create(2147876864u, "Unexpected type encountered while encoding an array of Variants: {0}", array.GetType());
}
default:
{
IEncodeable[] array2 = array as IEncodeable[];
if (array2 != null)
{
WriteEncodeableArray(fieldName, array2, array.GetType().GetElementType());
break;
}
if (array == null)
{
WriteSimpleField(fieldName, null, quotes: false);
break;
}
throw ServiceResultException.Create(2147876864u, "Unexpected BuiltInType encountered while encoding an array: {0}", builtInType);
}
}
}
else
{
if (valueRank <= 1)
{
return;
}
Matrix matrix = array as Matrix;
if (matrix == null)
{
Array array7 = array as Array;
if (array7 == null || array7.Rank != valueRank)
{
throw ServiceResultException.Create(2147876864u, "Unexpected array type encountered while encoding array: {0}", array.GetType().Name);
}
matrix = new Matrix(array7, builtInType);
}
if (matrix != null)
{
int index = 0;
WriteStructureMatrix(fieldName, matrix, 0, ref index, matrix.TypeInfo);
}
}
}
private void WriteDiagnosticInfo(string fieldName, DiagnosticInfo value, int depth)
{
if (value == null || value.IsNullDiagnosticInfo)
{
WriteSimpleField(fieldName, null, quotes: false);
return;
}
CheckAndIncrementNestingLevel();
try
{
PushStructure(fieldName);
if (value.SymbolicId >= 0)
{
WriteSimpleField("SymbolicId", value.SymbolicId.ToString(CultureInfo.InvariantCulture), quotes: false);
}
if (value.NamespaceUri >= 0)
{
WriteSimpleField("NamespaceUri", value.NamespaceUri.ToString(CultureInfo.InvariantCulture), quotes: false);
}
if (value.Locale >= 0)
{
WriteSimpleField("Locale", value.Locale.ToString(CultureInfo.InvariantCulture), quotes: false);
}
if (value.LocalizedText >= 0)
{
WriteSimpleField("LocalizedText", value.LocalizedText.ToString(CultureInfo.InvariantCulture), quotes: false);
}
if (value.AdditionalInfo != null)
{
WriteSimpleField("AdditionalInfo", value.AdditionalInfo, quotes: true);
}
if (value.InnerStatusCode != 0u)
{
WriteStatusCode("InnerStatusCode", value.InnerStatusCode);
}
if (value.InnerDiagnosticInfo != null)
{
if (depth < DiagnosticInfo.MaxInnerDepth)
{
WriteDiagnosticInfo("InnerDiagnosticInfo", value.InnerDiagnosticInfo, depth + 1);
}
else
{
Utils.LogWarning("InnerDiagnosticInfo dropped because nesting exceeds maximum of {0}.", DiagnosticInfo.MaxInnerDepth);
}
}
PopStructure();
}
finally
{
m_nestingLevel--;
}
}
private void WriteStructureMatrix(string fieldName, Matrix matrix, int dim, ref int index, TypeInfo typeInfo)
{
var (flag, num) = Matrix.ValidateDimensions(allowZeroDimension: true, matrix.Dimensions, Context.MaxArrayLength);
if (!flag || num != matrix.Elements.Length)
{
throw new ArgumentException("The number of elements in the matrix does not match the dimensions.");
}
CheckAndIncrementNestingLevel();
try
{
int num2 = matrix.Dimensions[dim];
if (dim == matrix.Dimensions.Length - 1)
{
Array array = Array.CreateInstance(matrix.Elements.GetType().GetElementType(), num2);
Array.Copy(matrix.Elements, index, array, 0, num2);
if (m_commaRequired)
{
m_writer.Write(",");
}
WriteVariantContents(array, new TypeInfo(typeInfo.BuiltInType, 1));
index += num2;
}
else
{
PushArray(fieldName);
for (int i = 0; i < num2; i++)
{
WriteStructureMatrix(null, matrix, dim + 1, ref index, typeInfo);
}
PopArray();
}
}
finally
{
m_nestingLevel--;
}
}
private void CheckAndIncrementNestingLevel()
{
if (m_nestingLevel > m_context.MaxEncodingNestingLevels)
{
throw ServiceResultException.Create(2148007936u, "Maximum nesting level of {0} was exceeded", m_context.MaxEncodingNestingLevels);
}
m_nestingLevel++;
}
}
}