Mercurial > pygame
annotate src/bufferproxy.c @ 898:424ef30fa1ea
Added numpy support for the sndarray module. BufferProxy now contains a length property, which indicates the length of the buffer in bytes.
| author | marcus |
|---|---|
| date | Sat, 26 Jan 2008 20:13:06 +0000 |
| parents | e8926413cb3e |
| children | d971d169536c |
| rev | line source |
|---|---|
| 860 | 1 /* |
| 2 pygame - Python Game Library | |
| 3 Copyright (C) 2007 Marcus von Appen | |
| 4 | |
| 5 This library is free software; you can redistribute it and/or | |
| 6 modify it under the terms of the GNU Library General Public | |
| 7 License as published by the Free Software Foundation; either | |
| 8 version 2 of the License, or (at your option) any later version. | |
| 9 | |
| 10 This library is distributed in the hope that it will be useful, | |
| 11 but WITHOUT ANY WARRANTY; without even the implied warranty of | |
| 12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | |
| 13 Library General Public License for more details. | |
| 14 | |
| 15 You should have received a copy of the GNU Library General Public | |
| 16 License along with this library; if not, write to the Free | |
| 17 Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA | |
| 18 | |
| 19 */ | |
| 20 | |
| 21 #define PYGAMEAPI_BUFFERPROXY_INTERNAL | |
| 22 | |
| 23 #include "pygame.h" | |
| 24 #include "pygamedocs.h" | |
| 25 | |
| 26 typedef struct | |
| 27 { | |
| 28 PyObject_HEAD | |
| 29 PyObject *dict; /* dict for subclassing */ | |
| 30 PyObject *weakrefs; /* Weakrefs for subclassing */ | |
| 31 void *buffer; /* Pointer to the buffer of the parent object. */ | |
| 32 Py_ssize_t length; /* Length of the buffer. */ | |
| 33 PyObject *parent; /* Parent object associated with this object. */ | |
| 34 PyObject *lock; /* Lock object for the surface. */ | |
| 35 | |
| 36 } PyBufferProxy; | |
| 37 | |
| 38 static PyObject* _bufferproxy_new (PyTypeObject *type, PyObject *args, | |
| 39 PyObject *kwds); | |
| 40 static void _bufferproxy_dealloc (PyBufferProxy *self); | |
| 41 static PyObject* _bufferproxy_get_dict (PyBufferProxy *self, void *closure); | |
|
898
424ef30fa1ea
Added numpy support for the sndarray module. BufferProxy now contains a length property, which indicates the length of the buffer in bytes.
marcus
parents:
876
diff
changeset
|
42 static PyObject* _bufferproxy_get_raw (PyBufferProxy *self, void *closure); |
|
424ef30fa1ea
Added numpy support for the sndarray module. BufferProxy now contains a length property, which indicates the length of the buffer in bytes.
marcus
parents:
876
diff
changeset
|
43 static PyObject* _bufferproxy_get_length (PyBufferProxy *self, void *closure); |
| 860 | 44 static PyObject* _bufferproxy_repr (PyBufferProxy *self); |
|
870
31fa129efd0f
Fixed Mask documentation. Added write() method to BufferProxy.
marcus
parents:
867
diff
changeset
|
45 static PyObject* _bufferproxy_write (PyBufferProxy *buffer, PyObject *args); |
| 860 | 46 |
| 47 /* Buffer methods */ | |
| 48 static Py_ssize_t _bufferproxy_getreadbuf (PyBufferProxy *buffer, | |
| 49 Py_ssize_t _index, | |
| 50 const void **ptr); | |
| 51 static Py_ssize_t _bufferproxy_getwritebuf (PyBufferProxy *buffer, | |
| 52 Py_ssize_t _index, | |
| 53 const void **ptr); | |
| 54 static Py_ssize_t _bufferproxy_getsegcount (PyBufferProxy *buffer, | |
| 55 Py_ssize_t *lenp); | |
| 56 | |
| 57 /* C API interfaces */ | |
| 58 static PyObject* PyBufferProxy_New (PyObject *parent, void *buffer, | |
| 59 Py_ssize_t length, PyObject *lock); | |
| 60 | |
| 61 /** | |
| 62 * Methods, which are bound to the PyBufferProxy type. | |
| 63 */ | |
| 64 static PyMethodDef _bufferproxy_methods[] = | |
| 65 { | |
|
870
31fa129efd0f
Fixed Mask documentation. Added write() method to BufferProxy.
marcus
parents:
867
diff
changeset
|
66 { "write", (PyCFunction) _bufferproxy_write, METH_VARARGS, |
|
31fa129efd0f
Fixed Mask documentation. Added write() method to BufferProxy.
marcus
parents:
867
diff
changeset
|
67 "Writes raw data to the buffer" }, |
| 860 | 68 { NULL, NULL, 0, NULL } |
| 69 }; | |
| 70 | |
| 71 /** | |
| 72 * Getters and setters for the PyBufferProxy. | |
| 73 */ | |
| 74 static PyGetSetDef _bufferproxy_getsets[] = | |
| 75 { | |
| 76 { "__dict__", (getter) _bufferproxy_get_dict, NULL, NULL, NULL }, | |
|
870
31fa129efd0f
Fixed Mask documentation. Added write() method to BufferProxy.
marcus
parents:
867
diff
changeset
|
77 { "raw", (getter) _bufferproxy_get_raw, NULL, |
|
31fa129efd0f
Fixed Mask documentation. Added write() method to BufferProxy.
marcus
parents:
867
diff
changeset
|
78 "The raw buffer data as string", NULL }, |
|
898
424ef30fa1ea
Added numpy support for the sndarray module. BufferProxy now contains a length property, which indicates the length of the buffer in bytes.
marcus
parents:
876
diff
changeset
|
79 { "length", (getter) _bufferproxy_get_length, NULL, |
|
424ef30fa1ea
Added numpy support for the sndarray module. BufferProxy now contains a length property, which indicates the length of the buffer in bytes.
marcus
parents:
876
diff
changeset
|
80 "The size of the buffer data.", NULL }, |
| 860 | 81 { NULL, NULL, NULL, NULL, NULL } |
| 82 }; | |
| 83 | |
| 84 | |
| 85 /** | |
| 86 * Buffer interface support for the PyBufferProxy. | |
| 87 */ | |
| 88 static PyBufferProcs _bufferproxy_as_buffer = | |
| 89 { | |
| 90 (readbufferproc) _bufferproxy_getreadbuf, | |
| 91 (writebufferproc) _bufferproxy_getwritebuf, | |
| 92 (segcountproc) _bufferproxy_getsegcount, | |
| 93 NULL, | |
| 94 }; | |
| 95 | |
| 96 static PyTypeObject PyBufferProxy_Type = | |
| 97 { | |
| 98 PyObject_HEAD_INIT(NULL) | |
| 99 0, | |
|
870
31fa129efd0f
Fixed Mask documentation. Added write() method to BufferProxy.
marcus
parents:
867
diff
changeset
|
100 "BufferProxy", /* tp_name */ |
|
31fa129efd0f
Fixed Mask documentation. Added write() method to BufferProxy.
marcus
parents:
867
diff
changeset
|
101 sizeof (PyBufferProxy), /* tp_basicsize */ |
| 860 | 102 0, /* tp_itemsize */ |
| 103 (destructor) _bufferproxy_dealloc, /* tp_dealloc */ | |
| 104 0, /* tp_print */ | |
| 105 0, /* tp_getattr */ | |
| 106 0, /* tp_setattr */ | |
| 107 0, /* tp_compare */ | |
|
867
a249a10980f0
Fixed bufferproxy stringifcation method. Fixed PixelArray's contains() method.
marcus
parents:
860
diff
changeset
|
108 (reprfunc) &_bufferproxy_repr, /* tp_repr */ |
| 860 | 109 0, /* tp_as_number */ |
| 110 0, /* tp_as_sequence */ | |
| 111 0, /* tp_as_mapping */ | |
| 112 0, /* tp_hash */ | |
| 113 0, /* tp_call */ | |
| 114 0, /* tp_str */ | |
| 115 0, /* tp_getattro */ | |
| 116 0, /* tp_setattro */ | |
| 117 &_bufferproxy_as_buffer, /* tp_as_buffer */ | |
| 118 Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE | Py_TPFLAGS_HAVE_WEAKREFS, | |
| 119 "", /* tp_doc */ | |
| 120 0, /* tp_traverse */ | |
| 121 0, /* tp_clear */ | |
| 122 0, /* tp_richcompare */ | |
| 123 offsetof (PyBufferProxy, weakrefs), /* tp_weaklistoffset */ | |
| 124 0, /* tp_iter */ | |
| 125 0, /* tp_iternext */ | |
| 126 _bufferproxy_methods, /* tp_methods */ | |
| 127 0, /* tp_members */ | |
| 128 _bufferproxy_getsets, /* tp_getset */ | |
| 129 0, /* tp_base */ | |
| 130 0, /* tp_dict */ | |
| 131 0, /* tp_descr_get */ | |
| 132 0, /* tp_descr_set */ | |
| 133 offsetof (PyBufferProxy, dict), /* tp_dictoffset */ | |
| 134 0, /* tp_init */ | |
| 135 0, /* tp_alloc */ | |
|
870
31fa129efd0f
Fixed Mask documentation. Added write() method to BufferProxy.
marcus
parents:
867
diff
changeset
|
136 _bufferproxy_new, /* tp_new */ |
| 860 | 137 0, /* tp_free */ |
| 138 0, /* tp_is_gc */ | |
| 139 0, /* tp_bases */ | |
| 140 0, /* tp_mro */ | |
| 141 0, /* tp_cache */ | |
| 142 0, /* tp_subclasses */ | |
| 143 0, /* tp_weaklist */ | |
| 144 0 /* tp_del */ | |
| 145 }; | |
| 146 | |
| 147 /** | |
| 148 * Creates a new PyBufferProxy. | |
| 149 */ | |
| 150 static PyObject* | |
| 151 _bufferproxy_new (PyTypeObject *type, PyObject *args, PyObject *kwds) | |
| 152 { | |
| 153 PyBufferProxy *self = (PyBufferProxy *) type->tp_alloc (type, 0); | |
| 154 if (!self) | |
| 155 return NULL; | |
| 156 | |
| 157 self->weakrefs = NULL; | |
| 158 self->dict = NULL; | |
| 159 self->parent = NULL; | |
| 160 self->buffer = NULL; | |
| 161 self->lock = NULL; | |
| 162 return (PyObject *) self; | |
| 163 } | |
| 164 | |
| 165 /** | |
| 166 * Deallocates the PyBufferProxy and its members. | |
| 167 */ | |
| 168 static void | |
| 169 _bufferproxy_dealloc (PyBufferProxy *self) | |
| 170 { | |
| 171 if (self->weakrefs) | |
| 172 PyObject_ClearWeakRefs ((PyObject *) self); | |
| 173 if (self->lock) | |
| 174 { | |
| 175 Py_DECREF (self->lock); | |
| 176 } | |
| 177 Py_XDECREF (self->dict); | |
| 178 self->ob_type->tp_free ((PyObject *) self); | |
| 179 } | |
| 180 | |
| 181 /**** Getter and setter access ****/ | |
| 182 | |
| 183 /** | |
| 184 * Getter for PyBufferProxy.__dict__. | |
| 185 */ | |
| 186 static PyObject* | |
| 187 _bufferproxy_get_dict (PyBufferProxy *self, void *closure) | |
| 188 { | |
| 189 if (!self->dict) | |
| 190 { | |
| 191 self->dict = PyDict_New (); | |
| 192 if (!self->dict) | |
| 193 return NULL; | |
| 194 } | |
| 195 | |
| 196 Py_INCREF (self->dict); | |
| 197 return self->dict; | |
| 198 } | |
| 199 | |
|
870
31fa129efd0f
Fixed Mask documentation. Added write() method to BufferProxy.
marcus
parents:
867
diff
changeset
|
200 /** |
|
31fa129efd0f
Fixed Mask documentation. Added write() method to BufferProxy.
marcus
parents:
867
diff
changeset
|
201 * Getter for PyBufferProxy.raw. |
|
31fa129efd0f
Fixed Mask documentation. Added write() method to BufferProxy.
marcus
parents:
867
diff
changeset
|
202 */ |
|
31fa129efd0f
Fixed Mask documentation. Added write() method to BufferProxy.
marcus
parents:
867
diff
changeset
|
203 static PyObject* |
|
898
424ef30fa1ea
Added numpy support for the sndarray module. BufferProxy now contains a length property, which indicates the length of the buffer in bytes.
marcus
parents:
876
diff
changeset
|
204 _bufferproxy_get_raw (PyBufferProxy *self, void *closure) |
|
870
31fa129efd0f
Fixed Mask documentation. Added write() method to BufferProxy.
marcus
parents:
867
diff
changeset
|
205 { |
|
898
424ef30fa1ea
Added numpy support for the sndarray module. BufferProxy now contains a length property, which indicates the length of the buffer in bytes.
marcus
parents:
876
diff
changeset
|
206 return PyString_FromStringAndSize (self->buffer, self->length); |
|
424ef30fa1ea
Added numpy support for the sndarray module. BufferProxy now contains a length property, which indicates the length of the buffer in bytes.
marcus
parents:
876
diff
changeset
|
207 } |
|
424ef30fa1ea
Added numpy support for the sndarray module. BufferProxy now contains a length property, which indicates the length of the buffer in bytes.
marcus
parents:
876
diff
changeset
|
208 |
|
424ef30fa1ea
Added numpy support for the sndarray module. BufferProxy now contains a length property, which indicates the length of the buffer in bytes.
marcus
parents:
876
diff
changeset
|
209 /** |
|
424ef30fa1ea
Added numpy support for the sndarray module. BufferProxy now contains a length property, which indicates the length of the buffer in bytes.
marcus
parents:
876
diff
changeset
|
210 * Getter for PyBufferProxy.length |
|
424ef30fa1ea
Added numpy support for the sndarray module. BufferProxy now contains a length property, which indicates the length of the buffer in bytes.
marcus
parents:
876
diff
changeset
|
211 */ |
|
424ef30fa1ea
Added numpy support for the sndarray module. BufferProxy now contains a length property, which indicates the length of the buffer in bytes.
marcus
parents:
876
diff
changeset
|
212 static PyObject* |
|
424ef30fa1ea
Added numpy support for the sndarray module. BufferProxy now contains a length property, which indicates the length of the buffer in bytes.
marcus
parents:
876
diff
changeset
|
213 _bufferproxy_get_length (PyBufferProxy *self, void *closure) |
|
424ef30fa1ea
Added numpy support for the sndarray module. BufferProxy now contains a length property, which indicates the length of the buffer in bytes.
marcus
parents:
876
diff
changeset
|
214 { |
|
424ef30fa1ea
Added numpy support for the sndarray module. BufferProxy now contains a length property, which indicates the length of the buffer in bytes.
marcus
parents:
876
diff
changeset
|
215 return PyInt_FromLong (self->length); |
|
870
31fa129efd0f
Fixed Mask documentation. Added write() method to BufferProxy.
marcus
parents:
867
diff
changeset
|
216 } |
|
31fa129efd0f
Fixed Mask documentation. Added write() method to BufferProxy.
marcus
parents:
867
diff
changeset
|
217 |
|
31fa129efd0f
Fixed Mask documentation. Added write() method to BufferProxy.
marcus
parents:
867
diff
changeset
|
218 /**** Methods ****/ |
|
31fa129efd0f
Fixed Mask documentation. Added write() method to BufferProxy.
marcus
parents:
867
diff
changeset
|
219 |
|
31fa129efd0f
Fixed Mask documentation. Added write() method to BufferProxy.
marcus
parents:
867
diff
changeset
|
220 /** |
|
31fa129efd0f
Fixed Mask documentation. Added write() method to BufferProxy.
marcus
parents:
867
diff
changeset
|
221 * Representation method. |
|
31fa129efd0f
Fixed Mask documentation. Added write() method to BufferProxy.
marcus
parents:
867
diff
changeset
|
222 */ |
| 860 | 223 static PyObject* |
| 224 _bufferproxy_repr (PyBufferProxy *self) | |
| 225 { | |
|
870
31fa129efd0f
Fixed Mask documentation. Added write() method to BufferProxy.
marcus
parents:
867
diff
changeset
|
226 /* zd is for Py_size_t which python < 2.5 doesn't have. */ |
| 860 | 227 #if PY_VERSION_HEX < 0x02050000 |
| 228 return PyString_FromFormat("<BufferProxy(%d)>", self->length); | |
| 229 #else | |
| 230 return PyString_FromFormat("<BufferProxy(%zd)>", self->length); | |
| 231 #endif | |
| 232 } | |
| 233 | |
|
870
31fa129efd0f
Fixed Mask documentation. Added write() method to BufferProxy.
marcus
parents:
867
diff
changeset
|
234 /** |
|
31fa129efd0f
Fixed Mask documentation. Added write() method to BufferProxy.
marcus
parents:
867
diff
changeset
|
235 * Writes raw data to the buffer. |
|
31fa129efd0f
Fixed Mask documentation. Added write() method to BufferProxy.
marcus
parents:
867
diff
changeset
|
236 */ |
|
31fa129efd0f
Fixed Mask documentation. Added write() method to BufferProxy.
marcus
parents:
867
diff
changeset
|
237 static PyObject* |
|
31fa129efd0f
Fixed Mask documentation. Added write() method to BufferProxy.
marcus
parents:
867
diff
changeset
|
238 _bufferproxy_write (PyBufferProxy *buffer, PyObject *args) |
|
31fa129efd0f
Fixed Mask documentation. Added write() method to BufferProxy.
marcus
parents:
867
diff
changeset
|
239 { |
|
31fa129efd0f
Fixed Mask documentation. Added write() method to BufferProxy.
marcus
parents:
867
diff
changeset
|
240 Py_ssize_t offset; |
|
31fa129efd0f
Fixed Mask documentation. Added write() method to BufferProxy.
marcus
parents:
867
diff
changeset
|
241 Py_ssize_t length; |
|
31fa129efd0f
Fixed Mask documentation. Added write() method to BufferProxy.
marcus
parents:
867
diff
changeset
|
242 char *buf; |
|
31fa129efd0f
Fixed Mask documentation. Added write() method to BufferProxy.
marcus
parents:
867
diff
changeset
|
243 |
|
31fa129efd0f
Fixed Mask documentation. Added write() method to BufferProxy.
marcus
parents:
867
diff
changeset
|
244 if (!PyArg_ParseTuple (args, "s#i", &buf, &length, &offset)) |
|
31fa129efd0f
Fixed Mask documentation. Added write() method to BufferProxy.
marcus
parents:
867
diff
changeset
|
245 return NULL; |
|
31fa129efd0f
Fixed Mask documentation. Added write() method to BufferProxy.
marcus
parents:
867
diff
changeset
|
246 |
|
31fa129efd0f
Fixed Mask documentation. Added write() method to BufferProxy.
marcus
parents:
867
diff
changeset
|
247 if (offset + length > buffer->length) |
|
31fa129efd0f
Fixed Mask documentation. Added write() method to BufferProxy.
marcus
parents:
867
diff
changeset
|
248 { |
|
31fa129efd0f
Fixed Mask documentation. Added write() method to BufferProxy.
marcus
parents:
867
diff
changeset
|
249 return RAISE (PyExc_IndexError, "bytes to write exceed buffer size"); |
|
31fa129efd0f
Fixed Mask documentation. Added write() method to BufferProxy.
marcus
parents:
867
diff
changeset
|
250 } |
|
31fa129efd0f
Fixed Mask documentation. Added write() method to BufferProxy.
marcus
parents:
867
diff
changeset
|
251 |
| 876 | 252 memcpy (buffer->buffer + offset, buf, (size_t) length); |
|
870
31fa129efd0f
Fixed Mask documentation. Added write() method to BufferProxy.
marcus
parents:
867
diff
changeset
|
253 |
|
31fa129efd0f
Fixed Mask documentation. Added write() method to BufferProxy.
marcus
parents:
867
diff
changeset
|
254 Py_RETURN_NONE; |
|
31fa129efd0f
Fixed Mask documentation. Added write() method to BufferProxy.
marcus
parents:
867
diff
changeset
|
255 } |
|
31fa129efd0f
Fixed Mask documentation. Added write() method to BufferProxy.
marcus
parents:
867
diff
changeset
|
256 |
| 860 | 257 /**** Buffer interfaces ****/ |
| 258 | |
| 259 static Py_ssize_t | |
| 260 _bufferproxy_getreadbuf (PyBufferProxy *buffer, Py_ssize_t _index, | |
| 261 const void **ptr) | |
| 262 { | |
| 263 if (_index != 0) | |
| 264 { | |
| 265 PyErr_SetString (PyExc_SystemError, | |
| 266 "Accessing non-existent buffer segment"); | |
| 267 return -1; | |
| 268 } | |
| 269 | |
| 270 if (!buffer->parent) | |
| 271 { | |
| 272 *ptr = NULL; | |
| 273 return 0; | |
| 274 } | |
| 275 | |
| 276 *ptr = buffer->buffer; | |
| 277 return buffer->length; | |
| 278 } | |
| 279 | |
| 280 static Py_ssize_t | |
| 281 _bufferproxy_getwritebuf (PyBufferProxy *buffer, Py_ssize_t _index, | |
| 282 const void **ptr) | |
| 283 { | |
| 284 if (_index != 0) | |
| 285 { | |
| 286 PyErr_SetString (PyExc_SystemError, | |
| 287 "Accessing non-existent array segment"); | |
| 288 return -1; | |
| 289 } | |
| 290 | |
| 291 if (!buffer->parent) | |
| 292 { | |
| 293 *ptr = NULL; | |
| 294 return 0; | |
| 295 } | |
| 296 | |
| 297 *ptr = buffer->buffer; | |
| 298 return buffer->length; | |
| 299 } | |
| 300 | |
| 301 static Py_ssize_t | |
| 302 _bufferproxy_getsegcount (PyBufferProxy *buffer, Py_ssize_t *lenp) | |
| 303 { | |
| 304 if (!buffer->parent) | |
| 305 { | |
| 306 *lenp = 0; | |
| 307 return 0; | |
| 308 } | |
| 309 | |
| 310 if (lenp) | |
| 311 *lenp = buffer->length; | |
| 312 return 1; | |
| 313 } | |
| 314 | |
| 315 static PyObject* | |
| 316 PyBufferProxy_New (PyObject *parent, void *buffer, Py_ssize_t length, | |
| 317 PyObject *lock) | |
| 318 { | |
| 319 PyBufferProxy *buf; | |
| 320 | |
| 321 buf = (PyBufferProxy *) _bufferproxy_new (&PyBufferProxy_Type, NULL, NULL); | |
| 322 | |
| 323 if (!buf) | |
| 324 return NULL; | |
| 325 buf->buffer = buffer; | |
| 326 buf->length = length; | |
| 327 buf->lock = lock; | |
| 328 buf->parent = parent; | |
| 329 return (PyObject *) buf; | |
| 330 } | |
| 331 | |
| 332 PYGAME_EXPORT | |
| 333 void initbufferproxy (void) | |
| 334 { | |
| 335 PyObject *module; | |
| 336 PyObject *dict; | |
| 337 PyObject *apiobj; | |
| 338 static void* c_api[PYGAMEAPI_BUFFERPROXY_NUMSLOTS]; | |
| 339 | |
| 340 if (PyType_Ready (&PyBufferProxy_Type) < 0) | |
| 341 return; | |
| 342 | |
| 343 /* create the module */ | |
|
870
31fa129efd0f
Fixed Mask documentation. Added write() method to BufferProxy.
marcus
parents:
867
diff
changeset
|
344 module = Py_InitModule3 ("bufferproxy", NULL, |
| 876 | 345 "A generic proxy module that can spend arbitrary objects a buffer " \ |
| 346 "interface"); | |
| 860 | 347 PyBufferProxy_Type.tp_getattro = PyObject_GenericGetAttr; |
| 348 Py_INCREF (&PyBufferProxy_Type); | |
| 349 PyModule_AddObject (module, "BufferProxy", (PyObject *)&PyBufferProxy_Type); | |
| 350 dict = PyModule_GetDict (module); | |
| 351 | |
| 352 c_api[0] = &PyBufferProxy_Type; | |
| 353 c_api[1] = PyBufferProxy_New; | |
| 354 apiobj = PyCObject_FromVoidPtr (c_api, NULL); | |
| 355 PyDict_SetItemString (dict, PYGAMEAPI_LOCAL_ENTRY, apiobj); | |
| 356 Py_DECREF (apiobj); | |
| 357 } |
