1from collections import namedtuple
2from enum import IntEnum
3
4from ._zstd import (
5 EndlessZstdDecompressor,
6 PYZSTD_CONFIG,
7 RichMemZstdCompressor,
8 ZstdCompressor,
9 ZstdDecompressor,
10 ZstdDict,
11 ZstdError,
12 ZstdFileReader,
13 ZstdFileWriter,
14 _ZSTD_CStreamSizes,
15 _ZSTD_DStreamSizes,
16 _ZSTD_btlazy2,
17 _ZSTD_btopt,
18 _ZSTD_btultra,
19 _ZSTD_btultra2,
20 _ZSTD_c_chainLog,
21 _ZSTD_c_checksumFlag,
22 _ZSTD_c_compressionLevel,
23 _ZSTD_c_contentSizeFlag,
24 _ZSTD_c_dictIDFlag,
25 _ZSTD_c_enableLongDistanceMatching,
26 _ZSTD_c_hashLog,
27 _ZSTD_c_jobSize,
28 _ZSTD_c_ldmBucketSizeLog,
29 _ZSTD_c_ldmHashLog,
30 _ZSTD_c_ldmHashRateLog,
31 _ZSTD_c_ldmMinMatch,
32 _ZSTD_c_minMatch,
33 _ZSTD_c_nbWorkers,
34 _ZSTD_c_overlapLog,
35 _ZSTD_c_searchLog,
36 _ZSTD_c_strategy,
37 _ZSTD_c_targetCBlockSize,
38 _ZSTD_c_targetLength,
39 _ZSTD_c_windowLog,
40 _ZSTD_d_windowLogMax,
41 _ZSTD_dfast,
42 _ZSTD_fast,
43 _ZSTD_greedy,
44 _ZSTD_lazy,
45 _ZSTD_lazy2,
46 _compressionLevel_values,
47 _finalize_dict,
48 _get_frame_info,
49 _get_param_bounds,
50 _set_parameter_types,
51 _train_dict,
52 compress_stream,
53 decompress,
54 decompress_stream,
55 get_frame_size,
56 zstd_version,
57 zstd_version_info
58)
59
60__all__ = (# From this file
61 'compressionLevel_values', 'get_frame_info',
62 'CParameter', 'DParameter', 'Strategy',
63 # From _zstd
64 'ZstdCompressor', 'RichMemZstdCompressor',
65 'ZstdDecompressor', 'EndlessZstdDecompressor',
66 'ZstdDict', 'ZstdError', 'decompress', 'get_frame_size',
67 'compress_stream', 'decompress_stream',
68 'zstd_version', 'zstd_version_info',
69 '_train_dict', '_finalize_dict',
70 'ZstdFileReader', 'ZstdFileWriter',
71 '_ZSTD_CStreamSizes', '_ZSTD_DStreamSizes',
72 'PYZSTD_CONFIG')
73
74
75# compressionLevel_values
76_nt_values = namedtuple('values', ['default', 'min', 'max'])
77compressionLevel_values = _nt_values(*_compressionLevel_values)
78
79
80_nt_frame_info = namedtuple('frame_info',
81 ['decompressed_size', 'dictionary_id'])
82
83def get_frame_info(frame_buffer):
84 """Get zstd frame information from a frame header.
85
86 Parameter
87 frame_buffer: A bytes-like object. It should starts from the beginning of
88 a frame, and needs to include at least the frame header (6 to
89 18 bytes).
90
91 Return a two-items namedtuple: (decompressed_size, dictionary_id)
92
93 If decompressed_size is None, decompressed size is unknown.
94
95 dictionary_id is a 32-bit unsigned integer value. 0 means dictionary ID was
96 not recorded in the frame header, the frame may or may not need a dictionary
97 to be decoded, and the ID of such a dictionary is not specified.
98
99 It's possible to append more items to the namedtuple in the future."""
100
101 ret_tuple = _get_frame_info(frame_buffer)
102 return _nt_frame_info(*ret_tuple)
103
104
105class _UnsupportedCParameter:
106 def __set_name__(self, _, name):
107 self.name = name
108
109 def __get__(self, *_, **__):
110 msg = ("%s CParameter only available when the underlying "
111 "zstd library's version is greater than or equal to v1.5.6. "
112 "At pyzstd module's run-time, zstd version is %s.") % \
113 (self.name, zstd_version)
114 raise NotImplementedError(msg)
115
116
117class CParameter(IntEnum):
118 """Compression parameters"""
119
120 compressionLevel = _ZSTD_c_compressionLevel
121 windowLog = _ZSTD_c_windowLog
122 hashLog = _ZSTD_c_hashLog
123 chainLog = _ZSTD_c_chainLog
124 searchLog = _ZSTD_c_searchLog
125 minMatch = _ZSTD_c_minMatch
126 targetLength = _ZSTD_c_targetLength
127 strategy = _ZSTD_c_strategy
128 if zstd_version_info >= (1, 5, 6):
129 targetCBlockSize = _ZSTD_c_targetCBlockSize
130 else:
131 targetCBlockSize = _UnsupportedCParameter()
132
133 enableLongDistanceMatching = _ZSTD_c_enableLongDistanceMatching
134 ldmHashLog = _ZSTD_c_ldmHashLog
135 ldmMinMatch = _ZSTD_c_ldmMinMatch
136 ldmBucketSizeLog = _ZSTD_c_ldmBucketSizeLog
137 ldmHashRateLog = _ZSTD_c_ldmHashRateLog
138
139 contentSizeFlag = _ZSTD_c_contentSizeFlag
140 checksumFlag = _ZSTD_c_checksumFlag
141 dictIDFlag = _ZSTD_c_dictIDFlag
142
143 nbWorkers = _ZSTD_c_nbWorkers
144 jobSize = _ZSTD_c_jobSize
145 overlapLog = _ZSTD_c_overlapLog
146
147 def bounds(self):
148 """Return lower and upper bounds of a compression parameter, both inclusive."""
149 # 1 means compression parameter
150 return _get_param_bounds(1, self.value)
151
152
153class DParameter(IntEnum):
154 """Decompression parameters"""
155
156 windowLogMax = _ZSTD_d_windowLogMax
157
158 def bounds(self):
159 """Return lower and upper bounds of a decompression parameter, both inclusive."""
160 # 0 means decompression parameter
161 return _get_param_bounds(0, self.value)
162
163
164class Strategy(IntEnum):
165 """Compression strategies, listed from fastest to strongest.
166
167 Note : new strategies _might_ be added in the future, only the order
168 (from fast to strong) is guaranteed.
169 """
170 fast = _ZSTD_fast
171 dfast = _ZSTD_dfast
172 greedy = _ZSTD_greedy
173 lazy = _ZSTD_lazy
174 lazy2 = _ZSTD_lazy2
175 btlazy2 = _ZSTD_btlazy2
176 btopt = _ZSTD_btopt
177 btultra = _ZSTD_btultra
178 btultra2 = _ZSTD_btultra2
179
180
181# Set CParameter/DParameter types for validity check
182_set_parameter_types(CParameter, DParameter)