예제 #1
0
        /// <summary>
        /// Retrieves all IsoField Attributes and Properties of TMessage Class
        /// </summary>
        /// <typeparam name="TMessage">TMessage</typeparam>
        /// <param name="messageType">message type</param>
        /// <returns>A Dictionary of TMessage Properties and IsoField Attributes of TMessage Class</returns>
        internal static Dictionary <PropertyInfo, IsoFieldAttribute> PropsAndIsoFieldAttributes <TMessage>(this Type messageType) where TMessage : BaseMessage
        {
#if NET40
            IEnumerable <PropertyInfo> isoFieldProps = messageType?.GetProperties().Where(
                prop => Attribute.GetCustomAttributes(prop).Any(attr => attr.GetType() == typeof(IsoFieldAttribute)));
#else
            IEnumerable <PropertyInfo> isoFieldProps = messageType?.GetProperties().Where(
                prop => prop.GetCustomAttributes().Any(attr => attr.GetType() == typeof(IsoFieldAttribute)));
#endif

            if (!isoFieldProps.Any())
            {
                throw new ArgumentException($"for type {messageType?.FullName} they have not been defined any properties with attibute of IsoFieldAttribute");
            }

            var isoAPropsttributesOfT = new Dictionary <PropertyInfo, IsoFieldAttribute>();

            foreach (PropertyInfo isoFieldProp in isoFieldProps)
            {
#if NET40
                IsoFieldAttribute isoFieldFieldAttr = (IsoFieldAttribute)Attribute.GetCustomAttribute(isoFieldProp, typeof(IsoFieldAttribute));
#else
                IsoFieldAttribute isoFieldFieldAttr = isoFieldProp.GetCustomAttribute <IsoFieldAttribute>();
#endif
                isoAPropsttributesOfT.Add(isoFieldProp, isoFieldFieldAttr);
            }

            return(isoAPropsttributesOfT);
        }
예제 #2
0
        /// <summary>
        /// Gets Custom Field Len according to Len Bytes
        /// </summary>
        /// <param name="isoFieldAttribute">iso Field Attribute</param>
        /// <param name="isoMessageBytes">iso message bytes</param>
        /// <param name="currentPos">current parsing position</param>
        /// <returns>length of Custom Field parsed</returns>
        internal static int TagFieldLength(this IsoFieldAttribute isoFieldAttribute, byte[] isoMessageBytes, ref int currentPos)
        {
            var fieldLen    = 0;
            var fieldValue  = string.Empty;
            var lengthBytes = (int)isoFieldAttribute.LengthType;

            if (isoFieldAttribute.LenDataType == DataType.ASCII)
            {
                var lenValue = isoMessageBytes.Skip(currentPos).Take(lengthBytes).ToASCIIString(isoFieldAttribute.Encoding);
                fieldLen = int.Parse(lenValue);
            }
            else if (isoFieldAttribute.LenDataType == DataType.HEX)
            {
                var lenValue = isoMessageBytes.Skip(currentPos).Take(lengthBytes).ToASCIIString(isoFieldAttribute.Encoding);
                fieldLen = lenValue.HexValueToInt();
            }
            else if (isoFieldAttribute.LenDataType == DataType.BCD)
            {
                lengthBytes = lengthBytes - 1;
                var lenValue = isoMessageBytes.Skip(currentPos).Take(lengthBytes).ToArray().BDCToString();
                fieldLen = int.Parse(lenValue);
            }

            currentPos = currentPos + lengthBytes;

            return(fieldLen);
        }
예제 #3
0
        /// <summary>
        /// Parse BitMap of Message to be Parsed
        /// </summary>
        /// <typeparam name="TMessage">TMessage class, a derived class of BaseMessage class</typeparam>
        /// <param name="message">message instance</param>
        /// <param name="isoMessageBytes">messageBytes</param>
        /// <param name="currentPos">position to Read</param>
        /// <returns>BitMap Value</returns>
        private string ParseBitMap <TMessage>(TMessage message, byte[] isoMessageBytes, ref int currentPos) where TMessage : BaseMessage, new()
        {
            IsoFieldAttribute bitMapIsoField = message.GetIsoFieldByPropName(nameof(BaseMessage.BitMap));
            var bitMap = bitMapIsoField.GetFieldValue(isoMessageBytes, ref currentPos);

            //Second BitMap Exists Read More Data
            if (bitMap.ToBinaryStringFromHex().First() == '1')
            {
                return(bitMap + bitMapIsoField.GetFieldValue(isoMessageBytes, ref currentPos));
            }

            return(bitMap);
        }
