Example #1
0
        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");
        }
Example #2
0
        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));
        }
Example #3
0
        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);
            }
        }
Example #4
0
        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));
        }
Example #5
0
        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)}')");
            }
        }
Example #6
0
        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);
                }
            }
        }
Example #7
0
        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);
            }
        }
Example #8
0
        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}");
            }
        }
Example #9
0
        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);
            }
        }