Example #1
0
        /// <summary>
        /// It decodes the data.
        /// </summary>
        /// <param name="parserContext">
        /// It's the parser context holding the data to be parsed.
        /// </param>
        /// <param name="length">
        /// It's the length of the data to get from the parser context.
        /// </param>
        /// <returns>
        /// A byte array with the decoded data.
        /// </returns>
        public byte[] Decode(ref ParserContext parserContext, int length)
        {
            if (parserContext.DataLength < (length << 1))
            {
                throw new ArgumentException(SR.InsufficientData, "length");
            }

            byte[] result = new byte[length];
            byte[] buffer = parserContext.GetBuffer();
            int    offset = parserContext.LowerDataBound;

            for (int i = offset + (length << 1) - 1; i >= offset; i--)
            {
                int right = buffer[i] > 0x40 ? 10 + (buffer[i] > 0x60 ?
                                                     buffer[i] - 0x61 : buffer[i] - 0x41) : buffer[i] - 0x30;
                int left = buffer[--i] > 0x40 ? 10 + (buffer[i] > 0x60 ?
                                                      buffer[i] - 0x61 : buffer[i] - 0x41) : buffer[i] - 0x30;

                result[(i - offset) >> 1] = ( byte)((left << 4) | right);
            }

            parserContext.Consumed(length << 1);

            return(result);
        }
Example #2
0
        /// <summary>
        /// Convierte los datos formateados del indicador de largo
        /// de los datos del componente de mensajería.
        /// </summary>
        /// <param name="parserContext">
        /// Es el contexto de análisis y construcción de mensajes donde
        /// reside la información a decodificar.
        /// </param>
        /// <returns>
        /// Es el largo de los datos del componente de mensajería.
        /// </returns>
        public int Decode(ref ParserContext parserContext)
        {
            // Check available data.
            if (parserContext.DataLength < (_lengthsIndex + 1))
            {
                throw new ArgumentException(SR.InsufficientData, "parserContext");
            }

            int length = 0;

            byte[] buffer = parserContext.GetBuffer();
            int    offset = parserContext.LowerDataBound;

            // Decode length.
            for (int i = offset; i < (offset + _lengthsIndex + 1); i++)
            {
                if ((buffer[i] < 0x30) || (buffer[i] > 0x39))
                {
                    throw new MessagingException(SR.InvalidByteLengthDetected(buffer[i]));
                }

                length = length * 10 + buffer[i] - 0x30;
            }

            // Consume parser context data.
            parserContext.Consumed(_lengthsIndex + 1);

            return(length);
        }
Example #3
0
        /// <summary>
        /// It decodes the data.
        /// </summary>
        /// <param name="parserContext">
        /// It's the parser context holding the data to be parsed.
        /// </param>
        /// <param name="length">
        /// It's the length of the data to get from the parser context.
        /// </param>
        /// <returns>
        /// A byte array with the decoded data.
        /// </returns>
        public byte[] Decode(ref ParserContext parserContext, int length)
        {
            if (parserContext.DataLength < ((length + 1) >> 1))
            {
                throw new ArgumentException(SR.InsufficientData, "length");
            }

            byte[] result = new byte[length];
            byte[] buffer = parserContext.GetBuffer();
            int    offset = parserContext.LowerDataBound;
            int    start  = (((length & 1) == 1) && _leftPadded) ? 1 : 0;

            for (int i = start; i < length + start; i++)
            {
                int shift = ((i & 1) == 1 ? 0 : 4);

                byte c = ( byte )((buffer[offset + (i >> 1)] >> shift) & 0x0F);

                if (c < 10)
                {
                    c += 0x30;
                }
                else
                {
                    c += 0x37;
                }

                result[i - start] = c;
            }

            parserContext.Consumed((length + 1) >> 1);

            return(result);
        }
        /// <summary>
        /// Gets the encoded length from the parser context.
        /// </summary>
        /// <param name="parserContext">
        /// It's the parser context holding the data to be parsed.
        /// </param>
        /// <returns>
        /// The length parsed from the parser context.
        /// </returns>
        public int Decode(ref ParserContext parserContext)
        {
            // Check available data.
            if (parserContext.DataLength < (_lengthsIndex + 1))
            {
                throw new ArgumentException(SR.InsufficientData, "parserContext");
            }

            int length = 0;
            int value;

            byte[] buffer = parserContext.GetBuffer();
            int    offset = parserContext.LowerDataBound;

            // Decode length.
            for (int i = offset; i <= (offset + _lengthsIndex); i++)
            {
                value = (buffer[i] & 0xF0) >> 4;
                if (value > 9)
                {
                    throw new MessagingException(SR.InvalidLengthDetected(value));
                }
                length = length * 10 + value;

                value = buffer[i] & 0x0F;
                if (value > 9)
                {
                    throw new MessagingException(SR.InvalidLengthType(value));
                }
                length = length * 10 + value;
            }

            // Consume parser context data.
            parserContext.Consumed(_lengthsIndex + 1);

            return(length);
        }
