Skip to content

Commit 7ac7a3a

Browse files
authored
Select between native and Python implementations of lz4 and lzo (#51)
Two new extra's "lz4" and "lzo" are defined which will install the needed Python packages to do naitve lz4 and lzo decompression. When installed the dissect.util.compression.lz4 and dissect.util.compression.lzo modules will point to these native versions. Otherwise they will point to the pure Python implementations in this project. The native (when available) and Python modules can be accessed explicitly through: - dissect.util.compression.lz4_native - dissect.util.compression.lz4_python - dissect.util.compression.lzo_native - dissect.util.compression.lzo_python
1 parent 73aac2c commit 7ac7a3a

File tree

4 files changed

+85
-2
lines changed

4 files changed

+85
-2
lines changed

README.md

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,17 @@ Information on the supported Python versions can be found in the Getting Started
1717
pip install dissect.util
1818
```
1919

20-
This module is also automatically installed if you install the `dissect` package.
20+
`dissect.util` includes pure Python implementations of the lz4 and lzo decompression algorithms. To automatically use
21+
the faster, native (C-based) lz4 and lzo implementations in other Dissect projects, install the package with the lz4 and
22+
lzo extras:
23+
24+
```bash
25+
pip install "dissect.util[lz4,lzo]"
26+
```
27+
28+
Unfortunately there is no binary `python-lzo` wheel for PyPy installations on Windows, so it won't be installed there.
29+
30+
This module including the lz4 and lzo extras is also automatically installed if you install the `dissect` package.
2131

2232
## Build and test instructions
2333

Lines changed: 57 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,57 @@
1+
from dissect.util.compression import lz4 as lz4_python
2+
from dissect.util.compression import lzo as lzo_python
3+
4+
# This selects between the native version of lz4 (when installed) and our own
5+
# pure-Python implementation.
6+
#
7+
# By doing a:
8+
# from dissect.util.compression import lz4
9+
#
10+
# in another project will automatically give you one or the other.
11+
#
12+
# The native version is also available as dissect.util.compression.lz4_native
13+
# (when installed) and the pure Python version is always available as
14+
# dissect.util.compression.lz4_python.
15+
#
16+
# Note that the pure Python implementation is not a full replacement of the
17+
# native lz4 Python package: only the decompress() function is implemented.
18+
try:
19+
import lz4.block as lz4
20+
import lz4.block as lz4_native
21+
except ImportError:
22+
lz4 = lz4_python
23+
lz4_native = None
24+
25+
# This selects between the native version of lzo (when installed) and our own
26+
# pure-Python implementation.
27+
#
28+
# By doing a:
29+
# from dissect.util.compression import lzo
30+
#
31+
# in another project will automatically give you one or the other.
32+
#
33+
# The native version is also available as dissect.util.compression.lzo_native
34+
# (when installed) and the pure Python version is always available as
35+
# dissect.util.compression.lzo_python.
36+
#
37+
# Note that the pure Python implementation is not a full replacement of the
38+
# native lzo Python package: only the decompress() function is implemented.
39+
try:
40+
import lzo
41+
import lzo as lzo_native
42+
except ImportError:
43+
lzo = lzo_python
44+
lzo_native = None
45+
46+
__all__ = [
47+
"lz4",
48+
"lz4_native",
49+
"lz4_python",
50+
"lznt1",
51+
"lzo",
52+
"lzo_native",
53+
"lzo_python",
54+
"lzxpress",
55+
"lzxpress_huffman",
56+
"sevenbit",
57+
]

dissect/util/compression/lz4.py

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -23,12 +23,18 @@ def _get_length(src: BinaryIO, length: int) -> int:
2323

2424

2525
def decompress(
26-
src: Union[bytes, BinaryIO], max_length: int = -1, return_bytearray: bool = False, return_bytes_read: bool = False
26+
src: Union[bytes, BinaryIO],
27+
uncompressed_size: int = -1,
28+
max_length: int = -1,
29+
return_bytearray: bool = False,
30+
return_bytes_read: bool = False,
2731
) -> Union[bytes, tuple[bytes, int]]:
2832
"""LZ4 decompress from a file-like object up to a certain length. Assumes no header.
2933
3034
Args:
3135
src: File-like object to decompress from.
36+
uncompressed_size: Ignored, present for compatibility with native lz4. The ``max_length``
37+
parameter sort-of but not completely has the same function.
3238
max_length: Decompress up to this many result bytes.
3339
return_bytearray: Whether to return ``bytearray`` or ``bytes``.
3440
return_bytes_read: Whether to return a tuple of ``(data, bytes_read)`` or just the data.

pyproject.toml

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,16 @@ homepage = "https://dissect.tools"
3131
documentation = "https://docs.dissect.tools/en/latest/projects/dissect.util"
3232
repository = "https://github.com/fox-it/dissect.util"
3333

34+
[project.optional-dependencies]
35+
lzo = [
36+
# There are no Windows PyPy wheels available for python-lzo
37+
# So we use a pure python fallback for it.
38+
"python-lzo; platform_system != 'Windows' or platform_python_implementation != 'PyPy'",
39+
]
40+
lz4 = [
41+
"lz4",
42+
]
43+
3444
[project.scripts]
3545
dump-nskeyedarchiver = "dissect.util.tools.dump_nskeyedarchiver:main"
3646

0 commit comments

Comments
 (0)