Using zlib compression from a COBOL program

Refer to the following example including instructions and tricks about using zlib compression from a COBOL program.

Example

//PROCLIB JCLLIB ORDER=IGYV6R30.SIGYPROC                               
//EXAMPLE1 EXEC IGYWCLG                                                
//COBOL.STEPLIB DD DISP=SHR,DSNAME=IGYV6R30.SIGYCOMP                   
//SYSADATA DD  SYSOUT=*                                                
//COBOL.SYSIN DD *                                                     
        CBL PGMNAME(LONGMIXED)                                         
      ******************************************************************
      *                                                                *
      *  This is a sample testcase to show how you can call zlib.      *
      *  It initializes compression (deflate) and then deflates some   *
      *  data, then initializes decompression (inflate) and inflates   *
      *  the same data.                                                *
      *                                                                *
      *  Some of the key differences from 'typical' COBOL are:         *
      *  - Compiler option PGMNAME(LONGMIXED) is required.             *
      *    This means that the Program-Id name has to be a literal     *
      *  - This program uses COMP-5 data items so that the program     *
      *    can work with any setting of the TRUNC compiler option      *
      *  - Rather than passing the zstream structure by REFERENCE like *
      *    most COBOL programs, we pass the ADDRESS OF using the       *
      *    BY VALUE phrase to avoid high-order bit getting set         *
      *  - This sample has DISPLAY statements to tell you if it was    *
      *    successful or not, and they should be removed for production*
      *  - The binder (linkage editor) needs to have LIBRARY           *
      *    statements in order to access the functions in the          *
      *    /usr/lpp/hzc/lib/libzz.a archive file. See the sample       *
      *    LKED.SYSIN statements below                                 *
      *                                                                *
      ******************************************************************
       Id Division.                                                    
       Program-id. 'ZLIB'.                                             
      *                                                                
       Data Division.                                                 

       Working-Storage Section.                       
      **> Memory for tests. 'data' to be compressed   
       01  zinput   pic X(65536) value x'00'.         
       01  zoutput  pic X(65536) value x'00'.         
       01  z.                                         
      *         next_in  is a  Pointer to zstring     
           02   next_in         Pointer.              
           02   avail_in        Pic S9(9)   Comp-5.   
           02   total_in        Pic S9(9)   Comp-5.   
      *         next_out is a  Pointer to zstring     
           02   next_out        Pointer.              
           02   avail_out       Pic S9(9)   Comp-5.   
           02   total_out       Pic S9(9)   Comp-5.   
      *         msg      is a  Pointer to zstring     
           02   msg             Pointer.              
           02   state           Pointer.              
           02   zalloc          Function-pointer.     
           02   zfree           Function-pointer.     
           02   opaque          Function-pointer.     
           02   data_type       Pic S9(9)   Comp-5.   
           02   adler           Pic S9(9)   Comp-5.   
           02   reserved        Pic S9(9)   Comp-5.   
       01  y.                                         
      *         next_in  is a  Pointer to zstring     
           02   next_in         Pointer.              
           02   avail_in        Pic S9(9)   Comp-5.   
           02   total_in        Pic S9(9)   Comp-5.   
      *         next_out is a  Pointer to zstring     
           02   next_out        Pointer.              
           02   avail_out       Pic S9(9)   Comp-5.   
           02   total_out       Pic S9(9)   Comp-5.   
      *         msg      is a  Pointer to zstring     
           02   msg             Pointer.              
           02   state           Pointer.              
           02   zalloc          Function-pointer.     
           02   zfree           Function-pointer.     
           02   opaque          Function-pointer.     
           02   data_type       Pic S9(9)   Comp-5.   
           02   adler           Pic S9(9)   Comp-5.   
           02   reserved        Pic S9(9)   Comp-5.  

                                                                      
        77  rc-disp  Pic S9(9) Display Sign leading separate.          
                                                                       
       Linkage Section.                                                
        77  zstring  Pic x(1000).                                      
        77  rc       Pic S9(9) Comp-5.                                 
                                                                       
       Procedure Division returning rc.                                
      **>*************************************************************/
      **>                                                            */
      **> Setup the z_stream structure with defaults                 */
      **>                                                            */
      **>*************************************************************/
            Set zalloc of z to Null                                    
            Set zfree  of z to Null                                    
            Set opaque of z to Null                                    
                                                                       
      *     *>********************************************************/
      *     *>                                                       */
      *     *> Call deflateInit to initialize the deflate stream     */
      *     *> service using a GZIP wrapper                          */
      *     *>                                                       */
      *     *>********************************************************/
            Call 'DEIN2' Using By Value Address of z,                  
                                       By Value   -1, 8, 31, 8,  0,    
                                       By Content '1.2.7',             
                                       By Value  Length Of z           
                 returning rc                                          
                                                                       
            If rc NOT = 0  Then                                        
              Move rc to rc-disp                                       
              Display 'Error: deflateInit failed with Return Code '    
                                                     rc-disp          
              If  msg of z NOT = Null Then                             
                 Set Address of zstring to msg of z                    
                 Display 'Message = ' zstring                          
              Else                                                     
                 Display 'Message pointer is NULL '                    
              End-if                                                   
              Move -1 To Return-code rc                               

              Goback                                                    
            Else                                                        
              Display 'deflatinit Successful ! '                        
            End-if                                                      
                                                                        
      ******************************************************************
      *  Initialize available input, output, total in for deflate       
      ******************************************************************
            Compute avail_in of z  = 65536                              
            Compute avail_out of z = 65536                              
            Compute total_in of z = 0                                   
      ******************************************************************
      *  Set input and output pointers                                  
      ******************************************************************
            Set next_out of z to Address of zoutput                     
            Set next_in of z  to Address of zinput                      
                                                                        
      *     *>***********************************************************/
      *     *>                                                          */
      *     *> Call deflate to compress the data. We only call it       */
      *     *> once with a flush mode of Z_FINISH (4) which indicates   */
      *     *> to end the stream                                        */
      *     *>                                                          */
      *     *>***********************************************************/
            Call 'deflate' Using By Value Address of z                  
                                 BY Value 4 Returning rc                
            If rc NOT = 1  Then                                         
               Move rc to rc-disp                                       
               Display ' Error: deflate returned ' rc-disp              
                                                                        
               If msg of z NOT = Null Then                              
                 Set Address of zstring to msg of z                     
                 Display zstring                                        
               End-if                                                   
               Display "avail_in of z= "  avail_in of z                 
               Display "total_in of z= "  total_in of z                 
               Display "avail_out of z= "  avail_out of z               
               Display "total_out of z= "  total_out of z               
                                                                        
               Call 'DEEND' Using By Value address of z returning rc   

                                                                       
               Move -1 To Return-code rc                                
               Goback                                                   
            Else                                                        
              Display 'deflate  Successful ! '                          
            End-if                                                      
                                                                        
            Display 'After deflate '                                    
            Display 'avail_in of z= '    avail_in of z                  
            Display 'total_in of z= '    total_in of z                  
            Display 'avail_out of z= '   avail_out of z                 
            Display 'total_out of z= '   total_out of z                 
                                                                        
      *   /************************************************************/
      *   /*                                                          */
      *   /* Now that we are done , call deflateEnd to cleanup the    */
      *   /* deflate internal state.                                  */
      *   /*                                                          */
      *   /************************************************************/
            Call 'DEEND' Using By Value Address of z returning rc       
            If rc Not = 0 Then                                          
               Move rc to rc-disp                                       
               Display 'Error: deflateEnd returned ' rc-disp            
                                                                        
               If msg of z NOT = Null Then                              
                 Move -1 To Return-code rc                              
                 Goback                                                 
               End-if                                                   
            Else                                                        
              Display 'deflateEnd  Successful ! '                       
            End-if                                                      
                                                                        
      *   /************************************************************/
      *   /*                                                          */
      *   /* Inflate the data we just deflated. Call inflateInit to   */
      *   /* initialize the inflate stream                            */
      *   /*                                                          */
      *   /************************************************************/
            Set zalloc of y to Null                                     
            Set zfree  of y to Null                                    

            Set opaque of y to Null                                     
                                                                        
            Call 'ININ2' Using By Value Address of y,                   
                                       By Value   31,                   
                                       By Content '1.2.7',              
                                       By VALUE Length Of y             
                 returning rc                                           
                                                                        
            If rc NOT = 0  Then                                         
               Move rc to rc-disp                                       
               Display 'Error: inflateInit failed with Return Code '    
                                                       rc-disp          
                                                                        
               If  msg of y NOT = Null Then                             
                  Set Address of zstring to msg of y                    
                  Display zstring                                       
               End-if                                                   
               Move -1 To Return-code rc                                
               Goback                                                   
            Else                                                        
               Display 'inflateInit  Successful ! '                     
            End-if                                                      
                                                                        
      *   /************************************************************/
      *   /*                                                          */
      *   /* Set the amount of input based on what deflate returned   */
      *   /* and what we expect the output size to be.                */
      *   /*                                                          */
      *   /************************************************************/
            Compute avail_in of y  = total_out of z                     
            Compute avail_out of y = 65536                              
            Compute total_in of y = 0                                   
                                                                        
            Set next_out of y to Address of zinput                      
            Set next_in of y  to Address of zoutput                     
                                                                        
      *   /************************************************************/
      *   /*                                                          */
      *   /* Call inflate to decompress the data. Note that we expect */
      *   /* this to end with a Z_STREAM_END (1)since we provided the */
      *   /* full stream above.                                       */
      *   /*                                                          */
      *   /************************************************************/
            Call 'inflate' Using By Value Address of y                  
                                 By Value  0 Returning rc               
            If rc Not = 1 Then                                          
               Move rc to rc-disp                                       
               Display ' Error: inflate returned ' rc-disp              
                                                                        
               If msg of z NOT = Null Then                              
                 Set Address of zstring to msg of z                     
                 Display zstring                                        
               End-if                                                   
                                                                        
               Display "avail_in of y= "  avail_in of z                 
               Disp5ay "total_in of y= "  total_in of z                 
               Display "avail_out of y= "  avail_out of z               
               Display "total_out of y= "  total_out of z               
                                                                        
               Call 'INEND' Using By Value Address of y Returning rc    
               Move -1 To Return-code rc                                
               Goback                                                   
            Else                                                        
              Display 'inflate  Successful ! '                          
            End-if                                                      
                                                                        
            Display 'After inflate '                                    
            Display 'avail_in of y= '    avail_in of y                  
            Display 'total_in of y= '    total_in of y                  
            Display 'avail_out of y= '   avail_out of y                 
            Display 'total_out of y= '   total_out of y                 
                                                                        
      *   /************************************************************/
      *   /*                                                          */
      *   /* Now that we are done call inflateEnd to cleanup the      */
      *   /* internal inflate state of the stream.                    */
      *   /*                                                          */
      *   /************************************************************/
            Call 'INEND' Using By Value Address of y Returning rc       
            If rc Not = 0 Then                                         

            If rc Not = 0 Then                               
               Move rc to rc-disp                            
               Display 'Error: inflateEnd returned ' rc-disp
                                                             
               If msg of z NOT = Null Then                   
                 Move -1 To Return-code rc                   
                 Goback                                      
               End-if                                        
            Else                                             
              Display 'inflateEnd  Successful ! '            
            End-if                                           
                                                             
            Move zero to return-code rc                      
            Goback.                                          
/*                                                           
//LKED.SYSIN DD *                                            
 LIBRARY  '/usr/lpp/hzc/lib/libzz.a'                         
/*                                                           
//LKED.SYSLIB DD DSN=CEEZ240.SCEELKED,DISP=SHR       
//LKED.SYSLMOD DD DSN=MYLOAD.COBOL.LOAD(ZLIB),DISP=SHR       
//GO.STEPLIB DD DSNAME=CEEV240.SCEERUN,DISP=SHR             
//GO.SYSUDUMP DD DUMMY                                       
//GO.SYSSORT  DD DUMMY                                       
//GO.SYSOUT   DD SYSOUT=*                                    
//