
/* Buffer object implementation */

#include "Python.h"


typedef struct {
    PyObject_HEAD
    PyObject *b_base;
    void *b_ptr;
    Py_ssize_t b_size;
    Py_ssize_t b_offset;
    int b_readonly;
    long b_hash;
} PyBufferObject;


enum buffer_t {
    READ_BUFFER,
    WRITE_BUFFER,
    CHAR_BUFFER,
    ANY_BUFFER
};

static int
get_buf(PyBufferObject *self, void **ptr, Py_ssize_t *size,
    enum buffer_t buffer_type)
{
    if (self->b_base == NULL) {
        assert (ptr != NULL);
        *ptr = self->b_ptr;
        *size = self->b_size;
    }
    else {
        Py_ssize_t count, offset;
        readbufferproc proc = 0;
        PyBufferProcs *bp = self->b_base->ob_type->tp_as_buffer;
        if ((*bp->bf_getsegcount)(self->b_base, NULL) != 1) {
            PyErr_SetString(PyExc_TypeError,
                "single-segment buffer object expected");
            return 0;
        }
        if ((buffer_type == READ_BUFFER) ||
            ((buffer_type == ANY_BUFFER) && self->b_readonly))
            proc = bp->bf_getreadbuffer;
        else if ((buffer_type == WRITE_BUFFER) ||
            (buffer_type == ANY_BUFFER))
            proc = (readbufferproc)bp->bf_getwritebuffer;
        else if (buffer_type == CHAR_BUFFER) {
            if (!PyType_HasFeature(self->ob_type,
                        Py_TPFLAGS_HAVE_GETCHARBUFFER)) {
            PyErr_SetString(PyExc_TypeError,
                "Py_TPFLAGS_HAVE_GETCHARBUFFER needed");
            return 0;
            }
            proc = (readbufferproc)bp->bf_getcharbuffer;
        }
        if (!proc) {
            char *buffer_type_name;
            switch (buffer_type) {
            case READ_BUFFER:
                buffer_type_name = "read";
                break;
            case WRITE_BUFFER:
                buffer_type_name = "write";
                break;
            case CHAR_BUFFER:
                buffer_type_name = "char";
                break;
            default:
                buffer_type_name = "no";
                break;
            }
            PyErr_Format(PyExc_TypeError,
                "%s buffer type not available",
                buffer_type_name);
            return 0;
        }
        if ((count = (*proc)(self->b_base, 0, ptr)) < 0)
            return 0;
        /* apply constraints to the start/end */
        if (self->b_offset > count)
            offset = count;
        else
            offset = self->b_offset;
        *(char **)ptr = *(char **)ptr + offset;
        if (self->b_size == Py_END_OF_BUFFER)
            *size = count;
        else
            *size = self->b_size;
        if (offset + *size > count)
            *size = count - offset;
    }
    return 1;
}


static PyObject *
buffer_from_memory(PyObject *base, Py_ssize_t size, Py_ssize_t offset, void *ptr,
                   int readonly)
{
    PyBufferObject * b;

    if (size < 0 && size != Py_END_OF_BUFFER) {
        PyErr_SetString(PyExc_ValueError,
                        "size must be zero or positive");
        return NULL;
    }
    if (offset < 0) {
        PyErr_SetString(PyExc_ValueError,
                        "offset must be zero or positive");
        return NULL;
    }

    b = PyObject_NEW(PyBufferObject, &PyBuffer_Type);
    if ( b == NULL )
        return NULL;

    Py_XINCREF(base);
    b->b_base = base;
    b->b_ptr = ptr;
    b->b_size = size;
    b->b_offset = offset;
    b->b_readonly = readonly;
    b->b_hash = -1;

    return (PyObject *) b;
}

static PyObject *
buffer_from_object(PyObject *base, Py_ssize_t size, Py_ssize_t offset, int readonly)
{
    if (offset < 0) {
        PyErr_SetString(PyExc_ValueError,
                        "offset must be zero or positive");
        return NULL;
    }
    if ( PyBuffer_Check(base) && (((PyBufferObject *)base)->b_base) ) {
        /* another buffer, refer to the base object */
        PyBufferObject *b = (PyBufferObject *)base;
        if (b->b_size != Py_END_OF_BUFFER) {
            Py_ssize_t base_size = b->b_size - offset;
            if (base_size < 0)
                base_size = 0;
            if (size == Py_END_OF_BUFFER || size > base_size)
                size = base_size;
        }
        offset += b->b_offset;
        base = b->b_base;
    }
    return buffer_from_memory(base, size, offset, NULL, readonly);
}


