private Dictionary<int, Dictionary<int, FieldParseInfo>> parseMap = new Dictionary<int, Dictionary<int, FieldParseInfo>>(); public void SetParseDictionary(int type, Dictionary<int, FieldParseInfo> dict) { parseMap[type] = dict; List<int> index = new List<int>(); for (int i = 2; i < 129; i++) { if (dict.ContainsKey(i)) { index.Add(i); } } parseOrder[type] = index; } 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; 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); } 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; } Dictionary<int, FieldParseInfo> guide = new Dictionary<int, FieldParseInfo>(); List<int> index = parseOrder[type]; try { foreach (int i in index) { FieldParseInfo fpi = guide[i]; if (bs.Get(i - 1)) { IsoValue val = fpi.Parse(buf, pos, encoder); m.SetField(i, val); pos += val.Length; if (val.Type == IsoType.LLVAR) { pos += 2; } else if (val.Type == IsoType.LLLVAR) { pos += 3; } } } } catch { } return m; }
public class FieldParseInfo { private IsoType type; private int length; public FieldParseInfo(IsoType t, int len) { type = t; length = len; } public int Length { get { return length; } } public IsoType Type { get { return type; } } public IsoValue Parse(byte[] buf, int pos, Encoding encoder) { if (type == IsoType.NUMERIC || type == IsoType.ALPHA) { return new IsoValue(type, encoder.GetString(buf, pos, length), length); } else if (type == IsoType.LLVAR) { length = ((buf[pos] - 48) * 10) + (buf[pos + 1] - 48); if (length < 1 || length > 99) { throw new ArgumentException("LLVAR field with invalid length"); } return new IsoValue(type, encoder.GetString(buf, pos + 2, length)); } else if (type == IsoType.LLLVAR) { length = ((buf[pos] - 48) * 100) + ((buf[pos + 1] - 48) * 10) + (buf[pos + 2] - 48); if (length < 1 || length > 999) { throw new ArgumentException("LLLVAR field with invalid length"); } return new IsoValue(type, encoder.GetString(buf, pos + 3, length)); } else if (type == IsoType.AMOUNT) { byte[] c = new byte[13]; Array.Copy(buf, pos, c, 0, 10); Array.Copy(buf, pos + 10, c, 11, 2); c[10] = (byte)'.'; return new IsoValue(type, Decimal.Parse(encoder.GetString(c))); } else if (type == IsoType.DATE10) { DateTime dt = DateTime.Now; dt = new DateTime(dt.Year, ((buf[pos] - 48) * 10) + buf[pos + 1] - 48, ((buf[pos + 2] - 48) * 10) + buf[pos + 3] - 48, ((buf[pos + 4] - 48) * 10) + buf[pos + 5] - 48, ((buf[pos + 6] - 48) * 10) + buf[pos + 7] - 48, ((buf[pos + 8] - 48) * 10) + buf[pos + 9] - 48); if (dt.CompareTo(DateTime.Now) > 0) { dt.AddYears(-1); } return new IsoValue(type, dt); } else if (type == IsoType.DATE4) { DateTime dt = DateTime.Now; dt = new DateTime(dt.Year, ((buf[pos] - 48) * 10) + buf[pos + 1] - 48, ((buf[pos + 2] - 48) * 10) + buf[pos + 3] - 48); if (dt.CompareTo(DateTime.Now) > 0) { dt.AddYears(-1); } return new IsoValue(type, dt); } else if (type == IsoType.DATE_EXP) { DateTime dt = DateTime.Now; dt = new DateTime(dt.Year - (dt.Year % 100) + ((buf[pos] - 48) * 10) + buf[pos + 1] - 48, ((buf[pos + 2] - 48) * 10) + buf[pos + 3] - 48, 1); return new IsoValue(type, dt); } else if (type == IsoType.TIME) { DateTime dt = DateTime.Now; dt = new DateTime(dt.Year, dt.Month, dt.Day, ((buf[pos] - 48) * 10) + buf[pos + 1] - 48, ((buf[pos + 2] - 48) * 10) + buf[pos + 3] - 48, ((buf[pos + 4] - 48) * 10) + buf[pos + 5] - 48); return new IsoValue(type, dt); } return null; } }