Skip to content

Commit

Permalink
Fixed issue cloning & serializing segment with newline
Browse files Browse the repository at this point in the history
  • Loading branch information
jaime-olivares committed Nov 24, 2024
1 parent 13e1914 commit 3be9f59
Show file tree
Hide file tree
Showing 7 changed files with 111 additions and 97 deletions.
31 changes: 31 additions & 0 deletions src/Field.cs
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace Efferent.HL7.V2
{
Expand Down Expand Up @@ -177,5 +179,34 @@ public void AddRepeatingField(Field field)

_RepetitionList.Add(field);
}

/// <summary>
/// Serializes a field into a string with proper encoding
/// </summary>
/// <param name="strMessage">A StringBuilder to write on</param>
public void SerializeField(StringBuilder strMessage)
{
if (this.ComponentList.Count > 0)
{
int indexCom = 0;

foreach (Component com in this.ComponentList)
{
indexCom++;

if (com.SubComponentList.Count > 0)
strMessage.Append(string.Join(Encoding.SubComponentDelimiter.ToString(), com.SubComponentList.Select(sc => Encoding.Encode(sc.Value))));
else
strMessage.Append(Encoding.Encode(com.Value));

if (indexCom < this.ComponentList.Count)
strMessage.Append(Encoding.ComponentDelimiter);
}
}
else
{
strMessage.Append(Encoding.Encode(this.Value));
}
}
}
}
4 changes: 2 additions & 2 deletions src/HL7-V2.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
<PropertyGroup>
<Description>Lightweight HL7 V2 library</Description>
<Copyright>(c) Efferent Health, LLC</Copyright>
<VersionPrefix>3.1</VersionPrefix>
<VersionPrefix>3.2</VersionPrefix>
<TargetFrameworks>netstandard2.0;net8.0</TargetFrameworks>
<AssemblyName>HL7-V2</AssemblyName>
<PackageId>HL7-V2</PackageId>
Expand All @@ -12,7 +12,7 @@
<RepositoryType>git</RepositoryType>
<RepositoryUrl>https://github.com/Efferent-Health/HL7-V2</RepositoryUrl>
<Configuration>Release</Configuration>
<Optimize>true</Optimize>
<Optimize>true</Optimize> <!-- Set to true for debugging -->
<LangVersion>12.0</LangVersion>
</PropertyGroup>

Expand Down
2 changes: 1 addition & 1 deletion src/HL7Encoding.cs
Original file line number Diff line number Diff line change
Expand Up @@ -64,7 +64,7 @@ public string Encode(string val)
if (val == null)
return PresentButNull;

if (string.IsNullOrWhiteSpace(val))
if (val.Length == 0)
return val;

// If there's nothing that needs encoding, just return the value as-is
Expand Down
82 changes: 1 addition & 81 deletions src/Message.cs
Original file line number Diff line number Diff line change
Expand Up @@ -159,62 +159,11 @@ public string SerializeMessage(bool validate = false)
throw new HL7Exception("Failed to validate the updated message", HL7Exception.BadMessage);

var strMessage = new StringBuilder();
string currentSegName = string.Empty;
List<Segment> _segListOrdered = getAllSegmentsInOrder();

try
{
try
{
foreach (Segment seg in _segListOrdered)
{
currentSegName = seg.Name;
strMessage.Append(seg.Name);

if (seg.FieldList.Count > 0)
strMessage.Append(Encoding.FieldDelimiter);

int startField = currentSegName == "MSH" ? 1 : 0;

for (int i = startField; i<seg.FieldList.Count; i++)
{
if (i > startField)
strMessage.Append(Encoding.FieldDelimiter);

var field = seg.FieldList[i];

if (field.IsDelimitersField)
{
strMessage.Append(field.UndecodedValue);
continue;
}

if (field.HasRepetitions)
{
for (int j = 0; j < field.RepetitionList.Count; j++)
{
if (j > 0)
strMessage.Append(Encoding.RepeatDelimiter);

serializeField(field.RepetitionList[j], strMessage);
}
}
else
{
serializeField(field, strMessage);
}
}

strMessage.Append(Encoding.SegmentDelimiter);
}
}
catch (Exception ex)
{
if (currentSegName == "MSH")
throw new HL7Exception("Failed to serialize the MSH segment with error - " + ex.Message, HL7Exception.SerializationError, ex);
else
throw;
}
_segListOrdered.ForEach(seg => seg.SerializeSegment(strMessage));

return strMessage.ToString();
}
Expand Down Expand Up @@ -910,35 +859,6 @@ private bool validateMessage()
return true;
}

/// <summary>
/// Serializes a field into a string with proper encoding
/// </summary>
/// <returns>A serialized string</returns>
private void serializeField(Field field, StringBuilder strMessage)
{
if (field.ComponentList.Count > 0)
{
int indexCom = 0;

foreach (Component com in field.ComponentList)
{
indexCom++;

if (com.SubComponentList.Count > 0)
strMessage.Append(string.Join(Encoding.SubComponentDelimiter.ToString(), com.SubComponentList.Select(sc => Encoding.Encode(sc.Value))));
else
strMessage.Append(Encoding.Encode(com.Value));

if (indexCom < field.ComponentList.Count)
strMessage.Append(Encoding.ComponentDelimiter);
}
}
else
{
strMessage.Append(Encoding.Encode(field.Value));
}
}

