[Python-checkins] r46351 - in sandbox/trunk/hotbuffer: Modules/_hotbuf.c hotbuf.py test_hotbuf.py
bob.ippolito
python-checkins at python.org
Fri May 26 18:15:51 CEST 2006
Author: bob.ippolito
Date: Fri May 26 18:15:50 2006
New Revision: 46351
Modified:
sandbox/trunk/hotbuffer/Modules/_hotbuf.c
sandbox/trunk/hotbuffer/hotbuf.py
sandbox/trunk/hotbuffer/test_hotbuf.py
Log:
rewrite hotbuf.unpack in C
Modified: sandbox/trunk/hotbuffer/Modules/_hotbuf.c
==============================================================================
--- sandbox/trunk/hotbuffer/Modules/_hotbuf.c (original)
+++ sandbox/trunk/hotbuffer/Modules/_hotbuf.c Fri May 26 18:15:50 2006
@@ -7,7 +7,7 @@
#include "structmember.h"
#include <string.h> /* for memmove */
-PyAPI_DATA(PyTypeObject) PyHotbuf_Type;
+static PyTypeObject PyHotbuf_Type;
#define PyHotbuf_Check(op) PyObject_TypeCheck((op), &PyHotbuf_Type)
@@ -86,6 +86,28 @@
* true if there was no error.
*/
+/* Internal Methods */
+
+static int
+hotbuf_advance_internal(PyHotbufObject *self, Py_ssize_t nbytes)
+{
+ Py_ssize_t newposition = self->b_position + nbytes;
+ if (newposition > self->b_limit) {
+ PyErr_SetString(PyExc_IndexError,
+ "position must be smaller than limit");
+ return -1;
+ }
+
+ /* Set the new position */
+ self->b_position = newposition;
+
+ /* Discard the mark if it is beyond the new position */
+ if (self->b_mark > self->b_position)
+ self->b_mark = -1;
+
+ return 0;
+}
+
/* Methods */
@@ -254,26 +276,12 @@
static PyObject*
hotbuf_advance(PyHotbufObject *self, PyObject* arg)
{
- Py_ssize_t nbytes;
- Py_ssize_t newposition;
-
- nbytes = PyInt_AsLong(arg);
+ Py_ssize_t nbytes = PyInt_AsLong(arg);
if (nbytes == -1 && PyErr_Occurred())
return NULL;
- newposition = self->b_position + nbytes;
- if ( newposition > self->b_limit ) {
- PyErr_SetString(PyExc_IndexError,
- "position must be smaller than limit");
+ if (hotbuf_advance_internal(self, nbytes) < 0)
return NULL;
- }
-
- /* Set the new position */
- self->b_position = newposition;
-
- /* Discard the mark if it is beyond the new position */
- if ( self->b_mark > self->b_position )
- self->b_mark = -1;
Py_RETURN_NONE;
}
@@ -642,7 +650,62 @@
Py_RETURN_NONE;
}
+PyDoc_STRVAR(unpack__doc__,
+"B.unpack(structobj) -> v1, v2, ...\n\
+\n\
+Unpack the given structure directly from this buffer and advance\n\
+the position accordingly.");
+static PyObject*
+hotbuf_unpack(PyHotbufObject *self, PyObject* structobj)
+{
+ static PyObject *str_size = NULL;
+ static PyObject *str_unpack_from = NULL;
+ Py_ssize_t len = -1;
+ PyObject *size_obj;
+ PyObject *result;
+
+ if (str_size == NULL) {
+ str_size = PyString_InternFromString("size");
+ if (str_size == NULL)
+ return NULL;
+ }
+
+ if (str_unpack_from == NULL) {
+ str_unpack_from = PyString_InternFromString("unpack_from");
+ if (str_unpack_from == NULL)
+ return NULL;
+ }
+
+ if (structobj == NULL) {
+ PyErr_SetString(PyExc_TypeError,
+ "unpack requires a single struct argument");
+ return NULL;
+ }
+
+ size_obj = PyObject_GetAttr(structobj, str_size);
+ if (size_obj == NULL) {
+ PyErr_SetString(PyExc_TypeError,
+ "unpack requires a single struct argument");
+ }
+
+ len = PyInt_AsLong(size_obj);
+ if (len < 0)
+ PyErr_SetString(PyExc_TypeError,
+ "unpack requires a single struct argument");
+
+ result = PyObject_CallMethodObjArgs(structobj, str_unpack_from, self, NULL);
+
+ if (result == NULL)
+ return NULL;
+
+ if (hotbuf_advance_internal(self, len) < 0) {
+ Py_DECREF(result);
+ result = NULL;
+ }
+
+ return result;
+}
/* ===========================================================================
@@ -747,6 +810,7 @@
{"putbyte", (PyCFunction)hotbuf_putbyte, METH_O, put__doc__},
{"getstr", (PyCFunction)hotbuf_getstr, METH_VARARGS, getstr__doc__},
{"putstr", (PyCFunction)hotbuf_putstr, METH_O, putstr__doc__},
+ {"unpack", (PyCFunction)hotbuf_unpack, METH_O, unpack__doc__},
{NULL, NULL} /* sentinel */
};
@@ -768,7 +832,7 @@
};
static PyTypeObject PyHotbuf_Type = {
- PyObject_HEAD_INIT(&PyType_Type)
+ PyObject_HEAD_INIT(NULL)
0,
"_hotbuf._hotbuf",
sizeof(PyHotbufObject),
@@ -852,6 +916,9 @@
if (m == NULL)
return;
+ if (PyType_Ready(&PyHotbuf_Type) < 0)
+ return;
+
Py_INCREF((PyObject *)&PyHotbuf_Type);
PyModule_AddObject(m, "HotbufType", (PyObject *)&PyHotbuf_Type);
Py_INCREF((PyObject *)&PyHotbuf_Type);
Modified: sandbox/trunk/hotbuffer/hotbuf.py
==============================================================================
--- sandbox/trunk/hotbuffer/hotbuf.py (original)
+++ sandbox/trunk/hotbuffer/hotbuf.py Fri May 26 18:15:50 2006
@@ -17,13 +17,3 @@
"""
structobj.pack_to(self, 0, *values)
self.advance(structobj.size)
-
- def unpack( self, structobj ):
- """
- Pack using the given Struct object 'structobj', the remaining arguments.
- """
- values = structobj.unpack_from(self, 0)
- self.advance(structobj.size)
- return values
-
-
Modified: sandbox/trunk/hotbuffer/test_hotbuf.py
==============================================================================
--- sandbox/trunk/hotbuffer/test_hotbuf.py (original)
+++ sandbox/trunk/hotbuffer/test_hotbuf.py Fri May 26 18:15:50 2006
@@ -175,6 +175,19 @@
b.setlimit(len(s))
self.assertEquals(str(b), s)
+ def test_pack_method(self):
+ ARGS = 42, 16, '@', 3
+ # Pack to a string.
+ s = fmt.pack(*ARGS)
+
+ # Pack directly into the buffer and compare the strings.
+ b = hotbuf(CAPACITY)
+ b.setlimit(len(s))
+ b.pack(fmt, *ARGS)
+ self.assertEquals(b.position, fmt.size)
+ b.flip()
+ self.assertEquals(str(b), s)
+
def test_unpack( self ):
ARGS = 42, 16, '@', 3
b = hotbuf(CAPACITY)
@@ -187,6 +200,19 @@
b.flip()
self.assertEquals(fmt.unpack_from(b), ARGS)
+ def test_unpack_method( self ):
+ ARGS = 42, 16, '@', 3
+ b = hotbuf(CAPACITY)
+
+ # Pack normally and put that string in the buffer.
+ s = fmt.pack(*ARGS)
+ b.putstr(s)
+
+ # Unpack directly from the buffer and compare.
+ b.flip()
+ self.assertEquals(b.unpack(fmt), ARGS)
+ self.assertEquals(b.position, fmt.size)
+
def test_zerolen( self ):
b = hotbuf(CAPACITY)
b.setlimit(0)
More information about the Python-checkins
mailing list