How to Decode ASCII string from Ensemble.

65 views
Skip to first unread message

Ravi

unread,
Nov 17, 2015, 10:45:49 AM11/17/15
to InterSystems: Ensemble in Healthcare
Hi,

I am working on MUSE EKG wave form interface, I am getting the binary image data as UUENCODED ASCII format string.

What is the procedure to  UUDECODE the encoded string from Ensemble, is there a command from Ensemble to decode the UUENCODED string.


Thank you,
Ravi

Lawrence

unread,
Nov 17, 2015, 2:05:31 PM11/17/15
to InterSystems: Ensemble in Healthcare
The algorithms are well documents on Wikipedia and others.  I don't think I have ever seen a uuencode/decode function in Cache but it's easy to write.

https://en.wikipedia.org/wiki/Uuencoding#Encoded_format

Lawrence

Ron Sweeney

unread,
Nov 17, 2015, 2:17:06 PM11/17/15
to Ensemble-in...@googlegroups.com
Ravi,

I was in the boat a long time ago with a MUSE EKG interface and resulted to the use of the Java Gateway for two reasons:
  1. For UUDecoding
  2. Downgrade the PDF to a different version for the resulting EMR (Cerner needed a 1.2 version)
I actually wrote a singleton in java that exposed those two methods, then wrapped that jar up in the java gateway.

The resulting class was a business operation (to file) and it went a little bit like this...hope this helps.