PyObject *
PyBuffer_FromObject(PyObject *base, Py_ssize_t offset, Py_ssize_t size)
{
    PyBufferProcs *pb = base->ob_type->tp_as_buffer;

    if ( pb == NULL ||
         pb->bf_getreadbuffer == NULL ||
         pb->bf_getsegcount == NULL )
    {
        PyErr_SetString(PyExc_TypeError, "buffer object expected");
        return NULL;
    }

    return buffer_from_object(base, size, offset, 1);
}

PyObject *
PyBuffer_FromReadWriteObject(PyObject *base, Py_ssize_t offset, Py_ssize_t size)
{
    PyBufferProcs *pb = base->ob_type->tp_as_buffer;

    if ( pb == NULL ||
         pb->bf_getwritebuffer == NULL ||
         pb->bf_getsegcount == NULL )
    {
        PyErr_SetString(PyExc_TypeError, "buffer object expected");
        return NULL;
    }

    return buffer_from_object(base, size,  offset, 0);
}

PyObject *
PyBuffer_FromMemory(void *ptr, Py_ssize_t size)
{
    return buffer_from_memory(NULL, size, 0, ptr, 1);
}

PyObject *
PyBuffer_FromReadWriteMemory(void *ptr, Py_ssize_t size)
{
    return buffer_from_memory(NULL, size, 0, ptr, 0);
}

PyObject *
PyBuffer_New(Py_ssize_t size)
{
    PyObject *o;
    PyBufferObject * b;

    if (size < 0) {
        PyErr_SetString(PyExc_ValueError,
                        "size must be zero or positive");
        return NULL;
    }
    if (sizeof(*b) > PY_SSIZE_T_MAX - size) {
        /* unlikely */
        return PyErr_NoMemory();
    }
    /* Inline PyObject_New */
    o = (PyObject *)PyObject_MALLOC(sizeof(*b) + size);
    if ( o == NULL )
        return PyErr_NoMemory();
    b = (PyBufferObject *) PyObject_INIT(o, &PyBuffer_Type);

    b->b_base = NULL;
    b->b_ptr = (void *)(b + 1);
    b->b_size = size;
    b->b_offset = 0;
    b->b_readonly = 0;
    b->b_hash = -1;

    return o;
}

/* Methods */

static PyObject *
buffer_new(PyTypeObject *type, PyObject *args, PyObject *kw)
{
    PyObject *ob;
    Py_ssize_t offset = 0;
    Py_ssize_t size = Py_END_OF_BUFFER;

    if (PyErr_WarnPy3k("buffer() not supported in 3.x", 1) < 0)
        return NULL;

    if (!_PyArg_NoKeywords("buffer()", kw))
        return NULL;

    if (!PyArg_ParseTuple(args, "O|nn:buffer", &ob, &offset, &size))
        return NULL;
    return PyBuffer_FromObject(ob, offset, size);
}

PyDoc_STRVAR(buffer_doc,
"buffer(object [, offset[, size]])\n\
\n\
Create a new buffer object which references the given object.\n\
The buffer will reference a slice of the target object from the\n\
start of the object (or at the specified offset). The slice will\n\
extend to the end of the target object (or with the specified size).");


static void
buffer_dealloc(PyBufferObject *self)
{
    Py_XDECREF(self->b_base);
    PyObject_DEL(self);
}

static int
buffer_compare(PyBufferObject *self, PyBufferObject *other)
{
    void *p1, *p2;
    Py_ssize_t len_self, len_other, min_len;
    int cmp;

    if (!get_buf(self, &p1, &len_self, ANY_BUFFER))
        return -1;
    if (!get_buf(other, &p2, &len_other, ANY_BUFFER))
        return -1;
    min_len = (len_self < len_other) ? len_self : len_other;
    if (min_len > 0) {
        cmp = memcmp(p1, p2, min_len);
        if (cmp != 0)
            return cmp < 0 ? -1 : 1;
    }
    return (len_self < len_other) ? -1 : (len_self > len_other) ? 1 : 0;
}

