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,41 @@ 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
+ static PyObject * PushNotificationType_New (Py_ssize_t size ) {
225
+ /* Check for negative size */
226
+ if (size < 0 ) {
227
+ PyErr_SetString (PyExc_SystemError , "negative list size" );
228
+ return NULL ;
229
+ }
230
+
231
+ /* Check for potential overflow */
232
+ if ((size_t )size > PY_SSIZE_T_MAX / sizeof (PyObject * )) {
233
+ return PyErr_NoMemory ();
234
+ }
235
+
236
+ #ifdef PYPY_VERSION
237
+ PyObject * obj = PyObject_CallObject ((PyObject * ) & PushNotificationType , NULL );
238
+ #else
239
+ PyObject * obj = PyType_GenericNew (& PushNotificationType , NULL , NULL );
240
+ #endif
241
+ if (obj == NULL ) {
242
+ return NULL ;
243
+ }
244
+
245
+ int res = PyList_SetSlice (obj , PY_SSIZE_T_MAX , PY_SSIZE_T_MAX , PyList_New (size ));
246
+
247
+ if (res == -1 ) {
248
+ Py_DECREF (obj );
249
+ return NULL ;
250
+ }
251
+
252
+ return obj ;
253
+ }
254
+
202
255
redisReplyObjectFunctions hiredis_ObjectFunctions = {
203
256
createStringObject , // void *(*createString)(const redisReadTask*, char*, size_t);
204
257
createArrayObject , // void *(*createArray)(const redisReadTask*, size_t);
0 commit comments