/// <summary> Populates the given Element with data from the given Segment, by inserting /// Elements corresponding to the Segment's fields, their components, etc. Returns /// true if there is at least one data value in the segment. /// </summary> public virtual bool Encode(ISegment segmentObject, XmlElement segmentElement) { var hasValue = false; var n = segmentObject.NumFields(); for (var i = 1; i <= n; i++) { var name = MakeElementName(segmentObject, i); var reps = segmentObject.GetField(i); for (var j = 0; j < reps.Length; j++) { var newNode = segmentElement.OwnerDocument.CreateElement(name); var componentHasValue = Encode(reps[j], newNode); if (componentHasValue) { try { segmentElement.AppendChild(newNode); } catch (Exception e) { throw new HL7Exception("DOMException encoding Segment: ", ErrorCode.APPLICATION_INTERNAL_ERROR, e); } hasValue = true; } } } return(hasValue); }
/// <summary> /// Populates the given Element with data from the given Segment, by inserting Elements /// corresponding to the Segment's fields, their components, etc. Returns true if there is at /// least one data value in the segment. /// </summary> /// /// <exception cref="HL7Exception"> Thrown when a HL 7 error condition occurs. </exception> /// /// <param name="segmentObject"> The segment object. </param> /// <param name="segmentElement"> Element describing the segment. </param> /// /// <returns> true if it succeeds, false if it fails. </returns> public virtual bool Encode(ISegment segmentObject, System.Xml.XmlElement segmentElement) { bool hasValue = false; int n = segmentObject.NumFields(); for (int i = 1; i <= n; i++) { System.String name = MakeElementName(segmentObject, i); IType[] reps = segmentObject.GetField(i); for (int j = 0; j < reps.Length; j++) { System.Xml.XmlElement newNode = segmentElement.OwnerDocument.CreateElement(name); bool componentHasValue = Encode(reps[j], newNode); if (componentHasValue) { try { segmentElement.AppendChild(newNode); } catch (System.Exception e) { throw new HL7Exception( "DOMException encoding Segment: ", HL7Exception.APPLICATION_INTERNAL_ERROR, e); } hasValue = true; } } } return(hasValue); }
/// <summary> Populates the given error segment with information from this Exception.</summary> // TODO: this is out of sync with hapi see // https://github.com/hapifhir/hapi-hl7v2/blob/809516e3f4851d7cd97573efb6dedf24959a1063/hapi-base/src/main/java/ca/uhn/hl7v2/AbstractHL7Exception.java#L134 public virtual void populate(ISegment errorSegment) { //make sure it's an ERR if (!errorSegment.GetStructureName().Equals("ERR")) { throw new HL7Exception("Can only populate an ERR segment with an exception -- got: " + errorSegment.GetType().FullName); } var rep = errorSegment.GetField(1).Length; //append after existing reps if (SegmentName != null) { Terser.Set(errorSegment, 1, rep, 1, 1, SegmentName); } if (SegmentRepetition >= 0) { Terser.Set(errorSegment, 1, rep, 2, 1, Convert.ToString(SegmentRepetition)); } if (FieldPosition >= 0) { Terser.Set(errorSegment, 1, rep, 3, 1, Convert.ToString(FieldPosition)); } Terser.Set(errorSegment, 1, rep, 4, 1, Convert.ToString(ErrorCode)); // this replaces the need to connect to the database Terser.Set(errorSegment, 1, rep, 4, 2, ErrorCode.GetName()); Terser.Set(errorSegment, 1, rep, 4, 3, "hl70357"); Terser.Set(errorSegment, 1, rep, 4, 5, Message); }
private void ParseReps(ISegment segmentObject, System.Xml.XmlElement segmentElement, System.String fieldName, int fieldNum) { System.Xml.XmlNodeList reps = segmentElement.GetElementsByTagName(fieldName); for (int i = 0; i < reps.Count; i++) { Parse(segmentObject.GetField(fieldNum, i), (System.Xml.XmlElement)reps.Item(i)); } }
private void ParseReps(ISegment segmentObject, XmlElement segmentElement, string fieldName, int fieldNum) { var reps = segmentElement.GetElementsByTagName(fieldName); for (var i = 0; i < reps.Count; i++) { Parse(segmentObject.GetField(fieldNum, i), (XmlElement)reps.Item(i)); } }
/// <summary> /// Sets the data type of field 5 in the given OBX segment to the value of OBX-2. The argument /// is a Segment as opposed to a particular OBX because it is meant to work with any version. /// </summary> /// /// <exception cref="HL7Exception"> Thrown when a HL 7 error condition occurs. </exception> /// /// <param name="segment"> The segment. </param> /// <param name="factory"> The factory. </param> public static void fixOBX5(ISegment segment, IModelClassFactory factory) { try { //get unqualified class name IPrimitive obx2 = (IPrimitive)segment.GetField(2, 0); Varies v = (Varies)segment.GetField(5, 0); if (obx2.Value == null) { if (v.Data != null) { if (!(v.Data is IPrimitive) || ((IPrimitive)v.Data).Value != null) { throw new HL7Exception( "OBX-5 is valued, but OBX-2 is not. A datatype for OBX-5 must be specified using OBX-2.", HL7Exception.REQUIRED_FIELD_MISSING); } } } else { //set class System.Type c = factory.GetTypeClass(obx2.Value, segment.Message.Version); // Class c = NHapi.Base.Parser.ParserBase.findClass(obx2.getValue(), // segment.getMessage().getVersion(), // "datatype"); v.Data = (IType)c.GetConstructor(new[] { typeof(IMessage) }).Invoke(new System.Object[] { v.Message }); } } catch (HL7Exception e) { throw e; } catch (System.Exception e) { throw new HL7Exception( e.GetType().FullName + " trying to set data type of OBX-5", HL7Exception.APPLICATION_INTERNAL_ERROR, e); } }
/// <summary> Sets the data type of field 5 in the given OBX segment to the value of OBX-2. The argument /// is a Segment as opposed to a particular OBX because it is meant to work with any version. /// </summary> public static void fixOBX5(ISegment segment, IModelClassFactory factory) { try { //get unqualified class name IPrimitive obx2 = (IPrimitive)segment.GetField(2, 0); foreach (IType repetition in segment.GetField(5)) { Varies v = (Varies)repetition; if (obx2.Value == null) { if (v.Data != null) { if (!(v.Data is IPrimitive) || ((IPrimitive)v.Data).Value != null) { throw new HL7Exception( "OBX-5 is valued, but OBX-2 is not. A datatype for OBX-5 must be specified using OBX-2.", ErrorCode.REQUIRED_FIELD_MISSING); } } } else { UseDTInsteadOfDTMForEarlierVersionsOfHL7(segment, obx2); Type c = factory.GetTypeClass(obx2.Value, segment.Message.Version); v.Data = (IType)c.GetConstructor(new [] { typeof(IMessage), typeof(String) }).Invoke(new Object[] { v.Message, v.Description }); } } } catch (HL7Exception e) { throw e; } catch (Exception e) { throw new HL7Exception(e.GetType().FullName + " trying to set data type of OBX-5", ErrorCode.APPLICATION_INTERNAL_ERROR, e); } }
/// <summary> Copies contents from the source segment to the destination segment. This /// method calls copy(Type, Type) on each repetition of each field (see additional /// behavioural description there). An attempt is made to copy each repetition of /// each field in the source segment, regardless of whether the corresponding /// destination field is repeating or even exists. /// </summary> /// <param name="from">the segment from which data are copied /// </param> /// <param name="to">the segment into which data are copied /// </param> public static void copy(ISegment from, ISegment to) { int n = from.NumFields(); for (int i = 1; i <= n; i++) { IType[] reps = from.GetField(i); for (int j = 0; j < reps.Length; j++) { copy(reps[j], to.GetField(i, j)); } } }
/// <summary> Copies contents from the source segment to the destination segment. This /// method calls copy(Type, Type) on each repetition of each field (see additional /// behavioural description there). An attempt is made to copy each repetition of /// each field in the source segment, regardless of whether the corresponding /// destination field is repeating or even exists. /// </summary> /// <param name="from">the segment from which data are copied. /// </param> /// <param name="to">the segment into which data are copied. /// </param> public static void Copy(ISegment from, ISegment to) { var n = from.NumFields(); for (var i = 1; i <= n; i++) { var reps = from.GetField(i); for (var j = 0; j < reps.Length; j++) { Copy(reps[j], to.GetField(i, j)); } } }
/// <summary> /// Formats a <see cref="IMessage"/> object into an HL7 message string using the given encoding. /// </summary> /// <param name="source">An <see cref="IMessage"/> object from which to construct an encoded message string.</param> /// <param name="encodingChars">Encoding characters to be used.</param> /// <returns>The encoded message.</returns> /// <exception cref="HL7Exception">Thrown if the data fields in the message do not permit encoding (e.g. required fields are null).</exception> /// <exception cref="EncodingNotSupportedException">Thrown if the requested encoding is not supported by this parser.</exception> public static string Encode(ISegment source, EncodingCharacters encodingChars) { var result = new StringBuilder(); result.Append(source.GetStructureName()); result.Append(encodingChars.FieldSeparator); // start at field 2 for MSH segment because field 1 is the field delimiter var startAt = 1; if (IsDelimDefSegment(source.GetStructureName())) { startAt = 2; } // loop through fields; for every field delimit any repetitions and add field delimiter after ... var numFields = source.NumFields(); for (var i = startAt; i <= numFields; i++) { try { var reps = source.GetField(i); for (var j = 0; j < reps.Length; j++) { var fieldText = Encode(reps[j], encodingChars); // if this is MSH-2, then it shouldn't be escaped, so un-escape it again if (IsDelimDefSegment(source.GetStructureName()) && i == 2) { fieldText = Escape.UnescapeText(fieldText, encodingChars); } result.Append(fieldText); if (j < reps.Length - 1) { result.Append(encodingChars.RepetitionSeparator); } } } catch (HL7Exception e) { Log.Error("Error while encoding segment: ", e); } result.Append(encodingChars.FieldSeparator); } // strip trailing delimiters ... return(StripExtraDelimiters(result.ToString(), encodingChars.FieldSeparator)); }
/// <summary> /// Encode un segment. /// </summary> /// <param name="segment">Segment à encoder.</param> /// <param name="encChars">Caractères d'encodage utilisés.</param> /// <returns></returns> public static string Encode(ISegment segment, EncodingCharacters encChars) { StringBuilder retSegment = new StringBuilder(); // Code du segment et premier séparateur de champ retSegment.Append(segment.SegmentName); retSegment.Append(encChars.FieldSeparator); // Si segment MSH : position de départ sur MSH-2 car MSH-1 correspond au séparateur de champ int startPos = InteropUtil.IsSegmentDefDelimiters(segment.SegmentName) ? 2 : 1; // Parcours des champs for (int i = startPos; i <= segment.Fields.Count; i++) { try { // Parcours des répétitions IType[] repetitions = segment.GetField(i); for (int j = 0; j < repetitions.Length; j++) { string repValue = PipeParser.Encode(repetitions[j], encChars); // Si MSH-2 : il faut annuler l'échappement des caractères réservés if (InteropUtil.IsSegmentDefDelimiters(segment.SegmentName) && i == 2) { repValue = EscapeCharacterUtil.Unescape(repValue, encChars); } retSegment.Append(repValue); if (j < repetitions.Length - 1) { retSegment.Append(encChars.RepetitionSeparator); } } } catch { throw; } retSegment.Append(encChars.FieldSeparator); } return(InteropUtil.RemoveExtraDelimiters(retSegment.ToString(), encChars.FieldSeparator)); }
/// <summary> Populates the given error segment with information from this Exception.</summary> public virtual void populate(ISegment errorSegment) { //make sure it's an ERR if (!errorSegment.GetStructureName().Equals("ERR")) { throw new HL7Exception("Can only populate an ERR segment with an exception -- got: " + errorSegment.GetType().FullName); } int rep = errorSegment.GetField(1).Length; //append after existing reps if (SegmentName != null) { Terser.Set(errorSegment, 1, rep, 1, 1, SegmentName); } if (SegmentRepetition >= 0) { Terser.Set(errorSegment, 1, rep, 2, 1, Convert.ToString(SegmentRepetition)); } if (FieldPosition >= 0) { Terser.Set(errorSegment, 1, rep, 3, 1, Convert.ToString(FieldPosition)); } Terser.Set(errorSegment, 1, rep, 4, 1, Convert.ToString(errCode)); Terser.Set(errorSegment, 1, rep, 4, 3, "hl70357"); Terser.Set(errorSegment, 1, rep, 4, 5, Message); //try to get error condition text try { String desc = TableRepository.Instance.getDescription(357, Convert.ToString(errCode)); Terser.Set(errorSegment, 1, rep, 4, 2, desc); } catch (LookupException e) { ourLog.Debug("Warning: LookupException getting error condition text (are we connected to a TableRepository?)", e); } catch (InvalidOperationException e) { ourLog.Debug("Warning: InvalidOperationException getting error condition text (are we connected to a TableRepository? Is a valid ConnectionString configured?)", e); } }
/// <summary> Sets the data type of field 5 in the given OBX segment to the value of OBX-2. The argument /// is a Segment as opposed to a particular OBX because it is meant to work with any version. /// </summary> public static void fixOBX5(ISegment segment, IModelClassFactory factory) { try { //get unqualified class name IPrimitive obx2 = (IPrimitive)segment.GetField(2, 0); Varies v = (Varies)segment.GetField(5, 0); if (obx2.Value == null) { if (v.Data != null) { if (!(v.Data is IPrimitive) || ((IPrimitive)v.Data).Value != null) { throw new HL7Exception("OBX-5 is valued, but OBX-2 is not. A datatype for OBX-5 must be specified using OBX-2.", HL7Exception.REQUIRED_FIELD_MISSING); } } } else { //set class System.Type c = factory.GetTypeClass(obx2.Value, segment.Message.Version); // Class c = NHapi.Base.Parser.ParserBase.findClass(obx2.getValue(), // segment.getMessage().getVersion(), // "datatype"); v.Data = (IType)c.GetConstructor(new System.Type[] { typeof(IMessage) }).Invoke(new System.Object[] { v.Message }); } } catch (HL7Exception e) { throw e; } catch (System.Exception e) { throw new HL7Exception(e.GetType().FullName + " trying to set data type of OBX-5", HL7Exception.APPLICATION_INTERNAL_ERROR, e); } }
private void ParseReps(ISegment segmentObject, XmlElement segmentElement, String fieldName, int fieldNum) { XmlNodeList reps = segmentElement.GetElementsByTagName(fieldName); for (int i = 0; i < reps.Count; i++) { Parse(segmentObject.GetField(fieldNum, i), (XmlElement) reps.Item(i)); } }
/// <summary> Populates the given Element with data from the given Segment, by inserting /// Elements corresponding to the Segment's fields, their components, etc. Returns /// true if there is at least one data value in the segment. /// </summary> public virtual bool Encode(ISegment segmentObject, XmlElement segmentElement) { bool hasValue = false; int n = segmentObject.NumFields(); for (int i = 1; i <= n; i++) { String name = MakeElementName(segmentObject, i); IType[] reps = segmentObject.GetField(i); for (int j = 0; j < reps.Length; j++) { XmlElement newNode = segmentElement.OwnerDocument.CreateElement(name); bool componentHasValue = Encode(reps[j], newNode); if (componentHasValue) { try { segmentElement.AppendChild(newNode); } catch (Exception e) { throw new HL7Exception("DOMException encoding Segment: ", HL7Exception.APPLICATION_INTERNAL_ERROR, e); } hasValue = true; } } } return hasValue; }
/// <summary> Parses a segment string and populates the given Segment object. Unexpected fields are /// added as Varies' at the end of the segment. /// /// </summary> /// <throws> HL7Exception if the given string does not contain the </throws> /// <summary> given segment or if the string is not encoded properly /// </summary> public virtual void Parse(ISegment destination, System.String segment, EncodingCharacters encodingChars) { int fieldOffset = 0; if (IsDelimDefSegment(destination.GetStructureName())) { fieldOffset = 1; //set field 1 to fourth character of string Terser.Set(destination, 1, 0, 1, 1, System.Convert.ToString(encodingChars.FieldSeparator)); } System.String[] fields = Split(segment, System.Convert.ToString(encodingChars.FieldSeparator)); //destination.setName(fields[0]); for (int i = 1; i < fields.Length; i++) { System.String[] reps = Split(fields[i], System.Convert.ToString(encodingChars.RepetitionSeparator)); if (log.DebugEnabled) { log.Debug(reps.Length + "reps delimited by: " + encodingChars.RepetitionSeparator); } //MSH-2 will get split incorrectly so we have to fudge it ... bool isMSH2 = IsDelimDefSegment(destination.GetStructureName()) && i + fieldOffset == 2; if (isMSH2) { reps = new System.String[1]; reps[0] = fields[i]; } for (int j = 0; j < reps.Length; j++) { try { System.Text.StringBuilder statusMessage = new System.Text.StringBuilder("Parsing field "); statusMessage.Append(i + fieldOffset); statusMessage.Append(" repetition "); statusMessage.Append(j); log.Debug(statusMessage.ToString()); //parse(destination.GetField(i + fieldOffset, j), reps[j], encodingChars, false); IType field = destination.GetField(i + fieldOffset, j); if (isMSH2) { Terser.getPrimitive(field, 1, 1).Value = reps[j]; } else { Parse(field, reps[j], encodingChars); } } catch (HL7Exception e) { //set the field location and throw again ... e.FieldPosition = i; e.SegmentRepetition = MessageIterator.getIndex(destination.ParentStructure, destination).rep; e.SegmentName = destination.GetStructureName(); throw e; } } } //set data type of OBX-5 if (destination.GetType().FullName.IndexOf("OBX") >= 0) { Varies.fixOBX5(destination, Factory); } }
/// <summary> /// Parses a segment string and populates the given Segment object. /// <para> /// Unexpected fields are added as Varies' at the end of the segment. /// </para> /// </summary> /// <param name="destination">Segment to parse the segment string into.</param> /// <param name="segment">Encoded segment.</param> /// <param name="encodingChars">Encoding characters to be used.</param> /// <param name="repetition">The repetition number of this segment within its group.</param> /// <param name="parserOptions">Contains configuration that will be applied when parsing.</param> /// <exception cref="HL7Exception"> /// If the given string does not contain the given segment or if the string is not encoded properly. /// </exception> public virtual void Parse(ISegment destination, string segment, EncodingCharacters encodingChars, int repetition, ParserOptions parserOptions) { parserOptions = parserOptions ?? DefaultParserOptions; var fieldOffset = 0; if (IsDelimDefSegment(destination.GetStructureName())) { fieldOffset = 1; // set field 1 to fourth character of string Terser.Set(destination, 1, 0, 1, 1, Convert.ToString(encodingChars.FieldSeparator)); } var fields = Split(segment, Convert.ToString(encodingChars.FieldSeparator)); for (var i = 1; i < fields.Length; i++) { var reps = Split(fields[i], Convert.ToString(encodingChars.RepetitionSeparator)); if (Log.DebugEnabled) { Log.Debug(reps.Length + "reps delimited by: " + encodingChars.RepetitionSeparator); } // MSH-2 will get split incorrectly so we have to fudge it ... var isMSH2 = IsDelimDefSegment(destination.GetStructureName()) && i + fieldOffset == 2; if (isMSH2) { reps = new string[1]; reps[0] = fields[i]; } for (var j = 0; j < reps.Length; j++) { try { var statusMessage = $"Parsing field {i + fieldOffset} repetition {j}"; Log.Debug(statusMessage); var field = destination.GetField(i + fieldOffset, j); if (isMSH2) { Terser.GetPrimitive(field, 1, 1).Value = reps[j]; } else { Parse(field, reps[j], encodingChars); } } catch (HL7Exception e) { // set the field location and throw again ... e.FieldPosition = i; if (repetition > 1) { e.SegmentRepetition = repetition; } e.SegmentName = destination.GetStructureName(); throw; } } } // set data type of OBX-5 if (destination.GetType().FullName.IndexOf("OBX") >= 0) { Varies.FixOBX5(destination, Factory, parserOptions); } }
/// <summary> Returns the Primitive object at the given location.</summary> private static IPrimitive getPrimitive(ISegment segment, int field, int rep, int component, int subcomponent) { IType type = segment.GetField(field, rep); return(getPrimitive(type, component, subcomponent)); }
/// <summary> Sets the data type of field 5 in the given OBX segment to the value of OBX-2. The argument /// is a Segment as opposed to a particular OBX because it is meant to work with any version. /// </summary> public static void fixOBX5(ISegment segment, IModelClassFactory factory) { try { //get unqualified class name IPrimitive obx2 = (IPrimitive) segment.GetField(2, 0); foreach (IType repetition in segment.GetField(5)) { Varies v = (Varies) repetition; if (obx2.Value == null) { if (v.Data != null) { if (!(v.Data is IPrimitive) || ((IPrimitive) v.Data).Value != null) { throw new HL7Exception( "OBX-5 is valued, but OBX-2 is not. A datatype for OBX-5 must be specified using OBX-2.", HL7Exception.REQUIRED_FIELD_MISSING); } } } else { Type c = factory.GetTypeClass(obx2.Value, segment.Message.Version); v.Data = (IType) c.GetConstructor(new [] {typeof (IMessage), typeof(String)}).Invoke(new Object[] {v.Message, v.Description}); } } } catch (HL7Exception e) { throw e; } catch (Exception e) { throw new HL7Exception(e.GetType().FullName + " trying to set data type of OBX-5", HL7Exception.APPLICATION_INTERNAL_ERROR, e); } }
public static String Encode(ISegment source, EncodingCharacters encodingChars) { StringBuilder result = new StringBuilder(); result.Append(source.GetStructureName()); result.Append(encodingChars.FieldSeparator); //start at field 2 for MSH segment because field 1 is the field delimiter int startAt = 1; if (IsDelimDefSegment(source.GetStructureName())) startAt = 2; //loop through fields; for every field delimit any repetitions and add field delimiter after ... int numFields = source.NumFields(); for (int i = startAt; i <= numFields; i++) { try { IType[] reps = source.GetField(i); for (int j = 0; j < reps.Length; j++) { String fieldText = Encode(reps[j], encodingChars); //if this is MSH-2, then it shouldn't be escaped, so unescape it again if (IsDelimDefSegment(source.GetStructureName()) && i == 2) fieldText = Escape.unescape(fieldText, encodingChars); result.Append(fieldText); if (j < reps.Length - 1) result.Append(encodingChars.RepetitionSeparator); } } catch (HL7Exception e) { log.Error("Error while encoding segment: ", e); } result.Append(encodingChars.FieldSeparator); } //strip trailing delimiters ... return StripExtraDelimiters(result.ToString(), encodingChars.FieldSeparator); }
/// <summary> Parses a segment string and populates the given Segment object. Unexpected fields are /// added as Varies' at the end of the segment. /// /// </summary> /// <throws> HL7Exception if the given string does not contain the </throws> /// <summary> given segment or if the string is not encoded properly /// </summary> public virtual void Parse(ISegment destination, String segment, EncodingCharacters encodingChars) { int fieldOffset = 0; if (IsDelimDefSegment(destination.GetStructureName())) { fieldOffset = 1; //set field 1 to fourth character of string Terser.Set(destination, 1, 0, 1, 1, Convert.ToString(encodingChars.FieldSeparator)); } String[] fields = Split(segment, Convert.ToString(encodingChars.FieldSeparator)); for (int i = 1; i < fields.Length; i++) { String[] reps = Split(fields[i], Convert.ToString(encodingChars.RepetitionSeparator)); if (log.DebugEnabled) { log.Debug(reps.Length + "reps delimited by: " + encodingChars.RepetitionSeparator); } //MSH-2 will get split incorrectly so we have to fudge it ... bool isMSH2 = IsDelimDefSegment(destination.GetStructureName()) && i + fieldOffset == 2; if (isMSH2) { reps = new String[1]; reps[0] = fields[i]; } for (int j = 0; j < reps.Length; j++) { try { StringBuilder statusMessage = new StringBuilder("Parsing field "); statusMessage.Append(i + fieldOffset); statusMessage.Append(" repetition "); statusMessage.Append(j); log.Debug(statusMessage.ToString()); IType field = destination.GetField(i + fieldOffset, j); if (isMSH2) { Terser.getPrimitive(field, 1, 1).Value = reps[j]; } else { Parse(field, reps[j], encodingChars); } } catch (HL7Exception e) { //set the field location and throw again ... e.FieldPosition = i + fieldOffset; e.SegmentRepetition = MessageIterator.getIndex(destination.ParentStructure, destination).rep; e.SegmentName = destination.GetStructureName(); throw; } } } //set data type of OBX-5 if (destination.GetType().FullName.IndexOf("OBX") >= 0) { Varies.fixOBX5(destination, Factory); } }
/// <summary> Returns the Primitive object at the given location.</summary> private static IPrimitive getPrimitive(ISegment segment, int field, int rep, int component, int subcomponent) { IType type = segment.GetField(field, rep); return getPrimitive(type, component, subcomponent); }
/// <summary> Populates the given error segment with information from this Exception.</summary> public virtual void populate(ISegment errorSegment) { //make sure it's an ERR if (!errorSegment.GetStructureName().Equals("ERR")) throw new HL7Exception("Can only populate an ERR segment with an exception -- got: " + errorSegment.GetType().FullName); int rep = errorSegment.GetField(1).Length; //append after existing reps if (this.SegmentName != null) Terser.Set(errorSegment, 1, rep, 1, 1, this.SegmentName); if (this.SegmentRepetition >= 0) Terser.Set(errorSegment, 1, rep, 2, 1, System.Convert.ToString(this.SegmentRepetition)); if (this.FieldPosition >= 0) Terser.Set(errorSegment, 1, rep, 3, 1, System.Convert.ToString(this.FieldPosition)); Terser.Set(errorSegment, 1, rep, 4, 1, System.Convert.ToString(this.errCode)); Terser.Set(errorSegment, 1, rep, 4, 3, "hl70357"); Terser.Set(errorSegment, 1, rep, 4, 5, this.Message); //try to get error condition text try { System.String desc = TableRepository.Instance.getDescription(357, System.Convert.ToString(this.errCode)); Terser.Set(errorSegment, 1, rep, 4, 2, desc); } catch (LookupException e) { ourLog.Debug("Warning: LookupException getting error condition text (are we connected to a TableRepository?)", e); } }
/// <summary> /// Sets the data type of field 5 in the given OBX segment to the value of OBX-2. The argument /// is a Segment as opposed to a particular OBX because it is meant to work with any version. /// <para> /// Note that if no value is present in OBX-2, or an invalid value is present in /// OBX-2, this method will throw an error.This behaviour can be corrected by using the /// <see cref="ParserOptions.DefaultObx2Type"/> and <see cref="ParserOptions.InvalidObx2Type"/>. /// </para> /// </summary> /// <param name="segment"><see cref="ISegment"/> instance.</param> /// <param name="factory"><see cref="IModelClassFactory"/> to be used.</param> /// <param name="parserOptions"><see cref="ParserOptions"/> to be used.</param> /// <exception cref="HL7Exception">If no value is present in OBX-2.</exception> /// <exception cref="HL7Exception">If an invalid value is present in OBX-2.</exception> public static void FixOBX5(ISegment segment, IModelClassFactory factory, ParserOptions parserOptions) { try { // get unqualified class name var obx2 = (IPrimitive)segment.GetField(2, 0); foreach (var repetition in segment.GetField(5)) { var v = (Varies)repetition; SetObx2Fallback(obx2, segment, parserOptions); if (obx2.Value == null) { if (v.Data != null) { if (!(v.Data is IPrimitive) || ((IPrimitive)v.Data).Value != null) { throw new HL7Exception( "OBX-5 is valued, but OBX-2 is not. A datatype for OBX-5 must be specified using OBX-2.", ErrorCode.REQUIRED_FIELD_MISSING); } } } else { UseDTInsteadOfDTMForEarlierVersionsOfHL7(segment, obx2); var type = GetObx5Type(obx2, segment, factory, parserOptions); if (type == null) { var obx1 = (IPrimitive)segment.GetField(1, 0); var hl7Exception = new HL7Exception( $"'{obx2.Value}' in record {obx1.Value} is invalid for version {segment.Message.Version}"); hl7Exception.SegmentName = ((AbstractSegment)segment).GetStructureName(); hl7Exception.FieldPosition = 2; throw hl7Exception; } try { var constructor = type.GetConstructor(new[] { typeof(IMessage), typeof(string) }); v.Data = (IType)constructor.Invoke(new object[] { v.Message, v.Description }); } catch (NullReferenceException) { var constructor = type.GetConstructor(new[] { typeof(IMessage) }); v.Data = (IType)constructor.Invoke(new object[] { v.Message }); } } } } catch (HL7Exception e) { throw e; } catch (Exception e) { throw new HL7Exception( $"{e.GetType().FullName} trying to set data type of OBX-5", ErrorCode.APPLICATION_INTERNAL_ERROR, e); } }