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=*
//