Skip to content

Commit 1a841c3

Browse files
committed
Support zstd compression
1 parent 3277c9d commit 1a841c3

File tree

3 files changed

+40
-6
lines changed

3 files changed

+40
-6
lines changed

can/io/logger.py

+20-3
Original file line numberDiff line numberDiff line change
@@ -42,6 +42,13 @@
4242
from .trc import TRCWriter
4343
from .pcapng import PcapngWriter
4444

45+
46+
try:
47+
import pyzstd
48+
except ImportError:
49+
pyzstd = None
50+
51+
4552
#: A map of file suffixes to their corresponding
4653
#: :class:`can.io.generic.MessageWriter` class
4754
MESSAGE_WRITERS: Final[Dict[str, Type[MessageWriter]]] = {
@@ -103,7 +110,16 @@ def _compress(
103110
else:
104111
mode = "at" if append else "wt"
105112

106-
return logger_type, gzip.open(filename, mode)
113+
if suffixes[-1] == ".gz":
114+
compressor = gzip.open(filename, mode)
115+
elif suffixes[-1] == ".zst" and pyzstd is not None:
116+
compressor = pyzstd.open(filename, mode)
117+
else:
118+
raise ValueError(
119+
f"Unknown compression type {suffixes[-1]} for file {filename}, maybe a dependency is missing?"
120+
)
121+
122+
return logger_type, compressor
107123

108124

109125
def Logger( # noqa: N802
@@ -125,7 +141,8 @@ def Logger( # noqa: N802
125141
126142
Any of these formats can be used with gzip compression by appending
127143
the suffix .gz (e.g. filename.asc.gz). However, third-party tools might not
128-
be able to read these files.
144+
be able to read these files. Zstandard (.zst) compression is also supported
145+
when an optional dependency is installed.
129146
130147
The **filename** may also be *None*, to fall back to :class:`can.Printer`.
131148
@@ -150,7 +167,7 @@ def Logger( # noqa: N802
150167

151168
suffix = pathlib.PurePath(filename).suffix.lower()
152169
file_or_filename: AcceptedIOType = filename
153-
if suffix == ".gz":
170+
if suffix == ".gz" or suffix == ".zst":
154171
logger_type, file_or_filename = _compress(filename, **kwargs)
155172
else:
156173
logger_type = _get_logger_for_suffix(suffix)

can/io/player.py

+19-3
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,13 @@
3131
from .trc import TRCReader
3232
from .pcapng import PcapngReader
3333

34+
35+
try:
36+
import pyzstd
37+
except ImportError:
38+
pyzstd = None
39+
40+
3441
#: A map of file suffixes to their corresponding
3542
#: :class:`can.io.generic.MessageReader` class
3643
MESSAGE_READERS: Final[Dict[str, Type[MessageReader]]] = {
@@ -81,7 +88,16 @@ def _decompress(
8188

8289
mode = "rb" if issubclass(reader_type, BinaryIOMessageReader) else "rt"
8390

84-
return reader_type, gzip.open(filename, mode)
91+
if suffixes[-1] == ".gz":
92+
decompressor = gzip.open(filename, mode)
93+
elif suffixes[-1] == ".zst" and pyzstd is not None:
94+
decompressor = pyzstd.open(filename, mode)
95+
else:
96+
raise ValueError(
97+
f"Unknown compression type {suffixes[-1]} for file {filename}, maybe a dependency is missing?"
98+
)
99+
100+
return reader_type, decompressor
85101

86102

87103
def LogReader(filename: StringPathLike, **kwargs: Any) -> MessageReader: # noqa: N802
@@ -98,7 +114,7 @@ def LogReader(filename: StringPathLike, **kwargs: Any) -> MessageReader: # noqa
98114
(optional, depends on `asammdf <https://github.com/danielhrisca/asammdf>`_)
99115
* .trc :class:`can.TRCReader`
100116
101-
Gzip compressed files can be used as long as the original
117+
Gzip and Zstd compressed files can be used as long as the original
102118
files suffix is one of the above (e.g. filename.asc.gz).
103119
104120
@@ -125,7 +141,7 @@ def LogReader(filename: StringPathLike, **kwargs: Any) -> MessageReader: # noqa
125141

126142
suffix = pathlib.PurePath(filename).suffix.lower()
127143
file_or_filename: AcceptedIOType = filename
128-
if suffix == ".gz":
144+
if suffix == ".gz" or suffix == ".zst":
129145
reader_type, file_or_filename = _decompress(filename)
130146
else:
131147
reader_type = _get_logger_for_suffix(suffix)

pyproject.toml

+1
Original file line numberDiff line numberDiff line change
@@ -84,6 +84,7 @@ viewer = [
8484
]
8585
mf4 = ["asammdf>=6.0.0"]
8686
pcapng = ["python-pcapng>=2.1.1"]
87+
zstd = ["pyzstd>=0.16.2"]
8788

8889
[tool.setuptools.dynamic]
8990
readme = { file = "README.rst" }

0 commit comments

Comments
 (0)