/// <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); }
/// <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); }
/// <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); }
/// <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); }