Question Smythe Smythee · Nov 15, 2024

Base 64 message is taking considering as a new segment

Hi Team,

I am converting xml message into HL7 message but the input XML message contains pdf which is converting into base 64 and getting mapped to OBX:5.5 in HL7 message and sending it to downstream 

In Downstream service i am using normal HL7 TCP class EnsLib.HL7.Service.TCPService but the message looks like below i am not sure why stream is taking as another segment in HL7 message,

Any thoughts on this?

Thanks,

Smythee

Product version: Ensemble 2018.1
$ZV: Cache for Windows (x86-64) 2018.1.1 (Build 312_1_18937U) Fri Apr 26 2019 17:58:36 EDT

Comments

Julian Matthews · Nov 15, 2024

Hey Smythe.

Your Base64 has line breaks, so is breaking onto a new line which is then being read as a new line in the HL7.

Depending on what method you are using to convert the PDF to Base 64, you should have a setting to not use line breaks.

0
Smythe Smythee  Nov 15, 2024 to Julian Matthews

hi ,

this is how i am converting pdf to base 64

Set pInput.LineTerminator = $C(10)
Set tMax=$$$MaxLocalLength*.5\1
Set tMax=tMax-(tMax#57)
If $IsObject(pInput) {
$$$TRACE("pInput = object")
Set tCurrLineLen = 0
Set tStream = ##class(%Stream.FileBinary).%New()
While 'pInput.AtEnd 
$$$TRACE("Reading filestream")
Set tData = pInput.Read(tMax)
Set tValue = $SYSTEM.Encryption.Base64Encode(tData)
Set tSC = tStream.Write(tValue)
If 'pInput.AtEnd {
Set tSC = tStream.Write($C(10))
$$$TRACE("Adding terminator.")
}
 

0
Enrico Parisi  Nov 15, 2024 to Smythe Smythee

Julian is correct, your code is inserting line breaks, remove the lines:

If 'pInput.AtEnd {
        Set tSC = tStream.Write($C(10))
        $$$TRACE("Adding terminator.")
    }
0
Julian Matthews  Nov 15, 2024 to Smythe Smythee

So to do what you're trying to do in your DTL, add in a code block and paste in the following:

Set CHUNKSIZE = 2097144Set outputStream=##class(%Stream.TmpCharacter).%New()
  Do source.EncodedPdf.Rewind()
  While ('source.EncodedPdf.AtEnd) {
    Set tReadLen=CHUNKSIZE
    Set tChunk=source.EncodedPdf.Read(.tReadLen)
    Do outputStream.Write($SYSTEM.Encryption.Base64Encode(tChunk,1))
  }
  Do outputStream.Rewind()
  Set Status = target.StoreFieldStreamRaw(outputStream,"OBXgrp(1).OBX:5.5")
  )

Yours is almost doing the same thing but, as Enrico points out with your code sample, you have the "Set tSC = tStream.Write($C(10))" line adding in the line breaks whereas my example has this excluded.

Separately, as alluded to by Scott, when adding the base 64 encoded PDF stream to the HL7, you'll want to use the StoreFieldStreamRaw method for the HL7. Trying to do a traditional set with a .Read() risks the input being truncated.

0
Scott Roth · Nov 15, 2024
<if condition='source.{ORCgrp(1).OBRgrp(1).OBXgrp(k1).OBX:ValueType}="ED"' >
<true>
<assign value='source.GetFieldStreamRaw(.tStream,"ORCgrp(1).OBRgrp(1).OBXgrp("_k1_").OBX:ObservationValue(1).AlternateText",.tRemainder)' property='tSC' action='set' />
</true>
</if>
</foreach>
<if condition='..Length($get(tSC))&gt;0' >
<true>
<assign value='"1"' property='target.{OBXgrp(1).OBX:SetIDOBX}' action='set' />
<assign value='"ED"' property='target.{OBXgrp(1).OBX:ValueType}' action='set' />
<assign value='"7"' property='target.{OBXgrp(1).OBX:ObservationIdentifier.Identifier}' action='set' />
<assign value='"URL"' property='target.{OBXgrp(1).OBX:ObservationIdentifier.Text}' action='set' />
<assign value='"EXTLRR"' property='target.{OBXgrp(1).OBX:ObservationIdentifier.NameofCodingSystem}' action='set' />
<assign value='"1"' property='target.{OBXgrp(1).OBX:ObservationSubID}' action='set' />
<assign value='"PDF"' property='target.{OBXgrp(1).OBX:ObservationValue(1).Identifier}' action='set' />
<assign value='"PDF"' property='target.{OBXgrp(1).OBX:ObservationValue(1).NameofCodingSystem}' action='set' />
<assign value='"PDF"' property='target.{OBXgrp(1).OBX:ObservationValue(1).AlternateIdentifier}' action='set' />
<assign value='target.StoreFieldStreamRaw(tStream,"OBXgrp(1).OBX:ObservationValue(1).AlternateText",tRemainder)' property='tSC' action='set' />
<assign value='"F"' property='$P(tRemainder,"|",11)' action='set' />
</true>
</if>

This is an example of what we pretty much do for any system that sends us a Base64 encoded PDF that we have to reformat to send to Epic EMR.

0
Smythe Smythee  Nov 15, 2024 to Scott Roth

My transformation is pretty much simple  actually 

<assign value='"Procedure notes"' property='target.{OBXgrp(1).OBX:5.2}' action='set' />
<assign value='"PDF"' property='target.{OBXgrp(1).OBX:5.3}' action='set' />
<assign value='"base64"' property='target.{OBXgrp(1).OBX:5.4}' action='set' />
<assign value='source.EncodedPdf.Read(9999999999)' property='target.{OBXgrp(1).OBX:5.5}' action='set' />
 

how do i avoid line breaks 

0
Scott Roth  Nov 15, 2024 to Smythe Smythee

you need to convert the Base64 to a Stream to put into OBX:5.5.

source.GetFieldStreamRaw(.tStream,"ORCgrp(1).OBRgrp(1).OBXgrp("_k1_").OBX:ObservationValue(1).AlternateText",.tRemainder)'

0
Scott Roth  Nov 16, 2024 to Smythe Smythee

If line feed and carriage returns still are problematic look into using $ZSTRIP

0
Smythe Smythee  Nov 17, 2024 to Scott Roth

just and example what i am getting at the end of every line 

0
Smythe Smythee  Nov 17, 2024 to Smythe Smythee

screenshot of base64 converted stream which has CRLF at the end

0
Scott Roth  Nov 17, 2024 to Smythe Smythee

I would suggest that you follow up with WRC, as I never seen that issue before.

0
Enrico Parisi  Nov 17, 2024 to Smythe Smythee

How did you converted the stream to base64?

0
Smythe Smythee  Nov 18, 2024 to Enrico Parisi

In Service class(by using record map as input) i am converting pdf to base 64 using below code  and the same source.encodedpdf is getting converted to HL7 in data transformation

Set pInput.LineTerminator $C(10)
Set tMax=$$$MaxLocalLength*.5\1
Set tMax=tMax-(tMax#57)
If $IsObject(pInput{
$$$TRACE("pInput = object")
Set tCurrLineLen = 0
Set tStream ##class(%Stream.FileBinary).%New()
While 'pInput.AtEnd 
$$$TRACE("Reading filestream")
Set tData pInput.Read(tMax)
Set tValue $SYSTEM.Encryption.Base64Encode(tData)
Set tSC tStream.Write(tValue)
If 'pInput.AtEnd {
Set tSC tStream.Write($C(10))
$$$TRACE("Adding terminator.")
}

0