@@ -45,98 +45,101 @@ typedef struct {
4545#include "clinic/compressor.c.h"
4646
4747static int
48- _zstd_set_c_parameters (ZstdCompressor * self , PyObject * level_or_options ,
49- const char * arg_name , const char * arg_type )
48+ _zstd_set_c_level (ZstdCompressor * self , const Py_ssize_t level )
5049{
51- size_t zstd_ret ;
52- _zstd_state * const mod_state = PyType_GetModuleState (Py_TYPE (self ));
53- if (mod_state == NULL ) {
50+ /* Set integer compression level */
51+ const int min_level = ZSTD_minCLevel ();
52+ const int max_level = ZSTD_maxCLevel ();
53+ if (level < min_level || level > max_level ) {
54+ PyErr_Format (PyExc_ValueError ,
55+ "compression level %zd not in valid range %d <= level <= %d." ,
56+ level , min_level , max_level );
5457 return -1 ;
5558 }
5659
57- /* Integer compression level */
58- if (PyLong_Check (level_or_options )) {
59- int level = PyLong_AsInt (level_or_options );
60- if (level == -1 && PyErr_Occurred ()) {
61- PyErr_Format (PyExc_ValueError ,
62- "Compression level should be an int value between %d and %d." ,
63- ZSTD_minCLevel (), ZSTD_maxCLevel ());
64- return -1 ;
65- }
66-
67- /* Save for generating ZSTD_CDICT */
68- self -> compression_level = level ;
60+ /* Save for generating ZSTD_CDICT */
61+ self -> compression_level = (int )level ;
6962
70- /* Set compressionLevel to compression context */
71- zstd_ret = ZSTD_CCtx_setParameter (self -> cctx ,
72- ZSTD_c_compressionLevel ,
73- level );
63+ /* Set compressionLevel to compression context */
64+ const size_t zstd_ret = ZSTD_CCtx_setParameter (
65+ self -> cctx , ZSTD_c_compressionLevel , (int )level );
7466
75- /* Check error */
76- if (ZSTD_isError (zstd_ret )) {
77- set_zstd_error (mod_state , ERR_SET_C_LEVEL , zstd_ret );
67+ /* Check error */
68+ if (ZSTD_isError (zstd_ret )) {
69+ const _zstd_state * const st = PyType_GetModuleState (Py_TYPE (self ));
70+ if (st == NULL ) {
7871 return -1 ;
7972 }
80- return 0 ;
73+ set_zstd_error (st , ERR_SET_C_LEVEL , zstd_ret );
74+ return -1 ;
8175 }
76+ return 0 ;
77+ }
8278
83- /* Options dict */
84- if (PyDict_Check (level_or_options )) {
85- PyObject * key , * value ;
86- Py_ssize_t pos = 0 ;
79+ static int
80+ _zstd_set_c_parameters (ZstdCompressor * self , PyObject * options )
81+ {
82+ /* Set options dict */
83+ _zstd_state * const mod_state = PyType_GetModuleState (Py_TYPE (self ));
84+ if (mod_state == NULL ) {
85+ return -1 ;
86+ }
8787
88- while (PyDict_Next (level_or_options , & pos , & key , & value )) {
89- /* Check key type */
90- if (Py_TYPE (key ) == mod_state -> DParameter_type ) {
91- PyErr_SetString (PyExc_TypeError ,
92- "Key of compression option dict should "
93- "NOT be DecompressionParameter." );
94- return -1 ;
95- }
88+ if (!PyDict_Check (options )) {
89+ PyErr_Format (PyExc_TypeError , "invalid type for options, expected dict" );
90+ return -1 ;
91+ }
9692
97- int key_v = PyLong_AsInt (key );
98- if (key_v == -1 && PyErr_Occurred ()) {
99- PyErr_SetString (PyExc_ValueError ,
100- "Key of options dict should be a CompressionParameter attribute." );
101- return -1 ;
102- }
93+ Py_ssize_t pos = 0 ;
94+ PyObject * key , * value ;
95+ while (PyDict_Next (options , & pos , & key , & value )) {
96+ /* Check key type */
97+ if (Py_TYPE (key ) == mod_state -> DParameter_type ) {
98+ PyErr_SetString (PyExc_TypeError ,
99+ "key should NOT be DecompressionParameter." );
100+ return -1 ;
101+ }
103102
104- // TODO(emmatyping): check bounds when there is a value error here for better
105- // error message?
106- int value_v = PyLong_AsInt (value );
107- if (value_v == -1 && PyErr_Occurred ()) {
108- PyErr_SetString (PyExc_ValueError ,
109- "Value of option dict should be an int." );
110- return -1 ;
111- }
103+ const int key_v = PyLong_AsInt (key );
104+ if (key_v == -1 && PyErr_Occurred ()) {
105+ PyErr_SetString (PyExc_ValueError ,
106+ "key should be a CompressionParameter attribute." );
107+ return -1 ;
108+ }
112109
113- if (key_v == ZSTD_c_compressionLevel ) {
114- /* Save for generating ZSTD_CDICT */
115- self -> compression_level = value_v ;
116- }
117- else if (key_v == ZSTD_c_nbWorkers ) {
118- /* From the zstd library docs:
119- 1. When nbWorkers >= 1, triggers asynchronous mode when
120- used with ZSTD_compressStream2().
121- 2, Default value is `0`, aka "single-threaded mode" : no
122- worker is spawned, compression is performed inside
123- caller's thread, all invocations are blocking. */
124- if (value_v != 0 ) {
125- self -> use_multithread = 1 ;
126- }
127- }
110+ // TODO(emmatyping): check bounds when there is a value error here for better
111+ // error message?
112+ int value_v = PyLong_AsInt (value );
113+ if (value_v == -1 && PyErr_Occurred ()) {
114+ PyErr_SetString (PyExc_ValueError ,
115+ "options dict value should be an int." );
116+ return -1 ;
117+ }
128118
129- /* Set parameter to compression context */
130- zstd_ret = ZSTD_CCtx_setParameter (self -> cctx , key_v , value_v );
131- if (ZSTD_isError (zstd_ret )) {
132- set_parameter_error (mod_state , 1 , key_v , value_v );
133- return -1 ;
119+ if (key_v == ZSTD_c_compressionLevel ) {
120+ /* Save for generating ZSTD_CDICT */
121+ self -> compression_level = value_v ;
122+ }
123+ else if (key_v == ZSTD_c_nbWorkers ) {
124+ /* From the zstd library docs:
125+ 1. When nbWorkers >= 1, triggers asynchronous mode when
126+ used with ZSTD_compressStream2().
127+ 2, Default value is `0`, aka "single-threaded mode" : no
128+ worker is spawned, compression is performed inside
129+ caller's thread, all invocations are blocking. */
130+ if (value_v != 0 ) {
131+ self -> use_multithread = 1 ;
134132 }
135133 }
136- return 0 ;
134+
135+ /* Set parameter to compression context */
136+ const size_t zstd_ret = ZSTD_CCtx_setParameter (self -> cctx , key_v , value_v );
137+ if (ZSTD_isError (zstd_ret )) {
138+ set_parameter_error (mod_state , 1 , key_v , value_v );
139+ return -1 ;
140+ }
137141 }
138- PyErr_Format (PyExc_TypeError , "Invalid type for %s. Expected %s" , arg_name , arg_type );
139- return -1 ;
142+ return 0 ;
140143}
141144
142145static void
@@ -314,7 +317,7 @@ _zstd_load_c_dict(ZstdCompressor *self, PyObject *dict)
314317/*[clinic input]
315318@classmethod
316319_zstd.ZstdCompressor.__new__ as _zstd_ZstdCompressor_new
317- level: object = None
320+ level: Py_ssize_t(c_default='PY_SSIZE_T_MIN', accept={int, NoneType}) = None
318321 The compression level to use. Defaults to COMPRESSION_LEVEL_DEFAULT.
319322 options: object = None
320323 A dict object that contains advanced compression parameters.
@@ -328,9 +331,9 @@ function instead.
328331[clinic start generated code]*/
329332
330333static PyObject *
331- _zstd_ZstdCompressor_new_impl (PyTypeObject * type , PyObject * level ,
334+ _zstd_ZstdCompressor_new_impl (PyTypeObject * type , Py_ssize_t level ,
332335 PyObject * options , PyObject * zstd_dict )
333- /*[clinic end generated code: output=cdef61eafecac3d7 input=92de0211ae20ffdc ]*/
336+ /*[clinic end generated code: output=a857ec0dc29fc5e2 input=9899740b24d11319 ]*/
334337{
335338 ZstdCompressor * self = PyObject_GC_New (ZstdCompressor , type );
336339 if (self == NULL ) {
@@ -353,20 +356,20 @@ _zstd_ZstdCompressor_new_impl(PyTypeObject *type, PyObject *level,
353356 /* Last mode */
354357 self -> last_mode = ZSTD_e_end ;
355358
356- if (level != Py_None && options != Py_None ) {
359+ if (level != PY_SSIZE_T_MIN && options != Py_None ) {
357360 PyErr_SetString (PyExc_RuntimeError , "Only one of level or options should be used." );
358361 goto error ;
359362 }
360363
361364 /* Set compressLevel/options to compression context */
362- if (level != Py_None ) {
363- if (_zstd_set_c_parameters (self , level , "level" , "int" ) < 0 ) {
365+ if (level != PY_SSIZE_T_MIN ) {
366+ if (_zstd_set_c_level (self , level ) < 0 ) {
364367 goto error ;
365368 }
366369 }
367370
368371 if (options != Py_None ) {
369- if (_zstd_set_c_parameters (self , options , "options" , "dict" ) < 0 ) {
372+ if (_zstd_set_c_parameters (self , options ) < 0 ) {
370373 goto error ;
371374 }
372375 }
0 commit comments