static PyObject *
buffer_repr(PyBufferObject *self)
{
    const char *status = self->b_readonly ? "read-only" : "read-write";

    if ( self->b_base == NULL )
        return PyString_FromFormat("<%s buffer ptr %p, size %zd at %p>",
                                   status,
                                   self->b_ptr,
                                   self->b_size,
                                   self);
    else
        return PyString_FromFormat(
            "<%s buffer for %p, size %zd, offset %zd at %p>",
            status,
            self->b_base,
            self->b_size,
            self->b_offset,
            self);
}

static long
buffer_hash(PyBufferObject *self)
{
    void *ptr;
    Py_ssize_t size;
    register Py_ssize_t len;
    register unsigned char *p;
    register long x;

    if ( self->b_hash != -1 )
        return self->b_hash;

    /* XXX potential bugs here, a readonly buffer does not imply that the
     * underlying memory is immutable.  b_readonly is a necessary but not
     * sufficient condition for a buffer to be hashable.  Perhaps it would
     * be better to only allow hashing if the underlying object is known to
     * be immutable (e.g. PyString_Check() is true).  Another idea would
     * be to call tp_hash on the underlying object and see if it raises
     * an error. */
    if ( !self->b_readonly )
    {
        PyErr_SetString(PyExc_TypeError,
                        "writable buffers are not hashable");
        return -1;
    }

    if (!get_buf(self, &ptr, &size, ANY_BUFFER))
        return -1;
    p = (unsigned char *) ptr;
    len = size;
    x = *p << 7;
    while (--len >= 0)
        x = (1000003*x) ^ *p++;
    x ^= size;
    if (x == -1)
        x = -2;
    self->b_hash = x;
    return x;
}

static PyObject *
buffer_str(PyBufferObject *self)
{
    void *ptr;
    Py_ssize_t size;
    if (!get_buf(self, &ptr, &size, ANY_BUFFER))
        return NULL;
    return PyString_FromStringAndSize((const char *)ptr, size);
}

/* Sequence methods */

static Py_ssize_t
buffer_length(PyBufferObject *self)
{
    void *ptr;
    Py_ssize_t size;
    if (!get_buf(self, &ptr, &size, ANY_BUFFER))
        return -1;
    return size;
}

static PyObject *
buffer_concat(PyBufferObject *self, PyObject *other)
{
    PyBufferProcs *pb = other->ob_type->tp_as_buffer;
    void *ptr1, *ptr2;
    char *p;
    PyObject *ob;
    Py_ssize_t size, count;

    if ( pb == NULL ||
         pb->bf_getreadbuffer == NULL ||
         pb->bf_getsegcount == NULL )
    {
        PyErr_BadArgument();
        return NULL;
    }
    if ( (*pb->bf_getsegcount)(other, NULL) != 1 )
    {
        /* ### use a different exception type/message? */
        PyErr_SetString(PyExc_TypeError,
                        "single-segment buffer object expected");
        return NULL;
    }

    if (!get_buf(self, &ptr1, &size, ANY_BUFFER))
        return NULL;

    /* optimize special case */
    if ( size == 0 )
    {
        Py_INCREF(other);
        return other;
    }

    if ( (count = (*pb->bf_getreadbuffer)(other, 0, &ptr2)) < 0 )
        return NULL;

    assert(count <= PY_SIZE_MAX - size);

    ob = PyString_FromStringAndSize(NULL, size + count);
    if ( ob == NULL )
        return NULL;
    p = PyString_AS_STRING(ob);
    memcpy(p, ptr1, size);
    memcpy(p + size, ptr2, count);

    /* there is an extra byte in the string object, so this is safe */
    p[size + count] = '\0';

    return ob;
}

static PyObject *
buffer_repeat(PyBufferObject *self, Py_ssize_t count)
{
    PyObject *ob;
    register char *p;
    void *ptr;
    Py_ssize_t size;

    if ( count < 0 )
        count = 0;
    if (!get_buf(self, &ptr, &size, ANY_BUFFER))
        return NULL;
    if (count > PY_SSIZE_T_MAX / size) {
        PyErr_SetString(PyExc_MemoryError, "result too large");
        return NULL;
    }
    ob = PyString_FromStringAndSize(NULL, size * count);
    if ( ob == NULL )
        return NULL;

    p = PyString_AS_STRING(ob);
    while ( count-- )
    {
        memcpy(p, ptr, size);
        p += size;
    }

    /* there is an extra byte in the string object, so this is safe */
    *p = '\0';

    return ob;
}

