how to decode base64 encoded zpl data back to ASCII/EBCDIC

Other open source tools published on ScottKlement.com
Scott Klement
Site Admin
Posts: 872
Joined: Sun Jul 04, 2021 5:12 am

Re: how to decode base64 encoded zpl data back to ASCII/EBCDIC

Post by Scott Klement »

sbehera wrote: Tue Jan 25, 2022 8:55 pm data written to ifs file i do see as zpl data but when i check value of variable ZplOut using debug, after base64_Decode is called it still shows as binary or hexadecimal.
The data is not EBCDIC. If you view it as ASCII or UTF-8 instead of EBCDIC, you'd be able to see it. Alternately, if you need it in EBCDIC, you can translate it.
sbehera wrote: Tue Jan 25, 2022 8:55 pm IFS file shows data in UTF-8 because file is created with CCSID 1208?
In my example, I created the file as CCSID 1208, which is the CCSID number for UTF-8. I don't know if that's what it should be -- but, it's certainly closer than the EBCDIC you seem to be using. Can you please find out what it's supposed to be? I've asked this a couple of times now.

Notice that when I created the IFS file, I specified O_CCSID and 1208 to specify that the file is 1208. However, I did NOT specify O_TEXTDATA or O_TEXT_CREAT, which means that the IFS APIs will not translate it from the program's EBCDIC to the file's UTF-8. I did it that way because the data is already in UTF-8, so translating would cause problems.
sbehera wrote: Tue Jan 25, 2022 8:55 pm I need to print this zpl data to spool file to send to printer. How to do that? Here what i am doing (after zpl data written to ifs) to achieve what i need:
- Created a physical file DMYPRTFL with as400 default CCSID 65535: CRTPF FILE(TEST1/DMYPRTFL) RCDLEN(132)
Depends on how your printer is set up, et al. One easy way to preserve the values would be to use a *USERASCII spooled file -- then you can just write the data to it without converting it to EBCDIC first. The disadvantage to this approach, however, is that you can't see the contents in the spool.
sbehera wrote: Tue Jan 25, 2022 8:55 pm cmd = 'CPY OBJ(' + #Quote + stmf + #Quote + ') ' +
'TOOBJ(' + #Quote + '/qsys.lib/test1.lib/' +
'dmyprtfl.file/dmyprtfl.mbr' +
#Quote + ') FROMCCSID(*OBJ) ' +
'TOCCSID(*JOBCCSID) DTAFMT(*TEXT) REPLACE(*YES)';
You are telling it to convert from the CCSID of the stream file (i.e. 1208, or UTF-8) to the job's CCSID. That means you are converting it to EBCDIC. If that's what you want, why not do it in the RPG program?

Are you on a recent release of RPG? (One where UTF-8 fields are allowed?) Or would you have to use APIs to translate it?
sbehera00
Posts: 16
Joined: Mon Jul 22, 2024 10:29 pm

Re: how to decode base64 encoded zpl data back to ASCII/EBCDIC

Post by sbehera00 »

Hello Scott,
followingup on this base64 thread for another need. I got to do some change to ZPL after decoded before writing to IFS. As far as writing to IFS is all working fine but %scan does not find the string ^POI what i am looking for to replace with '^PON because ZplOut is in not in ASCII format. Trying to avoid reading IFS file after it is written and manipulate content. If this change of data can be done before writing to IFS, i will save time and better performance. Please help..

