/// <summary> /// Saves object in an binary stream. /// </summary> /// <param name="context">The context user.</param> /// <param name="encoder">The encoder to write to.</param> /// <param name="attributesToSave">The masks indicating what attributes to write.</param> public override void Save(ISystemContext context, BinaryEncoder encoder, AttributesToSave attributesToSave) { base.Save(context, encoder, attributesToSave); if ((attributesToSave & AttributesToSave.Executable) != 0) { encoder.WriteBoolean(null, m_executable); } if ((attributesToSave & AttributesToSave.UserExecutable) != 0) { encoder.WriteBoolean(null, m_userExecutable); } }
public async Task <int> RespondAsync(GenericContext rpcContext, CancellationToken token) { using (var responseData = new FrameStream()) using (var encoder = new BinaryEncoder(responseData)) { if (DoHandshake()) { HANDSHAKE_RESPONSE_WRITER.Write(encoder, rpcContext.HandshakeResponse); _handshakePending = rpcContext.HandshakeResponse.match == HandshakeMatch.BOTH; } META_WRITER.Write(encoder, EMPTY_META); encoder.WriteBoolean(rpcContext.IsError); if (rpcContext.IsError) { _protocol.WriteError(encoder, rpcContext.MessageName, rpcContext.Error); } else { _protocol.WriteReponse(encoder, rpcContext.MessageName, rpcContext.Response); } encoder.WriteBytes(END_OF_FRAME); responseData.Seek(0, SeekOrigin.Begin); return(await _tranceiver.SendAsync(responseData, token)); } }
/// <summary> /// Perform event to message binary encoding /// </summary> /// <param name="messages"></param> /// <returns></returns> private IEnumerable <NetworkMessageModel> EncodeAsUadp( IEnumerable <DataSetMessageModel> messages) { var notifications = GetMonitoredItemMessages(messages, MessageEncoding.Uadp); if (notifications.Count() == 0) { yield break; } var encodingContext = messages.First().ServiceMessageContext; foreach (var networkMessage in notifications) { var encoder = new BinaryEncoder(encodingContext); encoder.WriteBoolean(null, false); // is not Batch encoder.WriteEncodeable(null, networkMessage); var encoded = new NetworkMessageModel { Body = encoder.CloseAndReturnBuffer(), Timestamp = DateTime.UtcNow, ContentType = ContentMimeType.UaBinary, MessageSchema = MessageSchemaTypes.MonitoredItemMessageBinary }; yield return(encoded); } }
public void EncodeBoolean(bool value, int expectedLength, byte[] expectedValue) { using (var stream = new MemoryStream()) using (var encoder = new BinaryEncoder(stream)) { encoder.WriteBoolean(value); Assert.AreEqual(expectedLength, stream.Position, "Encode offset error"); Assert.AreEqual(expectedValue, stream.GetBuffer().AsSpan(0, expectedLength).ToArray()); } }
public void TestBoolean(bool expected) { using (var stream = new MemoryStream()) using (var encoder = new BinaryEncoder(stream)) using (var decoder = new BinaryDecoder(stream)) { encoder.WriteBoolean(expected); stream.Seek(0, SeekOrigin.Begin); var actual = decoder.ReadBoolean(); Assert.AreEqual(expected, actual); } }
/// <summary> /// Perform DataSetMessageModel to batch NetworkMessageModel using binary encoding /// </summary> /// <param name="messages"></param> /// <param name="maxEncodedSize"></param> /// <returns></returns> private IEnumerable <NetworkMessageModel> EncodeBatchAsUadp( IEnumerable <DataSetMessageModel> messages, int maxEncodedSize) { var notifications = GetMonitoredItemMessages(messages, MessageEncoding.Uadp); if (notifications.Count() == 0) { yield break; } // take the message context of the first element since is the same for all messages var encodingContext = messages.First().ServiceMessageContext; var current = notifications.GetEnumerator(); var processing = current.MoveNext(); var messageSize = 4; // array length size maxEncodedSize -= 2048; // reserve 2k for header var chunk = new Collection <MonitoredItemMessage>(); while (processing) { var notification = current.Current; var messageCompleted = false; if (notification != null) { var helperEncoder = new BinaryEncoder(encodingContext); helperEncoder.WriteEncodeable(null, notification); var notificationSize = helperEncoder.CloseAndReturnBuffer().Length; messageCompleted = maxEncodedSize < (messageSize + notificationSize); if (!messageCompleted) { chunk.Add(notification); processing = current.MoveNext(); messageSize += notificationSize; } } if (!processing || messageCompleted) { var encoder = new BinaryEncoder(encodingContext); encoder.WriteBoolean(null, true); // is Batch encoder.WriteEncodeableArray(null, chunk); chunk.Clear(); messageSize = 4; var encoded = new NetworkMessageModel { Body = encoder.CloseAndReturnBuffer(), Timestamp = DateTime.UtcNow, ContentType = ContentMimeType.UaBinary, MessageSchema = MessageSchemaTypes.MonitoredItemMessageBinary }; yield return(encoded); } } }
/// <summary> /// Saves object in an binary stream. /// </summary> /// <param name="context">The context user.</param> /// <param name="encoder">The encoder to write to.</param> /// <param name="attributesToSave">The masks indicating what attributes to write.</param> public override void Save(ISystemContext context, BinaryEncoder encoder, AttributesToSave attributesToSave) { base.Save(context, encoder, attributesToSave); if ((attributesToSave & AttributesToSave.SuperTypeId) != 0) { encoder.WriteNodeId(null, m_superTypeId); } if ((attributesToSave & AttributesToSave.IsAbstract) != 0) { encoder.WriteBoolean(null, m_isAbstract); } }
/// <summary> /// Saves object in an binary stream. /// </summary> /// <param name="context">The context user.</param> /// <param name="encoder">The encoder to write to.</param> /// <param name="attributesToSave">The masks indicating what attributes to write.</param> public override void Save(ISystemContext context, BinaryEncoder encoder, AttributesToSave attributesToSave) { base.Save(context, encoder, attributesToSave); if ((attributesToSave & AttributesToSave.EventNotifier) != 0) { encoder.WriteByte(null, m_eventNotifier); } if ((attributesToSave & AttributesToSave.ContainsNoLoops) != 0) { encoder.WriteBoolean(null, m_containsNoLoops); } }
/// <summary> /// Saves object in an binary stream. /// </summary> /// <param name="context">The context user.</param> /// <param name="encoder">The encoder to write to.</param> /// <param name="attributesToSave">The masks indicating what attributes to write.</param> public override void Save(ISystemContext context, BinaryEncoder encoder, AttributesToSave attributesToSave) { base.Save(context, encoder, attributesToSave); if ((attributesToSave & AttributesToSave.InverseName) != 0) { encoder.WriteLocalizedText(null, m_inverseName); } if ((attributesToSave & AttributesToSave.Symmetric) != 0) { encoder.WriteBoolean(null, m_symmetric); } }
/// <summary> /// Perform uadp encoding /// </summary> /// <param name="messages"></param> /// <param name="maxMessageSize"></param> /// <returns></returns> private IEnumerable <NetworkMessageModel> EncodeAsUadp( IEnumerable <DataSetMessageModel> messages, int maxMessageSize) { // by design all messages are generated in the same session context, // therefore it is safe to get the first message's context var encodingContext = messages.FirstOrDefault(m => m.ServiceMessageContext != null) ?.ServiceMessageContext; var notifications = GetNetworkMessages(messages, MessageEncoding.Uadp, encodingContext); if (!notifications.Any()) { yield break; } var routingInfo = messages.FirstOrDefault(m => m?.WriterGroup != null)?.WriterGroup.WriterGroupId; foreach (var networkMessage in notifications) { int notificationsPerMessage = networkMessage.Messages.Sum(m => m.Payload.Count); var encoder = new BinaryEncoder(encodingContext); encoder.WriteBoolean(null, false); // is not Batch encoder.WriteEncodeable(null, networkMessage); networkMessage.Encode(encoder); var encoded = new NetworkMessageModel { Body = encoder.CloseAndReturnBuffer(), Timestamp = DateTime.UtcNow, ContentType = ContentMimeType.Uadp, MessageSchema = MessageSchemaTypes.NetworkMessageUadp, RoutingInfo = _enableRoutingInfo ? routingInfo : null, }; if (encoded.Body.Length > maxMessageSize) { // Message too large, drop it. NotificationsDroppedCount += (uint)notificationsPerMessage; _logger.Warning("Message too large, dropped {notificationsPerMessage} values", notificationsPerMessage); continue; } NotificationsProcessedCount += (uint)notificationsPerMessage; AvgMessageSize = (AvgMessageSize * MessagesProcessedCount + encoded.Body.Length) / (MessagesProcessedCount + 1); AvgNotificationsPerMessage = (AvgNotificationsPerMessage * MessagesProcessedCount + notificationsPerMessage) / (MessagesProcessedCount + 1); MessagesProcessedCount++; yield return(encoded); } }
/// <summary> /// Perform uadp encoding /// </summary> /// <param name="messages"></param> /// <param name="maxMessageSize"></param> /// <returns></returns> private IEnumerable <NetworkMessageModel> EncodeAsUadp( IEnumerable <DataSetMessageModel> messages, int maxMessageSize) { // by design all messages are generated in the same session context, // therefore it is safe to get the first message's context var encodingContext = messages.FirstOrDefault(m => m.ServiceMessageContext != null) ?.ServiceMessageContext; var notifications = GetNetworkMessages(messages, MessageEncoding.Uadp, encodingContext); if (notifications.Count() == 0) { yield break; } foreach (var networkMessage in notifications) { ulong notificationsPerMessage = (ulong)networkMessage.Messages.Sum(m => m.Payload.Count); var encoder = new BinaryEncoder(encodingContext); encoder.WriteBoolean(null, false); // is not Batch encoder.WriteEncodeable(null, networkMessage); networkMessage.Encode(encoder); var encoded = new NetworkMessageModel { Body = encoder.CloseAndReturnBuffer(), Timestamp = DateTime.UtcNow, ContentType = ContentMimeType.Uadp, MessageSchema = MessageSchemaTypes.NetworkMessageUadp }; if (encoded.Body.Length > maxMessageSize) { // this message is too large to be processed. Drop it // TODO Trace NotificationsDroppedCount++; yield break; } NotificationsProcessedCount++; AvgMessageSize = (AvgMessageSize * MessagesProcessedCount + encoded.Body.Length) / (MessagesProcessedCount + 1); AvgNotificationsPerMessage = (AvgNotificationsPerMessage * MessagesProcessedCount + notificationsPerMessage) / (MessagesProcessedCount + 1); MessagesProcessedCount++; yield return(encoded); } }
/// <summary> /// DataSetMessage to NetworkMessage binary batched encoding /// </summary> /// <param name="messages"></param> /// <param name="maxMessageSize"></param> /// <returns></returns> private IEnumerable <NetworkMessageModel> EncodeBatchAsUadp( IEnumerable <DataSetMessageModel> messages, int maxMessageSize) { // by design all messages are generated in the same session context, // therefore it is safe to get the first message's context var encodingContext = messages.FirstOrDefault(m => m.ServiceMessageContext != null) ?.ServiceMessageContext; var notifications = GetNetworkMessages(messages, MessageEncoding.Uadp, encodingContext); if (notifications.Count() == 0) { yield break; } var current = notifications.GetEnumerator(); var processing = current.MoveNext(); var messageSize = 4; // array length size var chunk = new Collection <NetworkMessage>(); int notificationsPerMessage = 0; while (processing) { var notification = current.Current; var messageCompleted = false; if (notification != null) { var helperEncoder = new BinaryEncoder(encodingContext); helperEncoder.WriteEncodeable(null, notification); var notificationSize = helperEncoder.CloseAndReturnBuffer().Length; notificationsPerMessage = notification.Messages.Sum(m => m.Payload.Count); if (notificationSize > maxMessageSize) { // Message too large, drop it. NotificationsDroppedCount += (uint)notificationsPerMessage; _logger.Warning("Message too large, dropped {notificationsPerMessage} values"); processing = current.MoveNext(); } else { messageCompleted = maxMessageSize < (messageSize + notificationSize); if (!messageCompleted) { chunk.Add(notification); NotificationsProcessedCount += (ulong)notificationsPerMessage; processing = current.MoveNext(); messageSize += notificationSize; } } } if (!processing || messageCompleted) { var encoder = new BinaryEncoder(encodingContext); encoder.WriteBoolean(null, true); // is Batch encoder.WriteEncodeableArray(null, chunk); var encoded = new NetworkMessageModel { Body = encoder.CloseAndReturnBuffer(), Timestamp = DateTime.UtcNow, ContentType = ContentMimeType.Uadp, MessageSchema = MessageSchemaTypes.NetworkMessageUadp }; AvgMessageSize = (AvgMessageSize * MessagesProcessedCount + encoded.Body.Length) / (MessagesProcessedCount + 1); AvgNotificationsPerMessage = (AvgNotificationsPerMessage * MessagesProcessedCount + notificationsPerMessage) / (MessagesProcessedCount + 1); MessagesProcessedCount++; chunk.Clear(); messageSize = 4; notificationsPerMessage = 0; yield return(encoded); } } }
/// <summary> /// Encodes field value as RawData /// </summary> /// <param name="binaryEncoder"></param> /// <param name="field"></param> private void EncodeFieldAsRawData(BinaryEncoder binaryEncoder, Field field) { try { // 01 RawData Field Encoding var variant = field.Value.WrappedValue; if (variant.TypeInfo == null || variant.TypeInfo.BuiltInType == BuiltInType.Null) { return; } object valueToEncode = variant.Value; if (field.FieldMetaData.ValueRank == ValueRanks.Scalar) { switch ((BuiltInType)field.FieldMetaData.BuiltInType) { case BuiltInType.Boolean: binaryEncoder.WriteBoolean("Bool", Convert.ToBoolean(valueToEncode)); break; case BuiltInType.SByte: binaryEncoder.WriteSByte("SByte", Convert.ToSByte(valueToEncode)); break; case BuiltInType.Byte: binaryEncoder.WriteByte("Byte", Convert.ToByte(valueToEncode)); break; case BuiltInType.Int16: binaryEncoder.WriteInt16("Int16", Convert.ToInt16(valueToEncode)); break; case BuiltInType.UInt16: binaryEncoder.WriteUInt16("UInt16", Convert.ToUInt16(valueToEncode)); break; case BuiltInType.Int32: binaryEncoder.WriteInt32("Int32", Convert.ToInt32(valueToEncode)); break; case BuiltInType.UInt32: binaryEncoder.WriteUInt32("UInt32", Convert.ToUInt32(valueToEncode)); break; case BuiltInType.Int64: binaryEncoder.WriteInt64("Int64", Convert.ToInt64(valueToEncode)); break; case BuiltInType.UInt64: binaryEncoder.WriteUInt64("UInt64", Convert.ToUInt64(valueToEncode)); break; case BuiltInType.Float: binaryEncoder.WriteFloat("Float", Convert.ToSingle(valueToEncode)); break; case BuiltInType.Double: binaryEncoder.WriteDouble("Double", Convert.ToDouble(valueToEncode)); break; case BuiltInType.DateTime: binaryEncoder.WriteDateTime("DateTime", Convert.ToDateTime(valueToEncode)); break; case BuiltInType.Guid: binaryEncoder.WriteGuid("GUID", (Uuid)valueToEncode); break; case BuiltInType.String: binaryEncoder.WriteString("String", valueToEncode as string); break; case BuiltInType.ByteString: binaryEncoder.WriteByteString("ByteString", (byte[])valueToEncode); break; case BuiltInType.QualifiedName: binaryEncoder.WriteQualifiedName("QualifiedName", valueToEncode as QualifiedName); break; case BuiltInType.LocalizedText: binaryEncoder.WriteLocalizedText("LocalizedText", valueToEncode as LocalizedText); break; case BuiltInType.NodeId: binaryEncoder.WriteNodeId("NodeId", valueToEncode as NodeId); break; case BuiltInType.ExpandedNodeId: binaryEncoder.WriteExpandedNodeId("ExpandedNodeId", valueToEncode as ExpandedNodeId); break; case BuiltInType.StatusCode: binaryEncoder.WriteStatusCode("StatusCode", (StatusCode)valueToEncode); break; case BuiltInType.XmlElement: binaryEncoder.WriteXmlElement("XmlElement", valueToEncode as XmlElement); break; case BuiltInType.Enumeration: binaryEncoder.WriteInt32("Enumeration", Convert.ToInt32(valueToEncode)); break; case BuiltInType.ExtensionObject: binaryEncoder.WriteExtensionObject("ExtensionObject", valueToEncode as ExtensionObject); break; } } else if (field.FieldMetaData.ValueRank >= ValueRanks.OneDimension) { binaryEncoder.WriteArray(null, valueToEncode, field.FieldMetaData.ValueRank, (BuiltInType)field.FieldMetaData.BuiltInType); } } catch (Exception ex) { Utils.Trace(ex, "Error encoding field {0}.", field.FieldMetaData.Name); } }
/// <summary> /// DataSetMessage to NetworkMessage binary batched encoding /// </summary> /// <param name="messages"></param> /// <param name="maxMessageSize"></param> /// <returns></returns> private IEnumerable <NetworkMessageModel> EncodeBatchAsUadp( IEnumerable <DataSetMessageModel> messages, int maxMessageSize) { var notifications = GetNetworkMessages(messages, MessageEncoding.Uadp); if (notifications.Count() == 0) { yield break; } // by design all messages are generated in the same session context, // therefore it is safe to get the first message's context var encodingContext = messages.First().ServiceMessageContext; var current = notifications.GetEnumerator(); var processing = current.MoveNext(); var messageSize = 4; // array length size maxMessageSize -= 2048; // reserve 2k for header var chunk = new Collection <NetworkMessage>(); while (processing) { var notification = current.Current; var messageCompleted = false; if (notification != null) { var helperEncoder = new BinaryEncoder(encodingContext); helperEncoder.WriteEncodeable(null, notification); var notificationSize = helperEncoder.CloseAndReturnBuffer().Length; if (notificationSize > maxMessageSize) { // we cannot handle this notification. Drop it. // TODO Trace NotificationsDroppedCount++; processing = current.MoveNext(); } else { messageCompleted = maxMessageSize < (messageSize + notificationSize); if (!messageCompleted) { chunk.Add(notification); NotificationsProcessedCount++; processing = current.MoveNext(); messageSize += notificationSize; } } } if (!processing || messageCompleted) { var encoder = new BinaryEncoder(encodingContext); encoder.WriteBoolean(null, true); // is Batch encoder.WriteEncodeableArray(null, chunk); var encoded = new NetworkMessageModel { Body = encoder.CloseAndReturnBuffer(), Timestamp = DateTime.UtcNow, ContentType = ContentMimeType.Uadp, MessageSchema = MessageSchemaTypes.NetworkMessageUadp }; AvgMessageSize = (AvgMessageSize * MessagesProcessedCount + encoded.Body.Length) / (MessagesProcessedCount + 1); AvgNotificationsPerMessage = (AvgNotificationsPerMessage * MessagesProcessedCount + chunk.Count) / (MessagesProcessedCount + 1); MessagesProcessedCount++; chunk.Clear(); messageSize = 4; yield return(encoded); } } }
public IList <MemoryStream> Respond(IList <MemoryStream> buffers, Transceiver connection) { Decoder input = new BinaryDecoder(new ByteBufferInputStream(buffers)); var bbo = new ByteBufferOutputStream(); var output = new BinaryEncoder(bbo); Exception error = null; var context = new RpcContext(); List <MemoryStream> handshake = null; bool wasConnected = connection != null && connection.IsConnected; try { Protocol remote = Handshake(input, output, connection); output.Flush(); if (remote == null) // handshake failed { return(bbo.GetBufferList()); } handshake = bbo.GetBufferList(); // read request using remote protocol specification context.RequestCallMeta = META_READER.Read(null, input); String messageName = input.ReadString(); if (messageName.Equals("")) // a handshake ping { return(handshake); } Message rm = remote.Messages[messageName]; if (rm == null) { throw new AvroRuntimeException("No such remote message: " + messageName); } Message m = Local.Messages[messageName]; if (m == null) { throw new AvroRuntimeException("No message named " + messageName + " in " + Local); } Object request = ReadRequest(rm.Request, m.Request, input); context.Message = rm; // create response using local protocol specification if ((m.Oneway.GetValueOrDefault() != rm.Oneway.GetValueOrDefault()) && wasConnected) { throw new AvroRuntimeException("Not both one-way: " + messageName); } Object response = null; try { response = Respond(m, request); context.Response = response; } catch (Exception e) { error = e; context.Error = error; log.Warn("user error", e); } if (m.Oneway.GetValueOrDefault() && wasConnected) // no response data { return(null); } output.WriteBoolean(error != null); if (error == null) { WriteResponse(m.Response, response, output); } else { try { WriteError(m.SupportedErrors, error, output); } catch (Exception) { // Presumably no match on the exception, throw the original throw error; } } } catch (Exception e) { // system error log.Warn("system error", e); context.Error = e; bbo = new ByteBufferOutputStream(); output = new BinaryEncoder(bbo); output.WriteBoolean(true); WriteError(errorSchema /*Protocol.SYSTEM_ERRORS*/, e.ToString(), output); if (null == handshake) { handshake = new ByteBufferOutputStream().GetBufferList(); } } output.Flush(); List <MemoryStream> payload = bbo.GetBufferList(); // Grab meta-data from plugins context.ResponsePayload = payload; META_WRITER.Write(context.ResponseCallMeta, output); output.Flush(); // Prepend handshake and append payload bbo.Prepend(handshake); bbo.Append(payload); return(bbo.GetBufferList()); }
/// <summary> /// Encodes field value as RawData /// </summary> /// <param name="binaryEncoder"></param> /// <param name="field"></param> private void EncodeFieldAsRawData(BinaryEncoder binaryEncoder, Field field) { try { // 01 RawData Field Encoding (TODO: StructuredValue) var variant = field.Value.WrappedValue; if (variant.TypeInfo == null || variant.TypeInfo.BuiltInType == BuiltInType.Null) { return; } if (field.FieldMetaData.ValueRank == ValueRanks.Scalar) { switch ((BuiltInType)field.FieldMetaData.BuiltInType) { case BuiltInType.Boolean: binaryEncoder.WriteBoolean("Bool", Convert.ToBoolean(variant.Value)); break; case BuiltInType.SByte: binaryEncoder.WriteSByte("SByte", Convert.ToSByte(variant.Value)); break; case BuiltInType.Byte: binaryEncoder.WriteByte("Byte", Convert.ToByte(variant.Value)); break; case BuiltInType.Int16: binaryEncoder.WriteInt16("Int16", Convert.ToInt16(variant.Value)); break; case BuiltInType.UInt16: binaryEncoder.WriteUInt16("UInt16", Convert.ToUInt16(variant.Value)); break; case BuiltInType.Int32: binaryEncoder.WriteInt32("Int32", Convert.ToInt32(variant.Value)); break; case BuiltInType.UInt32: binaryEncoder.WriteUInt32("UInt32", Convert.ToUInt32(variant.Value)); break; case BuiltInType.Int64: binaryEncoder.WriteInt64("Int64", Convert.ToInt64(variant.Value)); break; case BuiltInType.UInt64: binaryEncoder.WriteUInt64("UInt64", Convert.ToUInt64(variant.Value)); break; case BuiltInType.Float: binaryEncoder.WriteFloat("Float", Convert.ToSingle(variant.Value)); break; case BuiltInType.Double: binaryEncoder.WriteDouble("Double", Convert.ToDouble(variant.Value)); break; case BuiltInType.DateTime: binaryEncoder.WriteDateTime("DateTime", Convert.ToDateTime(variant.Value)); break; case BuiltInType.Guid: binaryEncoder.WriteGuid("GUID", (Uuid)variant.Value); break; case BuiltInType.String: binaryEncoder.WriteString("String", variant.Value as string); break; case BuiltInType.ByteString: binaryEncoder.WriteByteString("ByteString", (byte[])variant.Value); break; case BuiltInType.QualifiedName: binaryEncoder.WriteQualifiedName("QualifiedName", variant.Value as QualifiedName); break; case BuiltInType.LocalizedText: binaryEncoder.WriteLocalizedText("LocalizedText", variant.Value as LocalizedText); break; case BuiltInType.NodeId: binaryEncoder.WriteNodeId("NodeId", variant.Value as NodeId); break; case BuiltInType.ExpandedNodeId: binaryEncoder.WriteExpandedNodeId("ExpandedNodeId", variant.Value as ExpandedNodeId); break; case BuiltInType.StatusCode: binaryEncoder.WriteStatusCode("StatusCode", (StatusCode)variant.Value); break; case BuiltInType.XmlElement: binaryEncoder.WriteXmlElement("XmlElement", variant.Value as XmlElement); break; case BuiltInType.Enumeration: binaryEncoder.WriteInt32("Enumeration", Convert.ToInt32(variant.Value)); break; case BuiltInType.ExtensionObject: binaryEncoder.WriteExtensionObject("ExtensionObject", variant.Value as ExtensionObject); break; } } else { switch ((BuiltInType)field.FieldMetaData.BuiltInType) { case BuiltInType.Boolean: binaryEncoder.WriteBooleanArray("BooleanArray", (bool[])variant.Value); break; case BuiltInType.SByte: binaryEncoder.WriteSByteArray("SByteArray", (sbyte[])variant.Value); break; case BuiltInType.Byte: binaryEncoder.WriteByteArray("ByteArray", (byte[])variant.Value); break; case BuiltInType.Int16: binaryEncoder.WriteInt16Array("ByteArray", (short[])variant.Value); break; case BuiltInType.UInt16: binaryEncoder.WriteUInt16Array("UInt16Array", (ushort[])variant.Value); break; case BuiltInType.Int32: binaryEncoder.WriteInt32Array("Int32Array", (int[])variant.Value); break; case BuiltInType.UInt32: binaryEncoder.WriteUInt32Array("UInt32Array", (uint[])variant.Value); break; case BuiltInType.Int64: binaryEncoder.WriteInt64Array("Int64Array", (long[])variant.Value); break; case BuiltInType.UInt64: binaryEncoder.WriteUInt64Array("UInt64Array", (ulong[])variant.Value); break; case BuiltInType.Float: binaryEncoder.WriteFloatArray("FloatArray", (float[])variant.Value); break; case BuiltInType.Double: binaryEncoder.WriteDoubleArray("DoubleArray", (double[])variant.Value); break; case BuiltInType.DateTime: binaryEncoder.WriteDateTimeArray("DateTimeArray", (DateTime[])variant.Value); break; case BuiltInType.Guid: binaryEncoder.WriteGuidArray("GuidArray", (Uuid[])variant.Value); break; case BuiltInType.String: binaryEncoder.WriteStringArray("StringArray", (string[])variant.Value); break; case BuiltInType.ByteString: binaryEncoder.WriteByteStringArray("StringArray", (byte[][])variant.Value); break; case BuiltInType.QualifiedName: binaryEncoder.WriteQualifiedNameArray("QualifiedNameArray", (QualifiedName[])variant.Value); break; case BuiltInType.LocalizedText: binaryEncoder.WriteLocalizedTextArray("LocalizedTextArray", (LocalizedText[])variant.Value); break; case BuiltInType.NodeId: binaryEncoder.WriteNodeIdArray("NodeIdArray", (NodeId[])variant.Value); break; case BuiltInType.ExpandedNodeId: binaryEncoder.WriteExpandedNodeIdArray("ExpandedNodeIdArray", (ExpandedNodeId[])variant.Value); break; case BuiltInType.StatusCode: binaryEncoder.WriteStatusCodeArray("StatusCodeArray", (StatusCode[])variant.Value); break; case BuiltInType.XmlElement: binaryEncoder.WriteXmlElementArray("XmlElementArray", (System.Xml.XmlElement[])variant.Value); break; case BuiltInType.Variant: binaryEncoder.WriteVariantArray("VariantArray", (Variant[])variant.Value); break; case BuiltInType.Enumeration: //TODO make this work //binaryEncoder.WriteInt32Array("EnumerationArray", Convert.ToInt32(variant.Value)); binaryEncoder.WriteVariantArray("EnumerationArray", (Variant[])variant.Value); break; case BuiltInType.ExtensionObject: binaryEncoder.WriteExtensionObjectArray("ExtensionObjectArray", (ExtensionObject[])variant.Value); break; } } } catch (Exception ex) { Utils.Trace("Error encoding field {0} - {1}", field.FieldMetaData.Name, ex); } }