static PyObject *
buffer_item(PyBufferObject *self, Py_ssize_t idx)
{
    void *ptr;
    Py_ssize_t size;
    if (!get_buf(self, &ptr, &size, ANY_BUFFER))
        return NULL;
    if ( idx < 0 || idx >= size ) {
        PyErr_SetString(PyExc_IndexError, "buffer index out of range");
        return NULL;
    }
    return PyString_FromStringAndSize((char *)ptr + idx, 1);
}

static PyObject *
buffer_slice(PyBufferObject *self, Py_ssize_t left, Py_ssize_t right)
{
    void *ptr;
    Py_ssize_t size;
    if (!get_buf(self, &ptr, &size, ANY_BUFFER))
        return NULL;
    if ( left < 0 )
        left = 0;
    if ( right < 0 )
        right = 0;
    if ( right > size )
        right = size;
    if ( right < left )
        right = left;
    return PyString_FromStringAndSize((char *)ptr + left,
                                      right - left);
}

static PyObject *
buffer_subscript(PyBufferObject *self, PyObject *item)
{
    void *p;
    Py_ssize_t size;

    if (!get_buf(self, &p, &size, ANY_BUFFER))
        return NULL;
    if (PyIndex_Check(item)) {
        Py_ssize_t i = PyNumber_AsSsize_t(item, PyExc_IndexError);
        if (i == -1 && PyErr_Occurred())
            return NULL;
        if (i < 0)
            i += size;
        return buffer_item(self, i);
    }
    else if (PySlice_Check(item)) {
        Py_ssize_t start, stop, step, slicelength, cur, i;

        if (PySlice_GetIndicesEx((PySliceObject*)item, size,
                         &start, &stop, &step, &slicelength) < 0) {
            return NULL;
        }

        if (slicelength <= 0)
            return PyString_FromStringAndSize("", 0);
        else if (step == 1)
            return PyString_FromStringAndSize((char *)p + start,
                                              stop - start);
        else {
            PyObject *result;
            char *source_buf = (char *)p;
            char *result_buf = (char *)PyMem_Malloc(slicelength);

            if (result_buf == NULL)
                return PyErr_NoMemory();

            for (cur = start, i = 0; i < slicelength;
                 cur += step, i++) {
                result_buf[i] = source_buf[cur];
            }

            result = PyString_FromStringAndSize(result_buf,
                                                slicelength);
            PyMem_Free(result_buf);
            return result;
        }
    }
    else {
        PyErr_SetString(PyExc_TypeError,
                        "sequence index must be integer");
        return NULL;
    }
}

static int
buffer_ass_item(PyBufferObject *self, Py_ssize_t idx, PyObject *other)
{
    PyBufferProcs *pb;
    void *ptr1, *ptr2;
    Py_ssize_t size;
    Py_ssize_t count;

    if ( self->b_readonly ) {
        PyErr_SetString(PyExc_TypeError,
                        "buffer is read-only");
        return -1;
    }

    if (!get_buf(self, &ptr1, &size, ANY_BUFFER))
        return -1;

    if (idx < 0 || idx >= size) {
        PyErr_SetString(PyExc_IndexError,
                        "buffer assignment index out of range");
        return -1;
    }

    pb = other ? other->ob_type->tp_as_buffer : NULL;
    if ( pb == NULL ||
         pb->bf_getreadbuffer == NULL ||
         pb->bf_getsegcount == NULL )
    {
        PyErr_BadArgument();
        return -1;
    }
    if ( (*pb->bf_getsegcount)(other, NULL) != 1 )
    {
        /* ### use a different exception type/message? */
        PyErr_SetString(PyExc_TypeError,
                        "single-segment buffer object expected");
        return -1;
    }

    if ( (count = (*pb->bf_getreadbuffer)(other, 0, &ptr2)) < 0 )
        return -1;
    if ( count != 1 ) {
        PyErr_SetString(PyExc_TypeError,
                        "right operand must be a single byte");
        return -1;
    }

    ((char *)ptr1)[idx] = *(char *)ptr2;
    return 0;
}