예제 #4
0
        /// <summary>
        /// Parse a byte[] iso Message to an Instance of TMessage
        /// </summary>
        /// <typeparam name="TMessage">TMessage class, a derived class of BaseMessage class</typeparam>
        /// <param name="isoMessageBytes">bytes of received Message</param>
        /// <returns>an Instance of TMessage</returns>
        public TMessage Parse <TMessage>(byte[] isoMessageBytes) where TMessage : BaseMessage, new()
        {
            var currentPosition = 0;
            var messageIntance  = new TMessage();

            IsoFieldAttribute mtiIsoField = messageIntance.GetIsoFieldByPropName(nameof(messageIntance.MTI));

            messageIntance.MTI = mtiIsoField.GetFieldValue(isoMessageBytes, ref currentPosition);

            messageIntance.BitMap = ParseBitMap(messageIntance, isoMessageBytes, ref currentPosition);
            ParseFields(ref messageIntance, isoMessageBytes, currentPosition);
            return(messageIntance);
        }
예제 #5
0
        /// <summary>
        /// Builds Byte[] from Instance of Message
        /// </summary>
        /// <typeparam name="TMessage">TMessage class, a derived class of BaseMessage class</typeparam>
        /// <param name="message">message instance</param>
        /// <param name="MTI">MTI Response value</param>
        /// <param name="notIncludeFields">whether the BitMap will Contain Fields without values</param>
        /// <returns>byte array Iso Message</returns>
        public byte[] Build <TMessage>(TMessage message, string MTI, params IsoFields[] notIncludeFields) where TMessage : BaseMessage, new()
        {
            IEnumerable <int> orderedFieldPositions = message.MessagePropsIsoFieldAttributes.Select(c => (int)c.Value.Position);

            IsoFieldAttribute mtiIsoField = message.GetIsoFieldByPropName(nameof(message.MTI));
            var mtiBytes = mtiIsoField.BuildFieldValue(MTI);

            var messageBytes = new List <byte>(mtiBytes);

            IEnumerable <int> fieldsForBitMap = orderedFieldPositions.Where(pos => !notIncludeFields.Contains((IsoFields)pos));

            messageBytes.AddRange(BuildBitMap(message, fieldsForBitMap));

            IEnumerable <int> fieldsToBuild = fieldsForBitMap.Where(pos => pos != (int)IsoFields.F1 && pos != (int)IsoFields.BitMap && pos != (int)IsoFields.MTI);

            BuildFields(fieldsToBuild, message, ref messageBytes);
            return(messageBytes.ToArray());
        }
예제 #6
0
        private IEnumerable <byte> BuildTagFields(CustomField valueForMessage, IsoFieldAttribute propAttr)
        {
            var customFieldBytes = new List <byte>();

            foreach ((PropertyInfo propInfo, TagAttribute propTagAttr) in valueForMessage.TagPropsIsoFieldAttributes)
            {
                var tagFieldValue = GetValueFromInstance(valueForMessage, propInfo);

                if (tagFieldValue == null)
                {
                    continue;
                }

                customFieldBytes.AddRange(propTagAttr.GetTagBytes(tagFieldValue.ToString()));
            }

            return(customFieldBytes);
        }
예제 #7
0
        internal static byte[] BuildCustomFieldLentgh(this IsoFieldAttribute isoFieldAttribute, string lenValue)
        {
            lenValue = lenValue.PadLeft((int)isoFieldAttribute.LengthType, '0');

            switch (isoFieldAttribute.LenDataType)
            {
            case DataType.ASCII:
                return(lenValue.FromASCIIToBytes(isoFieldAttribute.Encoding));

            case DataType.HEX:
                var intLen = int.Parse(lenValue);
                return(intLen.IntToHexValue((int)isoFieldAttribute.LengthType).FromASCIIToBytes(isoFieldAttribute.Encoding));

            case DataType.BCD:
                return(lenValue.ConvertToBinaryCodedDecimal(false, (int)isoFieldAttribute.LengthType - 1));

            default:
                throw new BuildFieldException(isoFieldAttribute, $"Cannot Parse Length value for {isoFieldAttribute?.Position} and Len Type {isoFieldAttribute?.LenDataType}");
            }
        }
