public void TestParseLengthWithRadix10() { // Given var input = "0100" + // MTI "7000000000000000" + // bitmap "10" + "ABCDEFGHIJ" + // F2 length (10 = 10) + value "26" + "01234567890123456789012345" + // F3 length (26 = 26) + value "ZZZZZZZZ"; // F4 // When IsoMessage m = mfact.ParseMessage(input.GetSignedBytes(), 0); // Then Assert.NotNull(m); Assert.Equal("ABCDEFGHIJ", m.GetObjectValue(2)); Assert.Equal("01234567890123456789012345", HexCodec.HexEncode((sbyte[])m.GetObjectValue(3), 0, 13)); Assert.Equal("ZZZZZZZZ", m.GetObjectValue(4)); }
public override IsoValue ParseBinary(int field, sbyte[] buf, int pos, ICustomField custom) { if (pos < 0) { throw new ParseException($"Invalid BINARY field {field} position {pos}"); } if (pos + Length > buf.Length) { throw new ParseException($"Insufficient data for BINARY field {field} of length {Length}, pos {pos}"); } var v = new sbyte[Length]; var sbytes = buf; Array.Copy(sbytes, pos, v, 0, Length); if (custom == null) { return(new IsoValue(IsoType, v, Length)); } var dec = custom.DecodeField(HexCodec.HexEncode(v, 0, v.Length)); return(dec == null ? new IsoValue(IsoType, v, 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 TestMessages() { //Create a message with both factories var ascii = _mfactAscii.NewMessage(0x600); var bin = _mfactBin.NewMessage(0x600); Assert.False(ascii.Binary || ascii.BinBitmap); Assert.True(bin.Binary); //HEXencode the binary message, headers should be similar to the ASCII version sbyte[] v = bin.WriteData(); var hexBin = HexCodec.HexEncode(v, 0, v.Length); var hexAscii = ascii.WriteData().SbyteString(Encoding.Default).ToUpper(CultureInfo.CurrentCulture); Assert.Equal("0600", hexBin.Substring(0, 4)); //Should be the same up to the field 42 (first 80 chars) Assert.Equal(hexAscii.Substring(0, 88), hexBin.Substring(0, 88)); Assert.Equal(ascii.GetObjectValue(43), v.SbyteString(44, 40, Encoding.Default).Trim()); //Parse both messages sbyte[] asciiBuf = ascii.WriteData(); IsoMessage ascii2 = _mfactAscii.ParseMessage(asciiBuf, 0); TestParsed(ascii2); Assert.Equal(ascii.GetObjectValue(7).ToString(), ascii2.GetObjectValue(7).ToString()); IsoMessage bin2 = _mfactBin.ParseMessage(bin.WriteData(), 0); //Compare values, should be the same TestParsed(bin2); Assert.Equal(bin.GetObjectValue(7).ToString(), bin2.GetObjectValue(7).ToString()); //Test the debug string ascii.SetValue(60, "XXX", IsoType.LLVAR, 0); bin.SetValue(60, "XXX", IsoType.LLVAR, 0); Assert.Equal(ascii.DebugString(), bin.DebugString()); // "Debug strings differ" Assert.True(ascii.DebugString().Contains("03XXX"), "LLVAR fields wrong"); }
public override IsoValue ParseBinary(int field, sbyte[] buf, int pos, ICustomField custom) { if (pos < 0) { throw new ParseException($"Invalid bin LLBIN field {field} position {pos}"); } if (pos + 1 > buf.Length) { throw new ParseException($"Insufficient bin LLBIN header field {field}"); } var sbytes = buf; var l = ((sbytes[pos] & 0xf0) >> 4) * 10 + (sbytes[pos] & 0x0f); if (l < 0) { throw new ParseException($"Invalid bin LLBIN length {l} pos {pos}"); } if (l + pos + 1 > buf.Length) { throw new ParseException( $"Insufficient data for bin LLBIN field {field}, pos {pos}: need {l}, only {buf.Length} available"); } var v = new sbyte[l]; Array.Copy(sbytes, pos + 1, v, 0, l); if (custom == null) { return(new IsoValue(IsoType, v)); } if (custom is ICustomBinaryField) { try { var dec = ((ICustomBinaryField)custom).DecodeBinaryField(sbytes, pos + 1, l); return(dec == null ? new IsoValue(IsoType, v, v.Length) : new IsoValue(IsoType, dec, l, custom)); } catch (Exception) { throw new ParseException($"Insufficient data for LLBIN field {field}, pos {pos} length {l}"); } } { var dec = custom.DecodeField(HexCodec.HexEncode(v, 0, v.Length)); return(dec == null ? new IsoValue(IsoType, v) : new IsoValue(IsoType, dec, custom)); } }
public string DebugString() { var sb = new StringBuilder(); if (IsoHeader != null) { sb.Append(IsoHeader); } else if (BinIsoHeader != null) { sb.Append("[0x").Append(HexCodec.HexEncode(BinIsoHeader, 0, BinIsoHeader.Length)).Append("]"); } sb.Append(Type.ToString("x4")); //Bitmap var bs = CreateBitmapBitSet(); var pos = 0; var lim = bs.Length / 4; for (var i = 0; i < lim; i++) { var nibble = 0; if (bs.Get(pos++)) { nibble |= 8; } if (bs.Get(pos++)) { nibble |= 4; } if (bs.Get(pos++)) { nibble |= 2; } if (bs.Get(pos++)) { nibble |= 1; } var string0 = Hex.SignedBytesToString(nibble, 1, Encoding); sb.Append(string0); } //Fields for (var i = 2; i < 129; i++) { var v = _fields[i]; if (v == null) { continue; } var desc = v.ToString(); if (v.Type == IsoType.LLBIN || v.Type == IsoType.LLVAR) { sb.Append(desc.Length.ToString("D2")); } else if (v.Type == IsoType.LLLBIN || v.Type == IsoType.LLLVAR) { sb.Append(desc.Length.ToString("D3")); } else if (v.Type == IsoType.LLLLBIN || v.Type == IsoType.LLLLVAR) { sb.Append(desc.Length.ToString("D4")); } sb.Append(desc); } return(sb.ToString()); }
public void TestPartial() { Assert.Equal("FF01", HexCodec.HexEncode(new byte[] { 0, 0xff, 1, 2, 3, 4 }.ToInt8(), 1, 2)); }
public void TestPartial() { Assert.Equal("FF01", HexCodec.HexEncode(new byte[] { 0, (byte)0xff, 1, 2, 3, 4 }.ToSignedBytes(), 1, 2)); }
private void TestFieldType(IsoType type, FieldParseInfo fieldParser, int offset1, int offset2) { var bigintCodec = new BigIntBcdCodec(); var longCodec = new LongBcdCodec(); var mfact = new MessageFactory <IsoMessage>(); var tmpl = new IsoMessage { Binary = true, Type = 0x200 }; tmpl.SetValue(2, 1234567890L, longCodec, type, 0); tmpl.SetValue(3, b29, bigintCodec, type, 0); mfact.AddMessageTemplate(tmpl); mfact.SetCustomField(2, longCodec); mfact.SetCustomField(3, bigintCodec); var parser = new Dictionary <int, FieldParseInfo> { { 2, fieldParser }, { 3, fieldParser } }; mfact.SetParseMap(0x200, parser); mfact.UseBinaryMessages = true; //Test encoding tmpl = mfact.NewMessage(0x200); var buf = tmpl.WriteData(); var message = HexCodec.HexEncode(buf, 0, buf.Length); Console.WriteLine("MESSAGE: " + message); for (var i = 0; i < 5; i++) { var b = longData2[i]; Assert.Equal(b, buf[i + offset1]); } for (var i = 0; i < 15; i++) { Assert.Equal(bigintData1[i], buf[i + offset2]); } //Test parsing tmpl = mfact.ParseMessage(buf, 0); Assert.Equal(1234567890L, tmpl.GetObjectValue(2)); Assert.Equal(b29, tmpl.GetObjectValue(3)); }
public override string ToString() { if (Value == null) { return("ISOValue<null>"); } switch (Type) { case IsoType.NUMERIC: case IsoType.AMOUNT: if (Type == IsoType.AMOUNT) { if (Value is decimal) { return(Type.Format((decimal)Value, 12)); } else { return(Type.Format(Convert.ToDecimal(Value), 12)); } } else if (Value is BigInteger) { return(Type.Format(Encoder == null ? Value.ToString() : Encoder.EncodeField(Value), Length)); } else if (Value is long) { return(Type.Format((long)Value, Length)); } else { return(Type.Format(Encoder == null ? Value.ToString() : Encoder.EncodeField(Value), Length)); } case IsoType.ALPHA: return(Type.Format(Encoder == null ? Value.ToString() : Encoder.EncodeField(Value), Length)); case IsoType.LLVAR: case IsoType.LLLVAR: case IsoType.LLLLVAR: return(Encoder == null?Value.ToString() : Encoder.EncodeField(Value)); } if (Value is DateTime) { return(Type.Format((DateTime)Value)); } switch (Type) { case IsoType.BINARY: if (Value is sbyte[]) { var v = (sbyte[])Value; return(Type.Format(Encoder == null ? HexCodec.HexEncode(v, 0, v.Length) : Encoder.EncodeField(Value), Length * 2)); } else { return(Type.Format(Encoder == null ? Value.ToString() : Encoder.EncodeField(Value), Length * 2)); } case IsoType.LLBIN: case IsoType.LLLBIN: case IsoType.LLLLBIN: if (Value is sbyte[]) { var v = (sbyte[])Value; return(Encoder == null ? HexCodec.HexEncode(v, 0, v.Length) : Encoder.EncodeField(Value)); } else { var s = Encoder == null?Value.ToString() : Encoder.EncodeField(Value); return(s.Length % 2 == 1 ? $"0{s}" : s); } } return(Encoder == null?Value.ToString() : Encoder.EncodeField(Value)); }
public override IsoValue ParseBinary(int field, sbyte[] buf, int pos, ICustomField custom) { if (pos < 0) { throw new ParseException($"Invalid bin LLLLBIN field {field} pos {pos}"); } if (pos + 2 > buf.Length) { throw new ParseException($"Insufficient LLLLBIN header field {field}"); } int l = ((buf[pos] & 0xf0) * 1000) + ((buf[pos] & 0x0f) * 100) + (((buf[pos + 1] & 0xf0) >> 4) * 10) + (buf[pos + 1] & 0x0f); if (l < 0) { throw new ParseException($"Invalid LLLLBIN length {l} field {field} pos {pos}"); } if (l + pos + 2 > buf.Length) { throw new ParseException( $"Insufficient data for bin LLLLBIN field {field}, pos {pos} requires {l}, only {buf.Length - pos + 1} available"); } var v = new sbyte[l]; Array.Copy(buf, pos + 2, v, 0, l); if (custom == null) { return(new IsoValue(IsoType, v)); } var customBinaryField = custom as ICustomBinaryField; if (customBinaryField != null) { try { var dec = customBinaryField.DecodeBinaryField(buf, pos + 2, l); return(dec == null ? new IsoValue(IsoType, v, v.Length) : new IsoValue(IsoType, dec, l, custom)); } catch (Exception) { throw new ParseException($"Insufficient data for LLLLBIN field {field}, pos {pos}"); } } { var dec = custom.DecodeField(HexCodec.HexEncode(v, 0, v.Length)); return(dec == null ? new IsoValue(IsoType, v) : new IsoValue(IsoType, dec, custom)); } }
public override string ToString() { if (Value == null) { return("ISOValue<null>"); } switch (Type) { case IsoType.NUMERIC: case IsoType.AMOUNT: if (Type == IsoType.AMOUNT) { if (Value is decimal value) { return(Type.Format(value, 12)); } else { return(Type.Format(Convert.ToDecimal(Value), 12)); } } else { return Value switch { BigInteger _ => Type.Format(Encoder == null ? Value.ToString() : Encoder.EncodeField(Value), Length), long l => Type.Format(l, Length), _ => Type.Format(Encoder == null ? Value.ToString() : Encoder.EncodeField(Value), Length) } }; case IsoType.ALPHA: return(Type.Format(Encoder == null ? Value.ToString() : Encoder.EncodeField(Value), Length)); case IsoType.LLVAR: case IsoType.LLLVAR: case IsoType.LLLLVAR: return(Encoder == null?Value.ToString() : Encoder.EncodeField(Value)); } if (Value is DateTime dateTime) { return(Type.Format(dateTime)); } switch (Type) { case IsoType.BINARY: if (Value is sbyte[] v1) { return(Type.Format(Encoder == null ? HexCodec.HexEncode(v1, 0, v1.Length) : Encoder.EncodeField(v1), Length * 2)); } else { return(Type.Format(Encoder == null ? Value.ToString() : Encoder.EncodeField(Value), Length * 2)); } case IsoType.LLBIN: case IsoType.LLLBIN: case IsoType.LLLLBIN: if (Value is sbyte[] v) { return(Encoder == null ? HexCodec.HexEncode(v, 0, v.Length) : Encoder.EncodeField(v)); } else { var s = Encoder == null?Value.ToString() : Encoder.EncodeField(Value); return(s.Length % 2 == 1 ? $"0{s}" : s); } } return(Encoder == null?Value.ToString() : Encoder.EncodeField(Value)); }