/** * * @param formatCode * @param length - length in bytes * @param desiredNUmberOfLengthBytes */ protected SECSItem(SECSItemFormatCode formatCode, int length, int desiredNUmberOfLengthBytes) { this.formatCode = formatCode; outboundNumberOfLengthBytes = calculateMinimumNumberOfLengthBytes(length); if (desiredNUmberOfLengthBytes > 0 && desiredNUmberOfLengthBytes < 4 && outboundNumberOfLengthBytes < desiredNUmberOfLengthBytes) { outboundNumberOfLengthBytes = desiredNUmberOfLengthBytes; } }
/// <summary> /// This is a base class constructor for a <c>SECSItem</c>. When using this constructor, the /// outbound number of length bytes will be set to the minimum number required to /// handle an item with the length that is specified by the value of the /// <c>length</c> parameter. /// /// This constructor sets the following base class attributes from the provided data: /// <c>formatCode</c>, <c>lengthInBytes</c>, and <c>outboundNumberOfLengthBytes</c>. /// </summary> /// <param name="formatCode">The Format Code of the created <c>SECSItem</c>.</param> /// <param name="lengthInBytes">The length in bytes of the item, or in the case of a /// <c>ListSECSItem</c> the number of items it contains.It must be between 0 /// and 16777215 inclusive..</param> protected SECSItem(SECSItemFormatCode formatCode, int lengthInBytes) { if (lengthInBytes < 0 || lengthInBytes > (int)0x00FFFFFF) { throw new ArgumentException( "The value for the length argument must be between 0 and 16777215 inclusive."); } this.formatCode = formatCode; this.lengthInBytes = lengthInBytes; outboundNumberOfLengthBytes = CalculateMinimumNumberOfLengthBytes(lengthInBytes); }
/// <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); }
protected SECSItem(byte[] data, int itemOffset) { int incomingDataLength = 0; if (data.Length == 0) { formatCode = SECSItemFormatCode.HeaderOnly; inboundNumberOfLengthBytes = 0; data = null; return; } formatCode = SECSItemFormatCodeFunctions.getSECSItemFormatCodeFromNumber((byte)((data[itemOffset] >> 2) & 0x0000003F)); inboundNumberOfLengthBytes = (data[itemOffset] & 0x03); byte[] temp1 = new byte[4]; switch (inboundNumberOfLengthBytes) { case 1: { temp1[0] = 0; temp1[1] = 0; temp1[2] = 0; temp1[3] = data[itemOffset + 1]; break; } case 2: { temp1[0] = 0; temp1[1] = 0; temp1[2] = data[itemOffset + 1]; temp1[3] = data[itemOffset + 2]; break; } case 3: { temp1[0] = 0; temp1[1] = data[itemOffset + 1]; temp1[2] = data[itemOffset + 2]; temp1[3] = data[itemOffset + 3]; break; } } if (BitConverter.IsLittleEndian) { Array.Reverse(temp1); } incomingDataLength = BitConverter.ToInt32(temp1, 0); if (formatCode == SECSItemFormatCode.L) { numberOfElements = incomingDataLength; } else { lengthInBytes = incomingDataLength; } }
/** * * @param formatCode * @param length - length in bytes */ protected SECSItem(SECSItemFormatCode formatCode, int length) { this.formatCode = formatCode; outboundNumberOfLengthBytes = calculateMinimumNumberOfLengthBytes(length); }
/** * * @param itemFormatCode * @return */ internal static int mapFormatCodeToNumber(SECSItemFormatCode itemFormatCode) { return(codeToNumberMap[(int)itemFormatCode]); }
public SECSItemTest(SECSItemFormatCode formatCode, int length, SECSItemNumLengthBytes desiredNumberOfLengthBytes) : base(formatCode, length, desiredNumberOfLengthBytes) { }
public SECSItemTest(SECSItemFormatCode formatCode, int length) : base(formatCode, length) { }
/// <summary> /// This is a base class constructor for a SECSItem. This form of the constructor /// is used when parsing wire/transmission format data and converting it into /// its "C# form". /// /// This constructor sets the following base class attributes from the provided data: /// <c>formatCode</c>, /// <c>inboundNumberOfLengthBytes</c>, /// <c>outboundNumberOfLengthBytes</c> /// <c>lengthInBytes</c> or if the <c>formatCode</c> is of type <c>L</c>(List) <c>lengthInBytes</c> /// will be the number of items in the list. /// /// The exception <c>ArgumentException</c> will be thrown in the following circumstances: /// the <c>data</c> argument is <c>null</c>, the <c>data</c> argument has a length of zero, or /// the number of length bytes parsed out is zero. /// /// In normal use the only time the <c>ArgumentException</c> /// exception should be caught is if you are reading data from a piece of /// equipment that does not properly speak SECS and you want to be able to /// recover from the error gracefully.Typically the ACM process will have /// detected this equipment and it will not be allowed into the factory in /// the first place. /// </summary> protected SECSItem(byte[] data, int itemOffset) { if (data == null) { throw new ArgumentNullException("\"data\" argument must not be null."); } if (data.Length < 2) { throw new ArgumentException("\"data\" argument must have a length >= 2."); } /* * if (data.Length == 0) * { * throw new ArgumentException ("The number of length bytes is not allowed to be ZERO."); * } */ formatCode = SECSItemFormatCodeFunctions.GetSECSItemFormatCodeFromNumber((byte)((data[itemOffset] >> 2) & 0x0000003F)); byte[] temp1 = new byte[4]; switch (data [itemOffset] & 0x03) { case 0: { throw new ArgumentException("The number of length bytes is not allowed to be ZERO."); } case 1: { inboundNumberOfLengthBytes = SECSItemNumLengthBytes.ONE; outboundNumberOfLengthBytes = inboundNumberOfLengthBytes; temp1[0] = 0; temp1[1] = 0; temp1[2] = 0; temp1[3] = data[itemOffset + 1]; break; } case 2: { inboundNumberOfLengthBytes = SECSItemNumLengthBytes.TWO; outboundNumberOfLengthBytes = inboundNumberOfLengthBytes; if (data.Length < 3) { throw new ArgumentException("With two length bytes the minimum length for the \"data\" argument is 3."); } temp1[0] = 0; temp1[1] = 0; temp1[2] = data[itemOffset + 1]; temp1[3] = data[itemOffset + 2]; break; } case 3: { inboundNumberOfLengthBytes = SECSItemNumLengthBytes.THREE; outboundNumberOfLengthBytes = inboundNumberOfLengthBytes; if (data.Length < 4) { throw new ArgumentException("With three length bytes the minimum length for the \"data\" argument is 4."); } temp1[0] = 0; temp1[1] = data[itemOffset + 1]; temp1[2] = data[itemOffset + 2]; temp1[3] = data[itemOffset + 3]; break; } } if (BitConverter.IsLittleEndian) { Array.Reverse(temp1); } lengthInBytes = BitConverter.ToInt32(temp1, 0); /* * if (formatCode == SECSItemFormatCode.L) * numberOfElements = incomingDataLength; * else * lengthInBytes = incomingDataLength; */ }
/// <summary> /// This is a base class constructor for a SECSItem. When using this constructor, the /// number of length bytes will be set to the greater of, the specified number of /// length bytes, or the minimum number required to /// handle an item with the length that is specified by the value of the /// <c>lengthInBytes</c> parameter. /// This constructor sets the following base class attributes from the provided data: /// <c>formatCode</c>, /// <c>lengthInBytes</c>, and /// <c>outboundNumberOfLengthBytes</c>. /// Note: An <c>ArgumentException</c> will be thrown if the value of the /// <c>lengthInBytes</c> parameter is outside the range of 0 - 16777215 /// inclusive. /// </summary> /// <param name="formatCode">The SECS Item Format code for this SECSItem.</param> /// <param name="lengthInBytes">The length in bytes that this SECSItem will take up in /// its wire/transmission format.</param> /// <param name="desiredNumberOfLengthBytes">This parameter expresses the desired /// number or length bytes to be used for this SECSItem when it is converted /// to its wire/transmission format.</param> protected SECSItem(SECSItemFormatCode formatCode, int lengthInBytes, SECSItemNumLengthBytes desiredNumberOfLengthBytes) { this.formatCode = formatCode; this.lengthInBytes = lengthInBytes; SetOutboundNumberOfLengthBytes(lengthInBytes, desiredNumberOfLengthBytes); }
/// <summary> /// This method is typically only used the retrieve the proper numeric value /// of an Item Format Code during the conversion of a <c>SECSItem</c> into its /// "wire/transmission format". /// </summary> /// <returns>The number value of the specified <c>SECSItemFormatCode</c>.</returns> /// <param name="formatCode">Item format code.</param> public static int GetNumberFromSECSItemFormatCode(SECSItemFormatCode formatCode) { return(RawSECSItemFormatCode.mapFormatCodeToNumber(formatCode)); }