예제 #1
0
        internal override void Decode(Channel channel, uint nbElements)
        {
            Status   = (AlarmStatus)channel.DecodeData <ushort>(1, 0);
            Severity = (AlarmSeverity)channel.DecodeData <ushort>(1, 2);
            int  pos = 4;
            Type t   = typeof(TType);

            if (t.IsArray)
            {
                t = t.GetElementType();
            }
            if (t == typeof(object))
            {
                t = channel.ChannelDefinedType;
            }
            if (
                t == typeof(double) ||
                t == typeof(float)
                )
            {
                Precision = channel.DecodeData <short>(1, pos);
                pos      += 4; // 2 for precision field + 2 padding for "RISC alignment"
            }
            if (t != typeof(string))
            {
                EGU  = channel.DecodeData <string>(1, pos, 8);
                pos += 8;
                int tSize = TypeHandling.EpicsSize(t);

                // HighDisplayLimit = channel.DecodeData<TType>(1, pos) ;
                HighDisplayLimit = Convert.ToDouble(channel.DecodeData(t, 1, pos));
                pos += tSize;
                // LowDisplayLimit = channel.DecodeData<TType>(1, pos) ;
                LowDisplayLimit = Convert.ToDouble(channel.DecodeData(t, 1, pos));
                pos            += tSize;
                // HighAlertLimit = channel.DecodeData<TType>(1, pos) ;
                HighAlertLimit = Convert.ToDouble(channel.DecodeData(t, 1, pos));
                pos           += tSize;
                // HighWarnLimit = channel.DecodeData<TType>(1, pos) ;
                HighWarnLimit = Convert.ToDouble(channel.DecodeData(t, 1, pos));
                pos          += tSize;
                // LowWarnLimit = channel.DecodeData<TType>(1, pos) ;
                LowWarnLimit = Convert.ToDouble(channel.DecodeData(t, 1, pos));
                pos         += tSize;
                // LowAlertLimit = channel.DecodeData<TType>(1, pos) ;
                LowAlertLimit = Convert.ToDouble(channel.DecodeData(t, 1, pos));
                pos          += tSize;
            }
            else
            {
                EGU = "";
            }
            if (t == typeof(byte))
            {
                pos++; // 1 padding for "RISC alignment"
            }
            Value = channel.DecodeData <TType>(nbElements, pos);
        }
예제 #2
0
        internal object DecodeData(Type t, uint nbElements = 1, int startPost = 0, int maxSize = 40)
        {
            if (
                t.IsSubclassOf(typeof(Decodable)) &&
                !t.IsArray
                )
            {
                Decodable res = (Decodable)t.GetConstructor(
                    System.Reflection.BindingFlags.NonPublic | System.Reflection.BindingFlags.Instance,
                    null,
                    new Type[] {},
                    null
                    ).Invoke(
                    new object[] {}
                    );
                res.Decode(
                    this,
                    nbElements
                    );
                return(res);
            }

            if (t == typeof(object))
            {
                t = channelDefinedType;
            }

            Type baseT = t;

            if (baseT.IsArray)
            {
                baseT = t.GetElementType();
            }

            if (t.IsArray)
            {
                Type dl      = typeof(List <>);
                Type genList = dl.MakeGenericType(
                    new Type[] {
                    baseT
                }
                    );

                System.Collections.IList res = (System.Collections.IList)Activator.CreateInstance(genList);

                int pos         = (int)RawData.HeaderSize + startPost;
                int elementSize = TypeHandling.EpicsSize(baseT);
                for (int i = 0; i < nbElements; i++)
                {
                    switch (TypeHandling.Lookup[baseT])
                    {
                    case EpicsType.Int:
                        res.Add(
                            RawData.GetInt32(pos)
                            );
                        break;

                    case EpicsType.Short:
                        res.Add(
                            RawData.GetInt16(pos)
                            );
                        break;

                    case EpicsType.Float:
                        res.Add(
                            RawData.GetFloat(pos)
                            );
                        break;

                    case EpicsType.Double:
                        res.Add(
                            RawData.GetDouble(pos)
                            );
                        break;

                    case EpicsType.Byte:
                        res.Add(
                            RawData.GetByte(pos)
                            );
                        break;

                    default:
                        throw new Exception("Type not supported");
                    }
                    pos += elementSize;
                }
                return((
                           (dynamic)res
                           ).ToArray());
            }

            if (baseT == typeof(DateTime))
            {
                long secs = RawData.GetUInt32(
                    (int)RawData.HeaderSize
                    + startPost
                    );
                long nanoSecs = RawData.GetUInt32(
                    (int)RawData.HeaderSize
                    + startPost
                    + 4)
                ;
                DateTime d = (
                    new DateTime(
                        timestampBase.Ticks
                        + (secs * 10000000L)
                        + (nanoSecs / 100L)
                        )
                    ).ToLocalTime();
                return(d);
            }

            switch (TypeHandling.Lookup[baseT])
            {
            case EpicsType.Internal_UInt:
                return(RawData.GetUInt32((int)RawData.HeaderSize + startPost));

            case EpicsType.Internal_UShort:
                return(RawData.GetUInt16((int)RawData.HeaderSize + startPost));

            case EpicsType.Int:
                return(RawData.GetInt32((int)RawData.HeaderSize + startPost));

            case EpicsType.Short:
                return(RawData.GetInt16((int)RawData.HeaderSize + startPost));

            case EpicsType.Float:
                return(RawData.GetFloat((int)RawData.HeaderSize + startPost));

            case EpicsType.Double:
                return(RawData.GetDouble((int)RawData.HeaderSize + startPost));

            case EpicsType.String:
                return(RawData.GetDataAsString(startPost, maxSize));

            case EpicsType.Byte:
                return(RawData.GetByte((int)RawData.HeaderSize + startPost));

            default:
                // throw new Exception("Type not supported") ;
                return(new object());
            }
        }
예제 #3
0
        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);
        }