/// <summary>
/// Get all segments in order as they appear in original message. This the usual order: IN1|1 IN2|1 IN1|2 IN2|2
/// </summary>
Expand Down
62 changes: 54 additions & 8 deletions src/Segment.cs
Original file line number Diff line number Diff line change
@@ -1,13 +1,14 @@
using System;
using System.Collections.Generic;
using System.Text;

namespace Efferent.HL7.V2
{
public class Segment : MessageElement
{
internal FieldCollection FieldList { get; set; }
internal int SequenceNo { get; set; }

public string Name { get; set; }

public Segment(HL7Encoding encoding)
Expand All @@ -26,11 +27,11 @@ public Segment(string name, HL7Encoding encoding)
protected override void ProcessValue()
{
var allFields = _value.Split(this.Encoding.FieldDelimiter);

for (int i = 1; i < allFields.Length; i++)
{
string strField = allFields[i];
Field field = new Field(this.Encoding);
Field field = new Field(this.Encoding);

if (Name == "MSH" && i == 1)
field.IsDelimitersField = true; // special case
Expand All @@ -45,16 +46,16 @@ protected override void ProcessValue()
field1.IsDelimitersField = true;
field1.Value = this.Encoding.FieldDelimiter.ToString();

this.FieldList.Insert(0,field1);
this.FieldList.Insert(0, field1);
}
}

public Segment DeepCopy()
{
var newSegment = new Segment(this.Name, this.Encoding);
newSegment.Value = this.Value;
newSegment.Value = this.Value;

return newSegment;
return newSegment;
}

public void AddEmptyField()
Expand Down Expand Up @@ -86,12 +87,12 @@ public bool AddNewField(Field field, int position = -1)
{
this.FieldList.Add(field);
}
else
else
{
position--;
this.FieldList.Add(field, position);
}

return true;
}
catch (Exception ex)
Expand Down Expand Up @@ -123,5 +124,50 @@ public int GetSequenceNo()
{
return this.SequenceNo;
}

/// <summary>
/// Serializes a segment into a string with proper encoding
/// </summary>
/// <param name="strMessage">A StringBuilder to write on</param>
public void SerializeSegment(StringBuilder strMessage)
{
strMessage.Append(this.Name);

if (this.FieldList.Count > 0)
strMessage.Append(Encoding.FieldDelimiter);

int startField = this.Name == "MSH" ? 1 : 0;

for (int i = startField; i < this.FieldList.Count; i++)
{
if (i > startField)
strMessage.Append(Encoding.FieldDelimiter);

var field = this.FieldList[i];

if (field.IsDelimitersField)
{
strMessage.Append(field.UndecodedValue);
continue;
}

if (field.HasRepetitions)
{
for (int j = 0; j < field.RepetitionList.Count; j++)
{
if (j > 0)
strMessage.Append(Encoding.RepeatDelimiter);

field.RepetitionList[j].SerializeField(strMessage);
}
}
else
{
field.SerializeField(strMessage);
}
}

strMessage.Append(Encoding.SegmentDelimiter);
}
}
}
2 changes: 1 addition & 1 deletion test/HL7test.csproj
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<Copyright>(c) Efferent Health, LLC</Copyright>
<VersionPrefix>3.1</VersionPrefix>
<VersionPrefix>3.2</VersionPrefix>
<TargetFramework>net8.0</TargetFramework>
<AssemblyName>HL7Test</AssemblyName>
<PackageId>HL7Test</PackageId>
Expand Down
25 changes: 21 additions & 4 deletions test/Program.cs
Original file line number Diff line number Diff line change
Expand Up @@ -14,10 +14,7 @@ public class HL7Test
public static void Main(string[] args)
{
// var test = new HL7Test();
// test.ParseTest1();
// test.AddRepeatingField();
// test.GenerateAckShortSeparatorListTest();
// test.CustomDelimiterTest();
// test.CloneMessageWithNewline();
}

public HL7Test()
Expand Down Expand Up @@ -1045,5 +1042,25 @@ public void SpecialCharacter()

Assert.IsTrue(isParsed);
}

[TestMethod]
public void CloneMessageWithNewline()
{
string sampleMessage = @"MSH|^~\&|ATHENANET|18802555^Orthopaedic Sample Org|Aspyra - 18802555|13274090^ORTHOPAEDIC INSTITUTE|20241119113500||ORM^O01|57492555M18802|P|2.5.1||||||||
PID||500036547^^^Enterprise ID||500036547^^^Patient ID|JOHN^DOE^||20050904|M||2106-3|1380 SAMPLE STREET^\X0A\^NEW YORK^NY^55755-5055||(555)261-2203|||S||^^^||||2186-5||||||||
PV1||O|80D18802^^^SAMPLE ORTHO URGENT CARE||||1905555652^JANE^D^DOE||||||||||1037^ABCDE8|||||||||||||||||||||||||||20241119||||||||";

var message = new Message(sampleMessage);
message.ParseMessage();

var message2 = new Message();

foreach (var segment in message.Segments())
{
message2.AddNewSegment(segment.DeepCopy());
}

Assert.IsTrue(message2.GetValue("PID.11").IndexOf('\n') > 1);
}
}
}

0 comments on commit 3be9f59

Please sign in to comment.