예제 #8
0
        /// <summary>
        /// Builds BitMap value of Message to Send
        /// </summary>
        /// <typeparam name="TMessage">TMessage class, a derived class of BaseMessage class</typeparam>
        /// <param name="message">message instance</param>
        /// <param name="orderedFields">ordered fields positions</param>
        /// <returns>byte array bitMap value</returns>
        private byte[] BuildBitMap <TMessage>(TMessage message, IEnumerable <int> orderedFields) where TMessage : BaseMessage, new()
        {
            var secondBitRequired            = orderedFields.Any(pos => pos > 65 && pos < 128);
            IsoFieldAttribute bitMapIsoField = message.GetIsoFieldByPropName(nameof(BaseMessage.BitMap));

            char[] bitmapBinaryArray = null;

            if (secondBitRequired)
            {
                bitmapBinaryArray    = new char[129];
                bitmapBinaryArray[1] = '1';
            }
            else
            {
                bitmapBinaryArray    = new char[65];
                bitmapBinaryArray[1] = '0';
            }
            //Building BitMap
            for (var i = 2; i < bitmapBinaryArray.Length; i++)
            {
                if (orderedFields.Contains(i))
                {
                    bitmapBinaryArray[i] = '1';
                }
                else
                {
                    bitmapBinaryArray[i] = '0';
                }
            }

            var bitmapString = new string(bitmapBinaryArray);
            var bitMap       = Convert.ToInt64(bitmapString.Substring(1, 64), 2).ToString("X").PadLeft(16, '0');

            if (secondBitRequired)
            {
                bitMap = bitMap + Convert.ToInt64(bitmapString.Substring(65, 64), 2).ToString("X").PadLeft(16, '0');
            }

            return(bitMapIsoField.BuildFieldValue(bitMap));
        }
예제 #9
0
        /// <summary>
        /// Build Bytes from Field Value
        /// </summary>
        /// <param name="isoFieldAttribute">isofield attribute of Property</param>
        /// <param name="fieldValue">field value</param>
        /// <returns>byte array value of Field</returns>
        internal static byte[] BuildFieldValue(this IsoFieldAttribute isoFieldAttribute, string fieldValue)
        {
            var fieldBytes = new List <byte>();

            try
            {
                switch (isoFieldAttribute.LengthType)
                {
                case LengthType.FIXED:
                    if (fieldValue.Length < isoFieldAttribute.MaxLen)
                    {
                        fieldValue = fieldValue?.PadRight(isoFieldAttribute.MaxLen);
                    }
                    break;

                case LengthType.LVAR:
                case LengthType.LLVAR:
                case LengthType.LLLVAR:
                    if (isoFieldAttribute.LenDataType == DataType.ASCII)
                    {
                        var valueLen = fieldValue?.Length.ToString().PadLeft((int)isoFieldAttribute.LengthType, '0');
                        fieldBytes.AddRange(valueLen.FromASCIIToBytes(isoFieldAttribute.Encoding));
                    }
                    else if (isoFieldAttribute.LenDataType == DataType.HEX)
                    {
                        var valueLen = fieldValue?.Length.IntToHexValue((int)isoFieldAttribute.LengthType);
                        fieldBytes.AddRange(valueLen.FromASCIIToBytes(isoFieldAttribute.Encoding));
                    }
                    else if (isoFieldAttribute.LenDataType == DataType.BCD)
                    {
                        var valueLen = fieldValue?.Length.ToString().ConvertToBinaryCodedDecimal(false);
                        fieldBytes.AddRange(valueLen);
                    }
                    break;

                default:
                    throw new BuildFieldException(isoFieldAttribute, $"Cannot Parse Length value for {isoFieldAttribute?.Position} and Len Type {isoFieldAttribute?.LenDataType}");
                }

                switch (isoFieldAttribute.DataType)
                {
                case DataType.BIN:
                    fieldBytes.AddRange(fieldValue.ToBinaryStringFromHex().ToBytesFromBinaryString());
                    break;

                case DataType.BCD:
                    var bcdValue = fieldValue.ConvertToBinaryCodedDecimal(false);
                    fieldBytes.AddRange(bcdValue);
                    break;

                case DataType.ASCII:
                case DataType.HEX:
                    fieldBytes.AddRange(fieldValue.FromASCIIToBytes(isoFieldAttribute.Encoding));
                    break;

                default:
                    throw new BuildFieldException(isoFieldAttribute, $"Cannot Parse value for {isoFieldAttribute?.Position} and Type {isoFieldAttribute?.DataType}");
                }
            }
            catch (Exception ex)
            {
                throw new BuildFieldException(isoFieldAttribute, $"Cannot Parse value for {isoFieldAttribute?.Position} and Type {isoFieldAttribute?.DataType}", ex);
            }

            return(fieldBytes.ToArray());
        }
