[Python-checkins] r46215 - in python/branches/blais-bytebuf: Lib/test/test_hotbuf.py Modules/_hotbuf.c

martin.blais python-checkins at python.org
Thu May 25 17:34:29 CEST 2006


Author: martin.blais
Date: Thu May 25 17:34:28 2006
New Revision: 46215

Modified:
   python/branches/blais-bytebuf/Lib/test/test_hotbuf.py
   python/branches/blais-bytebuf/Modules/_hotbuf.c
Log:
Added getstr/putstr methods to the hot blue lagoon bufferola

Modified: python/branches/blais-bytebuf/Lib/test/test_hotbuf.py
==============================================================================
--- python/branches/blais-bytebuf/Lib/test/test_hotbuf.py	(original)
+++ python/branches/blais-bytebuf/Lib/test/test_hotbuf.py	Thu May 25 17:34:28 2006
@@ -12,6 +12,8 @@
 
 
 CAPACITY = 1024
+MSG = 'Martin Blais was here scribble scribble.'
+
 
 class HotbufTestCase(unittest.TestCase):
 
@@ -102,6 +104,23 @@
         # Test underflow.
         self.assertRaises(IndexError, b.putbyte, 42)
 
+    def test_str( self ):
+        b = hotbuf(256)
+
+        # Write into the buffer
+        b.putstr(MSG)
+        b.flip()
+
+        # Read back and assert message
+        self.assertEquals(b.getstr(len(MSG)), MSG)
+        
+        # Test overflow.
+        b.flip()
+        self.assertRaises(IndexError, b.putstr, ' ' * 1000)
+        
+        # Test underflow.
+        self.assertRaises(IndexError, b.getstr, 1000)
+
     def test_conversion( self ):
         b = hotbuf(CAPACITY)
 

Modified: python/branches/blais-bytebuf/Modules/_hotbuf.c
==============================================================================
--- python/branches/blais-bytebuf/Modules/_hotbuf.c	(original)
+++ python/branches/blais-bytebuf/Modules/_hotbuf.c	Thu May 25 17:34:28 2006
@@ -172,7 +172,7 @@
 
     min_len = ((len_self < len_other) ? len_self : len_other);
     if (min_len > 0) {
-        cmp = memcmp(self->b_ptr + self->b_position, 
+        cmp = memcmp(self->b_ptr + self->b_position,
                      other->b_ptr + other->b_position, min_len);
         if (cmp != 0)
             return cmp;
@@ -204,7 +204,7 @@
         return Py_None;
     }
     return PyString_FromStringAndSize(
-        (const char *)(self->b_ptr + self->b_position), 
+        (const char *)(self->b_ptr + self->b_position),
         self->b_limit - self->b_position);
 }
 
@@ -247,6 +247,44 @@
 }
 
 
