/// <summary> /// This method returns a SECSItem contained in this list based on its /// "address" or null if the item does not exist. /// /// In the example below a specified address of "3.2" would return the /// element with the value 'Answer'. /// /// <ol> /// <li>A 'ABC' </li> /// <li>A 'DEF' </li> /// <li>L 3 </li> /// <ol> /// <li>I2 -32768</li> /// <li>A 'Answer'</li> /// <li>U1 255</li> /// </ol> /// <li>F4 3.141592</li> /// </ol> /// </summary> /// <returns>The <see cref="com.CIMthetics.CSharpSECSTools.SECSItems.SECSItem"/>.</returns> /// <param name="address">The SECSItem at the provided address or null if not found.</param> public SECSItem getElementAt(String address) { SECSItem result = null; String[] addressArray = address.Split('.'); int elementNumber = int.Parse(addressArray[0]); if (elementNumber < 1 || elementNumber > value.Count) { return(null); } result = value.ElementAt(elementNumber - 1); if (addressArray.Length > 1) { if (result.getSECSItemFormatCode() != SECSItemFormatCode.L) { /* * If we are here the address has more levels, but, this * element is not a list so we cannot proceed. */ return(null); } else { return(getElementAt(addressArray[1])); } } return(result); }
public ListSECSItem(byte[] data, int itemOffset) : base(data, itemOffset) { int offset = 1 + inboundNumberOfLengthBytes + itemOffset; bytesConsumed = offset + lengthInBytes; value = new LinkedList <SECSItem>(); for (int i = 0; i < numberOfElements; i++) { SECSItem temp = RawSECSData.generateSECSItem(data, offset); offset += temp.getBytesConumed(); this.bytesConsumed += temp.getBytesConumed(); value.AddLast(temp); } }
/// <summary> /// Generates a <c>SECSItem</c> from data in "wire/transmission" format. /// </summary> /// <returns>The resulting <c>SECSItem</c>.</returns> /// <param name="data">An array of bytes that is in wire/transmission format.</param> /// <param name="offset">The byte offset into <c>data</c> where the data for /// a <c>SECSITEM</c> starts.</param> public static SECSItem GenerateSECSItem(byte[] data, int offset) { SECSItem result = null; SECSItemFormatCode formatCode = SECSItemFormatCodeFunctions.GetSECSItemFormatCodeFromNumber((byte)((data[offset] >> 2) & 0x0000003F)); int numberOfLengthBytes = (data[offset] & 0x03); int incomingDataLength = 0; switch (numberOfLengthBytes) { case 1: { byte[] temp = new byte[4]; temp[0] = 0; temp[1] = 0; temp[2] = 0; temp[3] = data[offset + 1]; if (BitConverter.IsLittleEndian) { Array.Reverse(temp); } incomingDataLength = BitConverter.ToInt32(temp, 0); break; } case 2: { byte[] temp = new byte[4]; temp[0] = 0; temp[1] = 0; temp[2] = data[offset + 1]; temp[3] = data[offset + 2]; if (BitConverter.IsLittleEndian) { Array.Reverse(temp); } incomingDataLength = BitConverter.ToInt32(temp, 0); break; } case 3: { byte[] temp = new byte[4]; temp[0] = 0; temp[1] = data[offset + 1]; temp[2] = data[offset + 2]; temp[3] = data[offset + 3]; if (BitConverter.IsLittleEndian) { Array.Reverse(temp); } incomingDataLength = BitConverter.ToInt32(temp, 0); break; } } switch (formatCode) { case SECSItemFormatCode.L: result = new ListSECSItem(data, offset); break; case SECSItemFormatCode.B: result = new BinarySECSItem(data, offset); break; case SECSItemFormatCode.BO: if (incomingDataLength == 1) { result = new BooleanSECSItem(data, offset); } else { result = new BooleanArraySECSItem(data, offset); } break; case SECSItemFormatCode.A: result = new ASCIISECSItem(data, offset); break; case SECSItemFormatCode.J8: break; case SECSItemFormatCode.C2: break; case SECSItemFormatCode.I8: if (incomingDataLength == 8) { result = new I8SECSItem(data, offset); } else { result = new I8ArraySECSItem(data, offset); } break; case SECSItemFormatCode.I1: if (incomingDataLength == 1) { result = new I1SECSItem(data, offset); } else { result = new I1ArraySECSItem(data, offset, 0); // Need to use this version because of method signature issues } break; case SECSItemFormatCode.I2: if (incomingDataLength == 2) { result = new I2SECSItem(data, offset); } else { result = new I2ArraySECSItem(data, offset); } break; case SECSItemFormatCode.I4: if (incomingDataLength == 4) { result = new I4SECSItem(data, offset); } else { result = new I4ArraySECSItem(data, offset); } break; case SECSItemFormatCode.F8: if (incomingDataLength == 8) { result = new F8SECSItem(data, offset); } else { result = new F8ArraySECSItem(data, offset); } break; case SECSItemFormatCode.F4: if (incomingDataLength == 4) { result = new F4SECSItem(data, offset); } else { result = new F4ArraySECSItem(data, offset); } break; case SECSItemFormatCode.U8: if (incomingDataLength == 8) { result = new U8SECSItem(data, offset); } else { result = new U8ArraySECSItem(data, offset); } break; case SECSItemFormatCode.U1: if (incomingDataLength == 1) { result = new U1SECSItem(data, offset); } else { result = new U1ArraySECSItem(data, offset, 0); // Remember to use the proper constructor for this case } break; case SECSItemFormatCode.U2: if (incomingDataLength == 2) { result = new U2SECSItem(data, offset); } else { result = new U2ArraySECSItem(data, offset); } break; case SECSItemFormatCode.U4: if (incomingDataLength == 4) { result = new U4SECSItem(data, offset); } else { result = new U4ArraySECSItem(data, offset); } break; case SECSItemFormatCode.UNDEFINED: break; case SECSItemFormatCode.HeaderOnly: break; default: break; } return(result); }
/// <summary> /// This constructor will most likely be used just before a SECS II /// message is to be sent out on a SECS I serial line or a HSMS connection. /// </summary> /// <param name="secsItem">A <c>SECSItem</c> that is intended to later be /// converted into wire/transmission format.</param> public RawSECSData(SECSItem secsItem) { data = secsItem.ToRawSECSItem(); }