Beispiel #1
0
        /// <summary>
        /// Receive an HL7 message over the connected network stream.
        /// </summary>
        /// <param name="messageDelimiters">Initial HL7 message delimiters - updated to actual delimters during method.</param>
        /// <returns>Correctly instantiated HL7 message.</returns>
        public Hl7Message ReceiveMessage(out Hl7MessageDelimiters messageDelimiters)
        {
            // initialize the message delimiters to the default values
            messageDelimiters = new Hl7MessageDelimiters();

            Hl7Message hl7Message = new Hl7Message();

            if (_networkStream == null)
            {
                return(null);
            }

            // set the read / write timeouts for this stream - zero means no timeout.
            if (_readTimeout != 0)
            {
                _networkStream.ReadTimeout = _readTimeout;
            }
            if (_writeTimeout != 0)
            {
                _networkStream.WriteTimeout = _writeTimeout;
            }

            // initialise the segment content
            System.String rxSegment = System.String.Empty;

            // initialise the MLLP state
            MllpStateEnum mllpState = MllpStateEnum.WaitingForStartOfMessageChar;

            // loop waiting for the end of message character
            while (mllpState != MllpStateEnum.DoneWaiting)
            {
                // check if data is available on network
                try
                {
                    // get the next character from the stream
                    int rxCode = _networkStream.ReadByte();
                    if (rxCode < 0)
                    {
                        return(null);
                    }

                    char rxChar = (char)rxCode;

                    // switch on MLLP state
                    switch (mllpState)
                    {
                    case MllpStateEnum.WaitingForStartOfMessageChar:
                        // check if we have got the SOM
                        if (rxChar == _StartOfMessageChar)
                        {
                            // reset the segment
                            rxSegment = System.String.Empty;

                            // change state to waiting for end of segment
                            mllpState = MllpStateEnum.WaitingForEndOfSegmentChar;
                        }
                        else
                        {
                            Console.WriteLine("HL7 - MLLP: Waiting for SOM - got {0}...", rxChar);
                        }
                        break;

                    case MllpStateEnum.WaitingForEndOfSegmentChar:
                        // check if we have got the end of segment
                        if (rxChar == _EndOfSegmentChar)
                        {
                            // check if we have the MSH segment
                            // - we need to get the message delimiters
                            if (rxSegment.StartsWith("MSH") == true)
                            {
                                // set the message delimiters to the values received
                                // - we assume that the MSH segment is formatted properly at least in the first few bytes
                                messageDelimiters = new Hl7MessageDelimiters(rxSegment.Substring(3, 5));
                            }

                            // segment is complete
                            Hl7Segment segment = new Hl7Segment();
                            segment.Decode(rxSegment, messageDelimiters);

                            // add the segment to the HL7 message
                            hl7Message.AddSegment(segment);

                            // reset the segment
                            rxSegment = System.String.Empty;
                        }
                        else if (rxChar == _EndOfMessageChar1)
                        {
                            // we have the first end of message - that's OK
                            // check if any characters have been received since the last end of segment
                            if (rxSegment == System.String.Empty)
                            {
                                // change state to waiting for second end of message
                                mllpState = MllpStateEnum.WaitingForEndOfMessageChar;
                            }
                            else
                            {
                                Console.WriteLine("HL7 - MLLP: First EOM does not immediately follow an EOS");
                                return(null);
                            }
                        }
                        else
                        {
                            // save the received character in the current segment
                            rxSegment += rxChar;
                        }
                        break;

                    case MllpStateEnum.WaitingForEndOfMessageChar:
                        // check if we have got the second end of message
                        if (rxChar == _EndOfMessageChar2)
                        {
                            // message is complete
                            mllpState = MllpStateEnum.DoneWaiting;
                        }
                        else
                        {
                            Console.WriteLine("HL7 - MLLP: Second EOM does not immediately follow first EOM");
                            return(null);
                        }
                        break;

                    default:
                        break;
                    }
                }
                catch (System.Exception e)
                {
                    Console.WriteLine("HL7 - MLLP: ReceiveMessage() Exception: {0}", e.Message);
                    return(null);
                }
            }

            // return the correct instantiation of the received HL7 message
            return(Hl7MessageFactory.CreateHl7Message(hl7Message, messageDelimiters));
        }