+PyDoc_STRVAR(advance__doc__,
+"B.advance(int)\n\
+\n\
+Advance this buffer's position by the given number of bytes. \n\
+If the mark is defined and larger than\n\
+the new position then it is discarded.  If the given position is\n\
+larger than the limit an exception is raised.");
+
+static PyObject*
+hotbuf_advance(PyHotbufObject *self, PyObject* arg)
+{
+    int nbytes;
+    int newposition;
+
+    nbytes = PyInt_AsLong(arg);
+    if (nbytes == -1 && PyErr_Occurred())
+        return NULL;
+
+    newposition = self->b_position + nbytes;
+    if ( newposition > self->b_capacity ) {
+        PyErr_SetString(PyExc_IndexError,
+                        "position must be smaller than capacity");
+        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;
+
+    return Py_None;
+}
+
+
+
+
 PyDoc_STRVAR(setlimit__doc__,
 "B.setlimit(int)\n\
 \n\
@@ -471,7 +509,7 @@
  * Object Methods (get/put methods)
  */
 
-PyDoc_STRVAR(relative_get__doc__,
+PyDoc_STRVAR(get__doc__,
 "B.get*() -> data\n\
 \n\
 Relative get methods. \n\
@@ -479,7 +517,7 @@
 and then increments the position.\n\
 An IndexError is raised if the position is at the end of the buffer.");
 
-PyDoc_STRVAR(relative_put__doc__,
+PyDoc_STRVAR(put__doc__,
 "B.put*(data)\n\
 \n\
 Relative put methods. \n\
@@ -530,53 +568,72 @@
 }
 
 
+PyDoc_STRVAR(getstr__doc__,
+"B.getstr(nbytes) -> data\n\
+\n\
+Extract a string of 'nbytes' bytes from the buffer and advance the \n\
+position accordingly.\n\
+An IndexError is raised if the position is at the end of the buffer.");
+
 static PyObject*
-hotbuf_getstring(PyHotbufObject *self, PyObject* arg)
+hotbuf_getstr(PyHotbufObject *self, PyObject* arg)
 {
     int len;
-    CHECK_LIMIT_ERROR(sizeof(byte));
+    PyObject* s;
 
+    /* Extract the given number of bytes */
     len = PyInt_AsLong(arg);
     if (len == -1 && PyErr_Occurred())
         return NULL;
+    
+    CHECK_LIMIT_ERROR(len);
 
-    if (len > (self->b_limit - self->b_position)) {
-        PyErr_SetString(PyExc_IndexError,
-                        "cannot read beyond limit");
-        return NULL;
-    }
+    /* Extract the string object from the buffer */
+    s = PyString_FromStringAndSize(
+        (const char *)(self->b_ptr + self->b_position), len);
 
-FIXME continue here
+    /* Advance to the new position */
+    self->b_position += len;
 
-    return PyString_FromStringAndSize(
-        (const char *)(self->b_ptr + self->b_position), len);
-}
+    /* Discard the mark if it is beyond the new position */
+    if ( self->b_mark > self->b_position )
+        self->b_mark = -1;
 
-FIXME continue here
+    /* Return the new string */
+    return s;
+}
 
-FIXME we need to find a way to automatically advance position without doing it in Python
 
+PyDoc_STRVAR(putstr__doc__,
+"B.putstr(str)\n\
+\n\
+Write a string of 'nbytes' bytes from the buffer and advance the \n\
+position accordingly.\n\
+An IndexError is raised if the position is at the end of the buffer.");
 
 static PyObject*
-hotbuf_putstring(PyHotbufObject *self, PyObject* arg)
+hotbuf_putstr(PyHotbufObject *self, PyObject* arg)
 {
-    int byte_i;
-    unsigned char byte;
-
-    byte_i = PyInt_AsLong(arg);
-    if (byte_i == -1 && PyErr_Occurred())
-        return NULL;
+    char *instring;
+    int len;
 
-    if ( byte_i > 255 ) {
+    /* Check and extract input string */
+    if ( arg == NULL || !PyString_Check(arg) ) {
         PyErr_SetString(PyExc_ValueError,
-                        "overflow for byte");
+                        "incorrect input type, require string");
         return NULL;
     }
-    byte = (unsigned char)byte_i;
+    instring = PyString_AsString(arg);
+    len = strlen(instring);
+
+    CHECK_LIMIT_ERROR(len);
+
+    /* Copy the string into the buffer */
+    memcpy(self->b_ptr, instring, len);
+
+    /* Advance the position */
+    self->b_position += len;
 
-    CHECK_LIMIT_ERROR(sizeof(byte));
-    *(unsigned char*)(self->b_ptr + self->b_position) = byte;
-    self->b_position += sizeof(byte);
     return Py_None;
 }
 
@@ -678,6 +735,7 @@
 hotbuf_methods[] = {
     {"clear", (PyCFunction)hotbuf_clear, METH_NOARGS, clear__doc__},
     {"setposition", (PyCFunction)hotbuf_setposition, METH_O, setposition__doc__},
+    {"advance", (PyCFunction)hotbuf_advance, METH_O, advance__doc__},
     {"setlimit", (PyCFunction)hotbuf_setlimit, METH_O, setlimit__doc__},
     {"setmark", (PyCFunction)hotbuf_setmark, METH_NOARGS, setmark__doc__},
     {"reset", (PyCFunction)hotbuf_reset, METH_NOARGS, reset__doc__},
@@ -685,8 +743,10 @@
     {"rewind", (PyCFunction)hotbuf_rewind, METH_NOARGS, rewind__doc__},
     {"remaining", (PyCFunction)hotbuf_remaining, METH_NOARGS, remaining__doc__},
     {"compact", (PyCFunction)hotbuf_compact, METH_NOARGS, compact__doc__},
-    {"getbyte", (PyCFunction)hotbuf_getbyte, METH_NOARGS, relative_get__doc__},
-    {"putbyte", (PyCFunction)hotbuf_putbyte, METH_O, relative_put__doc__},
+    {"getbyte", (PyCFunction)hotbuf_getbyte, METH_NOARGS, get__doc__},
+    {"putbyte", (PyCFunction)hotbuf_putbyte, METH_O, put__doc__},
+    {"getstr", (PyCFunction)hotbuf_getstr, METH_O, getstr__doc__},
+    {"putstr", (PyCFunction)hotbuf_putstr, METH_O, putstr__doc__},
     {NULL, NULL} /* sentinel */
 };
 


More information about the Python-checkins mailing list