1
1
#include "reader.h"
2
2
3
3
#include <assert.h>
4
+ #include <Python.h>
4
5
5
6
static void Reader_dealloc (hiredis_ReaderObject * self );
6
7
static int Reader_traverse (hiredis_ReaderObject * self , visitproc visit , void * arg );
@@ -14,6 +15,10 @@ static PyObject *Reader_len(hiredis_ReaderObject *self);
14
15
static PyObject * Reader_has_data (hiredis_ReaderObject * self );
15
16
static PyObject * Reader_set_encoding (hiredis_ReaderObject * self , PyObject * args , PyObject * kwds );
16
17
18
+ static int PushNotificationType_init (PushNotificationObject * self , PyObject * args , PyObject * kwds );
19
+ /* Create a new instance of PushNotificationType with preallocated number of elements */
20
+ static PyObject * PushNotificationType_New (Py_ssize_t size );
21
+
17
22
static PyMethodDef hiredis_ReaderMethods [] = {
18
23
{"feed" , (PyCFunction )Reader_feed , METH_VARARGS , NULL },
19
24
{"gets" , (PyCFunction )Reader_gets , METH_VARARGS , NULL },
@@ -66,6 +71,16 @@ PyTypeObject hiredis_ReaderType = {
66
71
Reader_new , /*tp_new */
67
72
};
68
73
74
+ PyTypeObject PushNotificationType = {
75
+ PyVarObject_HEAD_INIT (NULL , 0 )
76
+ .tp_name = MOD_HIREDIS ".PushNotification" ,
77
+ .tp_basicsize = sizeof (PushNotificationObject ),
78
+ .tp_itemsize = 0 ,
79
+ .tp_flags = Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE ,
80
+ .tp_doc = "Redis PUSH notification type" ,
81
+ .tp_init = (initproc ) PushNotificationType_init ,
82
+ };
83
+
69
84
static void * tryParentize (const redisReadTask * task , PyObject * obj ) {
70
85
PyObject * parent ;
71
86
if (task && task -> parent ) {
@@ -165,6 +180,9 @@ static void *createArrayObject(const redisReadTask *task, size_t elements) {
165
180
case REDIS_REPLY_MAP :
166
181
obj = PyDict_New ();
167
182
break ;
183
+ case REDIS_REPLY_PUSH :
184
+ obj = PushNotificationType_New (elements );
185
+ break ;
168
186
default :
169
187
obj = PyList_New (elements );
170
188
}
@@ -199,6 +217,55 @@ static void freeObject(void *obj) {
199
217
Py_XDECREF (obj );
200
218
}
201
219
220
+ static int PushNotificationType_init (PushNotificationObject * self , PyObject * args , PyObject * kwds ) {
221
+ return PyList_Type .tp_init ((PyObject * )self , args , kwds );
222
+ }
223
+
224
+ /* Create a new instance of PushNotificationType with preallocated number of elements */
225
+ static PyObject * PushNotificationType_New (Py_ssize_t size ) {
226
+ /* Check for negative size */
227
+ if (size < 0 ) {
228
+ PyErr_SetString (PyExc_SystemError , "negative list size" );
229
+ return NULL ;
230
+ }
231
+
232
+ /* Check for potential overflow */
233
+ if ((size_t )size > PY_SSIZE_T_MAX / sizeof (PyObject * )) {
234
+ return PyErr_NoMemory ();
235
+ }
236
+
237
+ /* Create a new instance of PushNotificationType */
238
+ PyObject * obj = PyType_GenericNew (& PushNotificationType , NULL , NULL );
239
+ if (obj == NULL ) {
240
+ return NULL ;
241
+ }
242
+
243
+ /* Cast to PyListObject to access its fields */
244
+ PyListObject * op = (PyListObject * )obj ;
245
+
246
+ /* Allocate memory for the list items if size > 0 */
247
+ if (size > 0 ) {
248
+ size_t nbytes = (size_t )size * sizeof (PyObject * );
249
+ op -> ob_item = (PyObject * * )PyMem_Malloc (nbytes );
250
+ if (op -> ob_item == NULL ) {
251
+ Py_DECREF (obj );
252
+ return PyErr_NoMemory ();
253
+ }
254
+ /* Initialize memory to zeros */
255
+ memset (op -> ob_item , 0 , nbytes );
256
+ }
257
+
258
+ /* Set the size and allocated fields */
259
+ #if PY_VERSION_HEX >= 0x03090000
260
+ Py_SET_SIZE (op , size );
261
+ #else
262
+ Py_SIZE (op ) = size ;
263
+ #endif
264
+ op -> allocated = size ;
265
+
266
+ return obj ;
267
+ }
268
+
202
269
redisReplyObjectFunctions hiredis_ObjectFunctions = {
203
270
createStringObject , // void *(*createString)(const redisReadTask*, char*, size_t);
204
271
createArrayObject , // void *(*createArray)(const redisReadTask*, size_t);
0 commit comments