Beispiel #2
0
        //
        // - Methods -
        //

        /// <summary>
        /// Decode a Hl7Message object from a given stream.
        /// </summary>
        /// <param name="stream">The stream.</param>
        /// <returns>The decoded Hl7Message.</returns>
        internal Hl7Message Decode(System.IO.Stream stream)
        {
            Hl7Message hl7Message = new Hl7Message();

            // initialize the message delimiters to the default values
            _messageDelimiters = new Hl7MessageDelimiters();

            // initialise the segment content
            System.String rxSegment = System.String.Empty;

            // read the first character from the stream to determine if the MLLP is used
            int rxCode = stream.ReadByte();

            if (rxCode < 0)
            {
                throw new System.Exception("Incomplete HL7 stream.");
            }
            stream.Seek(0, System.IO.SeekOrigin.Begin);

            // initialise the MLLP state
            MllpStateEnum mllpState = MllpStateEnum.MllpNotUsed;

            if ((char)rxCode == _StartOfMessageChar)
            {
                // SOM read - use the MLLP protocol
                mllpState = MllpStateEnum.WaitingForStartOfMessageChar;
            }

            // loop waiting for the end of message character
            while (_continueReading)
            {
                // get the next character from the stream
                rxCode = stream.ReadByte();
                if (rxCode < 0)
                {
                    // end of stream reached when not using the MLLP
                    // - check if there is any data left in the rxSegment
                    if ((rxSegment != System.String.Empty) &&
                        (mllpState == MllpStateEnum.MllpNotUsed))
                    {
                        // segment is complete
                        Hl7Segment segment = new Hl7Segment();
                        segment.Decode(rxSegment, _messageDelimiters);

                        // add the segment to the HL7 message
                        hl7Message.AddSegment(segment);
                    }

                    // message is complete
                    _continueReading = false;
                    break;
                }

                char rxChar = (char)rxCode;

                // switch on MLLP state
                switch (mllpState)
                {
                case MllpStateEnum.MllpNotUsed:
                    // check if we have got the end of segment
                    if (rxChar == _EndOfSegmentChar)
                    {
                        // check if we have the MSH segment
                        // - we need to get the message delimiters
                        if (rxSegment.StartsWith("MSH") == true)
                        {
                            // set the message delimiters to the values received
                            // - we assume that the MSH segment is formatted properly at least in the first few bytes
                            _messageDelimiters = new Hl7MessageDelimiters(rxSegment.Substring(3, 5));
                        }

                        // segment is complete
                        Hl7Segment segment = new Hl7Segment();
                        segment.Decode(rxSegment, _messageDelimiters);

                        // add the segment to the HL7 message
                        hl7Message.AddSegment(segment);

                        // reset the segment
                        rxSegment = System.String.Empty;
                    }
                    else if (rxChar == _NewLineChar)
                    {
                        // ignore the line feed character
                    }
                    else
                    {
                        // save the received character in the current segment
                        rxSegment += rxChar;
                    }
                    break;

                case MllpStateEnum.WaitingForStartOfMessageChar:
                    // check if we have got the SOM
                    if (rxChar == _StartOfMessageChar)
                    {
                        // reset the segment
                        rxSegment = System.String.Empty;

                        // change state to waiting for end of segment
                        mllpState = MllpStateEnum.WaitingForEndOfSegmentChar;
                    }
                    else
                    {
                        Console.WriteLine("HL7 - MLLP: Waiting for SOM - got {0}...", rxChar);
                    }
                    break;

                case MllpStateEnum.WaitingForEndOfSegmentChar:
                    // check if we have got the end of segment
                    if (rxChar == _EndOfSegmentChar)
                    {
                        // check if we have the MSH segment
                        // - we need to get the message delimiters
                        if (rxSegment.StartsWith("MSH") == true)
                        {
                            // set the message delimiters to the values received
                            // - we assume that the MSH segment is formatted properly at least in the first few bytes
                            _messageDelimiters = new Hl7MessageDelimiters(rxSegment.Substring(3, 5));
                        }

                        // segment is complete
                        Hl7Segment segment = new Hl7Segment();
                        segment.Decode(rxSegment, _messageDelimiters);

                        // add the segment to the HL7 message
                        hl7Message.AddSegment(segment);

                        // reset the segment
                        rxSegment = System.String.Empty;
                    }
                    else if (rxChar == _EndOfMessageChar1)
                    {
                        // we have the first end of message - that's OK
                        // check if any characters have been received since the last end of segment
                        if (rxSegment == System.String.Empty)
                        {
                            // change state to waiting for second end of message
                            mllpState = MllpStateEnum.WaitingForEndOfMessageChar;
                        }
                        else
                        {
                            Console.WriteLine("HL7 - MLLP: First EOM does not immediately follow an EOS");
                            return(null);
                        }
                    }
                    else
                    {
                        // save the received character in the current segment
                        rxSegment += rxChar;
                    }
                    break;

                case MllpStateEnum.WaitingForEndOfMessageChar:
                    // check if we have got the second end of message
                    if (rxChar == _EndOfMessageChar2)
                    {
                        // message is complete
                        _continueReading = false;
                    }
                    else
                    {
                        Console.WriteLine("HL7 - MLLP: Second EOM does not immediately follow first EOM");
                        return(null);
                    }
                    break;

                default:
                    break;
                }
            }

            // return the correct instantiation of the received HL7 message
            return(Hl7MessageFactory.CreateHl7Message(hl7Message, _messageDelimiters));
        }