[Python-checkins] r46192 - in python/branches/blais-bytebuf: Lib/hotbuf.py Lib/test/test_hotbuf.py Modules/_hotbuf.c Modules/hotbufmodule.c setup.py
martin.blais
python-checkins at python.org
Wed May 24 19:40:55 CEST 2006
Author: martin.blais
Date: Wed May 24 19:40:55 2006
New Revision: 46192
Added:
python/branches/blais-bytebuf/Lib/hotbuf.py (contents, props changed)
python/branches/blais-bytebuf/Modules/_hotbuf.c
- copied, changed from r46190, python/branches/blais-bytebuf/Modules/hotbufmodule.c
Removed:
python/branches/blais-bytebuf/Modules/hotbufmodule.c
Modified:
python/branches/blais-bytebuf/Lib/test/test_hotbuf.py
python/branches/blais-bytebuf/setup.py
Log:
Moved hotbufmodule to _hotbuf, created hotbuf.py wrapper and enabled as a base class.
Added: python/branches/blais-bytebuf/Lib/hotbuf.py
==============================================================================
--- (empty file)
+++ python/branches/blais-bytebuf/Lib/hotbuf.py Wed May 24 19:40:55 2006
@@ -0,0 +1,12 @@
+#!/usr/bin/env python
+
+"""
+A buffer class for fast I/O.
+"""
+
+from _hotbuf import _hotbuf
+
+class hotbuf(_hotbuf):
+ pass
+
+
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 Wed May 24 19:40:55 2006
@@ -97,18 +97,12 @@
b.flip()
for x in xrange(256):
nx = b.getbyte()
- print nx
assert nx == x
# Test underflow.
self.assertRaises(IndexError, b.putbyte, 42)
-
-
-
-
-
def test_main():
test_support.run_unittest(HotbufTestCase)
Copied: python/branches/blais-bytebuf/Modules/_hotbuf.c (from r46190, python/branches/blais-bytebuf/Modules/hotbufmodule.c)
==============================================================================
--- python/branches/blais-bytebuf/Modules/hotbufmodule.c (original)
+++ python/branches/blais-bytebuf/Modules/_hotbuf.c Wed May 24 19:40:55 2006
@@ -651,23 +651,23 @@
static PyMethodDef
hotbuf_methods[] = {
- {"clear", (PyCFunction)hotbuf_clear, METH_NOARGS, clear__doc__},
- {"capacity", (PyCFunction)hotbuf_capacity, METH_NOARGS, capacity__doc__},
- {"position", (PyCFunction)hotbuf_position, METH_NOARGS, position__doc__},
- {"setposition", (PyCFunction)hotbuf_setposition, METH_O, setposition__doc__},
- {"limit", (PyCFunction)hotbuf_limit, METH_NOARGS, limit__doc__},
- {"setlimit", (PyCFunction)hotbuf_setlimit, METH_O, setlimit__doc__},
- {"mark", (PyCFunction)hotbuf_mark, METH_NOARGS, mark__doc__},
- {"setmark", (PyCFunction)hotbuf_setmark, METH_NOARGS, setmark__doc__},
- {"reset", (PyCFunction)hotbuf_reset, METH_NOARGS, reset__doc__},
- {"flip", (PyCFunction)hotbuf_flip, METH_NOARGS, flip__doc__},
- {"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__},
- {NULL, NULL} /* sentinel */
+ {"clear", (PyCFunction)hotbuf_clear, METH_NOARGS, clear__doc__},
+ {"capacity", (PyCFunction)hotbuf_capacity, METH_NOARGS, capacity__doc__},
+ {"position", (PyCFunction)hotbuf_position, METH_NOARGS, position__doc__},
+ {"setposition", (PyCFunction)hotbuf_setposition, METH_O, setposition__doc__},
+ {"limit", (PyCFunction)hotbuf_limit, METH_NOARGS, limit__doc__},
+ {"setlimit", (PyCFunction)hotbuf_setlimit, METH_O, setlimit__doc__},
+ {"mark", (PyCFunction)hotbuf_mark, METH_NOARGS, mark__doc__},
+ {"setmark", (PyCFunction)hotbuf_setmark, METH_NOARGS, setmark__doc__},
+ {"reset", (PyCFunction)hotbuf_reset, METH_NOARGS, reset__doc__},
+ {"flip", (PyCFunction)hotbuf_flip, METH_NOARGS, flip__doc__},
+ {"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__},
+ {NULL, NULL} /* sentinel */
};
static PySequenceMethods hotbuf_as_sequence = {
@@ -687,46 +687,46 @@
(charbufferproc)hotbuf_getcharbuf,
};
-PyTypeObject PyHotbuf_Type = {
+static PyTypeObject PyHotbuf_Type = {
PyObject_HEAD_INIT(&PyType_Type)
0,
- "hotbuf",
+ "_hotbuf._hotbuf",
sizeof(PyHotbufObject),
0,
- (destructor)hotbuf_dealloc, /* tp_dealloc */
- 0, /* tp_print */
- 0, /* tp_getattr */
- 0, /* tp_setattr */
- (cmpfunc)hotbuf_compare, /* tp_compare */
- (reprfunc)hotbuf_repr, /* tp_repr */
- 0, /* tp_as_number */
- &hotbuf_as_sequence, /* tp_as_sequence */
- 0, /* tp_as_mapping */
- 0, /* tp_hash */
- 0, /* tp_call */
- (reprfunc)hotbuf_str, /* tp_str */
- PyObject_GenericGetAttr, /* tp_getattro */
- 0, /* tp_setattro */
- &hotbuf_as_buffer, /* tp_as_buffer */
- Py_TPFLAGS_DEFAULT, /* tp_flags */
- hotbuf_doc, /* tp_doc */
- 0, /* tp_traverse */
- 0, /* tp_clear */
- 0, /* tp_richcompare */
- 0, /* tp_weaklistoffset */
- 0, /* tp_iter */
- 0, /* tp_iternext */
- hotbuf_methods, /* tp_methods */
- 0, /* tp_members */
- 0, /* tp_getset */
- 0, /* tp_base */
- 0, /* tp_dict */
- 0, /* tp_descr_get */
- 0, /* tp_descr_set */
- 0, /* tp_dictoffset */
- 0, /* tp_init */
- 0, /* tp_alloc */
- hotbuf_new, /* tp_new */
+ (destructor)hotbuf_dealloc, /* tp_dealloc */
+ 0, /* tp_print */
+ 0, /* tp_getattr */
+ 0, /* tp_setattr */
+ (cmpfunc)hotbuf_compare, /* tp_compare */
+ (reprfunc)hotbuf_repr, /* tp_repr */
+ 0, /* tp_as_number */
+ &hotbuf_as_sequence, /* tp_as_sequence */
+ 0, /* tp_as_mapping */
+ 0, /* tp_hash */
+ 0, /* tp_call */
+ (reprfunc)hotbuf_str, /* tp_str */
+ PyObject_GenericGetAttr, /* tp_getattro */
+ 0, /* tp_setattro */
+ &hotbuf_as_buffer, /* tp_as_buffer */
+ Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, /* tp_flags */
+ hotbuf_doc, /* tp_doc */
+ 0, /* tp_traverse */
+ 0, /* tp_clear */
+ 0, /* tp_richcompare */
+ 0, /* tp_weaklistoffset */
+ 0, /* tp_iter */
+ 0, /* tp_iternext */
+ hotbuf_methods, /* tp_methods */
+ 0, /* tp_members */
+ 0, /* tp_getset */
+ 0, /* tp_base */
+ 0, /* tp_dict */
+ 0, /* tp_descr_get */
+ 0, /* tp_descr_set */
+ 0, /* tp_dictoffset */
+ 0, /* tp_init */
+ 0, /* tp_alloc */
+ hotbuf_new, /* tp_new */
};
@@ -762,38 +762,18 @@
PyMODINIT_FUNC
-inithotbuf(void)
+init_hotbuf(void)
{
PyObject *m;
PyHotbuf_Type.ob_type = &PyType_Type;
- m = Py_InitModule3("hotbuf", a_methods, module_doc);
+ m = Py_InitModule3("_hotbuf", a_methods, module_doc);
if (m == NULL)
return;
Py_INCREF((PyObject *)&PyHotbuf_Type);
PyModule_AddObject(m, "HotbufType", (PyObject *)&PyHotbuf_Type);
Py_INCREF((PyObject *)&PyHotbuf_Type);
- PyModule_AddObject(m, "hotbuf", (PyObject *)&PyHotbuf_Type);
- /* No need to check the error here, the caller will do that */
+ PyModule_AddObject(m, "_hotbuf", (PyObject *)&PyHotbuf_Type);
}
-
-
-/*
- TODO
- ----
- - Add hash function
- - Add support for sequence methods.
- - Perhaps implement returning the buffer object itself from some of
- the methods in order to allow chaining of operations on a single line.
- - Implement a resize function
- - Maybe remove the API methods declared at the top.
- - Add support for big vs. little endian
-
- Pending Issues
- --------------
- - Should we support weakrefs?
-
-*/
-
Deleted: /python/branches/blais-bytebuf/Modules/hotbufmodule.c
==============================================================================
--- /python/branches/blais-bytebuf/Modules/hotbufmodule.c Wed May 24 19:40:55 2006
+++ (empty file)
@@ -1,799 +0,0 @@
-/* ===========================================================================
- * Hotbuf object: an equivalent to Java's NIO ByteBuffer class for fast
- * network I/O.
- */
-
-#include "Python.h"
-#include <string.h> /* for memmove */
-
-PyAPI_DATA(PyTypeObject) PyHotbuf_Type;
-
-#define PyHotbuf_Check(op) ((op)->ob_type == &PyHotbuf_Type)
-
-#define Py_END_OF_HOTBUF (-1)
-
-PyAPI_FUNC(PyObject *) PyHotbuf_New(Py_ssize_t size);
-
-
-
-/* ===========================================================================
- * Byte Buffer object implementation
- */
-
-
-/*
- * hotbuf object structure declaration.
-
- From the Java Buffer docs:
-
- A buffer is a linear, finite sequence of elements of a specific
- primitive type. Aside from its content, the essential properties of a
- buffer are its capacity, limit, and position:
-
- A buffer's capacity is the number of elements it contains. The
- capacity of a buffer is never negative and never changes.
-
- A buffer's limit is the index of the first element that should not
- be read or written. A buffer's limit is never negative and is never
- greater than its capacity.
-
- A buffer's position is the index of the next element to be read or
- written. A buffer's position is never negative and is never greater
- than its limit.
-
- The following invariant holds for the mark, position, limit, and
- capacity values:
-
- 0 <= mark <= position <= limit <= capacity (length)
-
- */
-typedef struct {
- PyObject_HEAD
-
- /* Base pointer location */
- void* b_ptr;
-
- /* Total size in bytes of the area that we can access. The allocated
- memory must be at least as large as this size. */
- Py_ssize_t b_capacity;
-
- /*
- * The "active window" is defined by the interval [position, limit[.
- */
-
- /* The current position in the buffer. */
- int b_position;
-
- /* The limit position in the buffer. */
- int b_limit;
-
- /* The mark. From the Java Buffer docs:
-
- A buffer's mark is the index to which its position will be reset when
- the reset method is invoked. The mark is not always defined, but when
- it is defined it is never negative and is never greater than the
- position. If the mark is defined then it is discarded when the
- position or the limit is adjusted to a value smaller than the mark. If
- the mark is not defined then invoking the reset method causes an
- InvalidMarkException to be thrown.
-
- The mark is set to -1 to indicate that the mark is unset.
- */
- int b_mark;
-
-} PyHotbufObject;
-
-
-/*
- * Given a hotbuf object, return the buffer memory (in 'ptr' and 'size') and
- * true if there was no error.
- */
-
-/*
- * Create a new hotbuf where we allocate the memory ourselves.
- */
-PyObject *
-PyHotbuf_New(Py_ssize_t capacity)
-{
- PyObject *o;
- PyHotbufObject * b;
-
- if (capacity < 0) {
- PyErr_SetString(PyExc_ValueError,
- "capacity must be zero or positive");
- return NULL;
- }
-
- /* FIXME: check for overflow in multiply */
- o = (PyObject *)PyObject_MALLOC(sizeof(*b) + capacity);
- if ( o == NULL )
- return PyErr_NoMemory();
- b = (PyHotbufObject *) PyObject_INIT(o, &PyHotbuf_Type);
-
- /* We setup the memory buffer to be right after the object itself. */
- b->b_ptr = (void *)(b + 1);
- b->b_position = 0;
- b->b_mark = -1;
- b->b_limit = capacity;
- b->b_capacity = capacity;
-
- return o;
-}
-
-/* Methods */
-
-/*
- * Constructor.
- */
-static PyObject *
-hotbuf_new(PyTypeObject *type, PyObject *args, PyObject *kw)
-{
- Py_ssize_t size = -1;
-
- if (!_PyArg_NoKeywords("hotbuf()", kw))
- return NULL;
-
- if (!PyArg_ParseTuple(args, "n:hotbuf", &size))
- return NULL;
-
- if ( size <= 0 ) {
- PyErr_SetString(PyExc_ValueError,
- "size must be greater than zero");
- return NULL;
- }
-
- return PyHotbuf_New(size);
-}
-
-/*
- * Destructor.
- */
-static void
-hotbuf_dealloc(PyHotbufObject *self)
-{
- /* Note: by virtue of the memory buffer being allocated with the PyObject
- itself, this frees the buffer as well. */
- PyObject_DEL(self);
-}
-
-/*
- * Comparison. We compare the active windows, not the entire allocated buffer
- * memory.
- */
-static int
-hotbuf_compare(PyHotbufObject *self, PyHotbufObject *other)
-{
- Py_ssize_t min_len;
- int cmp;
-
- min_len = ((self->b_capacity < other->b_capacity) ?
- self->b_capacity : other->b_capacity);
- if (min_len > 0) {
- cmp = memcmp(self->b_ptr, other->b_ptr, min_len);
- if (cmp != 0)
- return cmp;
- }
- return ((self->b_capacity < other->b_capacity) ?
- -1 : (self->b_capacity > other->b_capacity) ? 1 : 0);
-}
-
-
-/*
- * Conversion to 'repr' string.
- */
-static PyObject *
-hotbuf_repr(PyHotbufObject *self)
-{
- return PyString_FromFormat("<hotbuf ptr %p, size %zd at %p>",
- self->b_ptr,
- self->b_capacity,
- self);
-}
-
-/*
- * Conversion to string. We convert only the active window.
- */
-static PyObject *
-hotbuf_str(PyHotbufObject *self)
-{
- return PyString_FromStringAndSize((const char *)self->b_ptr, self->b_capacity);
-}
-
-
-
-/* ===========================================================================
- * Object Methods (basic interface)
- */
-
-PyDoc_STRVAR(capacity__doc__,
-"B.capacity() -> int\n\
-\n\
-Returns this buffer's capacity. \n\
-(the entire size of the allocated buffer.)");
-
-static PyObject*
-hotbuf_capacity(PyHotbufObject *self)
-{
- return PyInt_FromLong(self->b_capacity);
-}
-
-
-PyDoc_STRVAR(position__doc__,
-"B.position() -> int\n\
-\n\
-Returns this buffer's position.");
-
-static PyObject*
-hotbuf_position(PyHotbufObject *self)
-{
- return PyInt_FromLong(self->b_position);
-}
-
-
-PyDoc_STRVAR(setposition__doc__,
-"B.setposition(int)\n\
-\n\
-Sets this buffer's position. 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_setposition(PyHotbufObject *self, PyObject* arg)
-{
- int newposition;
-
- newposition = PyInt_AsLong(arg);
- if (newposition == -1 && PyErr_Occurred())
- return NULL;
-
- 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(limit__doc__,
-"B.limit() -> int\n\
-\n\
-Returns this buffer's limit.");
-
-static PyObject*
-hotbuf_limit(PyHotbufObject *self)
-{
- return PyInt_FromLong(self->b_limit);
-}
-
-
-PyDoc_STRVAR(setlimit__doc__,
-"B.setlimit(int)\n\
-\n\
-Sets this buffer's limit. If the position is larger than the new limit\n\
-then it is set to the new limit. If the mark is defined and larger\n\
-than the new limit then it is discarded.");
-
-static PyObject*
-hotbuf_setlimit(PyHotbufObject *self, PyObject* arg)
-{
- int newlimit;
-
- newlimit = PyInt_AsLong(arg);
- if (newlimit == -1 && PyErr_Occurred())
- return NULL;
-
- if ( newlimit > self->b_capacity ) {
- PyErr_SetString(PyExc_IndexError,
- "limit must be smaller than capacity");
- return NULL;
- }
-
- /* Set the new limit. */
- self->b_limit = newlimit;
-
- /* If the position is larger than the new limit, set it to the new
- limit. */
- if ( self->b_position > self->b_limit )
- self->b_position = newlimit;
-
- /* Discard the mark if it is beyond the new limit */
- if ( self->b_mark > self->b_position )
- self->b_mark = -1;
-
- return Py_None;
-}
-
-
-PyDoc_STRVAR(mark__doc__,
-"B.mark() -> int\n\
-\n\
-Returns this buffer's mark. \n\
-Return -1 if the mark is not set.");
-
-static PyObject*
-hotbuf_mark(PyHotbufObject *self)
-{
- return PyInt_FromLong(self->b_mark);
-}
-
-
-PyDoc_STRVAR(setmark__doc__,
-"B.setmark()\n\
-\n\
-Sets this buffer's mark at its position.");
-
-static PyObject*
-hotbuf_setmark(PyHotbufObject *self)
-{
- self->b_mark = self->b_position;
- return Py_None;
-}
-
-
-PyDoc_STRVAR(reset__doc__,
-"B.reset() -> int\n\
-\n\
-Resets this buffer's position to the previously-marked position.\n\
-Invoking this method neither changes nor discards the mark's value.\n\
-An IndexError is raised if the mark has not been set.\n\
-This method returns the new position's value.");
-
-static PyObject*
-hotbuf_reset(PyHotbufObject *self)
-{
- if ( self->b_mark == -1 ) {
- PyErr_SetString(PyExc_IndexError,
- "mark has not been yet set");
- return NULL;
- }
-
- self->b_position = self->b_mark;
- return PyInt_FromLong(self->b_position);
-}
-
-
-PyDoc_STRVAR(clear__doc__,
-"B.clear()\n\
-\n\
-Clears this buffer. The position is set to zero, the limit is set to\n\
-the capacity, and the mark is discarded.\n\
-\n\
-Invoke this method before using a sequence of channel-read or put\n\
-operations to fill this buffer. For example:\n\
-\n\
- buf.clear() # Prepare buffer for reading\n\
- in.read(buf) # Read data\n\
-\n\
-(This method does not actually erase the data in the buffer, but it is\n\
-named as if it did because it will most often be used in situations in\n\
-which that might as well be the case.)");
-
-static PyObject*
-hotbuf_clear(PyHotbufObject *self)
-{
- self->b_position = 0;
- self->b_limit = self->b_capacity;
- self->b_mark = -1;
- return Py_None;
-}
-
-
-PyDoc_STRVAR(flip__doc__,
-"B.flip()\n\
-\n\
-Flips this buffer. The limit is set to the current position and then\n\
-the position is set to zero. If the mark is defined then it is\n\
-discarded.\n\
-\n\
-After a sequence of channel-read or put operations, invoke this method\n\
-to prepare for a sequence of channel-write or relative get\n\
-operations. For example:\n\
-\n\
- buf.put(magic) # Prepend header\n\
- in.read(buf) # Read data into rest of buffer\n\
- buf.flip() # Flip buffer\n\
- out.write(buf) # Write header + data to channel\n\
-\n\
-This method is often used in conjunction with the compact method when\n\
-transferring data from one place to another.");
-
-static PyObject*
-hotbuf_flip(PyHotbufObject *self)
-{
- self->b_limit = self->b_position;
- self->b_position = 0;
- self->b_mark = -1;
- return Py_None;
-}
-
-
-PyDoc_STRVAR(rewind__doc__,
-"B.rewind()\n\
-\n\
-Rewinds this buffer. The position is set to zero and the mark is\n\
-discarded.\n\
-\n\
-Invoke this method before a sequence of channel-write or get\n\
-operations, assuming that the limit has already been set\n\
-appropriately. For example:\n\
-\n\
- out.write(buf) # Write remaining data\n\
- buf.rewind() # Rewind buffer\n\
- buf.get(array) # Copy data into array\n\
-");
-
-static PyObject*
-hotbuf_rewind(PyHotbufObject *self)
-{
- self->b_position = 0;
- self->b_mark = -1;
- return Py_None;
-}
-
-
-PyDoc_STRVAR(remaining__doc__,
-"B.remaining() -> int\n\
-\n\
-Returns the number of bytes between the current position and the limit.");
-
-static PyObject*
-hotbuf_remaining(PyHotbufObject *self)
-{
- return PyInt_FromLong(self->b_limit - self->b_position);
-}
-
-
-PyDoc_STRVAR(compact__doc__,
-"B.compact()\n\
-\n\
-public abstract ByteBuffer compact()\n\
-\n\
-Compacts this buffer (optional operation).\n\
-\n\
-The bytes between the buffer's current position and its limit, if\n\
-any, are copied to the beginning of the buffer. That is, the byte\n\
-at index p = position() is copied to index zero, the byte at index\n\
-p + 1 is copied to index one, and so forth until the byte at index\n\
-limit() - 1 is copied to index n = limit() - 1 - p. The buffer's\n\
-position is then set to n+1 and its limit is set to its\n\
-capacity. The mark, if defined, is discarded.\n\
-\n\
-The buffer's position is set to the number of bytes copied, rather\n\
-than to zero, so that an invocation of this method can be followed\n\
-immediately by an invocation of another relative put method.\n\
-\n\
-Invoke this method after writing data from a buffer in case the\n\
-write was incomplete. The following loop, for example, copies\n\
-bytes from one channel to another via the buffer buf:\n\
-\n\
- buf.clear() # Prepare buffer for use\n\
- while 1:\n\
- if in.read(buf) < 0 and buf.remaining() == 0:\n\
- break # No more bytes to transfer\n\
- buf.flip()\n\
- out.write(buf)\n\
- buf.compact() # In case of partial write\n\
-\n\
-");
-
-static PyObject*
-hotbuf_compact(PyHotbufObject *self)
-{
- int length;
-
- /* Calculate the number of bytes in the active window */
- length = self->b_limit - self->b_position;
-
- /* Move the memory from the active window to the beginning of the
- allocated buffer (only if we need to). */
- if ( length > 0 && self->b_position > 0 ) {
- memmove(self->b_ptr, self->b_ptr + self->b_position, length);
- }
-
- self->b_position = length;
- self->b_limit = self->b_capacity;
- self->b_mark = -1;
-
- return Py_None;
-}
-
-
-
-/* ===========================================================================
- * Object Methods (get/put methods)
- */
-
-PyDoc_STRVAR(relative_get__doc__,
-"B.get*() -> data\n\
-\n\
-Relative get methods. \n\
-Reads something at this buffer's current position, \n\
-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__,
-"B.put*(data)\n\
-\n\
-Relative put methods. \n\
-Writes the given byte into this buffer at the current position,\n\
-and then increments the position.\n\
-An IndexError is raised if the position is at the end of the buffer.");
-
-
-/* Check if we're going to be trying to year beyond the buffer active
- window limit, and if so, sets and error and return */
-#define CHECK_LIMIT_ERROR(sz) \
- if ( (self->b_position + sz) > self->b_limit ) { \
- PyErr_SetString(PyExc_IndexError, \
- "attempted read beyond buffer limit"); \
- return NULL; \
- }
-
-
-static PyObject*
-hotbuf_getbyte(PyHotbufObject *self)
-{
- unsigned char byte;
- CHECK_LIMIT_ERROR(sizeof(byte));
-
- byte = *(unsigned char*)(self->b_ptr + self->b_position);
- self->b_position += sizeof(byte);
- return PyInt_FromLong(byte);
-}
-
-static PyObject*
-hotbuf_putbyte(PyHotbufObject *self, PyObject* arg)
-{
- int byte_i;
- unsigned char byte;
-
- byte_i = PyInt_AsLong(arg);
- if ( byte_i > 255 ) {
- PyErr_SetString(PyExc_ValueError,
- "overflow for byte");
- return NULL;
- }
- byte = (unsigned char)byte_i;
-
- CHECK_LIMIT_ERROR(sizeof(byte));
- *(unsigned char*)(self->b_ptr + self->b_position) = byte;
- self->b_position += sizeof(byte);
- return Py_None;
-}
-
-
-
-
-/* ===========================================================================
- * Buffer protocol methods
- */
-
-/*
- * Returns the buffer for reading or writing.
- */
-static Py_ssize_t
-hotbuf_getwritebuf(PyHotbufObject *self, Py_ssize_t idx, void **pp)
-{
- if ( idx != 0 ) {
- PyErr_SetString(PyExc_SystemError,
- "accessing non-existent hotbuf segment");
- return -1;
- }
-
- *pp = self->b_ptr;
- return self->b_capacity;
-}
-
-static Py_ssize_t
-hotbuf_getsegcount(PyHotbufObject *self, Py_ssize_t *lenp)
-{
- if (lenp)
- *lenp = self->b_capacity;
- return 1;
-}
-
-static Py_ssize_t
-hotbuf_getcharbuf(PyHotbufObject *self, Py_ssize_t idx, const char **pp)
-{
- if ( idx != 0 ) {
- PyErr_SetString(PyExc_SystemError,
- "accessing non-existent hotbuf segment");
- return -1;
- }
-
- *pp = (const char *)self->b_ptr;
- return self->b_capacity;
-}
-
-
-
-/* ===========================================================================
- * Sequence methods
- */
-
-static Py_ssize_t
-hotbuf_length(PyHotbufObject *self)
-{
- assert(self->b_position <= self->b_limit);
- return self->b_limit - self->b_position;
-}
-
-
-
-/* ===========================================================================
- * Object interfaces declaration
- */
-
-
-PyDoc_STRVAR(hotbuf_doc,
-"hotbuf(capacity) -> hotbuf\n\
-\n\
-Return a new hotbuf with a buffer of fixed size 'capacity'.\n\
-\n\
-hotbuf is a C encapsulation of a fixed-size buffer of bytes in memory.\n\
-One can read and write objects of different primitive types directly\n\
-into it, without having to convert from/to strings. Also, this is\n\
-meant for the network I/O functions (recv, recvfrom, send, sendto) to\n\
-read/write directly into without having to create temporary strings.\n\
-\n\
-Note that hotbuf is a direct Python equivalent of Java's NIO\n\
-ByteBuffer class.");
-
-
-static PyMethodDef
-hotbuf_methods[] = {
- {"clear", (PyCFunction)hotbuf_clear, METH_NOARGS, clear__doc__},
- {"capacity", (PyCFunction)hotbuf_capacity, METH_NOARGS, capacity__doc__},
- {"position", (PyCFunction)hotbuf_position, METH_NOARGS, position__doc__},
- {"setposition", (PyCFunction)hotbuf_setposition, METH_O, setposition__doc__},
- {"limit", (PyCFunction)hotbuf_limit, METH_NOARGS, limit__doc__},
- {"setlimit", (PyCFunction)hotbuf_setlimit, METH_O, setlimit__doc__},
- {"mark", (PyCFunction)hotbuf_mark, METH_NOARGS, mark__doc__},
- {"setmark", (PyCFunction)hotbuf_setmark, METH_NOARGS, setmark__doc__},
- {"reset", (PyCFunction)hotbuf_reset, METH_NOARGS, reset__doc__},
- {"flip", (PyCFunction)hotbuf_flip, METH_NOARGS, flip__doc__},
- {"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__},
- {NULL, NULL} /* sentinel */
-};
-
-static PySequenceMethods hotbuf_as_sequence = {
- (lenfunc)hotbuf_length, /*sq_length*/
- 0 /* (binaryfunc)hotbuf_concat */, /*sq_concat*/
- 0 /* (ssizeargfunc)hotbuf_repeat */, /*sq_repeat*/
- 0 /* (ssizeargfunc)hotbuf_item */, /*sq_item*/
- 0 /*(ssizessizeargfunc)hotbuf_slice*/, /*sq_slice*/
- 0 /*(ssizeobjargproc)hotbuf_ass_item*/, /*sq_ass_item*/
- 0 /*(ssizessizeobjargproc)hotbuf_ass_slice*/, /*sq_ass_slice*/
-};
-
-static PyBufferProcs hotbuf_as_buffer = {
- (readbufferproc)hotbuf_getwritebuf,
- (writebufferproc)hotbuf_getwritebuf,
- (segcountproc)hotbuf_getsegcount,
- (charbufferproc)hotbuf_getcharbuf,
-};
-
-PyTypeObject PyHotbuf_Type = {
- PyObject_HEAD_INIT(&PyType_Type)
- 0,
- "hotbuf",
- sizeof(PyHotbufObject),
- 0,
- (destructor)hotbuf_dealloc, /* tp_dealloc */
- 0, /* tp_print */
- 0, /* tp_getattr */
- 0, /* tp_setattr */
- (cmpfunc)hotbuf_compare, /* tp_compare */
- (reprfunc)hotbuf_repr, /* tp_repr */
- 0, /* tp_as_number */
- &hotbuf_as_sequence, /* tp_as_sequence */
- 0, /* tp_as_mapping */
- 0, /* tp_hash */
- 0, /* tp_call */
- (reprfunc)hotbuf_str, /* tp_str */
- PyObject_GenericGetAttr, /* tp_getattro */
- 0, /* tp_setattro */
- &hotbuf_as_buffer, /* tp_as_buffer */
- Py_TPFLAGS_DEFAULT, /* tp_flags */
- hotbuf_doc, /* tp_doc */
- 0, /* tp_traverse */
- 0, /* tp_clear */
- 0, /* tp_richcompare */
- 0, /* tp_weaklistoffset */
- 0, /* tp_iter */
- 0, /* tp_iternext */
- hotbuf_methods, /* tp_methods */
- 0, /* tp_members */
- 0, /* tp_getset */
- 0, /* tp_base */
- 0, /* tp_dict */
- 0, /* tp_descr_get */
- 0, /* tp_descr_set */
- 0, /* tp_dictoffset */
- 0, /* tp_init */
- 0, /* tp_alloc */
- hotbuf_new, /* tp_new */
-};
-
-
-
-/* ===========================================================================
- * Install Module
- */
-
-PyDoc_STRVAR(module_doc,
- "This module defines an object type which can represent a fixed size\n\
-buffer of bytes in momery, from which you can directly read and into\n\
-which you can directly write objects in various other types. This is\n\
-used to avoid buffer copies in network I/O as much as possible. For\n\
-example, socket recv() can directly fill a byte buffer's memory and\n\
-send() can read the data to be sent from one as well.\n\
-\n\
-In addition, a byte buffer has two pointers within it, that delimit\n\
-an active slice, the current \"position\" and the \"limit\". The\n\
-active region of a byte buffer is located within these boundaries.\n\
-\n\
-This class is heaviliy inspired from Java's NIO Hotbuffer class.\n\
-\n\
-The constructor is:\n\
-\n\
-hotbuf(nbytes) -- create a new hotbuf\n\
-");
-
-
-/* No functions in array module. */
-static PyMethodDef a_methods[] = {
- {NULL, NULL, 0, NULL} /* Sentinel */
-};
-
-
-PyMODINIT_FUNC
-inithotbuf(void)
-{
- PyObject *m;
-
- PyHotbuf_Type.ob_type = &PyType_Type;
- m = Py_InitModule3("hotbuf", a_methods, module_doc);
- if (m == NULL)
- return;
-
- Py_INCREF((PyObject *)&PyHotbuf_Type);
- PyModule_AddObject(m, "HotbufType", (PyObject *)&PyHotbuf_Type);
- Py_INCREF((PyObject *)&PyHotbuf_Type);
- PyModule_AddObject(m, "hotbuf", (PyObject *)&PyHotbuf_Type);
- /* No need to check the error here, the caller will do that */
-}
-
-
-
-/*
- TODO
- ----
- - Add hash function
- - Add support for sequence methods.
- - Perhaps implement returning the buffer object itself from some of
- the methods in order to allow chaining of operations on a single line.
- - Implement a resize function
- - Maybe remove the API methods declared at the top.
- - Add support for big vs. little endian
-
- Pending Issues
- --------------
- - Should we support weakrefs?
-
-*/
-
Modified: python/branches/blais-bytebuf/setup.py
==============================================================================
--- python/branches/blais-bytebuf/setup.py (original)
+++ python/branches/blais-bytebuf/setup.py Wed May 24 19:40:55 2006
@@ -336,7 +336,7 @@
exts.append( Extension('array', ['arraymodule.c']) )
# array objects
- exts.append( Extension('hotbuf', ['hotbufmodule.c']) )
+ exts.append( Extension('_hotbuf', ['_hotbuf.c']) )
# complex math library functions
exts.append( Extension('cmath', ['cmathmodule.c'],
More information about the Python-checkins
mailing list