public override bool Equals(object other) { if (other == null || !(other is IsoValue)) { return(false); } IsoValue comp = (IsoValue)other; return(comp.Type == _type && comp.Value.Equals(_fval) && comp.Length == _length); }
/// <summary> /// Stores the given IsoValue in the specified field index. /// </summary> /// <param name="index">The field index (2 to 128)</param> /// <param name="field">The IsoValue to store under that index.</param> public void SetField(int index, IsoValue field) { if (index < 2 || index > 128) { throw new ArgumentOutOfRangeException(nameof(index), "Index must be between 2 and 128"); } if (field == null) { _fields.Remove(index); } else { _fields[index] = field; } }
/// <summary> /// Creates an IsoValue with the given values and stores it in the specified index. /// </summary> /// <param name="index">The field index (2 to 128)</param> /// <param name="value">An object value to store inside an IsoValue.</param> /// <param name="t">The ISO8583 for this value.</param> /// <param name="length">The length of the value (useful only for NUMERIC and ALPHA types).</param> public void SetValue(int index, object value, IsoType t, int length) { if (index < 2 || index > 128) { throw new ArgumentOutOfRangeException(nameof(index), "Index must be between 2 and 128"); } if (value == null) { _fields.Remove(index); } else { IsoValue v = null; v = IsoTypeHelper.NeedsLength(t) ? new IsoValue(t, value, length) : new IsoValue(t, value); _fields[index] = v; } }
/// <summary> /// Parses a byte buffer containing an ISO8583 message. The buffer must /// not include the length header. If it includes the ISO message header, /// then its length must be specified so the message type can be found. /// </summary> /// <param name="buf">The byte buffer containing the message, starting /// at the ISO header or the message type.</param> /// <param name="isoHeaderLength">Specifies the position at which the message /// type is located, which is algo the length of the ISO header.</param> /// <param name="encoder">The encoder to use for reading string values.</param> /// <returns>The parsed message.</returns> public IsoMessage ParseMessage(byte[] buf, int isoHeaderLength, Encoding encoder) { IsoMessage m = new IsoMessage(isoHeaderLength > 0 ? encoder.GetString(buf, 0, isoHeaderLength) : null); int type = ((buf[isoHeaderLength] - 48) << 12) | ((buf[isoHeaderLength + 1] - 48) << 8) | ((buf[isoHeaderLength + 2] - 48) << 4) | (buf[isoHeaderLength + 3] - 48); m.Type = type; //Parse the bitmap bool extended = (HexByteValue(buf[isoHeaderLength + 4]) & 8) > 0; BitArray bs = new BitArray(extended ? 128 : 64); int pos = 0; for (int i = isoHeaderLength + 4; i < isoHeaderLength + 20; i++) { int hex = HexByteValue(buf[i]); bs.Set(pos++, (hex & 8) > 0); bs.Set(pos++, (hex & 4) > 0); bs.Set(pos++, (hex & 2) > 0); bs.Set(pos++, (hex & 1) > 0); } //Extended bitmap? if (bs.Get(0)) { for (int i = isoHeaderLength + 20; i < isoHeaderLength + 36; i++) { int hex = HexByteValue(buf[i]); bs.Set(pos++, (hex & 8) > 0); bs.Set(pos++, (hex & 4) > 0); bs.Set(pos++, (hex & 2) > 0); bs.Set(pos++, (hex & 1) > 0); } pos = 36 + isoHeaderLength; } else { pos = 20 + isoHeaderLength; } //Parse each field Dictionary <int, FieldParseInfo> guide = _parseMap[type]; List <int> index = _parseOrder[type]; foreach (int i in index) { FieldParseInfo fpi = guide[i]; if (i <= bs.Count) { // TM extended parsing if (bs.Get(i - 1)) { IsoValue val = fpi.Parse(buf, pos, encoder); m.SetField(i, val); pos += val.Length; if (val.Type == IsoType.LLVAR || val.Type == IsoType.LLVARnp) { pos += 2; //@@@ TAM temporary hardcode, must be a better way to parse Padding F if (val.Type == IsoType.LLVAR && (val.Length % 2 != 0)) { pos += 1; } } else if (val.Type == IsoType.LLLVAR) { //@@@ TAM packe 3 change to 4 for Paymark //pos += 3; pos += 4; } else if (val.Type == IsoType.LLLVARnp) // for NAB the LLLVAR Non packed(ascci codec) will have HEX as length so 6 digits(303139 = 019) { pos += 6; } } } } return(m); }
/// <summary> /// Returns the stored object value in a specified field. Fields /// are represented by IsoValues which contain objects so this /// method can return the contained objects directly. /// </summary> /// <param name="field">The field number (2 to 128)</param> /// <returns>The stored object value in that field, or null if the message does not have the field.</returns> public object GetObjectValue(int field) { IsoValue v = _fields[field]; return(v?.Value); }
public byte[] WriteInternal() { MemoryStream memoryStream = new MemoryStream(16); byte[] buf = null; if (_isoHeader != null) { buf = Encoding.ASCII.GetBytes(_isoHeader); memoryStream.Write(buf, 0, buf.Length); } if (_binary) { memoryStream.WriteByte((byte)((_type & 0xff00) >> 8)); memoryStream.WriteByte((byte)(_type & 0xff)); } else { string x = _type.ToString("x4"); memoryStream.Write(Encoding.ASCII.GetBytes(x), 0, 4); } //TODO write the bitmap Dictionary <int, IsoValue> .KeyCollection keys = _fields.Keys; BitArray bits = new BitArray(64); foreach (int i in keys) { if (i > 64) { bits.Length = 128; bits.Set(0, true); } bits.Set(i - 1, true); } if (_binary) { buf = new byte[bits.Length / 8]; bits.CopyTo(buf, 0); } else { buf = new byte[bits.Length / 4]; int pos = 0; int lim = bits.Length / 4; for (int i = 0; i < lim; i++) { int nibble = 0; if (bits.Get(pos++)) { nibble += 8; } if (bits.Get(pos++)) { nibble += 4; } if (bits.Get(pos++)) { nibble += 2; } if (bits.Get(pos++)) { nibble++; } Encoding.ASCII.GetBytes(Hex, nibble, 1, buf, i); } } memoryStream.Write(buf, 0, buf.Length); //Write each field for (int i = 1; i < bits.Length; i++) { if (_fields.ContainsKey(i)) { IsoValue v = _fields[i]; v.Write(memoryStream); } } return(memoryStream.ToArray()); }