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); }
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()); } }
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); }