5151/* the C variable of a constant dict */
5252#define TDICT (subtype ) _dictPYALSASEQ_CONST_##subtype
5353
54- /* the C enumeration of a constant dict */
55- #define TTYPE (subtype ) PYALSASEQ_CONST_##subtype
56-
5754/* defines constant dict by type */
5855#define TCONSTDICT (subtype ) \
5956 static PyObject * TDICT(subtype);
7168/* creates a typed constant and add it to the module and dictionary */
7269#define TCONSTADD (module , subtype , name ) { \
7370 PyObject *tmp = \
74- Constant_create(#name, SND_##name, TTYPE(subtype) ); \
71+ Constant_create(#name, SND_##name); \
7572 if (tmp == NULL) { \
7673 return MOD_ERROR_VAL; \
7774 } \
109106 } \
110107 }
111108
112-
113- /* num protocol support for binary Constant operations */
114- #define NUMPROTOCOL2 (name , oper ) \
115- static PyObject * \
116- Constant_##name (PyObject *v, PyObject *w) { \
117- int type = 0; \
118- long val1, val2, val; \
119- if (get_long1(v, &val1) || get_long1(w, &val2)) { \
120- Py_INCREF(Py_NotImplemented); \
121- return Py_NotImplemented; \
122- } \
123- val = val1 oper val2; \
124- /* always asume left will be the type */ \
125- if (PyObject_TypeCheck (v , & ConstantType )) { \
126- type = ((ConstantObject * ) v )-> type ; \
127- } else if (PyObject_TypeCheck (w , & ConstantType )) { \
128- type = ((ConstantObject * ) w )-> type ; \
129- } \
130- PyObject * self = Constant_create (#oper , val, type); \
131- return self; \
132- }
133-
134- /* num protocol support for unary Constant operations */
135- #define NUMPROTOCOL1 (name , oper ) \
136- static PyObject * \
137- Constant_##name (PyObject *v) { \
138- int type = 0; \
139- long val1, val; \
140- if (get_long1(v, &val1)) { \
141- Py_INCREF(Py_NotImplemented); \
142- return Py_NotImplemented; \
143- } \
144- val = oper val1; \
145- if (PyObject_TypeCheck(v, &ConstantType)) { \
146- type = ((ConstantObject *) v)->type; \
147- } \
148- PyObject *self = Constant_create(#oper, val, type); \
149- return self; \
150- }
151-
152109/* sets the object into the dict */
153110#define SETDICTOBJ (name , object ) \
154111 PyDict_SetItemString(dict, name, object)
328285// alsaseq.Constant implementation
329286//////////////////////////////////////////////////////////////////////////////
330287
331- /* alsaseq.Constant->type enumeration */
332- enum {
333- PYALSASEQ_CONST_STREAMS ,
334- PYALSASEQ_CONST_MODE ,
335- PYALSASEQ_CONST_QUEUE ,
336- PYALSASEQ_CONST_CLIENT_TYPE ,
337- PYALSASEQ_CONST_PORT_CAP ,
338- PYALSASEQ_CONST_PORT_TYPE ,
339- PYALSASEQ_CONST_EVENT_TYPE ,
340- PYALSASEQ_CONST_EVENT_TIMESTAMP ,
341- PYALSASEQ_CONST_EVENT_TIMEMODE ,
342- PYALSASEQ_CONST_ADDR_CLIENT ,
343- PYALSASEQ_CONST_ADDR_PORT ,
344- };
345-
346288// constants dictionaries
347289
348290TCONSTDICT (STREAMS );
@@ -390,34 +332,66 @@ PyDoc_STRVAR(Constant__doc__,
390332 "Python number protocol."
391333);
392334
393- /** alsaseq.Constant object structure type */
335+ /** alsaseq.Constant additional fields */
336+ /* This follows the variable length portion of the Long type */
394337typedef struct {
395- PyObject_HEAD
396- ;
397-
398- /* value of constant */
399- unsigned long int value ;
400338 /* name of constant */
401339 const char * name ;
402- /* type of constant */
403- int type ;
340+ } ConstantExtraFields ;
341+
342+ /** alsaseq.Constant object structure type */
343+ typedef struct {
344+ #if PY_MAJOR_VERSION < 3
345+ PyIntObject base ;
346+ #else
347+ /* NOTE: this only works if the value fits in one digit */
348+ PyLongObject base ;
349+ #endif
350+ /* This field is actually offset by the base type's variable size portion */
351+ ConstantExtraFields extra ;
404352} ConstantObject ;
405353
354+ #if PY_MAJOR_VERSION < 3
355+ /* PyInt is fixed size in Python 2 */
356+ # define CONST_VALUE (x ) PyInt_AsLong((PyObject *)x)
357+ # define CONST_EXTRA (x ) (&(x->extra))
358+ #else
359+ /* PyLong is variable size in Python 3 */
360+ # define CONST_VALUE (x ) PyLong_AsLong((PyObject *)x)
361+ # define CONST_EXTRA (x ) \
362+ ((ConstantExtraFields *)( \
363+ ((intptr_t)(&x->extra)) \
364+ + abs(Py_SIZE(&x->base)) * Py_TYPE(x)->tp_itemsize \
365+ ))
366+ #endif
367+
406368/** alsaseq.Constant type (initialized later...) */
407369static PyTypeObject ConstantType ;
408370
409371/** alsaseq.Constant internal create */
410372static PyObject *
411- Constant_create (const char * name , long value , int type ) {
412- ConstantObject * self = PyObject_New (ConstantObject , & ConstantType );
373+ Constant_create (const char * name , long value ) {
374+ #if PY_MAJOR_VERSION < 3
375+ PyObject * val = PyInt_FromLong (value );
376+ #else
377+ PyObject * val = PyLong_FromLong (value );
378+ #endif
379+
380+ PyObject * args = PyTuple_Pack (1 , val );
381+ Py_DECREF (val );
382+
383+ #if PY_MAJOR_VERSION < 3
384+ ConstantObject * self = (ConstantObject * )PyInt_Type .tp_new (& ConstantType , args , NULL );
385+ #else
386+ ConstantObject * self = (ConstantObject * )PyLong_Type .tp_new (& ConstantType , args , NULL );
387+ #endif
388+ Py_DECREF (args );
413389
414390 if (self == NULL ) {
415391 return NULL ;
416392 }
417393
418- self -> value = value ;
419- self -> name = name ;
420- self -> type = type ;
394+ CONST_EXTRA (self )-> name = name ;
421395
422396 return (PyObject * )self ;
423397}
@@ -426,34 +400,16 @@ Constant_create(const char *name, long value, int type) {
426400static PyObject *
427401Constant_repr (ConstantObject * self ) {
428402 return PyUnicode_FromFormat ("%s(0x%x)" ,
429- self -> name ,
430- (unsigned int )self -> value );
403+ CONST_EXTRA ( self ) -> name ,
404+ (unsigned int )CONST_VALUE ( self ) );
431405}
432406
433407/** alsaseq.Constant tp_str */
434408static PyObject *
435409Constant_str (ConstantObject * self ) {
436410 return PyUnicode_FromFormat ("%s" ,
437- self -> name );
438- }
439-
440- /** alsaseq.Constant Number protocol support (note: not all ops supported) */
441- NUMPROTOCOL2 (Add , + )
442- NUMPROTOCOL2 (Subtract , - )
443- NUMPROTOCOL2 (Xor , ^)
444- NUMPROTOCOL2 (Or , |)
445- NUMPROTOCOL2 (And , & )
446- NUMPROTOCOL1 (Invert , ~)
447-
448- /** alsaseq.Constant number protocol methods */
449- static PyNumberMethods Constant_as_number = {
450- nb_add : (binaryfunc )Constant_Add ,
451- nb_subtract : (binaryfunc )Constant_Subtract ,
452- nb_xor : (binaryfunc )Constant_Xor ,
453- nb_or : (binaryfunc )Constant_Or ,
454- nb_and : (binaryfunc )Constant_And ,
455- nb_invert : (unaryfunc )Constant_Invert
456- };
411+ CONST_EXTRA (self )-> name );
412+ }
457413
458414/** alsaseq.Constant type */
459415static PyTypeObject ConstantType = {
@@ -464,7 +420,7 @@ static PyTypeObject ConstantType = {
464420#else
465421 tp_base : & PyLong_Type ,
466422#endif
467- tp_basicsize : sizeof (ConstantObject ),
423+ tp_basicsize : sizeof (ConstantObject ) + sizeof ( ConstantExtraFields ) ,
468424 tp_flags :
469425#if PY_MAJOR_VERSION < 3
470426 Py_TPFLAGS_HAVE_GETCHARBUFFER
@@ -474,7 +430,6 @@ static PyTypeObject ConstantType = {
474430 0 ,
475431#endif
476432 tp_doc : Constant__doc__ ,
477- tp_as_number : & Constant_as_number ,
478433 tp_free : PyObject_Del ,
479434 tp_str : (reprfunc )Constant_str ,
480435 tp_repr : (reprfunc )Constant_repr
@@ -1730,7 +1685,7 @@ SeqEvent_repr(SeqEventObject *self) {
17301685 unsigned int ntime = 0 ;
17311686 Py_DECREF (key );
17321687 if (constObject != NULL ) {
1733- typestr = constObject -> name ;
1688+ typestr = constObject -> extra . name ;
17341689 }
17351690
17361691 if (snd_seq_ev_is_real (self -> event )) {
0 commit comments