11 #if PY_VERSION_HEX >= 0x03000000
12 static PyObject* PyBuffer_FromReadWriteMemory(
void* ptr,
int size ) {
13 Py_buffer bufinfo = { ptr,
NULL, size, 1, 0, 1,
NULL,
NULL,
NULL,
NULL,
14 #if PY_VERSION_HEX < 0x03030000
18 return PyMemoryView_FromBuffer( &bufinfo );
27 struct PyBufferTop_t {
35 std::map< PyObject*, PyObject* > gSizeCallbacks;
38 #define PYROOT_PREPARE_PYBUFFER_TYPE( name ) \
39 PyTypeObject Py##name##Buffer_Type; \
40 PySequenceMethods Py##name##Buffer_SeqMethods = *(PyBuffer_Type.tp_as_sequence);\
41 PyMappingMethods Py##name##Buffer_MapMethods;
57 #if PY_VERSION_HEX < 0x03000000
58 Py_ssize_t nlen = (*(PyBuffer_Type.tp_as_sequence->sq_length))(
self);
61 (*(
Py_TYPE(
self)->tp_as_buffer->bf_getbuffer))(
self, &bufinfo, PyBUF_SIMPLE );
64 if ( nlen != INT_MAX )
67 std::map< PyObject*, PyObject* >::iterator iscbp = gSizeCallbacks.find(
self );
68 if ( iscbp != gSizeCallbacks.end() ) {
69 PyObject* pylen = PyObject_CallObject( iscbp->second,
NULL );
73 if ( nlen2 == (
Py_ssize_t)-1 && PyErr_Occurred() )
85 const char* buffer_get(
PyObject*
self,
int idx )
87 if ( idx < 0 || idx >= buffer_length(
self ) ) {
88 PyErr_SetString( PyExc_IndexError,
"buffer index out of range" );
92 #if PY_VERSION_HEX < 0x02050000
97 #if PY_VERSION_HEX < 0x03000000
98 (*(PyBuffer_Type.tp_as_buffer->bf_getcharbuffer))(
self, 0, &buf );
101 (*(PyBuffer_Type.tp_as_buffer->bf_getbuffer))(
self, &bufinfo, PyBUF_SIMPLE );
102 buf = (
char*)bufinfo.buf;
106 PyErr_SetString( PyExc_IndexError,
"attempt to index a null-buffer" );
113 #define PYROOT_IMPLEMENT_PYBUFFER_METHODS( name, type, stype, F1, F2 ) \
114 PyObject* name##_buffer_str( PyObject* self ) \
116 Py_ssize_t l = buffer_length( self ); \
117 return PyROOT_PyUnicode_FromFormat( "<"#type" buffer, size " PY_SSIZE_T_FORMAT ">", l );\
120 PyObject* name##_buffer_item( PyObject* self, Py_ssize_t idx ) { \
121 const char* buf = buffer_get( self, idx ); \
123 return F1( (stype)*((type*)buf + idx) ); \
127 int name##_buffer_ass_item( PyObject* self, Py_ssize_t idx, PyObject* val ) {\
128 const char* buf = buffer_get( self, idx ); \
132 type value = F2( val ); \
133 if ( value == (type)-1 && PyErr_Occurred() ) \
136 *((type*)buf+idx) = (type)value; \
140 PyObject* name##_buffer_subscript( PyObject* self, PyObject* item ) { \
141 if ( PyIndex_Check( item ) ) { \
142 Py_ssize_t idx = PyNumber_AsSsize_t( item, PyExc_IndexError ); \
143 if ( idx == -1 && PyErr_Occurred() ) \
145 return name##_buffer_item( self, idx ); \
164 if ( i == -1 && PyErr_Occurred() )
166 return Py_TYPE(
self)->tp_as_sequence->sq_ass_item(
self, i, val );
168 PyErr_SetString( PyExc_TypeError,
"buffer indices must be integers" );
180 if ( nlen == -1 && PyErr_Occurred() )
183 #if PY_VERSION_HEX < 0x03000000
184 ((PyBufferTop_t*)
self)->fSize = nlen;
186 PyMemoryView_GET_BUFFER(
self)->len = nlen;
189 Py_INCREF( Py_None );
198 if ( PyObject_TypeCheck( pyobject, &PyBoolBuffer_Type ) )
200 else if ( PyObject_TypeCheck( pyobject, &PyShortBuffer_Type ) )
202 else if ( PyObject_TypeCheck( pyobject, &PyUShortBuffer_Type ) )
204 else if ( PyObject_TypeCheck( pyobject, &PyIntBuffer_Type ) )
206 else if ( PyObject_TypeCheck( pyobject, &PyUIntBuffer_Type ) )
208 else if ( PyObject_TypeCheck( pyobject, &PyLongBuffer_Type ) )
210 else if ( PyObject_TypeCheck( pyobject, &PyULongBuffer_Type ) )
212 else if ( PyObject_TypeCheck( pyobject, &PyFloatBuffer_Type ) )
214 else if ( PyObject_TypeCheck( pyobject, &PyDoubleBuffer_Type ) )
217 PyErr_SetString( PyExc_TypeError,
"received unknown buffer object" );
223 PyGetSetDef buffer_getset[] = {
230 PyMethodDef buffer_methods[] = {
231 { (
char*)
"SetSize", (PyCFunction)buffer_setsize, METH_O,
NULL },
248 #define PYROOT_INSTALL_PYBUFFER_METHODS( name, type ) \
249 Py##name##Buffer_Type.tp_name = (char*)"ROOT.Py"#name"Buffer"; \
250 Py##name##Buffer_Type.tp_base = &PyBuffer_Type; \
251 Py##name##Buffer_Type.tp_as_buffer = PyBuffer_Type.tp_as_buffer; \
252 Py##name##Buffer_SeqMethods.sq_item = (ssizeargfunc)name##_buffer_item; \
253 Py##name##Buffer_SeqMethods.sq_ass_item = (ssizeobjargproc)name##_buffer_ass_item;\
254 Py##name##Buffer_SeqMethods.sq_length = (lenfunc)buffer_length; \
255 Py##name##Buffer_Type.tp_as_sequence = &Py##name##Buffer_SeqMethods; \
256 if ( PyBuffer_Type.tp_as_mapping ) { \
257 Py##name##Buffer_MapMethods.mp_length = (lenfunc)buffer_length; \
258 Py##name##Buffer_MapMethods.mp_subscript = (binaryfunc)name##_buffer_subscript;\
259 Py##name##Buffer_MapMethods.mp_ass_subscript = (objobjargproc)pyroot_buffer_ass_subscript;\
260 Py##name##Buffer_Type.tp_as_mapping = &Py##name##Buffer_MapMethods; \
262 Py##name##Buffer_Type.tp_str = (reprfunc)name##_buffer_str; \
263 Py##name##Buffer_Type.tp_methods = buffer_methods; \
264 Py##name##Buffer_Type.tp_getset = buffer_getset; \
265 PyType_Ready( &Py##name##Buffer_Type );
289 #define PYROOT_IMPLEMENT_PYBUFFER_FROM_MEMORY( name, type ) \
290 PyObject* PyROOT::TPyBufferFactory::PyBuffer_FromMemory( type* address, Py_ssize_t size )\
292 size = size < 0 ? INT_MAX : size; \
293 PyObject* buf = PyBuffer_FromReadWriteMemory( (void*)address, size ); \
295 Py_INCREF( (PyObject*)(void*)&Py##name##Buffer_Type ); \
296 buf->ob_type = &Py##name##Buffer_Type; \
301 PyObject* PyROOT::TPyBufferFactory::PyBuffer_FromMemory( type* address, PyObject* scb )\
303 PyObject* buf = PyBuffer_FromMemory( address, Py_ssize_t(0) ); \
304 if ( buf != 0 && PyCallable_Check( scb ) ) { \
306 gSizeCallbacks[ buf ] = scb; \
#define PyROOT_PyUnicode_FromString
Py_ssize_t PyNumber_AsSsize_t(PyObject *obj, PyObject *)
if(pyself &&pyself!=Py_None)
#define PYROOT_INSTALL_PYBUFFER_METHODS(name, type)
Factory for python buffers of non-string type.
#define PYROOT_IMPLEMENT_PYBUFFER_FROM_MEMORY(name, type)
static TPyBufferFactory * Instance()
#define PyIndex_Check(obj)
#define PYROOT_PREPARE_PYBUFFER_TYPE(name)
#define PYROOT_IMPLEMENT_PYBUFFER_METHODS(name, type, stype, F1, F2)