override public void Encode(Tag tag, int offset, Sequence value) { var DINT0 = value.Step_No; var DINT1 = value.Next_Step; var DINT2 = value.Command; var DINT3 = value.Idle_Step; var DINT4 = value.Fault_Step; var DINT5 = value.Init_Step; var bools = new BitArray(32); bools[0] = value.Stop; bools[1] = value.Hold; bools[2] = value.Fault; var DINT6 = BitArrayToInt(bools); tag.SetInt32(offset + 0, DINT0); tag.SetInt32(offset + 4, DINT1); tag.SetInt32(offset + 8, DINT2); tag.SetInt32(offset + 12, DINT3); tag.SetInt32(offset + 16, DINT4); tag.SetInt32(offset + 20, DINT5); tag.SetInt32(offset + 24, DINT6); var timerPlcMapper = new TimerPlcMapper(); for (int ii = 0; ii < 20; ii++) { var timerOffset = offset + 28 + ii * timerPlcMapper.ElementSize.Value; timerPlcMapper.Encode(tag, timerOffset, value.Timer[ii]); } }
// This function is used to decode the binary buffer // into a CLR data transfer object // The function is called once per array element, so we only // need to decode one array element at a time. override public Sequence Decode(Tag tag, int offset) { // If our UDT has a size that does not change, we can set this based on ElementSize // Some types have an ElementSize that varies with it's contents (e.g. STRING on some controllers) // Those types must wait until they know the actual elementSize before returning it //elementSize = ElementSize.Value; // Plain DINT objects // // Note that the buffer access is always offset // This is so that our PlcMapper can be used in both // Single Values or Arrays var DINT0 = tag.GetInt32(offset + 0); var DINT1 = tag.GetInt32(offset + 4); var DINT2 = tag.GetInt32(offset + 8); var DINT3 = tag.GetInt32(offset + 12); var DINT4 = tag.GetInt32(offset + 16); var DINT5 = tag.GetInt32(offset + 20); // Our BOOLs are packed into this object. // I've chosen to make use of the BitArray class // which takes an integer array or byte array var PACKED_BOOLS = tag.GetInt32(offset + 24); var bools = new BitArray(new int[] { PACKED_BOOLS }); // We can make use of other PlcMappers! // This means that if our UDT contains other structures (or UDTs) var timerPlcMapper = new TimerPlcMapper() { PlcType = this.PlcType }; // Pass the PlcType through to this PlcMapper just in case it's behaviour depends on PlcType var TIMERS = new AbTimer[20]; for (int ii = 0; ii < 20; ii++) { var timerOffset = offset + 28 + ii * timerPlcMapper.ElementSize.Value; TIMERS[ii] = timerPlcMapper.Decode(tag, timerOffset); } // We now have all of our objects Decoded // and can instantiate our Plain Old Class Object (POCO) // With the appropriate values return(new Sequence() { Step_No = DINT0, Next_Step = DINT1, Command = DINT2, Idle_Step = DINT3, Fault_Step = DINT4, Init_Step = DINT5, Stop = bools[0], Hold = bools[1], Fault = bools[2], Timer = TIMERS }); }