static int
buffer_ass_slice(PyBufferObject *self, Py_ssize_t left, Py_ssize_t right, PyObject *other)
{
    PyBufferProcs *pb;
    void *ptr1, *ptr2;
    Py_ssize_t size;
    Py_ssize_t slice_len;
    Py_ssize_t count;

    if ( self->b_readonly ) {
        PyErr_SetString(PyExc_TypeError,
                        "buffer is read-only");
        return -1;
    }

    pb = other ? other->ob_type->tp_as_buffer : NULL;
    if ( pb == NULL ||
         pb->bf_getreadbuffer == NULL ||
         pb->bf_getsegcount == NULL )
    {
        PyErr_BadArgument();
        return -1;
    }
    if ( (*pb->bf_getsegcount)(other, NULL) != 1 )
    {
        /* ### use a different exception type/message? */
        PyErr_SetString(PyExc_TypeError,
                        "single-segment buffer object expected");
        return -1;
    }
    if (!get_buf(self, &ptr1, &size, ANY_BUFFER))
        return -1;
    if ( (count = (*pb->bf_getreadbuffer)(other, 0, &ptr2)) < 0 )
        return -1;

    if ( left < 0 )
        left = 0;
    else if ( left > size )
        left = size;
    if ( right < left )
        right = left;
    else if ( right > size )
        right = size;
    slice_len = right - left;

    if ( count != slice_len ) {
        PyErr_SetString(
            PyExc_TypeError,
            "right operand length must match slice length");
        return -1;
    }

    if ( slice_len )
        memcpy((char *)ptr1 + left, ptr2, slice_len);

    return 0;
}

static int
buffer_ass_subscript(PyBufferObject *self, PyObject *item, PyObject *value)
{
    PyBufferProcs *pb;
    void *ptr1, *ptr2;
    Py_ssize_t selfsize;
    Py_ssize_t othersize;

    if ( self->b_readonly ) {
        PyErr_SetString(PyExc_TypeError,
                        "buffer is read-only");
        return -1;
    }

    pb = value ? value->ob_type->tp_as_buffer : NULL;
    if ( pb == NULL ||
         pb->bf_getreadbuffer == NULL ||
         pb->bf_getsegcount == NULL )
    {
        PyErr_BadArgument();
        return -1;
    }
    if ( (*pb->bf_getsegcount)(value, NULL) != 1 )
    {
        /* ### use a different exception type/message? */
        PyErr_SetString(PyExc_TypeError,
                        "single-segment buffer object expected");
        return -1;
    }
    if (!get_buf(self, &ptr1, &selfsize, ANY_BUFFER))
        return -1;
    if (PyIndex_Check(item)) {
        Py_ssize_t i = PyNumber_AsSsize_t(item, PyExc_IndexError);
        if (i == -1 && PyErr_Occurred())
            return -1;
        if (i < 0)
            i += selfsize;
        return buffer_ass_item(self, i, value);
    }
    else if (PySlice_Check(item)) {
        Py_ssize_t start, stop, step, slicelength;

        if (PySlice_GetIndicesEx((PySliceObject *)item, selfsize,
                        &start, &stop, &step, &slicelength) < 0)
            return -1;

        if ((othersize = (*pb->bf_getreadbuffer)(value, 0, &ptr2)) < 0)
            return -1;

        if (othersize != slicelength) {
            PyErr_SetString(
                PyExc_TypeError,
                "right operand length must match slice length");
            return -1;
        }

        if (slicelength == 0)
            return 0;
        else if (step == 1) {
            memcpy((char *)ptr1 + start, ptr2, slicelength);
            return 0;
        }
        else {
            Py_ssize_t cur, i;

            for (cur = start, i = 0; i < slicelength;
                 cur += step, i++) {
                ((char *)ptr1)[cur] = ((char *)ptr2)[i];
            }

            return 0;
        }
    } else {
        PyErr_SetString(PyExc_TypeError,
                        "buffer indices must be integers");
        return -1;
    }
}

/* Buffer methods */