Code:
zplLen = base64_decode( %addr(B64In:*data)
: %len(B64In)
: %addr(ZplOut)
: %size(ZplOut) );
#strpos = %Scan('^POI':ZplOut);
If #strpos > 0;
ZplOut = %SubSt(ZplOut:1:#strpos-1) + '^PON' +
%SubSt(ZplOut:#strpos+4:(%Len(ZplOut)- #strp
EndIf;
there are file open etc, not putting here but just the write part
callp write(fd: %addr(ZplOut): zplLen);
sbehera00
Posts: 16
Joined: Mon Jul 22, 2024 10:29 pm

Re: how to decode base64 encoded zpl data back to ASCII/EBCDIC

Post by sbehera00 »

Data looks like this:

EVAL ZplOut
ZPLOUT =
....5...10...15...20...25...30...35...40...45...50...55...60
1 ';ãì!&<ÅÁ>ÁÊ/ÈÁÀÂ`î;ãë;ì ;&ï;&|ñ;&ê'
61 ';ã|;åâ;ãë;ãè; +;ãàå'
121 ';ãë;ã|;åã ÃÃÃÃÃÄÄÄÃÄÃÄÃ'
181 'ÄÄÃÃÄÃÄÃÄÄÃÃÄÃÃÄÃÃÄÃÃÄÃÄ'
241 'ÄÄÃÄÃÃÃÄÃÃÃÃÃÄÄÄÃÄÃÄÃÄÄÃÃ'
301 'ÄÃÄÃÄÄÃÃÄÃÃÄÃÃÄÃÃÄÃÄÄÄÃÄÃÃÃÄ'
361 'ÃÃÃÃÃÄÄÄÃÄÃÄÃÄÄÃÃÄÃÄÃÄÄÃÃÄ'
421 'ÃÃÄÃÃÄÃÃÄÃÄÄÄÃÄÃÃÃÄÃÃÃÃÃÄÄÄÃ'
481 'ÄÃÄÃÄÄÃÃÄÃÄÃÄÄÃÃÄÃÃÄÃÃÄÃÃ'
541 'ÄÃÄÄÄÃÄÃÃÃÄÃÃÃÃÃÄÄÄÃÄÃÄÃ'
601 'ÄÄÃÃÄÃÄÃÄÄÃÃÄÃÃÄÃÃÄÃÃÄÃÄÄÄÃ'
Scott Klement
Site Admin
Posts: 872
Joined: Sun Jul 04, 2021 5:12 am

Re: how to decode base64 encoded zpl data back to ASCII/EBCDIC

Post by Scott Klement »

Why are you posting all the mistranslated characters? Am I supposed to be able to make something of that?

Seems to me that if your data is in UTF-8 and you want to work with it, you can't be scanning for EBCDIC data and expecting that to work. Instead, scan for UTF-8 data...

Use the ccsid(*utf8) character on the strings that will be in UTf-8.

Code: Select all

     D zplOut          s          20000a   ccsid(*utf8)
     D CPOI            s              4a   ccsid(*utf8) inz('^POI')
     D CPON            s              4a   ccsid(*utf8) inz('^PON')
Then use the UTF-8 strings in your work

Code: Select all

       
       #strpos = %Scan(CPOI: ZplOut);
       If #strpos > 0;
         ZplOut = %SubSt(ZplOut:1:#strpos-1) + CPON +
                  %SubSt(ZplOut:#strpos+4:(%Len(ZplOut) - #strpos) - 3);
       EndIf;
Alternately, just use the %SCANRPL or %SCAN/%REPLACE BIFs.
sbehera00
Posts: 16
Joined: Mon Jul 22, 2024 10:29 pm

Re: how to decode base64 encoded zpl data back to ASCII/EBCDIC

Post by sbehera00 »

Hello Scott,
when i do
D ZplOutU s 65535A ccsid(*utf8)
SEU gives error "The parameter for keyword CCSID is not valid" then i changed to
D ZplOutU s 65535A ccsid(1208) i get error
The CCSID keyword is not valid with the specified definition.

I have made other way to work. Ideal way i was thinking is to do change when i get the data but at this time i am not sent to printer but just store in folder. When i am sending to printe i am reading the file and able to change this piece of data before writing to spool.

I thought there will be quick/easy way but does not look like...
Scott Klement
Site Admin
Posts: 872
Joined: Sun Jul 04, 2021 5:12 am

Re: how to decode base64 encoded zpl data back to ASCII/EBCDIC

Post by Scott Klement »

Support for ccsid(*utf8) (or ccsid(1208)) was released with V7R2 back in 2014. If you don't have that support on your system, you're VERY out of date.

That will certainly make things more difficult. You'll have to code constants with the hex values of ^POI and ^PON and scan/replace those.
sbehera00
Posts: 16
Joined: Mon Jul 22, 2024 10:29 pm

Re: how to decode base64 encoded zpl data back to ASCII/EBCDIC

Post by sbehera00 »

Hello Scott,
i was able to manage so far by converting this "^POI" to "^PON" by opening ifs file with ccsid 37 and converting value while sending content to printer but now some other system going to use this ifs file so the content in the ifs needs to be replaced with "^PON".

Here are steps i am doing:

HTTP call returns data in variable B64In, base64 encoded. I am using base64_decode to ZplOut
zplLen = base64_decode( %addr(B64In:*data)
: %len(B64In)
: %addr(ZplOut)
: %size(ZplOut) );

Because ZplOut is in binary i am not able to replace "^POI" with "^PON" directly in the variable ZplOut. So first i am writing to ifs
callp write(fd: %addr(ZplOut): zplLen); -- TempIfsFile
TempIfsFile content: After writing to ifs file content looks like this
^FX ZPL generated by V1.0.0.0 ^FS
^XA
^PW812
^POI
^PR8,8,8

I am reading TempIfsFile and writing same content to FinalIfsFile and during this process replacing "^POI" with "^PON"
fd = open( %Trim(FinalIfsFile)
: O_CREAT + O_EXCL + O_WRONLY + O_INHERITMODE
+ O_CCSID
: 0
: 1208
: 0 );
fdi = open( %Trim(TempIfsFile)
: O_RDONLY + O_TEXTDATA + O_CCSID :
S_IRGRP : 37) ;
Len = Read(fdi:%addr(Data):%size(Data)) ;
#strpos = %Scan('^POI':Data);
If #strpos > 0;
Data = %SubSt(Data:1:#strpos-1) + '^PON' +
%SubSt(Data:#strpos+4:(%Len(Data)- (#strpos+9)
-- Looking through debug value of variable Data looks good "^FX ZPL generated by V1.0.0.0 ^FS^XA^PW812^PON^PR8"
EndIf;
callp write(fd: %addr(Data): Len);

My FinalIfsFile content looks junk. Possibly issue is i am opening "TempIfsFile" with CCSID 37 and "FinalIfsFile" with CCSID 1208 causing this issue?
Please help how to address this issue or if there is any better way to achieve this?

FinalIfsFile content:
@@ @ @ @ K K K @@
%
%
%
% k k
%
Scott Klement
Site Admin
Posts: 872
Joined: Sun Jul 04, 2021 5:12 am

Re: how to decode base64 encoded zpl data back to ASCII/EBCDIC

Post by Scott Klement »

sbehera00 wrote: Wed Dec 11, 2024 12:30 pm i was able to manage so far by converting this "^POI" to "^PON" by opening ifs file with ccsid 37 and converting value while sending content to printer but now some other system going to use this ifs file so the content in the ifs needs to be replaced with "^PON".
I would very much discourage you from converting the data to CCSID 37 (or any other flavor of EBCDIC.) Keep the character encoding the same as the original document.
Here are steps i am doing:

HTTP call returns data in variable B64In, base64 encoded. I am using base64_decode to ZplOut
zplLen = base64_decode( %addr(B64In:*data)
: %len(B64In)
: %addr(ZplOut)
: %size(ZplOut) );
Because ZplOut is in binary i am not able to replace "^POI" with "^PON" directly in the variable ZplOut. So first i am writing to ifs
When we talked earlier I recommended creating hex constants and doing the find/replace on those. But now you say you're "not able to because it's binary". That doesn't make sense. You can't scan/replace EBCDIC values because the data is not EBCDIC. But you should be able to use the hex constants I discussed. Or use UTF-8 support in RPG, as I originally suggested -- but you said you are on an extraordinarily out of date machine that doesn't support this -- can you explain what release of the OS you are on? I don't want to spend time giving you a solution only to find out it won't work for you, so it's important to understand what your situation is.
callp write(fd: %addr(ZplOut): zplLen); -- TempIfsFile
TempIfsFile content: After writing to ifs file content looks like this
^FX ZPL generated by V1.0.0.0 ^FS
^XA
^PW812
^POI
^PR8,8,8
I don't understand why you are writing to disk prior to changing the ^POI to ^PON. But, writing to disk doesn't hurt anything (aside from performance, perhaps) provided that you don't enable translation. Knowing the write() statement isn't very helpful to knowing what you're doing to keep the data as binary, as that is defined in the open() API -- and you didn't include that.
I am reading TempIfsFile and writing same content to FinalIfsFile and during this process replacing "^POI" with "^PON"
fd = open( %Trim(FinalIfsFile)
: O_CREAT + O_EXCL + O_WRONLY + O_INHERITMODE
+ O_CCSID
: 0
: 1208
: 0 );
fdi = open( %Trim(TempIfsFile)
: O_RDONLY + O_TEXTDATA + O_CCSID :
S_IRGRP : 37) ;
Len = Read(fdi:%addr(Data):%size(Data)) ;
#strpos = %Scan('^POI':Data);
If #strpos > 0;
Data = %SubSt(Data:1:#strpos-1) + '^PON' +
%SubSt(Data:#strpos+4:(%Len(Data)- (#strpos+9)
-- Looking through debug value of variable Data looks good "^FX ZPL generated by V1.0.0.0 ^FS^XA^PW812^PON^PR8"
EndIf;
callp write(fd: %addr(Data): Len);


Not impressed at all. You're doing exactly what I recommended against... you are converting the data to EBCDIC. Please don't do that. Furthermore, you're doing something odd and providing permissions and CCSID to be assigned to a file that you aren't creating here... that code will be ignored, but... its confusing to the next programmer to code it. They might incorrectly assume that it works.

Please don't do this. Do the work in the original ASCII/UTF-8 don't convert it to EBCDIC.
My FinalIfsFile content looks junk. Possibly issue is i am opening "TempIfsFile" with CCSID 37 and "FinalIfsFile" with CCSID 1208 causing this issue?
Please help how to address this issue or if there is any better way to achieve this?
You are converting the data to EBCDIC. Then you say to the system "Create FinalIfsFile and mark it as ccsid 1208 aka UTF-8. I will provide UTF-8 data to put in the file". After saying that you promptly provide EBCDIC data instead of UTF-8 data, causing it to look like junk.
sbehera00
Posts: 16
Joined: Mon Jul 22, 2024 10:29 pm

Re: how to decode base64 encoded zpl data back to ASCII/EBCDIC

Post by sbehera00 »

Hello Scott,
My OS level is V7R3M0

Giving these details running through debug and copy from debug variable display to notepad. Not sure what format the data is in each step...

Base64 encoded data i get is this: B64In =
....5...10...15...20...25...30...35...40...45...50...55...60
'XkZYICBaUEwgZ2VuZXJhdGVkIGJ5IFYxLjAuMC4wICBeRlMNCl5YQQ0KXlBX'
'ODEyDQpeUE9JDQpeUFI4LDgsOA0KDQpeRk8yMDMsMA0KXkdCMCwyMDMsMl5G'
'Uw0KXkZUNDEsMTg1DQpeQTBOLDIxMiwwDQpeRkRQXkZTDQpeRk8yMTMsMTA0'
'XkdGQSw0NjgwLDQ2ODAsNTIsZmZmZjMzMzAzZmYzMzBmZmNmMzAwYzAwZjMw'
'MDMwMGMwY2ZjZjNjM2YwM2YzMGYwM2ZjZjMwMGMwZjAzYzMwY2YwMDBmYzMw'
'MzBmYzMzYzBmMzAwMGZjY2MwZmMwM2ZmZjMwMzMwYzBmZmZmMzMzMDNmZjMz'
'MGZmY2YzMDBjMDBmMzAwMzAwYzBjZmNmM2MzZjAzZjMwZjAzZmNmMzAwYzBm'
'MDNjMzBjZjAwMGZjMzAzMGZjMzNjMGYzMDAwZmNjYzBmYzAzZmZmMzAzMzBj'
'MGZmZmYzMzMwM2ZmMzMwZmZjZjMwMGMwMGYzMDAzMDBjMGNmY2YzYzNmMDNm'
'MzBmMDNmY2YzMDBjMGYwM2MzMGNmMDAwZmMzMDMwZmMzM2MwZjMwMDBmY2Nj'
'MGZjMDNmZmYzMDMzMGMwZmZmZjMzMzAzZmYzMzBmZmNmMzAwYzAwZjMwMDMw'

zplLen = base64_decode( %addr(B64In:*data)
: %len(B64In)
: %addr(ZplOut)
: %size(ZplOut) );

After i use base64_decode to decode, data is this: ZplOut =

....5...10...15...20...25...30...35...40...45...50...55...60
';ãì!&<ÅÁ>ÁÊ/ÈÁÀÂ`î;ãë;ì ;&ï;&|ñ;&ê'
';ã|;åâ;ãë;ãè; +;ãà&'
';ãë;ã|;åã ÃÃÃÃÃÃÃÃÄÃÄÃ'
'ÄÄÃÄÃÄÃÃÃÃÄÃÄÃÄÄÃÃÄÃÄÄÃÃÄ'
'ÄÄÃÄÃÃÃÄÃÃÃÃÃÃÃÃÄÃÄÃÄÄÃÄÃÄÃ'
'ÃÃÃÄÃÄÃÄÄÃÃÄÃÄÄÃÃÄÄÄÃÄÃÃÃÄ'
'ÃÃÃÃÃÃÃÃÄÃÄÃÄÄÃÄÃÄÃÃÃÃÄÃÄÃ'
'ÄÄÃÃÄÃÄÄÃÃÄÄÄÃÄÃÃÃÄÃÃÃÃÃÃÃ'
'ÃÄÃÄÃÄÄÃÄÃÄÃÃÃÃÄÃÄÃÄÄÃÃÄÃ'
'ÄÄÃÃÄÄÄÃÄÃÃÃÄÃÃÃÃÃÃÃÃÄÃÄÃ'
'ÄÄÃÄÃÄÃÃÃÃÄÃÄÃÄÄÃÃÄÃÄÄÃÃÄÄÄÃ'

I completely agree if i can replace ^POI to ^PON before writing to ifs is best choice from performance and all other prospective and i wish to do but so far i am not able to do because as i have given sample the data in my variable (how i get and after base64 decoding) i do not think i can search hex value of ^POI. Translating char ^POI to hex on some website gives (5E504F49 or B0D7D6C9) which i do not see in my B64In or ZplOut.

First looking into the data if we can figureout what is format you will able to give precise solution..
sbehera00
Posts: 16
Joined: Mon Jul 22, 2024 10:29 pm

Re: how to decode base64 encoded zpl data back to ASCII/EBCDIC

Post by sbehera00 »

Just want to give one more piece of information:
This is how i am writing to IFS and once data is in IFS this becomes readable (may be ASCII format).
fd = open( %Trim(UEPFIL)
: O_CREAT + O_EXCL + O_WRONLY + O_INHERI
+ O_CCSID
: 0
: 1208
: 0 );
callp write(fd: %addr(ZplOut): zplLen);
Note: Zplout is variable after base64_decode and value in this variable i have given in my previous post.
Post Reply