/// <summary> /// Class constructor. /// </summary> /// <param name="messageType">Message Type</param> /// <param name="messageSubType">Message Sub Type</param> public Hl7Message(System.String messageType, System.String messageSubType) { // constructor activities _messageType = messageType; _messageSubType = messageSubType; _segments = new Hashtable(); Hl7Segment segment = new Hl7Segment(0, Hl7SegmentEnum.MSH); _segments.Add(segment.SegmentId.Id, segment); // Set up MSH segment // - use default message delimiters for now Hl7MessageDelimiters messageDelimiters = new Hl7MessageDelimiters(); FieldDelimiter = messageDelimiters.FieldDelimiter; EncodingCharacters = messageDelimiters.ComponentDelimiter + messageDelimiters.RepetitionSeparator + messageDelimiters.EscapeCharacter + messageDelimiters.SubComponentDelimiter; SendingApplication = "DVTK-IHE"; SendingFacility = "DVTK"; ReceivingApplication = "DVTK-IHE"; ReceivingFacility = "DVTK"; ProcessingId = "P"; VersionId = "2.3.1"; if (messageSubType == System.String.Empty) { this.MSH[9] = messageType; } else { this.MSH[9] = messageType + messageDelimiters.ComponentDelimiter + messageSubType; } }
/// <summary> /// Generate string representation to HL7 Message - include the end of segment character. /// </summary> /// <param name="messageDelimiters">HL7 message delimiters.</param> /// <param name="addNewLine">Add new line boolean - for display purposes.</param> /// <returns>string - HL7 ER7 format string.</returns> private System.String ToString(Hl7MessageDelimiters messageDelimiters, bool addNewLine) { System.String stringValue = System.String.Empty; // stream all the segments - ordered by sequence number and then segment index int sequenceNumber = 0; int segmentIndex = 1; bool streaming = true; while (streaming == true) { bool segmentStreamed = false; ICollection segments = _segments.Values; foreach (Hl7Segment hl7Segment in segments) { if (hl7Segment.SequenceNumber == sequenceNumber) { if (hl7Segment.SegmentId.SegmentIndex == segmentIndex) { System.String encodedStream = hl7Segment.Encode(messageDelimiters); if (encodedStream != System.String.Empty) { stringValue += (encodedStream + _EndOfSegmentChar); if (addNewLine == true) { // for display purposes only stringValue += _NewLineChar; } } segmentIndex++; segmentStreamed = true; break; } } } if (segmentStreamed == false) { if (sequenceNumber < _segments.Count) { sequenceNumber++; segmentIndex = 1; } else { streaming = false; } } } return(stringValue); }
private System.String ReplaceString(System.String inputString, Hl7MessageDelimiters messageDelimiters) { // get the default message delimiters - these will have been used in the HL7 scripts, etc Hl7MessageDelimiters defaultMessageDelimiters = new Hl7MessageDelimiters(); // update the string to use the given message delimiters System.String localString1 = inputString.Replace(defaultMessageDelimiters.ComponentDelimiter, messageDelimiters.ComponentDelimiter); System.String localString2 = localString1.Replace(defaultMessageDelimiters.SubComponentDelimiter, messageDelimiters.SubComponentDelimiter); System.String outputString = localString2.Replace(defaultMessageDelimiters.RepetitionSeparator, messageDelimiters.RepetitionSeparator); return(outputString); }
/// <summary> /// Decode the segment. The HL7 message delimiters has been set to the correct value before calling this method. /// </summary> /// <param name="segmentString">Encoded segment string.</param> /// <param name="messageDelimiters">HL7 message delimiters to use to encode the message.</param> public void Decode(System.String segmentString, Hl7MessageDelimiters messageDelimiters) { int index = 0; System.String val = System.String.Empty; int i = 0; bool isVal = false; while (i < segmentString.Length) { if (segmentString.Substring(i, 1) == messageDelimiters.FieldDelimiter) { _values.Insert(index, val); index++; if ((index == 1) && ((System.String)_values[0] == "MSH")) { // special insert for the field delimiter itself. _values.Insert(index, messageDelimiters.FieldDelimiter); index++; } val = System.String.Empty; isVal = false; } else { val += segmentString[i]; isVal = true; } i++; } if (isVal == true) { _values.Insert(index, val); } if (_values.Count > 0) { // use segment index 0 here - the correct value will be determined when the segment is added to the message _segmentId = new Hl7SegmentId(SegmentNames.NameEnum((System.String)_values[0]), 0); } }
/// <summary> /// Encode the segment. /// </summary> /// <param name="messageDelimiters">HL7 message delimiters to use to encode the message.</param> /// <returns>String - encoded segment.</returns> public System.String Encode(Hl7MessageDelimiters messageDelimiters) { System.String segment = System.String.Empty; if (_values.Count > 1) { if (_segmentId.SegmentName == Hl7SegmentEnum.MSH) { // initialize the first fields of the MSH segment segment = (System.String)_values[0] + messageDelimiters.ToString() + messageDelimiters.FieldDelimiter; // ecode the rest of the MSH segment from the 3rd field for (int index = 3; index < _values.Count; index++) { segment += ReplaceString((System.String)_values[index], messageDelimiters);; if (index + 1 != _values.Count) { segment += messageDelimiters.FieldDelimiter; } } } else { int index = 0; foreach (System.String val in _values) { segment += ReplaceString(val, messageDelimiters); index++; if (index != _values.Count) { segment += messageDelimiters.FieldDelimiter; } } } } return(segment); }
// // - 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)); }
/// <summary> /// Create a correctly typed HL7 message instance based on the incoming Hl7 message. /// </summary> /// <param name="inHl7Message">Incoming HL7 message.</param> /// <param name="messageDelimiters">HL7 message delimiters.</param> /// <returns>Correctly typed HL7 message instance.</returns> public static Hl7Message CreateHl7Message(Hl7Message inHl7Message, Hl7MessageDelimiters messageDelimiters) { Hl7SegmentId segmentId = new Hl7SegmentId(Hl7SegmentEnum.MSH); Hl7Segment mshSegment = (Hl7Segment)inHl7Message.Segments[segmentId.Id]; // can not determine what kind of message we have - so return the inHl7Message if (mshSegment == null) { return(inHl7Message); } System.String messageType = mshSegment[9]; Hl7Message hl7Message = null; // check for ACK message if (messageType == "ACK") { // now try to get the ORC segment segmentId = new Hl7SegmentId(Hl7SegmentEnum.ORC); Hl7Segment orcSegment = (Hl7Segment)inHl7Message.Segments[segmentId.Id]; if (orcSegment != null) { hl7Message = new OrrMessage(); } else { hl7Message = new AckMessage(); } } else { System.String [] messageTypeComponent = new System.String[3]; messageTypeComponent = messageType.Split(messageDelimiters.ComponentDelimiter[0]); System.String messageMainType = System.String.Empty; if (messageTypeComponent.Length > 0) { messageMainType = messageTypeComponent[0]; } switch (messageMainType) { case "ADR": // ADR message hl7Message = new AdrMessage(); break; case "ADT": // ADT message hl7Message = new AdtMessage(); break; case "ORM": // ORM message hl7Message = new OrmMessage(); break; case "ORU": // ORU message hl7Message = new OruMessage(); break; case "QRY": // QRY message hl7Message = new QryMessage(); break; default: // do not know what kind of HL7 message this is - simply return it return(inHl7Message); } } // add the segments from the inMessage to the new hl7Message ICollection segments = inHl7Message.Segments.Values; foreach (Hl7Segment segment in segments) { hl7Message.CopySegment(segment); } return(hl7Message); }
/// <summary> /// Generate string representation to HL7 Message - include the end of segment character. /// </summary> /// <param name="messageDelimiters">HL7 message delimiters.</param> /// <returns>string - HL7 ER7 format string.</returns> public System.String ToString(Hl7MessageDelimiters messageDelimiters) { return(ToString(messageDelimiters, false)); }