Example #5
0
        /// <summary>
        /// Gets the encoded length from the parser context.
        /// </summary>
        /// <param name="parserContext">
        /// It's the parser context holding the data to be parsed.
        /// </param>
        /// <returns>
        /// The length parsed from the parser context.
        /// </returns>
        public int Decode(ref ParserContext parserContext)
        {
            // Check available data.
            if (parserContext.DataLength < (_lengthsIndex + 1))
            {
                throw new ArgumentException(SR.InsufficientData, "parserContext");
            }

            int length = 0;

            byte[] buffer = parserContext.GetBuffer();
            int    offset = parserContext.LowerDataBound;

            // Decode length.
            for (int i = offset; i <= (offset + _lengthsIndex); i++)
            {
                length = (length * 256) + (( int )buffer[i]);
            }

            // Consume parser context data.
            parserContext.Consumed(_lengthsIndex + 1);

            return(length);
        }
        /// <summary>
        /// It parses the data contained in the parser context.
        /// </summary>
        /// <param name="parserContext">
        /// It's the context holding the information to produce a new message instance.
        /// </param>
        /// <returns>
        /// The parsed message, or a null reference if the data contained in the context
        /// is insufficient to produce a new message.
        /// </returns>
        public virtual Message Parse(ref ParserContext parserContext)
        {
            // Create a new message if we are parsing a new one.
            if (parserContext.CurrentMessage == null)
            {
                parserContext.CurrentMessage = NewMessage();
                // The message must known its formatter for message.ToString()
                parserContext.CurrentMessage.Formatter = this;
            }

            // Remove packet header data.
            if ((_packetHeader != null) && !parserContext.PacketHeaderDataStripped)
            {
                parserContext.Consumed(_packetHeader.Length);
                parserContext.PacketHeaderDataStripped = true;
            }

            // Parse header if we have a header formatter.
            if (_headerFormatter != null)
            {
                // Check if the header hasn't been parsed yet.
                if (parserContext.CurrentMessage.Header == null)
                {
                    try {
                        parserContext.CurrentMessage.Header =
                            _headerFormatter.Parse(ref parserContext);
                    } catch (Exception e) {
                        throw new MessagingException(SR.CantParseMessageHeader, e);
                    }

                    // If null, more data is needed.
                    if (parserContext.CurrentMessage.Header == null)
                    {
                        return(null);
                    }

                    parserContext.ResetDecodedLength();
                }
            }

            // Allow subclasses to get information between header data and
            // fields data.
            if (!parserContext.Signaled)
            {
                if (!BeforeFieldsParsing(parserContext.CurrentMessage, ref parserContext))
                {
                    return(null);
                }
                parserContext.Signaled = true;
            }

            for (int i = parserContext.CurrentField;
                 i <= _fieldsFormatters.MaximumFieldFormatterNumber; i++)
            {
                // If we have a bitmap use it to detect present fields,
                // otherwise parse known message formatter fields.
                if (parserContext.CurrentBitMap != null)
                {
                    // Check if field number is out of bitmap bounds.
                    if (i > parserContext.CurrentBitMap.UpperFieldNumber)
                    {
                        // Locate another bitmap.
                        bool found = false;
                        for (int j = parserContext.CurrentBitMap.FieldNumber + 1;
                             j < i; j++)
                        {
                            if (parserContext.CurrentMessage.Fields.Contains(j))
                            {
                                Field field = parserContext.CurrentMessage.Fields[j];
                                if (field is BitMapField)
                                {
                                    // Another bitmap found.
                                    parserContext.CurrentBitMap = ( BitMapField)field;
                                    found = true;
                                    break;
                                }
                            }
                        }

                        if (!found)
                        {
                            parserContext.CurrentBitMap = null;

                            // No more bitmaps, continue with posible mandatory fields
                            // (start from last field covered by known bitmaps, plus one).
                            i = ((BitMapFieldFormatter)
                                 (_fieldsFormatters[_bitmaps[_bitmaps.Length - 1]])).UpperFieldNumber + 1;
                            continue;
                        }
                    }

                    if (!parserContext.CurrentBitMap[i])
                    {
                        // Save current field number in context.
                        parserContext.CurrentField = i;

                        // Bit is not set, field is not present in the received data.
                        continue;
                    }
                }

                // Save current field number in context.
                parserContext.CurrentField = i;

                if (_fieldsFormatters.Contains(i))
                {
                    // Get field formatter.
                    FieldFormatter fieldFormatter = _fieldsFormatters[i];

                    Field field;
                    try {
                        // to parse field.
                        field = fieldFormatter.Parse(ref parserContext);
                    } catch (Exception e) {
                        throw new MessagingException(SR.CantParseField(i), e);
                    }

                    if (field == null)
                    {
                        if (Logger.IsDebugEnabled)
                        {
                            Logger.Debug(SR.MoreDataNeeded);
                        }

                        // More data needed to parse message.
                        return(null);
                    }
                    else
                    {
                        parserContext.CurrentMessage.Fields.Add(field);

                        // Set parent message.
                        if (field is InnerMessageField)
                        {
                            InnerMessageField innerMessageField = field as InnerMessageField;
                            Message           innerMessage      = innerMessageField.Value as Message;
                            if (innerMessage != null)
                            {
                                innerMessage.Parent = parserContext.CurrentMessage;
                            }
                        }

                        if (Logger.IsDebugEnabled)
                        {
                            if (field is BitMapField)
                            {
                                Logger.Debug(SR.DecodedBitmap(field.FieldNumber, field.ToString()));
                            }
                            else
                            {
                                Logger.Debug(SR.DecodedField(field.FieldNumber, field.ToString()));
                            }
                        }

                        parserContext.ResetDecodedLength();

                        // If this is the first located bitmap, save it.
                        if ((parserContext.CurrentBitMap == null) &&
                            (field is BitMapField))
                        {
                            parserContext.CurrentBitMap = ( BitMapField)field;
                        }
                    }
                }
                else
                {
                    if (parserContext.CurrentBitMap != null)
                    {
                        // A field is present in current bitmap, but message formatter
                        // can't parse it because field formatter isn't present.
                        throw new MessagingException(SR.UnknownFormatter(i));
                    }
                }
            }

            // We have a new message, get it and initialize parsing context.
            Message parsedMessage = parserContext.CurrentMessage;

            // Reset parser context.
            parserContext.MessageHasBeenConsumed();

            return(parsedMessage);
        }