[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