Packages

LZMA compression library for Elixir via Rust NIF

Current section

Files

Jump to
lzma lib lzma.ex
Raw

lib/lzma.ex

defmodule LZMA do
@moduledoc """
LZMA compression library for Elixir.
Provides compression and decompression using LZMA, LZMA2, and XZ formats
via a Rust NIF powered by the lzma-rs library.
## Examples
# XZ format
iex> {:ok, compressed} = LZMA.xz_compress("Hello World")
iex> {:ok, decompressed} = LZMA.xz_decompress(compressed)
iex> decompressed
"Hello World"
# LZMA format
iex> {:ok, compressed} = LZMA.lzma_compress("Hello World")
iex> {:ok, decompressed} = LZMA.lzma_decompress(compressed)
iex> decompressed
"Hello World"
# LZMA2 format
iex> {:ok, compressed} = LZMA.lzma2_compress("Hello World")
iex> {:ok, decompressed} = LZMA.lzma2_decompress(compressed)
iex> decompressed
"Hello World"
"""
alias LZMA.Native
@type compressed :: binary()
@type uncompressed :: binary()
# XZ Format
@doc """
Compresses binary data using XZ format.
## Examples
iex> {:ok, compressed} = LZMA.xz_compress("Hello World")
iex> is_binary(compressed)
true
"""
@spec xz_compress(binary()) :: {:ok, compressed()} | {:error, String.t()}
def xz_compress(data) when is_binary(data) do
Native.xz_compress(data)
end
@doc """
Same as `xz_compress/1` but raises on error.
"""
@spec xz_compress!(binary()) :: compressed()
def xz_compress!(data) do
unwrap!(xz_compress(data), "XZ compression")
end
@doc """
Decompresses XZ-compressed binary data.
## Examples
iex> {:ok, compressed} = LZMA.xz_compress("Test Data")
iex> {:ok, decompressed} = LZMA.xz_decompress(compressed)
iex> decompressed
"Test Data"
"""
@spec xz_decompress(binary()) :: {:ok, uncompressed()} | {:error, String.t()}
def xz_decompress(data) when is_binary(data) do
Native.xz_decompress(data)
end
@doc """
Same as `xz_decompress/1` but raises on error.
"""
@spec xz_decompress!(binary()) :: uncompressed()
def xz_decompress!(data) do
unwrap!(xz_decompress(data), "XZ decompression")
end
# LZMA Format
@doc """
Compresses binary data using LZMA format.
## Options
* `:unpacked_size` - The unpacked size to write to the LZMA header (optional, defaults to no size)
## Examples
iex> {:ok, compressed} = LZMA.lzma_compress("Hello World")
iex> is_binary(compressed)
true
iex> data = "Hello World"
iex> {:ok, compressed} = LZMA.lzma_compress(data, unpacked_size: byte_size(data))
iex> {:ok, decompressed} = LZMA.lzma_decompress(compressed)
iex> decompressed
"Hello World"
"""
@spec lzma_compress(binary(), keyword()) :: {:ok, compressed()} | {:error, String.t()}
def lzma_compress(data, opts \\ []) when is_binary(data) and is_list(opts) do
case opts do
[] ->
Native.lzma_compress(data)
_ ->
options_map = %{
unpacked_size: Keyword.get(opts, :unpacked_size)
}
Native.lzma_compress_with_options(data, options_map)
end
end
@doc """
Same as `lzma_compress/2` but raises on error.
"""
@spec lzma_compress!(binary(), keyword()) :: compressed()
def lzma_compress!(data, opts \\ []) do
unwrap!(lzma_compress(data, opts), "LZMA compression")
end
@doc """
Decompresses LZMA-compressed binary data.
## Options
* `:unpacked_size` - The unpacked size (optional, reads from header if not provided)
* `:memlimit` - Memory limit in bytes (optional, defaults to no limit)
* `:allow_incomplete` - Allow incomplete decompression (optional, defaults to false)
## Examples
iex> {:ok, compressed} = LZMA.lzma_compress("Test Data")
iex> {:ok, decompressed} = LZMA.lzma_decompress(compressed)
iex> decompressed
"Test Data"
iex> data = "Test Data"
iex> {:ok, compressed} = LZMA.lzma_compress(data, unpacked_size: byte_size(data))
iex> {:ok, decompressed} = LZMA.lzma_decompress(compressed, unpacked_size: byte_size(data))
iex> decompressed
"Test Data"
"""
@spec lzma_decompress(binary(), keyword()) :: {:ok, uncompressed()} | {:error, String.t()}
def lzma_decompress(data, opts \\ []) when is_binary(data) and is_list(opts) do
case opts do
[] ->
Native.lzma_decompress(data)
_ ->
options_map = %{
unpacked_size: Keyword.get(opts, :unpacked_size),
memlimit: Keyword.get(opts, :memlimit),
allow_incomplete: Keyword.get(opts, :allow_incomplete, false)
}
Native.lzma_decompress_with_options(data, options_map)
end
end
@doc """
Same as `lzma_decompress/2` but raises on error.
"""
@spec lzma_decompress!(binary(), keyword()) :: uncompressed()
def lzma_decompress!(data, opts \\ []) do
unwrap!(lzma_decompress(data, opts), "LZMA decompression")
end
# LZMA2 Format
@doc """
Compresses binary data using LZMA2 format.
## Examples
iex> {:ok, compressed} = LZMA.lzma2_compress("Hello World")
iex> is_binary(compressed)
true
"""
@spec lzma2_compress(binary()) :: {:ok, compressed()} | {:error, String.t()}
def lzma2_compress(data) when is_binary(data) do
Native.lzma2_compress(data)
end
@doc """
Same as `lzma2_compress/1` but raises on error.
"""
@spec lzma2_compress!(binary()) :: compressed()
def lzma2_compress!(data) do
unwrap!(lzma2_compress(data), "LZMA2 compression")
end
@doc """
Decompresses LZMA2-compressed binary data.
## Examples
iex> {:ok, compressed} = LZMA.lzma2_compress("Test Data")
iex> {:ok, decompressed} = LZMA.lzma2_decompress(compressed)
iex> decompressed
"Test Data"
"""
@spec lzma2_decompress(binary()) :: {:ok, uncompressed()} | {:error, String.t()}
def lzma2_decompress(data) when is_binary(data) do
Native.lzma2_decompress(data)
end
@doc """
Same as `lzma2_decompress/1` but raises on error.
"""
@spec lzma2_decompress!(binary()) :: uncompressed()
def lzma2_decompress!(data) do
unwrap!(lzma2_decompress(data), "LZMA2 decompression")
end
# Private helpers
defp unwrap!(result, operation) do
case result do
{:ok, data} -> data
{:error, reason} -> raise "#{operation} error: #{reason}"
end
end
end