Skip to content

Commit 3e549a5

Browse files
committed
Support zstd compression
1 parent 4eb72d9 commit 3e549a5

File tree

3 files changed

+38
-6
lines changed

3 files changed

+38
-6
lines changed

can/io/logger.py

Lines changed: 19 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -42,6 +42,12 @@
4242
from .sqlite import SqliteWriter
4343
from .trc import TRCWriter
4444

45+
try:
46+
import pyzstd
47+
except ImportError:
48+
pyzstd = None
49+
50+
4551
#: A map of file suffixes to their corresponding
4652
#: :class:`can.io.generic.MessageWriter` class
4753
MESSAGE_WRITERS: Final[Dict[str, Type[MessageWriter]]] = {
@@ -103,7 +109,16 @@ def _compress(
103109
else:
104110
mode = "at" if append else "wt"
105111

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

108123

109124
def Logger( # noqa: N802
@@ -125,7 +140,8 @@ def Logger( # noqa: N802
125140
126141
Any of these formats can be used with gzip compression by appending
127142
the suffix .gz (e.g. filename.asc.gz). However, third-party tools might not
128-
be able to read these files.
143+
be able to read these files. Zstandard (.zst) compression is also supported
144+
when an optional dependency is installed.
129145
130146
The **filename** may also be *None*, to fall back to :class:`can.Printer`.
131147
@@ -150,7 +166,7 @@ def Logger( # noqa: N802
150166

151167
suffix = pathlib.PurePath(filename).suffix.lower()
152168
file_or_filename: AcceptedIOType = filename
153-
if suffix == ".gz":
169+
if suffix in (".gz", ".zst"):
154170
logger_type, file_or_filename = _compress(filename, **kwargs)
155171
else:
156172
logger_type = _get_logger_for_suffix(suffix)

can/io/player.py

Lines changed: 18 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,12 @@
3131
from .sqlite import SqliteReader
3232
from .trc import TRCReader
3333

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

8288
mode = "rb" if issubclass(reader_type, BinaryIOMessageReader) else "rt"
8389

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

86101

87102
def LogReader(filename: StringPathLike, **kwargs: Any) -> MessageReader: # noqa: N802
@@ -98,7 +113,7 @@ def LogReader(filename: StringPathLike, **kwargs: Any) -> MessageReader: # noqa
98113
(optional, depends on `asammdf <https://github.com/danielhrisca/asammdf>`_)
99114
* .trc :class:`can.TRCReader`
100115
101-
Gzip compressed files can be used as long as the original
116+
Gzip and Zstd compressed files can be used as long as the original
102117
files suffix is one of the above (e.g. filename.asc.gz).
103118
104119
@@ -125,7 +140,7 @@ def LogReader(filename: StringPathLike, **kwargs: Any) -> MessageReader: # noqa
125140

126141
suffix = pathlib.PurePath(filename).suffix.lower()
127142
file_or_filename: AcceptedIOType = filename
128-
if suffix == ".gz":
143+
if suffix in (".gz", ".zst"):
129144
reader_type, file_or_filename = _decompress(filename)
130145
else:
131146
reader_type = _get_logger_for_suffix(suffix)

pyproject.toml

Lines changed: 1 addition & 0 deletions
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)