Create() публичный статический Метод

Merges 2 packets together
public static Create ( DataPacket remaining, DataPacket newPacket ) : DataPacket
remaining DataPacket
newPacket DataPacket
Результат DataPacket
        /// <summary>
        /// Clone this packet, creating an exact copy.
        /// As the clone function is an implementation of IClonable it must return an object.
        /// </summary>
        /// <returns></returns>
        public object Clone()
        {
            DataPacket p = DataPacket.Create(Data);

            p.Sender      = this.Sender;
            p.Destination = this.Destination;
            return(p);
        }
        /// <summary>
        /// Skips a given size from the data block
        /// </summary>
        /// <param name="size"></param>
        public DataPacket SkipSize(UInt32 size)
        {
            DataPacket p = DataPacket.Create(Data.Length - (int)size);

            p.Sender      = this.Sender;
            p.Destination = this.Destination;
            Buffer.BlockCopy(this.Data, (int)size, p.Data, 0, p.Data.Length);
            return(p);
        }
        internal virtual void Disconnect()
        {
            if (Disposed)
            {
                return;
            }
            if (ioc != null)
            {
                ioc.RemoveChannel(this);
            }
            lock (ConnectionLock)
            {
                if (Status != ChannelStatus.CONNECTED)
                {
                    return;
                }
                Status          = ChannelStatus.DISCONNECTED;
                StartSearchTime = DateTime.Now;
                ioc             = null;
                SID             = 0;

                if (PrivMonitorChanged != null)
                {
                    AfterConnect(action =>
                    {
                        if (MonitoredType == null)
                        {
                            return;
                        }
                        DataPacket p = DataPacket.Create(16 + 16);
                        p.Command    = (ushort)CommandID.CA_PROTO_EVENT_ADD;
                        p.DataType   = (ushort)TypeHandling.Lookup[MonitoredType];
                        p.DataCount  = ChannelDataCount;
                        p.Parameter1 = SID;
                        p.Parameter2 = CID;

                        p.SetUInt16(12 + 16, (ushort)MonitorMask);

                        if (ioc != null)
                        {
                            ioc.Send(p);
                        }
                        else
                        {
                            Disconnect();
                        }
                    });
                }
            }
        }
        internal EpicsChannel(EpicsClient client, string channelName)
        {
            this.ChannelName = channelName;
            this.Status      = ChannelStatus.REQUESTED;
            this.Client      = client;
            MonitorMask      = MonitorMask.VALUE;
            HasValue         = false;

            SearchPacket            = DataPacket.Create(16 + ChannelName.Length + TypeHandling.Padding(ChannelName.Length));
            SearchPacket.Command    = (ushort)CommandID.CA_PROTO_SEARCH;
            SearchPacket.DataType   = (ushort)EpicsConstants.DONT_REPLY;
            SearchPacket.DataCount  = (ushort)EpicsConstants.CA_MINOR_PROTOCOL_REVISION;
            SearchPacket.Parameter1 = cid;
            SearchPacket.Parameter2 = cid;
            SearchPacket.SetDataAsString(ChannelName);
        }
        internal void SendReadNotify <TType>(uint nbElements)
        {
            if (Client.Configuration.DebugTiming)
            {
                lock (ElapsedTimings)
                {
                    if (!ElapsedTimings.ContainsKey("SendReadNotify"))
                    {
                        ElapsedTimings.Add("SendReadNotify", Stopwatch.Elapsed);
                    }
                }
            }

            DataPacket packet = DataPacket.Create(16);

            packet.Command = (ushort)CommandID.CA_PROTO_READ_NOTIFY;
            Type t = typeof(TType);

            if (typeof(TType).IsArray)
            {
                t = (typeof(TType)).GetElementType();
            }
            else if (t.IsGenericType)
            {
                if (t.GetGenericArguments().First() == typeof(object))
                {
                    t = t.GetGenericTypeDefinition().MakeGenericType(new Type[] { channelDefinedType });
                }
            }
            if (t == typeof(object))
            {
                t = channelDefinedType;
            }
            packet.DataType   = (ushort)TypeHandling.Lookup[t];
            packet.DataCount  = nbElements;
            packet.Parameter1 = SID;
            uint ioid = (NextIoId++);

            packet.Parameter2 = ioid;

            lock (ioc.PendingIo)
            {
                ioc.PendingIo.Add(ioid, this);
            }

            ioc.Send(packet);
        }
        void SendMonitor(EpicsChannel action)
        {
            if (ChannelDataCount == 0)
            {
                return;
            }

            //Console.WriteLine("Sending new event add");
            DataPacket p = DataPacket.Create(16 + 16);

            p.Command = (ushort)CommandID.CA_PROTO_EVENT_ADD;
            Type t = typeof(TType);

            if (t.IsArray)
            {
                t = t.GetElementType();
            }
            else if (t.IsGenericType)
            {
                if (t.GetGenericArguments().First() == typeof(object))
                {
                    t = t.GetGenericTypeDefinition().MakeGenericType(new Type[] { channelDefinedType });
                }
            }
            p.DataType   = (ushort)TypeHandling.Lookup[t];
            p.DataCount  = ChannelDataCount;
            p.Parameter1 = SID;
            p.Parameter2 = CID;

            p.SetUInt16(12 + 16, (ushort)MonitorMask);

            if (ioc != null)
            {
                ioc.Send(p);
            }
        }
        internal void SetIoc(DataPipe pipe)
        {
            TcpReceiver tcpReceiver = (TcpReceiver)pipe[0];

            tcpReceiver.AddChannel(this);
            lock (ConnectionLock)
            {
                if (!Client.Searcher.Contains(this))
                {
                    return;
                }
                Client.Searcher.Remove(this);
                SID = 0;

                ioc = tcpReceiver;
                lock (ioc.ChannelSID)
                {
                    //Console.WriteLine(ioc.ChannelSID.Count);
                    // Channel already known
                    if (ioc.ChannelSID.ContainsKey(ChannelName))
                    {
                        SID = ioc.ChannelSID[ChannelName];
                        //Console.WriteLine("Here");
                        EpicsChannel chan = ioc.ConnectedChannels.FirstOrDefault(row => row.ChannelName == ChannelName && row.ChannelDataCount != 0);
                        if (chan != null)
                        {
                            this.ChannelDataCount   = chan.ChannelDataCount;
                            this.channelDefinedType = chan.channelDefinedType;
                            this.ChannelDataCount   = chan.ChannelDataCount;
                            this.channelDefinedType = chan.ChannelDefinedType;
                            Status = ChannelStatus.CONNECTED;
                            ConnectionEvent.Set();
                        }
                    }
                }
            }
            if (SID != 0)
            {
                //Console.WriteLine("SID " + SID + " STATUS CHANGED");
                if (StatusChanged != null)
                {
                    StatusChanged(this, Status);
                }
                return;
            }
            if (Client.Configuration.DebugTiming)
            {
                lock (ElapsedTimings)
                {
                    if (!ElapsedTimings.ContainsKey("IocConnection"))
                    {
                        ElapsedTimings.Add("IocConnection", Stopwatch.Elapsed);
                    }
                }
            }

            // We need to create the channel
            int padding;

            if (ChannelName.Length % 8 == 0)
            {
                padding = 8;
            }
            else
            {
                padding = (8 - (ChannelName.Length % 8));
            }

            DataPacket packet = DataPacket.Create(16 + ChannelName.Length + padding);

            packet.Command    = (ushort)CommandID.CA_PROTO_CREATE_CHAN;
            packet.DataType   = 0;
            packet.DataCount  = 0;
            packet.Parameter1 = cid;
            packet.Parameter2 = (uint)EpicsConstants.CA_MINOR_PROTOCOL_REVISION;
            packet.SetDataAsString(ChannelName);

            if (ioc != null)
            {
                ioc.Send(packet);
            }
            else
            {
                Disconnect();
                return;
            }
            lock (ElapsedTimings)
            {
                if (!ElapsedTimings.ContainsKey("SendCreateChannel"))
                {
                    ElapsedTimings.Add("SendCreateChannel", Stopwatch.Elapsed);
                }
            }
        }
        protected DataPacket WritePacket <TType>(TType newValue)
        {
            int  headerSize = 16;
            uint nbElem     = 1;

            if (newValue is IEnumerable <object> )
            {
                nbElem = (uint)((IEnumerable <object>)newValue).Count();
            }
            Type t = typeof(TType);

            if (t.IsArray)
            {
                nbElem = (uint)((Array)((object)newValue)).Length;
                // if too many array elements, use extended header
                if (nbElem > 0xffff)
                {
                    headerSize = 24;
                }
                t = t.GetElementType();
            }
            else if (t.IsGenericType)
            {
                if (t.GetGenericArguments().First() == typeof(object))
                {
                    t = t.GetGenericTypeDefinition().MakeGenericType(new Type[] { channelDefinedType });
                }
            }
            if (t == typeof(object))
            {
                t = channelDefinedType;
            }

            int payloadSize = (int)(nbElem * TypeHandling.EpicsSize(t));

            if (payloadSize % 8 > 0)
            {
                payloadSize += 8 - (payloadSize % 8);
            }
            // if payload too large, use extended header
            if (payloadSize > 0x4000)
            {
                headerSize = 24;
            }
            DataPacket packet = DataPacket.Create(headerSize + payloadSize);

            packet.Command    = (ushort)CommandID.CA_PROTO_WRITE_NOTIFY;
            packet.DataCount  = nbElem;
            packet.DataType   = (ushort)TypeHandling.Lookup[t];
            packet.Parameter1 = SID;
            uint ioid = (NextIoId++);

            packet.Parameter2 = ioid;

            if (nbElem > 1)
            {
                int pos         = headerSize;
                int elementSize = TypeHandling.EpicsSize(t);
                foreach (var elem in (System.Collections.IEnumerable)newValue)
                {
                    switch (TypeHandling.Lookup[t])
                    {
                    case EpicsType.Int:
                        packet.SetInt32(pos, (int)elem);
                        break;

                    case EpicsType.Short:
                        packet.SetInt16(pos, (short)elem);
                        break;

                    case EpicsType.Float:
                        packet.SetFloat(pos, (float)elem);
                        break;

                    case EpicsType.Double:
                        packet.SetDouble(pos, (double)elem);
                        break;

                    case EpicsType.Byte:
                        packet.SetByte(pos, (byte)elem);
                        break;

                    default:
                        throw new Exception("Type not supported");
                    }
                    pos += elementSize;
                }
            }
            else
            {
                switch (TypeHandling.Lookup[t])
                {
                case EpicsType.Int:
                    packet.SetInt32((int)packet.HeaderSize, (int)(object)newValue);
                    break;

                case EpicsType.Short:
                    packet.SetInt16((int)packet.HeaderSize, (short)(object)newValue);
                    break;

                case EpicsType.Float:
                    packet.SetFloat((int)packet.HeaderSize, (float)(object)newValue);
                    break;

                case EpicsType.Double:
                    packet.SetDouble((int)packet.HeaderSize, (double)(object)newValue);
                    break;

                case EpicsType.String:
                    packet.SetDataAsString((string)(object)newValue);
                    break;

                case EpicsType.Byte:
                    packet.SetByte((int)packet.HeaderSize, (byte)(object)newValue);
                    break;

                default:
                    throw new Exception("Type not currently supported.");
                }
            }

            return(packet);
        }