Z64

A high-performance, robust Elixir library for parsing and extracting ZIP archives, with native support for PKWARE's Deflate64 (Compression Method 9) decompression algorithm.

Erlang's built-in :zip module and zlib wrapper do not support the Deflate64 compression method. This library bridges that gap by wrapping the official zlib infback9 C extension in a safe and efficient Zig-based NIF using the zigler compiler.

Memory allocations for the sliding window and decompression buffers are managed directly through Erlang's allocator, ensuring safety, performance, and complete compatibility with the BEAM.

Features

Installation

Add z64 to your list of dependencies in mix.exs:

def deps do
[
{:z64, "~> 0.1.0"}
]
end

Quick Start

1. List Entries in a ZIP Archive

List all file metadata (including names, compressed size, uncompressed size, compression method, and CRC-32) within a ZIP file:

{:ok, entries} = Z64.list_entries("path/to/archive.zip")
# Or pass a binary
{:ok, entries} = Z64.list_entries(zip_binary)
# Output structure:
# [
# %Z64.Entry{
# filename: "document.txt",
# compression_method: 9, # Method 9 is Deflate64
# compressed_size: 4567,
# uncompressed_size: 15432,
# crc32: 3456789012,
# local_header_offset: 124,
# ...
# }
# ]

2. Extract a Specific Entry

Retrieve the uncompressed content of a single file from the ZIP archive:

case Z64.extract_entry("archive.zip", "large_deflate64_file.csv") do
{:ok, binary} ->
# Work with the decompressed binary data
IO.puts("Extracted #{byte_size(binary)} bytes!")
{:error, :file_not_found} ->
IO.puts("File not found in archive")
{:error, reason} ->
IO.puts("Decompression failed: #{inspect(reason)}")
end

3. Extract All Files (Unzip)

Extract the entire ZIP archive to a destination directory on the disk:

case Z64.unzip("archive.zip", "output_directory/") do
:ok ->
IO.puts("Archive extracted successfully!")
{:error, reason} ->
IO.puts("Extraction failed: #{inspect(reason)}")
end

How It Works

Deflate64 differs from standard DEFLATE (RFC 1951) primarily in:

  1. Sliding Window Size: 64KB instead of 32KB.
  2. Additional Distance Codes: Codes 30 and 31 represent distances up to 65,536 bytes.
  3. Larger Block/Length Limits: Support for lengths up to 65,538 bytes.

This library includes the official zlib contrib/infback9 implementation (written by Mark Adler) inside c_src/. This C code is compiled alongside a Zig wrapper (lib/z64/nif.ex), which acts as the NIF bridging Elixir and the C library.

All buffer management and allocation use the BEAM's internal memory allocator, ensuring zero memory leaks and complete safety.

Tests

Run the test suite using mix:

mix test