public void TestCodec() { var buf = HexCodec.HexDecode("A"); Assert.Equal(0x0a, buf[0]); EncodeDecode("A"); EncodeDecode("0123456789ABCDEF"); buf = HexCodec.HexDecode("0123456789ABCDEF"); Assert.Equal(1, buf[0]); Assert.Equal(0x23, buf[1]); Assert.Equal(0x45, buf[2]); Assert.Equal(0x67, buf[3]); Assert.Equal(0x89, buf[4] & 0xff); Assert.Equal(0xab, buf[5] & 0xff); Assert.Equal(0xcd, buf[6] & 0xff); Assert.Equal(0xef, buf[7] & 0xff); buf = HexCodec.HexDecode("ABC"); Assert.Equal(0x0a, buf[0] & 0xff); Assert.Equal(0xbc, buf[1] & 0xff); EncodeDecode("ABC"); }
public override IsoValue Parse(int field, sbyte[] buf, int pos, ICustomField custom) { if (pos < 0) { throw new ParseException($"Invalid BINARY field {field} position {pos}"); } if (pos + Length * 2 > buf.Length) { throw new ParseException($"Insufficient data for BINARY field {field} of length {Length}, pos {pos}"); } var s = buf.ToString(pos, Length * 2, Encoding.Default); //var binval = HexCodec.HexDecode(Encoding.ASCII.GetString(buf, // pos, // Length * 2)); var binval = HexCodec.HexDecode(s); if (custom == null) { return(new IsoValue(IsoType, binval, binval.Length)); } s = buf.ToString(pos, Length * 2, Encoding); //var dec = custom.DecodeField(Encoding.GetString(buf, // pos, // Length * 2)); var dec = custom.DecodeField(s); return(dec == null ? new IsoValue(IsoType, binval, binval.Length) : new IsoValue(IsoType, dec, Length, custom)); }
public void EncodeDecode(string hex) { var buf = HexCodec.HexDecode(hex); Assert.Equal(hex.Length / 2 + hex.Length % 2, buf.Length); var reenc = HexCodec.HexEncode(buf, 0, buf.Length); if (reenc.StartsWith("0", StringComparison.Ordinal) && !hex.StartsWith("0", StringComparison.Ordinal)) { Assert.Equal(reenc.Substring(1), hex); } else { Assert.Equal(hex, reenc); } }
public void TestMessage() { var trama = HexCodec.HexDecode( "f1f8f1f42030010002000000f0f0f0f0f0f0f0f1f5f9f5f5f1f3f0f6f1f2f1f1f2f9f0f8f8f3f1f8f0f0"); var mfact = new MessageFactory <IsoMessage> { UseBinaryBitmap = true }; var pinfo = new Dictionary <int, FieldParseInfo> { { 3, new AlphaParseInfo(6) }, { 11, new AlphaParseInfo(6) }, { 12, new AlphaParseInfo(12) }, { 24, new AlphaParseInfo(3) }, { 39, new AlphaParseInfo(3) } }; mfact.SetParseMap(0x1814, pinfo); mfact.Encoding = CodePagesEncodingProvider.Instance.GetEncoding(1047); mfact.ForceStringEncoding = true; var iso = mfact.ParseMessage(trama, 0); Assert.NotNull(iso); Assert.Equal("000000", iso.GetObjectValue(3)); Assert.Equal("015955", iso.GetObjectValue(11)); Assert.Equal("130612112908", iso.GetObjectValue(12)); Assert.Equal("831", iso.GetObjectValue(24)); Assert.Equal("800", iso.GetObjectValue(39)); }
public override IsoValue Parse(int field, sbyte[] buf, int pos, ICustomField custom) { if (pos < 0) { throw new ParseException($"Invalid LLBIN field {field} position {pos}"); } if (pos + 2 > buf.Length) { throw new ParseException($"Invalid LLBIN field {field} position {pos}"); } var len = DecodeLength(buf, pos, 2); if (len < 0) { throw new ParseException($"Invalid LLBIN field {field} length {len} pos {pos}"); } if (len + pos + 2 > buf.Length) { throw new ParseException( $"Insufficient data for LLBIN field {field}, pos {pos} (LEN states '{buf.SignedBytesToString(pos, 2, Encoding.Default)}')"); } var binval = len == 0 ? new sbyte[0] : HexCodec.HexDecode(buf.SignedBytesToString(pos + 2, len, Encoding.Default)); if (custom == null) { return(new IsoValue(IsoType, binval, binval.Length)); } var binaryField = custom as ICustomBinaryField; if (binaryField != null) { try { var dec = binaryField.DecodeBinaryField(buf, pos + 2, len); if (dec == null) { return(new IsoValue(IsoType, binval, binval.Length)); } return(new IsoValue(IsoType, dec, 0, custom)); } catch (Exception) { throw new ParseException( $"Insufficient data for LLBIN field {field}, pos {pos} (LEN states '{buf.SignedBytesToString(pos, 2, Encoding.Default)}')"); } } try { var dec = custom.DecodeField(buf.SignedBytesToString(pos + 2, len, Encoding.Default)); return(dec == null ? new IsoValue(IsoType, binval, binval.Length) : new IsoValue(IsoType, dec, binval.Length, custom)); } catch (Exception) { throw new ParseException( $"Insufficient data for LLBIN field {field}, pos {pos} (LEN states '{buf.SignedBytesToString(pos, 2, Encoding.Default)}')"); } }
private static void ParseHeaders <T>(XmlNodeList nodes, MessageFactory <T> mfact) where T : IsoMessage { List <XmlElement> refs = null; for (var i = 0; i < nodes.Count; i++) { var elem = (XmlElement)nodes.Item(i); if (elem == null) { continue; } var type = ParseType(elem.GetAttribute("type")); if (type == -1) { throw new IOException($"Invalid type {elem.GetAttribute("type")} for ISO8583 header: "); } if (elem.ChildNodes.Count == 0) { if (elem.GetAttribute("ref") != null && !string.IsNullOrEmpty(elem.GetAttribute("ref"))) { refs ??= new List <XmlElement>(nodes.Count - i); refs.Add(elem); } else { throw new IOException("Invalid ISO8583 header element"); } } else { var header = elem.ChildNodes.Item(0)?.Value; var binHeader = "true".Equals(elem.GetAttribute("binary")); if (Logger.IsEnabled(LogEventLevel.Debug)) { var binary = binHeader ? "binary" : string.Empty; Logger.Debug( $"Adding {binary} ISO8583 header for type {elem.GetAttribute("type")} : {header}"); } if (binHeader) { mfact.SetBinaryIsoHeader( type, HexCodec.HexDecode(header).ToUnsignedBytes()); } else { mfact.SetIsoHeader( type, header); } } } if (refs == null) { return; } { foreach (var elem in refs) { if (elem == null) { continue; } var type = ParseType(elem.GetAttribute("type")); if (type == -1) { throw new IOException("Invalid type for ISO8583 header: " + elem.GetAttribute("type")); } if (elem.GetAttribute("ref") == null || elem.GetAttribute("ref").IsEmpty()) { continue; } var t2 = ParseType(elem.GetAttribute("ref")); if (t2 == -1) { throw new IOException( "Invalid type reference " + elem.GetAttribute("ref") + " for ISO8583 header " + type); } var h = mfact.GetIsoHeader(t2); if (h == null) { throw new ArgumentException("Header def " + type + " refers to nonexistent header " + t2); } if (Logger.IsEnabled(LogEventLevel.Debug)) { Logger.Debug( "Adding ISO8583 header for type {Type}: {H} (copied from {Ref})", elem.GetAttribute("type"), h, elem.GetAttribute("ref")); } mfact.SetIsoHeader( type, h); } } }
public void Write(Stream outs, bool binary, bool forceStringEncoding) { switch (Type) { case IsoType.LLLVAR: case IsoType.LLVAR: case IsoType.LLLLVAR: WriteLengthHeader(Length, outs, Type, binary, forceStringEncoding); break; case IsoType.LLBIN: case IsoType.LLLBIN: case IsoType.LLLLBIN: WriteLengthHeader(binary ? Length : Length * 2, outs, Type, binary, forceStringEncoding); break; default: if (binary) { //numeric types in binary are coded like this sbyte[] buf = null; switch (Type) { case IsoType.NUMERIC: buf = new sbyte[Length / 2 + Length % 2]; break; case IsoType.AMOUNT: buf = new sbyte[6]; break; case IsoType.DATE10: case IsoType.DATE4: case IsoType.DATE_EXP: case IsoType.TIME: case IsoType.DATE12: case IsoType.DATE14: buf = new sbyte[Length / 2]; break; } //Encode in BCD if it's one of these types if (buf != null) { Bcd.Encode(ToString(), buf); outs.Write(buf.ToUnsignedBytes(), 0, buf.Length); return; } } break; } if (binary && (Type == IsoType.BINARY || Type == IsoType.LLBIN || Type == IsoType.LLLBIN || Type == IsoType.LLLLBIN)) { var missing = 0; if (Value is sbyte[]) { var bytes = (sbyte[])Value; outs.Write(bytes.ToUnsignedBytes(), 0, bytes.Length); missing = Length - bytes.Length; } else if (Encoder is ICustomBinaryField) { var binval = ((ICustomBinaryField)Encoder).EncodeBinaryField(Value); outs.Write(binval.ToUnsignedBytes(), 0, binval.Length); missing = Length - binval.Length; } else { var binval = HexCodec.HexDecode(Value.ToString()); outs.Write(binval.ToUnsignedBytes(), 0, binval.Length); missing = Length - binval.Length; } if (Type != IsoType.BINARY || missing <= 0) { return; } for (var i = 0; i < missing; i++) { outs.WriteByte(0); } } else { var bytes = ToString().GetSignedbytes(Encoding); outs.Write(bytes.ToUnsignedBytes(), 0, bytes.Length); } }
public override IsoValue Parse(int field, sbyte[] buf, int pos, ICustomField custom) { if (pos < 0) { throw new ParseException($"Invalid LLLBIN field {field} pos {pos}"); } if (pos + 3 > buf.Length) { throw new ParseException($"Insufficient LLLBIN header field {field}"); } var l = DecodeLength(buf, pos, 3); if (l < 0) { throw new ParseException($"Invalid LLLBIN length {l} field {field} pos {pos}"); } if (l + pos + 3 > buf.Length) { throw new ParseException($"Insufficient data for LLLBIN field {field}, pos {pos}"); } var binval = l == 0 ? new sbyte[0] : HexCodec.HexDecode(buf.SignedBytesToString(pos + 3, l, Encoding.Default)); if (custom == null) { return(new IsoValue(IsoType, binval, binval.Length)); } var customBinaryField = custom as ICustomBinaryField; if (customBinaryField != null) { try { var dec = customBinaryField.DecodeBinaryField(buf, pos + 3, l); return(dec == null ? new IsoValue(IsoType, binval, binval.Length) : new IsoValue(IsoType, dec, 0, custom)); } catch (Exception) { throw new ParseException($"Insufficient data for LLLBIN field {field}, pos {pos}"); } } try { var dec = custom.DecodeField(l == 0 ? "" : buf.SignedBytesToString(pos + 3, l, Encoding.Default)); return(dec == null ? new IsoValue(IsoType, binval, binval.Length) : new IsoValue(IsoType, dec, l, custom)); } catch (Exception) { throw new Exception($"Insufficient data for LLLBIN field {field}, pos {pos}"); } }
public void Write(Stream outs, bool binary, bool forceStringEncoding) { switch (Type) { case IsoType.LLLVAR: case IsoType.LLVAR: case IsoType.LLLLVAR: WriteLengthHeader(Length, outs, Type, binary, forceStringEncoding); break; case IsoType.LLBIN: case IsoType.LLLBIN: case IsoType.LLLLBIN: WriteLengthHeader(binary ? Length : Length * 2, outs, Type, binary, forceStringEncoding); break; default: if (binary) { //numeric types in binary are coded like this var buf = Type switch { IsoType.NUMERIC => new sbyte[Length / 2 + Length % 2], IsoType.AMOUNT => new sbyte[6], IsoType.DATE10 => new sbyte[Length / 2], IsoType.DATE4 => new sbyte[Length / 2], IsoType.DATE_EXP => new sbyte[Length / 2], IsoType.TIME => new sbyte[Length / 2], IsoType.DATE12 => new sbyte[Length / 2], IsoType.DATE14 => new sbyte[Length / 2], IsoType.DATE6 => new sbyte[Length / 2], _ => null }; //Encode in BCD if it's one of these types if (buf != null) { Bcd.Encode(ToString(), buf); outs.Write(buf.ToUint8(), 0, buf.Length); return; } } break; } if (binary && (Type == IsoType.BINARY || Type == IsoType.LLBIN || Type == IsoType.LLLBIN || Type == IsoType.LLLLBIN)) { var missing = 0; if (Value is sbyte[] bytes) { outs.Write(bytes.ToUint8(), 0, bytes.Length); missing = Length - bytes.Length; } else { switch (Encoder) { case ICustomBinaryField customBinaryField: { var binval = customBinaryField.EncodeBinaryField(Value); outs.Write(binval.ToUint8(), 0, binval.Length); missing = Length - binval.Length; break; } default: { var binval = HexCodec.HexDecode(Value.ToString()); outs.Write(binval.ToUint8(), 0, binval.Length); missing = Length - binval.Length; break; } } } if (Type != IsoType.BINARY || missing <= 0) { return; } for (var i = 0; i < missing; i++) { outs.WriteByte(0); } } else { var bytes = ToString().GetSignedBytes(Encoding); outs.Write(bytes.ToUint8(), 0, bytes.Length); } }