|
1 /** |
|
2 * Copyright (c) 2016-present, Gregory Szorc |
|
3 * All rights reserved. |
|
4 * |
|
5 * This software may be modified and distributed under the terms |
|
6 * of the BSD license. See the LICENSE file for details. |
|
7 */ |
|
8 |
|
9 #include "python-zstandard.h" |
|
10 |
|
11 void ztopy_compression_parameters(CompressionParametersObject* params, ZSTD_compressionParameters* zparams) { |
|
12 zparams->windowLog = params->windowLog; |
|
13 zparams->chainLog = params->chainLog; |
|
14 zparams->hashLog = params->hashLog; |
|
15 zparams->searchLog = params->searchLog; |
|
16 zparams->searchLength = params->searchLength; |
|
17 zparams->targetLength = params->targetLength; |
|
18 zparams->strategy = params->strategy; |
|
19 } |
|
20 |
|
21 CompressionParametersObject* get_compression_parameters(PyObject* self, PyObject* args) { |
|
22 int compressionLevel; |
|
23 unsigned PY_LONG_LONG sourceSize = 0; |
|
24 Py_ssize_t dictSize = 0; |
|
25 ZSTD_compressionParameters params; |
|
26 CompressionParametersObject* result; |
|
27 |
|
28 if (!PyArg_ParseTuple(args, "i|Kn", &compressionLevel, &sourceSize, &dictSize)) { |
|
29 return NULL; |
|
30 } |
|
31 |
|
32 params = ZSTD_getCParams(compressionLevel, sourceSize, dictSize); |
|
33 |
|
34 result = PyObject_New(CompressionParametersObject, &CompressionParametersType); |
|
35 if (!result) { |
|
36 return NULL; |
|
37 } |
|
38 |
|
39 result->windowLog = params.windowLog; |
|
40 result->chainLog = params.chainLog; |
|
41 result->hashLog = params.hashLog; |
|
42 result->searchLog = params.searchLog; |
|
43 result->searchLength = params.searchLength; |
|
44 result->targetLength = params.targetLength; |
|
45 result->strategy = params.strategy; |
|
46 |
|
47 return result; |
|
48 } |
|
49 |
|
50 PyObject* estimate_compression_context_size(PyObject* self, PyObject* args) { |
|
51 CompressionParametersObject* params; |
|
52 ZSTD_compressionParameters zparams; |
|
53 PyObject* result; |
|
54 |
|
55 if (!PyArg_ParseTuple(args, "O!", &CompressionParametersType, ¶ms)) { |
|
56 return NULL; |
|
57 } |
|
58 |
|
59 ztopy_compression_parameters(params, &zparams); |
|
60 result = PyLong_FromSize_t(ZSTD_estimateCCtxSize(zparams)); |
|
61 return result; |
|
62 } |
|
63 |
|
64 PyDoc_STRVAR(CompressionParameters__doc__, |
|
65 "CompressionParameters: low-level control over zstd compression"); |
|
66 |
|
67 static PyObject* CompressionParameters_new(PyTypeObject* subtype, PyObject* args, PyObject* kwargs) { |
|
68 CompressionParametersObject* self; |
|
69 unsigned windowLog; |
|
70 unsigned chainLog; |
|
71 unsigned hashLog; |
|
72 unsigned searchLog; |
|
73 unsigned searchLength; |
|
74 unsigned targetLength; |
|
75 unsigned strategy; |
|
76 |
|
77 if (!PyArg_ParseTuple(args, "IIIIIII", &windowLog, &chainLog, &hashLog, &searchLog, |
|
78 &searchLength, &targetLength, &strategy)) { |
|
79 return NULL; |
|
80 } |
|
81 |
|
82 if (windowLog < ZSTD_WINDOWLOG_MIN || windowLog > ZSTD_WINDOWLOG_MAX) { |
|
83 PyErr_SetString(PyExc_ValueError, "invalid window log value"); |
|
84 return NULL; |
|
85 } |
|
86 |
|
87 if (chainLog < ZSTD_CHAINLOG_MIN || chainLog > ZSTD_CHAINLOG_MAX) { |
|
88 PyErr_SetString(PyExc_ValueError, "invalid chain log value"); |
|
89 return NULL; |
|
90 } |
|
91 |
|
92 if (hashLog < ZSTD_HASHLOG_MIN || hashLog > ZSTD_HASHLOG_MAX) { |
|
93 PyErr_SetString(PyExc_ValueError, "invalid hash log value"); |
|
94 return NULL; |
|
95 } |
|
96 |
|
97 if (searchLog < ZSTD_SEARCHLOG_MIN || searchLog > ZSTD_SEARCHLOG_MAX) { |
|
98 PyErr_SetString(PyExc_ValueError, "invalid search log value"); |
|
99 return NULL; |
|
100 } |
|
101 |
|
102 if (searchLength < ZSTD_SEARCHLENGTH_MIN || searchLength > ZSTD_SEARCHLENGTH_MAX) { |
|
103 PyErr_SetString(PyExc_ValueError, "invalid search length value"); |
|
104 return NULL; |
|
105 } |
|
106 |
|
107 if (targetLength < ZSTD_TARGETLENGTH_MIN || targetLength > ZSTD_TARGETLENGTH_MAX) { |
|
108 PyErr_SetString(PyExc_ValueError, "invalid target length value"); |
|
109 return NULL; |
|
110 } |
|
111 |
|
112 if (strategy < ZSTD_fast || strategy > ZSTD_btopt) { |
|
113 PyErr_SetString(PyExc_ValueError, "invalid strategy value"); |
|
114 return NULL; |
|
115 } |
|
116 |
|
117 self = (CompressionParametersObject*)subtype->tp_alloc(subtype, 1); |
|
118 if (!self) { |
|
119 return NULL; |
|
120 } |
|
121 |
|
122 self->windowLog = windowLog; |
|
123 self->chainLog = chainLog; |
|
124 self->hashLog = hashLog; |
|
125 self->searchLog = searchLog; |
|
126 self->searchLength = searchLength; |
|
127 self->targetLength = targetLength; |
|
128 self->strategy = strategy; |
|
129 |
|
130 return (PyObject*)self; |
|
131 } |
|
132 |
|
133 static void CompressionParameters_dealloc(PyObject* self) { |
|
134 PyObject_Del(self); |
|
135 } |
|
136 |
|
137 static Py_ssize_t CompressionParameters_length(PyObject* self) { |
|
138 return 7; |
|
139 }; |
|
140 |
|
141 static PyObject* CompressionParameters_item(PyObject* o, Py_ssize_t i) { |
|
142 CompressionParametersObject* self = (CompressionParametersObject*)o; |
|
143 |
|
144 switch (i) { |
|
145 case 0: |
|
146 return PyLong_FromLong(self->windowLog); |
|
147 case 1: |
|
148 return PyLong_FromLong(self->chainLog); |
|
149 case 2: |
|
150 return PyLong_FromLong(self->hashLog); |
|
151 case 3: |
|
152 return PyLong_FromLong(self->searchLog); |
|
153 case 4: |
|
154 return PyLong_FromLong(self->searchLength); |
|
155 case 5: |
|
156 return PyLong_FromLong(self->targetLength); |
|
157 case 6: |
|
158 return PyLong_FromLong(self->strategy); |
|
159 default: |
|
160 PyErr_SetString(PyExc_IndexError, "index out of range"); |
|
161 return NULL; |
|
162 } |
|
163 } |
|
164 |
|
165 static PySequenceMethods CompressionParameters_sq = { |
|
166 CompressionParameters_length, /* sq_length */ |
|
167 0, /* sq_concat */ |
|
168 0, /* sq_repeat */ |
|
169 CompressionParameters_item, /* sq_item */ |
|
170 0, /* sq_ass_item */ |
|
171 0, /* sq_contains */ |
|
172 0, /* sq_inplace_concat */ |
|
173 0 /* sq_inplace_repeat */ |
|
174 }; |
|
175 |
|
176 PyTypeObject CompressionParametersType = { |
|
177 PyVarObject_HEAD_INIT(NULL, 0) |
|
178 "CompressionParameters", /* tp_name */ |
|
179 sizeof(CompressionParametersObject), /* tp_basicsize */ |
|
180 0, /* tp_itemsize */ |
|
181 (destructor)CompressionParameters_dealloc, /* tp_dealloc */ |
|
182 0, /* tp_print */ |
|
183 0, /* tp_getattr */ |
|
184 0, /* tp_setattr */ |
|
185 0, /* tp_compare */ |
|
186 0, /* tp_repr */ |
|
187 0, /* tp_as_number */ |
|
188 &CompressionParameters_sq, /* tp_as_sequence */ |
|
189 0, /* tp_as_mapping */ |
|
190 0, /* tp_hash */ |
|
191 0, /* tp_call */ |
|
192 0, /* tp_str */ |
|
193 0, /* tp_getattro */ |
|
194 0, /* tp_setattro */ |
|
195 0, /* tp_as_buffer */ |
|
196 Py_TPFLAGS_DEFAULT, /* tp_flags */ |
|
197 CompressionParameters__doc__, /* tp_doc */ |
|
198 0, /* tp_traverse */ |
|
199 0, /* tp_clear */ |
|
200 0, /* tp_richcompare */ |
|
201 0, /* tp_weaklistoffset */ |
|
202 0, /* tp_iter */ |
|
203 0, /* tp_iternext */ |
|
204 0, /* tp_methods */ |
|
205 0, /* tp_members */ |
|
206 0, /* tp_getset */ |
|
207 0, /* tp_base */ |
|
208 0, /* tp_dict */ |
|
209 0, /* tp_descr_get */ |
|
210 0, /* tp_descr_set */ |
|
211 0, /* tp_dictoffset */ |
|
212 0, /* tp_init */ |
|
213 0, /* tp_alloc */ |
|
214 CompressionParameters_new, /* tp_new */ |
|
215 }; |
|
216 |
|
217 void compressionparams_module_init(PyObject* mod) { |
|
218 Py_TYPE(&CompressionParametersType) = &PyType_Type; |
|
219 if (PyType_Ready(&CompressionParametersType) < 0) { |
|
220 return; |
|
221 } |
|
222 |
|
223 Py_IncRef((PyObject*)&CompressionParametersType); |
|
224 PyModule_AddObject(mod, "CompressionParameters", |
|
225 (PyObject*)&CompressionParametersType); |
|
226 } |