@@ -26,7 +26,7 @@ class _zstd.ZstdDict "ZstdDict *" "&zstd_dict_type_spec"
26
26
/*[clinic input]
27
27
@classmethod
28
28
_zstd.ZstdDict.__new__ as _zstd_ZstdDict_new
29
- dict_content: object
29
+ dict_content: Py_buffer
30
30
The content of a Zstandard dictionary as a bytes-like object.
31
31
/
32
32
*
@@ -42,16 +42,15 @@ by multiple ZstdCompressor or ZstdDecompressor objects.
42
42
[clinic start generated code]*/
43
43
44
44
static PyObject *
45
- _zstd_ZstdDict_new_impl (PyTypeObject * type , PyObject * dict_content ,
45
+ _zstd_ZstdDict_new_impl (PyTypeObject * type , Py_buffer * dict_content ,
46
46
int is_raw )
47
- /*[clinic end generated code: output=3ebff839cb3be6d7 input=6b5de413869ae878 ]*/
47
+ /*[clinic end generated code: output=685b7406a48b0949 input=9e8c493e31c98383 ]*/
48
48
{
49
49
ZstdDict * self = PyObject_GC_New (ZstdDict , type );
50
50
if (self == NULL ) {
51
- goto error ;
51
+ return NULL ;
52
52
}
53
53
54
- self -> dict_content = NULL ;
55
54
self -> d_dict = NULL ;
56
55
self -> dict_id = 0 ;
57
56
self -> lock = (PyMutex ){0 };
@@ -63,16 +62,21 @@ _zstd_ZstdDict_new_impl(PyTypeObject *type, PyObject *dict_content,
63
62
}
64
63
65
64
/* Check dict_content's type */
66
- self -> dict_content = PyBytes_FromObject (dict_content );
67
- if (self -> dict_content == NULL ) {
65
+ if (dict_content == NULL ) {
68
66
PyErr_SetString (PyExc_TypeError ,
69
67
"dict_content argument should be bytes-like object." );
70
68
goto error ;
71
69
}
72
70
73
- /* Both ordinary dictionary and "raw content" dictionary should
74
- at least 8 bytes */
75
- if (Py_SIZE (self -> dict_content ) < 8 ) {
71
+ self -> dict_buffer = PyMem_RawMalloc (dict_content -> len );
72
+ if (!self -> dict_buffer ) {
73
+ return PyErr_NoMemory ();
74
+ }
75
+ memcpy (self -> dict_buffer , dict_content -> buf , dict_content -> len );
76
+ self -> dict_len = dict_content -> len ;
77
+
78
+ /* Both ordinary and "raw content" dictionaries must be 8 bytes minimum */
79
+ if (self -> dict_len < 8 ) {
76
80
PyErr_SetString (PyExc_ValueError ,
77
81
"Zstandard dictionary content should at least "
78
82
"8 bytes." );
@@ -81,8 +85,7 @@ _zstd_ZstdDict_new_impl(PyTypeObject *type, PyObject *dict_content,
81
85
82
86
/* Get dict_id, 0 means "raw content" dictionary. */
83
87
self -> dict_id = ZSTD_getDictID_fromDict (
84
- PyBytes_AS_STRING (self -> dict_content ),
85
- Py_SIZE (self -> dict_content ));
88
+ self -> dict_buffer , self -> dict_len );
86
89
87
90
/* Check validity for ordinary dictionary */
88
91
if (!is_raw && self -> dict_id == 0 ) {
@@ -91,13 +94,13 @@ _zstd_ZstdDict_new_impl(PyTypeObject *type, PyObject *dict_content,
91
94
goto error ;
92
95
}
93
96
94
- // Can only track self once self->dict_content is included
95
97
PyObject_GC_Track (self );
96
98
97
99
return (PyObject * )self ;
98
100
99
101
error :
100
102
Py_XDECREF (self );
103
+ PyObject_GC_Del (self );
101
104
return NULL ;
102
105
}
103
106
@@ -115,12 +118,12 @@ ZstdDict_dealloc(PyObject *ob)
115
118
116
119
assert (!PyMutex_IsLocked (& self -> lock ));
117
120
118
- /* Release dict_content after Free ZSTD_CDict/ZSTD_DDict instances */
119
- Py_CLEAR (self -> dict_content );
121
+ /* Release dict_buffer after Free ZSTD_CDict/ZSTD_DDict instances */
122
+ PyMem_RawFree (self -> dict_buffer );
120
123
Py_CLEAR (self -> c_dicts );
121
124
122
125
PyTypeObject * tp = Py_TYPE (self );
123
- PyObject_GC_Del ( ob );
126
+ tp -> tp_free ( self );
124
127
Py_DECREF (tp );
125
128
}
126
129
@@ -131,25 +134,33 @@ PyDoc_STRVAR(ZstdDict_dictid_doc,
131
134
"The special value '0' means a 'raw content' dictionary,"
132
135
"without any restrictions on format or content." );
133
136
134
- PyDoc_STRVAR (ZstdDict_dictcontent_doc ,
135
- "The content of a Zstandard dictionary, as a bytes object." );
136
-
137
137
static PyObject *
138
138
ZstdDict_str (PyObject * ob )
139
139
{
140
140
ZstdDict * dict = ZstdDict_CAST (ob );
141
141
return PyUnicode_FromFormat ("<ZstdDict dict_id=%u dict_size=%zd>" ,
142
- dict -> dict_id , Py_SIZE ( dict -> dict_content ) );
142
+ dict -> dict_id , dict -> dict_len );
143
143
}
144
144
145
145
static PyMemberDef ZstdDict_members [] = {
146
- {"dict_id" , Py_T_UINT , offsetof(ZstdDict , dict_id ), Py_READONLY ,
147
- ZstdDict_dictid_doc },
148
- {"dict_content" , Py_T_OBJECT_EX , offsetof(ZstdDict , dict_content ),
149
- Py_READONLY , ZstdDict_dictcontent_doc },
146
+ {"dict_id" , Py_T_UINT , offsetof(ZstdDict , dict_id ), Py_READONLY , ZstdDict_dictid_doc },
150
147
{NULL }
151
148
};
152
149
150
+ /*[clinic input]
151
+ @getter
152
+ _zstd.ZstdDict.dict_content
153
+
154
+ The content of a Zstandard dictionary, as a bytes object.
155
+ [clinic start generated code]*/
156
+
157
+ static PyObject *
158
+ _zstd_ZstdDict_dict_content_get_impl (ZstdDict * self )
159
+ /*[clinic end generated code: output=0d05caa5b550eabb input=4ed526d1c151c596]*/
160
+ {
161
+ return PyBytes_FromStringAndSize (self -> dict_buffer , self -> dict_len );
162
+ }
163
+
153
164
/*[clinic input]
154
165
@getter
155
166
_zstd.ZstdDict.as_digested_dict
@@ -219,6 +230,7 @@ _zstd_ZstdDict_as_prefix_get_impl(ZstdDict *self)
219
230
}
220
231
221
232
static PyGetSetDef ZstdDict_getset [] = {
233
+ _ZSTD_ZSTDDICT_DICT_CONTENT_GETSETDEF
222
234
_ZSTD_ZSTDDICT_AS_DIGESTED_DICT_GETSETDEF
223
235
_ZSTD_ZSTDDICT_AS_UNDIGESTED_DICT_GETSETDEF
224
236
_ZSTD_ZSTDDICT_AS_PREFIX_GETSETDEF
@@ -229,24 +241,14 @@ static Py_ssize_t
229
241
ZstdDict_length (PyObject * ob )
230
242
{
231
243
ZstdDict * self = ZstdDict_CAST (ob );
232
- assert (PyBytes_Check (self -> dict_content ));
233
- return Py_SIZE (self -> dict_content );
244
+ return self -> dict_len ;
234
245
}
235
246
236
247
static int
237
248
ZstdDict_traverse (PyObject * ob , visitproc visit , void * arg )
238
249
{
239
250
ZstdDict * self = ZstdDict_CAST (ob );
240
251
Py_VISIT (self -> c_dicts );
241
- Py_VISIT (self -> dict_content );
242
- return 0 ;
243
- }
244
-
245
- static int
246
- ZstdDict_clear (PyObject * ob )
247
- {
248
- ZstdDict * self = ZstdDict_CAST (ob );
249
- Py_CLEAR (self -> dict_content );
250
252
return 0 ;
251
253
}
252
254
@@ -259,7 +261,6 @@ static PyType_Slot zstddict_slots[] = {
259
261
{Py_tp_doc , (void * )_zstd_ZstdDict_new__doc__ },
260
262
{Py_sq_length , ZstdDict_length },
261
263
{Py_tp_traverse , ZstdDict_traverse },
262
- {Py_tp_clear , ZstdDict_clear },
263
264
{0 , 0 }
264
265
};
265
266
0 commit comments