1

I'm needing to do some base64 encoding in ascii mode from a RPGLE program. Below is a strip down program of my attempt. This program uses the apr_base64_encode_binary procedure in the QSYSDIR/QAXIS10HT service program to do perform the encoding. The field (myPlainData) that it tries to encode has a value of 'Hello'. This field has a ccsid of 819 (ascii), and I'm needing the encoded result to be in ascii also. But apr_base64_encode_binary keeps return the encoded result in EBCDIC. Is there a way to get the result in ASCII?

  * play variables                                                                    
 D myPlainData     s            200    ccsid(819)                                     
 D myPlainDataLen...                                                                  
 D                 s             10I 0                                                
 D myBase64Data    s          65535A   ccsid(819)                                     
 D myBase64DataLen...                                                                 
 D                 s             10I 0                                                
                                                                                      
  * ibm base 64 encoder                                                               
  * note: apr_base64_* functions can be found in the QSYSDIR/QAXIS10HT service program
 D apr_base64_encode_binary...                                                        
 D                 pr            10i 0 extproc('apr_base64_encode_binary')            
 D  piBase64Data...                                                                   
 D                            65535A   options(*varsize) ccsid(819)                   
 D  piPlainData...                                                                    
 D                            65535A   options(*varsize) const                        
 D  piPlainDataLen...                                                                 
 D                               10i 0 value                                          
                                                                                    
  /free                                                                             
                                                                                    
     myPlainData = 'Hello';      // myPlainData is a ccsid(819) field (ascii field) 
     myPlainDataLen  = %len(%trimr(myPlainData));                                   
     //encode the data                                                              
     myBase64DataLen = apr_base64_encode_binary(myBase64Data                        
                                              :myPlainData                          
                                              :myPlainDataLen);                     
                                                                                    
                                                                                    
    *inlr = *on;                                                                    
   /end-free                                                                        
HockChai Lim
  • 1,675
  • 2
  • 20
  • 30

3 Answers3

2

The second parameter of your prototype doesn't have the CCSID keyword, so it defaults to the job CCSID. When you pass the CCSID(819) field for the second parameter, the compiler converts it to the job CCSID.

The reason your workaround is working is that the compiler now thinks that the second parameter is already in the job CCSID, so it doesn't have to convert it.

I think your first program will work correctly if you add CCSID(819) to the second parameter.

Barbara Morris
  • 3,195
  • 8
  • 10
  • the `apr_base64_xxxxx_binary` are a bit confusing to me. They specifically mention EBCDIC strings. I was wondering if they are even the correct routines to use if you've already got the data in ASCII. – Charles Apr 13 '21 at 22:17
1

It works if I change my code to below. This new code creates a temporary myPlainData2 field, assigns its base pointer to the myPlainData field, and uses this temporary field to call the encoder.

  * play variables                                                                     
 D myPlainData     s            200    ccsid(819)                                      
 D myPlainDataLen...                                                                   
 D                 s             10I 0                                                 
 D myBase64Data    s          65535A                                                   
 D myBase64DataLen...                                                                  
 D                 s             10I 0                                                 
 D myPlainData2    s            200    based(myPlainData2_p)                           
                                                                                       
  * ibm base 64 encoder                                                                
  * note: apr_base64_* functions can be found in the QSYSDIR/QAXIS10HT service program 
 D apr_base64_encode_binary...                                                         
 D                 pr            10i 0 extproc('apr_base64_encode_binary')             
 D  piBase64Data...                                                                    
 D                            65535A   options(*varsize)                               
 D  piPlainData...                                                                     
 D                            65535a   options(*varsize)                               
 D  piPlainDataLen...                                                                  
 D                               10i 0 value                                         
                                                                                     
  /free                                                                              
                                                                                     
     myPlainData = 'Hello';      // myPlainData is a ccsid(819) field (ascii field)  
     myPlainDataLen  = %len(%trimr(myPlainData));                                    
     myPlainData2_p = %addr(myPlainData);                                            
     //encode the data                                                               
     myBase64DataLen = apr_base64_encode_binary(myBase64Data                         
                                               :myPlainData2                         
                                               :myPlainDataLen);                     
                                                                                     
    *inlr = *on;                                                                     
   /end-free                                                                         
HockChai Lim
  • 1,675
  • 2
  • 20
  • 30
1

Ok, finally found something...

From the Apache docs

apr_base64_encode - Encode a text string using base64encoding. On EBCDIC machines, the input is first converted to ASCII.

apr_base64_encode_binary - Encode an text string using base64encoding. This is the same as apr_base64_encode() except on EBCDIC machines, where the conversion of the input to ASCII is left out.

So I agree with Barbara's answer that you should include CCSID(819) on both the procedures text parameters.

Charles
  • 21,637
  • 1
  • 20
  • 44