Git Product home page Git Product logo

rb-zlib's Introduction

Introduction

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.

Highlights

  • 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.

Become a sponsor

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

Getting started

The following section covers using zlib for general purpose compression. Refer to the PKZip and USTAR modules for information on working with archives.

Utility methods

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.

ZStream class

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

Inflater and Deflater classes

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)

More examples

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

How to incorporate these modules into your Realbasic/Xojo project

Import the zlib, USTAR, and/or PKZip modules

  1. Download the RB-zlib project either in ZIP archive format or by cloning the repository with your Git client.
  2. Open the RB-zlib project in REALstudio or Xojo. Open your project in a separate window.
  3. Copy the zlib, USTAR, and/or PKZip 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.

Ensure the zlib shared library is installed

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.

rb-zlib's People

Contributors

charonn0 avatar

Stargazers

 avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar

rb-zlib's Issues

How to read the content of an entry as a String in memory without extracting the Zip file?

The following code returns an array of Strings to show us the filenames of all entries within a zip folder without the need of physically extract the zip file to the disk (in-memory). This is very handy.

Dim zip As New PKZip.ZipReader(FolderItem.ShowOpenFileDialog(""))
Dim ret() As String

Do Until zip.LastError <> 0

  ret.Add(zip.CurrentName)

Loop Until Not zip.MoveNext(Nil)

zip.Close

What I'm looking for is, to get the String value of each zip entry. Something like ZipReader.CurrentContent As String which returns the raw String of entry (textfile, picture etc.).

zlib in 64 bit Xojo application

When I use the RB-zlib binding in a 32 bit Xojo application, it works fine.
But in a 64 bit Xojo applicaiton in Mac OS X 10.10.5, I get an "Incompatible Version" error.
The error occurs in the following routine

Sub Constructor(CompressionLevel As Integer = zlib.Z_DEFAULT_COMPRESSION, CompressionStrategy As Integer = zlib.Z_DEFAULT_STRATEGY, Encoding As Integer = zlib.DEFLATE_ENCODING, MemoryLevel As Integer = zlib.DEFAULT_MEM_LVL)
' Construct a new Deflater instance using the specified compression options.
' If the deflate engine could not be initialized an exception will be raised.

// Calling the overridden superclass constructor.
// Constructor() -- From zlib.FlateEngine
Super.Constructor()

If CompressionStrategy <> Z_DEFAULT_STRATEGY Or Encoding <> DEFLATE_ENCODING Or MemoryLevel <> DEFAULT_MEM_LVL Then
' Open the compressed stream using custom options
mLastError = deflateInit2_(zstruct, CompressionLevel, Z_DEFLATED, Encoding, MemoryLevel, CompressionStrategy, zlib.Version, zstruct.Size)

Else
' process zlib-wrapped deflate data
mLastError = deflateInit_(zstruct, CompressionLevel, zlib.Version, zstruct.Size)

End If

If mLastError <> Z_OK Then Raise New zlibException(mLastError)
mLevel = CompressionLevel
mStrategy = CompressionStrategy
End Sub

.docx files generated by ZipWriter don't work in WordPad

Expected behavior: a zip file which was created with the ZipWriter class, and which conforms to the .docx format, should be readable by any application which understands the .docx format.

Actual behavior: Such a zip file fails to open in Microsoft Wordpad. LibreOffice Reader opens it fine, as does Microsoft Word.

RB-zlib Xojo Question

Hi Andrew,

I'd like to create a Zip File from Memory. Say I have the following structure I wanna zip:

Root

  • index.html
  • images/
    ++ picture.png

How can I write/create Zip items directly from String like Chilkat Zip Plugin does (https://www.example-code.com/excel/zip_api_concepts.asp):

zip.AppendString2("HelloWorld2.txt","hello world!","utf-8")

This directly writes a String as a Textfile to the Zip Structure. Any analoge methods in your Library?

Thanks.

How to read ZIP Content in Memory without extracting to HDD?

Hello,

Ones again a Question how to use your Library. Say we have the following structure:

Root

  • Index.xml
  • Subfolder
    • Test.xml
    • Subfolder
      • MyFiles.xml

How can i read/parse the zip file in memory without extract them physically? Iโ€˜d like to get the XML content to String variables.

I hope you can help me. Thanks!

IOException with alias

When we try to compress a folder with alias in it, an IOException (21) occurs.
The same with any archive format.
It would be great if the archiver could handle alias files as many Applications folder have Frameworks and have several alias in them.

If we make an archive with external archiver that handles aliases and unarchive it with RB-zlib the aliases are juste empty files that doesn't work.

ZStream.Sync and Inflater.SyncToNextFlush are unreliable

I'm not sure whether it's because I'm doing something wrong or because this feature is naturally flakey. It appears that syncing only works is the stream is set to RAW_ENCODING, but sometimes my tests fail even when using that.

ZipWriter and TarWriter open too many files at once

Expected behavior

Being able to create zip archives with thousands of files, at least up to the standard limit of 65,535 entries, and TAR archives with an infinite number of entries.

Actual behavior

Depending on the system configuration and the number of files in the archive, creating the archive may fail with an IOException.

Steps to reproduce the behavior

Add more entries to the archive than the maximum number of files the OS allows to have open at once.

TapeArchive produces malformed tar files

Evidently 7Zip, the standard by which the correctness of the TapeArchive output is measured, was being too lenient. Recent versions of 7zip will refuse to open tar files generated by this class.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.