zlib is the reference implementation for the deflate compression algorithm. Deflate is the algorithm used by the gzip container format, the zip archive format, and HTTP compression.
RB-zlib is a zlib binding for Realbasic and Xojo projects.
The minimum supported zlib version is 1.2.8. The minimum supported Xojo version is RS2009R3.
- Read and write compressed file or memory streams using a simple BinaryStream work-alike.
- Read and write zip archives (.zip)
- Read and write tape archives (.tar), with or without gzip compression.
- Supports gzip, deflate, and raw deflate compressed streams
- Supports Windows, Linux, and OS X.
- 64-bit ready.
If you use this code in a commercial project, or just want to show your appreciation, please consider sponsoring me through GitHub. https://github.com/sponsors/charonn0
The following section covers using zlib for general purpose compression. Refer to the PKZip and USTAR modules for information on working with archives.
The zlib module provides several utility methods for basic compression or decompression of data:
All of these methods are overloaded with several useful variations on input and output parameters. All variations follow either this signature:
function(source, destination, options[...]) As Boolean
or this signature:
function(source, options[...]) As MemoryBlock
where source
is a MemoryBlock
, FolderItem
, or an object which implements the Readable
interface; and destination
(when provided) is a FolderItem
or an object which implements the Writeable
interface. Methods that do not have a Destination
parameter return output as a MemoryBlock
instead. Refer to the examples below for demonstrations of some of these functions.
Additional optional arguments may be passed, to control the compression level, strategy, dictionary, and encoding. For example, GZip
and GUnZip
are just wrappers around Deflate
and Inflate
with options that specify the gzip format.
The second way to compress or decompress data is with the ZStream
class. The ZStream
is a BinaryStream
work-alike and implements both the Readable
and Writeable
interfaces. Anything written to a ZStream
is compressed and emitted to the output stream (another Writeable
); reading from a ZStream
decompresses data from the input stream (another Readable
).
Instances of ZStream
can be created from MemoryBlocks, FolderItems, and objects that implement the Readable
and/or Writeable
interfaces. For example, creating an in-memory compression stream from a zero-length MemoryBlock and writing a string to it:
Dim output As New MemoryBlock(0)
Dim z As New zlib.ZStream(output) ' zero-length creates a compressor
z.Write("Hello, world!")
z.Close
The string will be processed through the compressor and written to the output
MemoryBlock. To create a decompressor pass a MemoryBlock whose size is > 0 (continuing from above):
z = New zlib.ZStream(output) ' output contains the compressed string
MsgBox(z.ReadAll) ' read the decompressed string
The third and final way to use zlib is through the Inflater and Deflater classes. These classes provide a low-level wrapper to the zlib API. All compression and decompression done using the ZStream
class or the utility methods is ultimately carried out by an instance of Deflater
and Inflater
, respectively.
Dim d As New zlib.Deflater()
Dim data As MemoryBlock = d.Deflate("H")
data = data + d.Deflate("el")
data = data + d.Deflate("lo", zlib.Z_FINISH)
Dim i As New zlib.Inflater()
data = i.Inflate(data)
MsgBox(data)
This example compresses and decompresses a MemoryBlock using deflate compression:
Dim data As MemoryBlock = "Potentially very large MemoryBlock goes here!"
Dim comp As MemoryBlock = zlib.Deflate(data)
Dim dcmp As MemoryBlock = zlib.Inflate(comp)
This example compresses and decompresses a MemoryBlock using GZip:
Dim data As MemoryBlock = "Potentially very large MemoryBlock goes here!"
Dim comp As MemoryBlock = zlib.GZip(data)
Dim dcmp As MemoryBlock = zlib.GUnZip(comp)
This example gzips a file:
Dim src As FolderItem = GetOpenFolderItem("") ' a file to be gzipped
Dim dst As FolderItem = src.Parent.Child(src.Name + ".gz")
If zlib.GZip(src, dst) Then
MsgBox("Compression succeeded!")
Else
MsgBox("Compression failed!")
End If
This example opens an existing gzip file and decompresses it into a MemoryBlock
:
Dim f As FolderItem = GetOpenFolderItem("") ' the gzip file to open
Dim data As MemoryBlock = zlib.GUnZip(f)
If data <> Nil Then
MsgBox("Decompression succeeded!")
Else
MsgBox("Decompression failed!")
End If
This example extracts a zip archive into a directory:
Dim src As FolderItem = GetOpenFolderItem("") ' a zip file to extract
Dim dst As FolderItem = SelectFolder() ' the destination directory
Dim extracted() As FolderItem ' the list of extracted files/folders
extracted = PKZip.ReadZip(src, dst)
This example performs an HTTP request that asks for compression, and decompresses the response:
Dim h As New URLConnection
h.RequestHeader("Accept-Encoding") = "gzip, deflate"
Dim page As String = h.SendSync("GET", "http://www.example.com", 10)
If h.ResponseHeader("Content-Encoding") = "gzip" Then
page = zlib.GUnZip(page)
ElseIf h.ResponseHeader("Content-Encoding") = "deflate" Then
page = zlib.Inflate(page) ' assume DEFLATE_ENCODING; some servers send RAW_ENCODING
End If
This example performs a hand-rolled HTTP request using a TCPSocket, and demonstrates how the ZStream can be used with any object that implements the Readable
and/or Writeable
interfaces:
Static CRLF As String = EndOfLine.Windows
Dim sock As New TCPSocket
sock.Address = "www.example.com"
sock.Port = 80
sock.Connect()
Do Until sock.IsConnected
sock.Poll
Loop Until sock.LastErrorCode <> 0
sock.Write("GET / HTTP/1.0" + CRLF + "Accept-Encoding: gzip" + CRLF + "Connection: close" + CRLF + "Host: www.example.com" + CRLF + CRLF)
Do
sock.Poll
Loop Until Not sock.IsConnected
Dim headers As String = sock.Read(InStrB(sock.Lookahead, CRLF + CRLF) + 3)
Dim z As zlib.ZStream = zlib.ZStream.Open(sock)
Dim webpage As String = z.ReadAll ' read/decompress from the socket
z.Close
- Download the RB-zlib project either in ZIP archive format or by cloning the repository with your Git client.
- Open the RB-zlib project in REALstudio or Xojo. Open your project in a separate window.
- Copy the
zlib
,USTAR
, and/orPKZip
modules into your project and save.
The zlib
module does not depend on either the PKZip
or USTAR
modules, and can be used separately.
The PKZip
and USTAR
modules do not depend on each other and can be used separately.
The PKZip
and USTAR
modules optionally depend on the zlib
module for compression/decompression. To use them separately for reading and writing uncompressed archives, set the PKZip.USE_ZLIB
and/or USTAR.USE_ZLIB
constants to False
.
zlib is installed by default on most Unix-like operating systems, including OS X and most Linux distributions, however at least zlib version 1.2.8 is needed.
Windows does not have it installed by default, you will need to ship the DLL with your application. You can use pre-built DLL available here (Win32x86), or you can build them yourself from source.
RB-zlib will raise a PlatformNotSupportedException when used if all required DLLs/SOs/DyLibs are not available at runtime.