예제 #10
0
        /// <summary>
        /// Parses bytes value to an object value
        /// </summary>
        /// <param name="isoFieldAttribute">iso Field Attribute</param>
        /// <param name="isoMessageBytes">whole Message bytes</param>
        /// <param name="currentPos">current Position of Parsed Message bytes, passed as a Reference</param>
        /// <returns>field object value</returns>
        internal static string GetFieldValue(this IsoFieldAttribute isoFieldAttribute, byte[] isoMessageBytes, ref int currentPos)
        {
            var fieldLen    = 0;
            var fieldValue  = string.Empty;
            var lengthBytes = (int)isoFieldAttribute.LengthType;

            try
            {
                switch (isoFieldAttribute.LengthType)
                {
                case LengthType.FIXED:
                case LengthType.LVAR:
                    fieldLen = isoFieldAttribute.MaxLen;
                    break;

                case LengthType.LLVAR:
                case LengthType.LLLVAR:
                    if (isoFieldAttribute.LenDataType == DataType.ASCII)
                    {
                        var lenValue = isoMessageBytes.Skip(currentPos).Take(lengthBytes).ToASCIIString(isoFieldAttribute.Encoding);
                        fieldLen = int.Parse(lenValue);
                    }
                    else if (isoFieldAttribute.LenDataType == DataType.HEX)
                    {
                        var lenValue = isoMessageBytes.Skip(currentPos).Take(lengthBytes).ToASCIIString(isoFieldAttribute.Encoding);
                        fieldLen = lenValue.HexValueToInt();
                    }
                    else if (isoFieldAttribute.LenDataType == DataType.BCD)
                    {
                        lengthBytes = lengthBytes - 1;     //BCD Always one byte less for Lentgh
                        var lenValue = isoMessageBytes.Skip(currentPos).Take(lengthBytes).ToArray().BDCToString();
                        fieldLen = int.Parse(lenValue);
                    }
                    break;

                default:
                    throw new ParseFieldException(isoFieldAttribute, $"Cannot Parse Length value for {isoFieldAttribute?.Position} and Len Type {isoFieldAttribute?.LenDataType}");
                }

                currentPos = currentPos + lengthBytes;

                switch (isoFieldAttribute.DataType)
                {
                case DataType.BIN:
                    fieldValue = isoMessageBytes.Skip(currentPos).Take(fieldLen).ToStringFromBinary();
                    currentPos = currentPos + fieldLen;
                    break;

                case DataType.BCD:
                    if (isoFieldAttribute.ContentType != ContentType.B)
                    {
                        fieldLen = fieldLen % 2 == 1 ? (fieldLen / 2 + 1) : fieldLen / 2;
                    }

                    fieldValue = isoMessageBytes.Skip(currentPos).Take(fieldLen).ToArray().BDCToString();
                    currentPos = currentPos + fieldLen;
                    break;

                case DataType.ASCII:
                    fieldValue = isoMessageBytes.Skip(currentPos).Take(fieldLen).ToASCIIString(isoFieldAttribute.Encoding);
                    currentPos = currentPos + fieldLen;
                    break;

                case DataType.HEX:
                    fieldValue = isoMessageBytes.Skip(currentPos).Take(fieldLen * 2).HexBytesToString();
                    currentPos = currentPos + (fieldLen * 2);
                    break;

                default:
                    throw new ParseFieldException(isoFieldAttribute, $"Cannot Parse value for {isoFieldAttribute?.Position} and Type {isoFieldAttribute?.DataType}");
                }
            }
            catch (Exception ex)
            {
                throw new ParseFieldException(isoFieldAttribute, $"Cannot Parse value for {isoFieldAttribute?.Position} and Type {isoFieldAttribute?.DataType}", ex);
            }

            return(fieldValue);
        }
 /// <summary>
 /// Contructor of Exception
 /// </summary>
 /// <param name="isoFieldAttr">iso field Attribute</param>
 /// <param name="innerEx">Inner exception details</param>
 /// <param name="exMessage">error message</param>
 public BuildFieldException(IsoFieldAttribute isoFieldAttr, string exMessage, Exception innerEx) : base(exMessage, innerEx)
 {
     IsoFieldData = isoFieldAttr;
 }
예제 #12
0
 /// <summary>
 /// Contructor of Exception
 /// </summary>
 /// <param name="isoFieldAttr">iso field Attribute</param>
 /// <param name="exMessage">error message</param>
 public ParseFieldException(IsoFieldAttribute isoFieldAttr, string exMessage) : base(exMessage)
 {
     IsoFieldData = isoFieldAttr;
 }