mirror of
				https://github.com/python/cpython.git
				synced 2025-11-04 07:31:38 +00:00 
			
		
		
		
	
		
			
				
	
	
		
			102 lines
		
	
	
	
		
			2.3 KiB
		
	
	
	
		
			C
		
	
	
	
	
	
			
		
		
	
	
			102 lines
		
	
	
	
		
			2.3 KiB
		
	
	
	
		
			C
		
	
	
	
	
	
/* Test PEP 688 - Buffers */
 | 
						|
 | 
						|
#include "parts.h"
 | 
						|
 | 
						|
#include "structmember.h"           // PyMemberDef
 | 
						|
#include <stddef.h>                 // offsetof
 | 
						|
 | 
						|
typedef struct {
 | 
						|
    PyObject_HEAD
 | 
						|
    PyObject *obj;
 | 
						|
    Py_ssize_t references;
 | 
						|
} testBufObject;
 | 
						|
 | 
						|
static PyObject *
 | 
						|
testbuf_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
 | 
						|
{
 | 
						|
    PyObject *obj = PyBytes_FromString("test");
 | 
						|
    if (obj == NULL) {
 | 
						|
        return NULL;
 | 
						|
    }
 | 
						|
    testBufObject *self = (testBufObject *)type->tp_alloc(type, 0);
 | 
						|
    if (self == NULL) {
 | 
						|
        Py_DECREF(obj);
 | 
						|
        return NULL;
 | 
						|
    }
 | 
						|
    self->obj = obj;
 | 
						|
    self->references = 0;
 | 
						|
    return (PyObject *)self;
 | 
						|
}
 | 
						|
 | 
						|
static int
 | 
						|
testbuf_traverse(testBufObject *self, visitproc visit, void *arg)
 | 
						|
{
 | 
						|
    Py_VISIT(self->obj);
 | 
						|
    return 0;
 | 
						|
}
 | 
						|
 | 
						|
static int
 | 
						|
testbuf_clear(testBufObject *self)
 | 
						|
{
 | 
						|
    Py_CLEAR(self->obj);
 | 
						|
    return 0;
 | 
						|
}
 | 
						|
 | 
						|
static void
 | 
						|
testbuf_dealloc(testBufObject *self)
 | 
						|
{
 | 
						|
    PyObject_GC_UnTrack(self);
 | 
						|
    Py_XDECREF(self->obj);
 | 
						|
    Py_TYPE(self)->tp_free((PyObject *) self);
 | 
						|
}
 | 
						|
 | 
						|
static int
 | 
						|
testbuf_getbuf(testBufObject *self, Py_buffer *view, int flags)
 | 
						|
{
 | 
						|
    int buf = PyObject_GetBuffer(self->obj, view, flags);
 | 
						|
    Py_SETREF(view->obj, Py_NewRef(self));
 | 
						|
    self->references++;
 | 
						|
    return buf;
 | 
						|
}
 | 
						|
 | 
						|
static void
 | 
						|
testbuf_releasebuf(testBufObject *self, Py_buffer *view)
 | 
						|
{
 | 
						|
    self->references--;
 | 
						|
    assert(self->references >= 0);
 | 
						|
}
 | 
						|
 | 
						|
static PyBufferProcs testbuf_as_buffer = {
 | 
						|
    .bf_getbuffer = (getbufferproc) testbuf_getbuf,
 | 
						|
    .bf_releasebuffer = (releasebufferproc) testbuf_releasebuf,
 | 
						|
};
 | 
						|
 | 
						|
static struct PyMemberDef testbuf_members[] = {
 | 
						|
    {"references", T_PYSSIZET, offsetof(testBufObject, references), READONLY},
 | 
						|
    {NULL},
 | 
						|
};
 | 
						|
 | 
						|
static PyTypeObject testBufType = {
 | 
						|
    PyVarObject_HEAD_INIT(NULL, 0)
 | 
						|
    .tp_name = "testBufType",
 | 
						|
    .tp_basicsize = sizeof(testBufObject),
 | 
						|
    .tp_flags = Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC,
 | 
						|
    .tp_new = testbuf_new,
 | 
						|
    .tp_dealloc = (destructor) testbuf_dealloc,
 | 
						|
    .tp_traverse = (traverseproc) testbuf_traverse,
 | 
						|
    .tp_clear = (inquiry) testbuf_clear,
 | 
						|
    .tp_as_buffer = &testbuf_as_buffer,
 | 
						|
    .tp_members = testbuf_members
 | 
						|
};
 | 
						|
 | 
						|
int
 | 
						|
_PyTestCapi_Init_Buffer(PyObject *m) {
 | 
						|
    if (PyType_Ready(&testBufType) < 0) {
 | 
						|
        return -1;
 | 
						|
    }
 | 
						|
    if (PyModule_AddObjectRef(m, "testBuf", (PyObject *)&testBufType)) {
 | 
						|
        return -1;
 | 
						|
    }
 | 
						|
 | 
						|
    return 0;
 | 
						|
}
 |