static Py_ssize_t
buffer_getreadbuf(PyBufferObject *self, Py_ssize_t idx, void **pp)
{
    Py_ssize_t size;
    if ( idx != 0 ) {
        PyErr_SetString(PyExc_SystemError,
                        "accessing non-existent buffer segment");
        return -1;
    }
    if (!get_buf(self, pp, &size, READ_BUFFER))
        return -1;
    return size;
}

static Py_ssize_t
buffer_getwritebuf(PyBufferObject *self, Py_ssize_t idx, void **pp)
{
    Py_ssize_t size;

    if ( self->b_readonly )
    {
        PyErr_SetString(PyExc_TypeError, "buffer is read-only");
        return -1;
    }

    if ( idx != 0 ) {
        PyErr_SetString(PyExc_SystemError,
                        "accessing non-existent buffer segment");
        return -1;
    }
    if (!get_buf(self, pp, &size, WRITE_BUFFER))
        return -1;
    return size;
}

static Py_ssize_t
buffer_getsegcount(PyBufferObject *self, Py_ssize_t *lenp)
{
    void *ptr;
    Py_ssize_t size;
    if (!get_buf(self, &ptr, &size, ANY_BUFFER))
        return -1;
    if (lenp)
        *lenp = size;
    return 1;
}

static Py_ssize_t
buffer_getcharbuf(PyBufferObject *self, Py_ssize_t idx, const char **pp)
{
    void *ptr;
    Py_ssize_t size;
    if ( idx != 0 ) {
        PyErr_SetString(PyExc_SystemError,
                        "accessing non-existent buffer segment");
        return -1;
    }
    if (!get_buf(self, &ptr, &size, CHAR_BUFFER))
        return -1;
    *pp = (const char *)ptr;
    return size;
}

static PySequenceMethods buffer_as_sequence = {
    (lenfunc)buffer_length, /*sq_length*/
    (binaryfunc)buffer_concat, /*sq_concat*/
    (ssizeargfunc)buffer_repeat, /*sq_repeat*/
    (ssizeargfunc)buffer_item, /*sq_item*/
    (ssizessizeargfunc)buffer_slice, /*sq_slice*/
    (ssizeobjargproc)buffer_ass_item, /*sq_ass_item*/
    (ssizessizeobjargproc)buffer_ass_slice, /*sq_ass_slice*/
};

static PyMappingMethods buffer_as_mapping = {
    (lenfunc)buffer_length,
    (binaryfunc)buffer_subscript,
    (objobjargproc)buffer_ass_subscript,
};

static PyBufferProcs buffer_as_buffer = {
    (readbufferproc)buffer_getreadbuf,
    (writebufferproc)buffer_getwritebuf,
    (segcountproc)buffer_getsegcount,
    (charbufferproc)buffer_getcharbuf,
};

PyTypeObject PyBuffer_Type = {
    PyVarObject_HEAD_INIT(&PyType_Type, 0)
    "buffer",
    sizeof(PyBufferObject),
    0,
    (destructor)buffer_dealloc,                 /* tp_dealloc */
    0,                                          /* tp_print */
    0,                                          /* tp_getattr */
    0,                                          /* tp_setattr */
    (cmpfunc)buffer_compare,                    /* tp_compare */
    (reprfunc)buffer_repr,                      /* tp_repr */
    0,                                          /* tp_as_number */
    &buffer_as_sequence,                        /* tp_as_sequence */
    &buffer_as_mapping,                         /* tp_as_mapping */
    (hashfunc)buffer_hash,                      /* tp_hash */
    0,                                          /* tp_call */
    (reprfunc)buffer_str,                       /* tp_str */
    PyObject_GenericGetAttr,                    /* tp_getattro */
    0,                                          /* tp_setattro */
    &buffer_as_buffer,                          /* tp_as_buffer */
    Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GETCHARBUFFER, /* tp_flags */
    buffer_doc,                                 /* tp_doc */
    0,                                          /* tp_traverse */
    0,                                          /* tp_clear */
    0,                                          /* tp_richcompare */
    0,                                          /* tp_weaklistoffset */
    0,                                          /* tp_iter */
    0,                                          /* tp_iternext */
    0,                                          /* 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 */
    buffer_new,                                 /* tp_new */
};