Try {

Set sc = $System.Status.OK()

Set pResponse = ##class(Ens.StringContainer).%New()

Set pResponse.StringValue = "OK"

// Unescape stream

// See EnsLib.HL7.Segment:Unescape()

//

// Set up replacement array

//Set replace("\.br\") = $Char(13)

Set replace("\E\") = "\"

Set replace("\F\") = "|"

Set replace("\R\") = "~"

Set replace("\S\") = "^"

Set replace("\T\") = "&"

Set replace("\X0A\") = $Char(10)

Set replace("\X0D\") = $Char(13)

// Loop through stream and replace strings

// Store output in a new stream

Set uuepdf = ##class(%Stream.GlobalCharacter).%New()

Set chars = 1

// Need to read one character at a time and if a "\" is found,

// search for a match in the replace array

Do {

Set text = pRequest.pdfsegment.Read(.chars, .sc)

Quit:$System.Status.IsError(sc)

// If we find a "\" keep reading until we find the matching

// (ending) "\"

If (text = "\") {

Do {

Set text = text _ pRequest.pdfsegment.Read(.chars, .sc)

Quit:$System.Status.IsError(sc)

} While ($Extract(text, $Length(text)) '= "\")

Quit:$System.Status.IsError(sc)

// Replace the escape sequence with the proper

// replacement character

Set text = $$replaceArray^EnsUtil(text, .replace)

}

// Write text to the unescaped uuencoded stream

Do uuepdf.Write(text)

} While (chars '= -1)

Quit:$System.Status.IsError(sc)

// Save the stream

Set sc = uuepdf.%Save()

Quit:$System.Status.IsError(sc)

$$$LOGINFO("uuepdf size = " _ uuepdf.Size)


//************************** Date Function ***********************

// Legacy JavUrScript

// function string_to_date(strg,returnformat){


Set timeraw = $EXTRACT(pRequest.ekgdate,9,14)

$$$LOGINFO("Near My stuff")

// Pull apart the time and put it back together with colons

Set time1 = $EXTRACT(timeraw,0,1)

Set time2 = $EXTRACT(timeraw,2,3)

Set time3 = $EXTRACT(timeraw,4,5)

Set timejoin = time1 _":"_ time2 _":"_ time3

Set datez = $ZDATEH(dateraw,8)

Set timez = $ZDATEH(""""_timejoin_"""",1)

Set date = $ZDATE(datez,3)

Set time = $REPLACE($ZTIME(timez),":","-") 

*/

//Set datetime = ##class(Ens.Util.Time).ConvertDateTime(pRequest.ekgdate,"%q(0)","%Y-%m-%d_%H-%M-%S")

Set datetime = ##class(Ens.Util.Time).ConvertDateTime(pRequest.ekgdate,"%q(0)","%m-%d-%Y_%H-%M-%S")

$$$LOGINFO("DateTime = " _ datetime)

//Set fileName2 = pRequest.firstname _".pdf"

//Set sc = ..Adapter.PutStream(fileName2, uuepdf)

//************************************************************************************

Set tSC = ..GetConnection(.tJavaGateway)

$$$LOGINFO("tSC: "_tSC)

If $$$ISOK(tSC){

$$$LOGINFO("here")

set PDFUpgrader = ##class(IntegrationRequired.EKG.Muse.PDFUpgrader).%New(tJavaGateway)

$$$LOGINFO("PDF: "_PDFUpgrader)

set uudpdf = PDFUpgrader.upgradechararray(uuepdf)

$$$LOGINFO("UUPDF: "_uudpdf)

}

//************************************************************************************

//

//Check that an object was returned

If '$IsObject(uudpdf){

Set sc = $System.Status.Error($$$GeneralError,"PDFUpgrader returned a null reference")

Quit

}

// Save the stream

Set sc = uudpdf.%Save()

Quit:$System.Status.IsError(sc)

// Store PDF contents to temporary file

// Set filename to PatientName_PID_timestamp.uue

Set fileName = pRequest.firstname _ "_" _ pRequest.lastname _ "_" _ pRequest.fin _ "_" _ pRequest.mrn _ "_" _ datetime _ ".pdf"

Set sc = ..Adapter.PutStream(fileName, uudpdf)

}

Catch (exception) {

Set sc = exception.AsStatus()

}

Quit sc




--
You received this message because you are subscribed to the Google Groups "InterSystems: Ensemble in Healthcare Community" group.
To post to this group, send email to Ensemble-in...@googlegroups.com
To unsubscribe from this group, send email to Ensemble-in-Healt...@googlegroups.com
For more options, visit this group at http://groups.google.com/group/Ensemble-in-Healthcare?hl=en
---
You received this message because you are subscribed to the Google Groups "InterSystems: Ensemble in Healthcare" group.
To unsubscribe from this group and stop receiving emails from it, send an email to Ensemble-in-Healt...@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.



--
RON SWEENEY | ARCHITECT | INTEGRATION REQUIRED
285 THIRD STREET | CAMBRIDGE, MA 02142
DIR: 616-303-1375 | MOB: 616-217-6516 | SKYPE: SWEEN6412 

DAYS OFF THROUGH END OF THE YEAR:

11/13 - OFF (Personal)
11/26 - Thanksgiving Holiday
11/25, 11/27 - Request for Remote
12/3, 12/7 - OFF (Family Wedding)
12/17, 12/18 - Request for Remote (Star Wars in Detroit)
12/25 - OFF (Christmas)
12/31 - Request for Remote
1/1 - OFF (New Years)

PRIVILEGED AND CONFIDENTIAL: This document and the information contained herein are confidential and protected from disclosure pursuant to Federal law. This message is intended only for the use of the Addressee(s) and may contain information that is privileged and confidential. If you are not the intended recipient, you are hereby notified that the use, dissemination, or copying of this information is strictly prohibited. If you received this communication in error, please erase all copies of the message and its attachments and notify the sender immediately.

Ravi

unread,
Nov 17, 2015, 3:36:48 PM11/17/15
to InterSystems: Ensemble in Healthcare
Hello Ron,

Thank you so much for your help.

Best Regards,
Ravi
To unsubscribe from this group, send email to Ensemble-in-Healthcare-unsub...@googlegroups.com

For more options, visit this group at http://groups.google.com/group/Ensemble-in-Healthcare?hl=en
---
You received this message because you are subscribed to the Google Groups "InterSystems: Ensemble in Healthcare" group.
To unsubscribe from this group and stop receiving emails from it, send an email to Ensemble-in-Healthcare+unsub...@googlegroups.com.

For more options, visit https://groups.google.com/d/optout.

Amir Samary

unread,
Nov 18, 2015, 5:24:35 AM11/18/15
to Ensemble-in...@googlegroups.com
Hi!

See %SYSTEM.Encryption class… There are all kinds of encryption functions there. Base64Encode (uucode) is not encryption of course, but they are there too together with hashing (MD5/SHA) and real encryption functions (like AES).

You can easily access the methods of this class with the following shortcut:

USER>Write $System.Encryption.Base64Encode("Hellow World!")
SGVsbG93IFdvcmxkIQ==

USER>

You can find its documentation here:


Kind regards,
AS


To unsubscribe from this group, send email to Ensemble-in-Healt...@googlegroups.com

For more options, visit this group at http://groups.google.com/group/Ensemble-in-Healthcare?hl=en
--- 
You received this message because you are subscribed to the Google Groups "InterSystems: Ensemble in Healthcare" group.
To unsubscribe from this group and stop receiving emails from it, send an email to Ensemble-in-Healt...@googlegroups.com.

Ravi

unread,
Nov 18, 2015, 9:01:15 AM11/18/15
to InterSystems: Ensemble in Healthcare
Thank you Amir. I will look into the Encryption class.

Kind regards,
AS


To unsubscribe from this group, send email to Ensemble-in-Healthcare-unsub...@googlegroups.com

For more options, visit this group at http://groups.google.com/group/Ensemble-in-Healthcare?hl=en
--- 
You received this message because you are subscribed to the Google Groups "InterSystems: Ensemble in Healthcare" group.
To unsubscribe from this group and stop receiving emails from it, send an email to Ensemble-in-Healthcare+unsub...@googlegroups.com.
...

Ravi

unread,
Nov 27, 2015, 10:30:15 AM11/27/15
to InterSystems: Ensemble in Healthcare
Hello Ron,

How did you use UUDECODE in your JAVA class,  did you write your custom method to do UUDECODE or does Ensemble had any specific function similar to UUDECODE.

I see that sun.misc.uudecode function is in earlier version of java, now it is kind of deprecated.

Can you please suggest, because I need to convert the UUENCODED string into binary format.

Thank you,
Ravi



On Tuesday, November 17, 2015 at 2:17:06 PM UTC-5, Ron Sweeney wrote:
To unsubscribe from this group, send email to Ensemble-in-Healthcare-unsub...@googlegroups.com

For more options, visit this group at http://groups.google.com/group/Ensemble-in-Healthcare?hl=en
---
You received this message because you are subscribed to the Google Groups "InterSystems: Ensemble in Healthcare" group.
To unsubscribe from this group and stop receiving emails from it, send an email to Ensemble-in-Healthcare+unsub...@googlegroups.com.

For more options, visit https://groups.google.com/d/optout.

Ryan

unread,
Dec 29, 2015, 7:53:36 PM12/29/15
to InterSystems: Ensemble in Healthcare
Ravi - First, is the string you are attempting to decode back into binary longer than 32K? Also, are you attempting to stitch together multiple OBX's together to reconstitute the whole payload from the HL7 message?

If it's across multiple OBX segments, you need to first create a %Stream.TmpCharacter variable to hold it all. Just loop through all the OBX's and keep appending to the stream until you're done. If it's all in one fat OBX, you have to read the field using something like this snippet here:

  Set tSourceField=##class(%Stream.TmpCharacter).%New()
  Set tStatus=pMessage.GetFieldStreamUnescaped(.tSourceField,"OBX(1):5(1)",.tRemainder)

pMessage is the whole message passed to the method that is doing all the work. I try to use external methods where I can instead of CDATA code blocks in the DTL. Doing CDATA blocks leads to what I call "coding in notepad" with no syntax highlighting and makes reading the code a little harder. But I digress..

Your next step would be to create an instance of %Stream.FileBinary and set the filename properties appropriately. We'll call it tOutputFileStream. This would hold the Base64 decoded binary payload
Then start "chunking" the tSourceField stream in this example. Something like:

Set tOutputFileStream=##class(%Stream.FileBinary).%New()
Set tOutputFileStream.Filename="testfile.bin"
Set tReadLength=1200
Set tSC=tSouceField.Rewind()
While ('tSourceField.AtEnd)) {
  Set tDecodedLine=##class(%SYSTEM.Encryption).Base64Decode(tSourceField.Read(tReadLength,.tReadStatus))
  Do tOutputFileStream.Write(tDecodedLine)
}
 then close the streams and clean up stuff when you're done :-)

The reason we "chunk" the read and decode is because the Base64Encode and Decode methods in the Encryption library only extend to 32K - they aren't stream based (though that would be an awesome enhancement to have that as part of the base code one day)

Now I've not run this example code, just pulled snippets from other interfaces I've written but I think the approach itself if sound. I've only needed to ENCODE data from external files - where a system drops off a PDF file and sends an HL7 message with an OBX that has the URI location of the file, then I had to go get it, then put it in a bunch of OBX segme

I too would love to see Ron's Java code that the gateway imported - but in this case if you can do it all in the DTL and one external API class you write to handle the above? Well, your mileage may vary :)

Anyway - hopefully this helps. 

Ryan


 
Reply all
Reply to author
Forward
0 new messages