Ignore:
Timestamp:
Mar 19, 2014, 11:11:30 AM (11 years ago)
Author:
dmik
Message:

python: Update vendor to 2.7.6.

File:
1 edited

Legend:

Unmodified
Added
Removed
  • python/vendor/current/Objects/bufferobject.c

    r2 r388  
    66
    77typedef struct {
    8         PyObject_HEAD
    9         PyObject *b_base;
    10         void *b_ptr;
    11         Py_ssize_t b_size;
    12         Py_ssize_t b_offset;
    13         int b_readonly;
    14         long b_hash;
     8    PyObject_HEAD
     9    PyObject *b_base;
     10    void *b_ptr;
     11    Py_ssize_t b_size;
     12    Py_ssize_t b_offset;
     13    int b_readonly;
     14    long b_hash;
    1515} PyBufferObject;
    1616
     
    2525static int
    2626get_buf(PyBufferObject *self, void **ptr, Py_ssize_t *size,
    27         enum buffer_t buffer_type)
    28 {
    29         if (self->b_base == NULL) {
    30                 assert (ptr != NULL);
    31                 *ptr = self->b_ptr;
    32                 *size = self->b_size;
    33         }
    34         else {
    35                 Py_ssize_t count, offset;
    36                 readbufferproc proc = 0;
    37                 PyBufferProcs *bp = self->b_base->ob_type->tp_as_buffer;
    38                 if ((*bp->bf_getsegcount)(self->b_base, NULL) != 1) {
    39                         PyErr_SetString(PyExc_TypeError,
    40                                 "single-segment buffer object expected");
    41                         return 0;
    42                 }
    43                 if ((buffer_type == READ_BUFFER) ||
    44                         ((buffer_type == ANY_BUFFER) && self->b_readonly))
    45                     proc = bp->bf_getreadbuffer;
    46                 else if ((buffer_type == WRITE_BUFFER) ||
    47                         (buffer_type == ANY_BUFFER))
    48                     proc = (readbufferproc)bp->bf_getwritebuffer;
    49                 else if (buffer_type == CHAR_BUFFER) {
    50                     if (!PyType_HasFeature(self->ob_type,
    51                                 Py_TPFLAGS_HAVE_GETCHARBUFFER)) {
    52                         PyErr_SetString(PyExc_TypeError,
    53                                 "Py_TPFLAGS_HAVE_GETCHARBUFFER needed");
    54                         return 0;
    55                     }
    56                     proc = (readbufferproc)bp->bf_getcharbuffer;
    57                 }
    58                 if (!proc) {
    59                     char *buffer_type_name;
    60                     switch (buffer_type) {
    61                         case READ_BUFFER:
    62                             buffer_type_name = "read";
    63                             break;
    64                         case WRITE_BUFFER:
    65                             buffer_type_name = "write";
    66                             break;
    67                         case CHAR_BUFFER:
    68                             buffer_type_name = "char";
    69                             break;
    70                         default:
    71                             buffer_type_name = "no";
    72                             break;
    73                     }
    74                     PyErr_Format(PyExc_TypeError,
    75                             "%s buffer type not available",
    76                             buffer_type_name);
    77                     return 0;
    78                 }
    79                 if ((count = (*proc)(self->b_base, 0, ptr)) < 0)
    80                         return 0;
    81                 /* apply constraints to the start/end */
    82                 if (self->b_offset > count)
    83                         offset = count;
    84                 else
    85                         offset = self->b_offset;
    86                 *(char **)ptr = *(char **)ptr + offset;
    87                 if (self->b_size == Py_END_OF_BUFFER)
    88                         *size = count;
    89                 else
    90                         *size = self->b_size;
    91                 if (offset + *size > count)
    92                         *size = count - offset;
    93         }
    94         return 1;
     27    enum buffer_t buffer_type)
     28{
     29    if (self->b_base == NULL) {
     30        assert (ptr != NULL);
     31        *ptr = self->b_ptr;
     32        *size = self->b_size;
     33    }
     34    else {
     35        Py_ssize_t count, offset;
     36        readbufferproc proc = 0;
     37        PyBufferProcs *bp = self->b_base->ob_type->tp_as_buffer;
     38        if ((*bp->bf_getsegcount)(self->b_base, NULL) != 1) {
     39            PyErr_SetString(PyExc_TypeError,
     40                "single-segment buffer object expected");
     41            return 0;
     42        }
     43        if ((buffer_type == READ_BUFFER) ||
     44            ((buffer_type == ANY_BUFFER) && self->b_readonly))
     45            proc = bp->bf_getreadbuffer;
     46        else if ((buffer_type == WRITE_BUFFER) ||
     47            (buffer_type == ANY_BUFFER))
     48            proc = (readbufferproc)bp->bf_getwritebuffer;
     49        else if (buffer_type == CHAR_BUFFER) {
     50            if (!PyType_HasFeature(self->ob_type,
     51                        Py_TPFLAGS_HAVE_GETCHARBUFFER)) {
     52            PyErr_SetString(PyExc_TypeError,
     53                "Py_TPFLAGS_HAVE_GETCHARBUFFER needed");
     54            return 0;
     55            }
     56            proc = (readbufferproc)bp->bf_getcharbuffer;
     57        }
     58        if (!proc) {
     59            char *buffer_type_name;
     60            switch (buffer_type) {
     61            case READ_BUFFER:
     62                buffer_type_name = "read";
     63                break;
     64            case WRITE_BUFFER:
     65                buffer_type_name = "write";
     66                break;
     67            case CHAR_BUFFER:
     68                buffer_type_name = "char";
     69                break;
     70            default:
     71                buffer_type_name = "no";
     72                break;
     73            }
     74            PyErr_Format(PyExc_TypeError,
     75                "%s buffer type not available",
     76                buffer_type_name);
     77            return 0;
     78        }
     79        if ((count = (*proc)(self->b_base, 0, ptr)) < 0)
     80            return 0;
     81        /* apply constraints to the start/end */
     82        if (self->b_offset > count)
     83            offset = count;
     84        else
     85            offset = self->b_offset;
     86        *(char **)ptr = *(char **)ptr + offset;
     87        if (self->b_size == Py_END_OF_BUFFER)
     88            *size = count;
     89        else
     90            *size = self->b_size;
     91        if (offset + *size > count)
     92            *size = count - offset;
     93    }
     94    return 1;
    9595}
    9696
     
    9898static PyObject *
    9999buffer_from_memory(PyObject *base, Py_ssize_t size, Py_ssize_t offset, void *ptr,
    100                    int readonly)
    101 {
    102         PyBufferObject * b;
    103 
    104         if (size < 0 && size != Py_END_OF_BUFFER) {
    105                 PyErr_SetString(PyExc_ValueError,
    106                                 "size must be zero or positive");
    107                 return NULL;
    108         }
    109         if (offset < 0) {
    110                 PyErr_SetString(PyExc_ValueError,
    111                                 "offset must be zero or positive");
    112                 return NULL;
    113         }
    114 
    115         b = PyObject_NEW(PyBufferObject, &PyBuffer_Type);
    116         if ( b == NULL )
    117                 return NULL;
    118 
    119         Py_XINCREF(base);
    120         b->b_base = base;
    121         b->b_ptr = ptr;
    122         b->b_size = size;
    123         b->b_offset = offset;
    124         b->b_readonly = readonly;
    125         b->b_hash = -1;
    126 
    127         return (PyObject *) b;
     100                   int readonly)
     101{
     102    PyBufferObject * b;
     103
     104    if (size < 0 && size != Py_END_OF_BUFFER) {
     105        PyErr_SetString(PyExc_ValueError,
     106                        "size must be zero or positive");
     107        return NULL;
     108    }
     109    if (offset < 0) {
     110        PyErr_SetString(PyExc_ValueError,
     111                        "offset must be zero or positive");
     112        return NULL;
     113    }
     114
     115    b = PyObject_NEW(PyBufferObject, &PyBuffer_Type);
     116    if ( b == NULL )
     117        return NULL;
     118
     119    Py_XINCREF(base);
     120    b->b_base = base;
     121    b->b_ptr = ptr;
     122    b->b_size = size;
     123    b->b_offset = offset;
     124    b->b_readonly = readonly;
     125    b->b_hash = -1;
     126
     127    return (PyObject *) b;
    128128}
    129129
     
    131131buffer_from_object(PyObject *base, Py_ssize_t size, Py_ssize_t offset, int readonly)
    132132{
    133         if (offset < 0) {
    134                 PyErr_SetString(PyExc_ValueError,
    135                                 "offset must be zero or positive");
    136                 return NULL;
    137         }
    138         if ( PyBuffer_Check(base) && (((PyBufferObject *)base)->b_base) ) {
    139                 /* another buffer, refer to the base object */
    140                 PyBufferObject *b = (PyBufferObject *)base;
    141                 if (b->b_size != Py_END_OF_BUFFER) {
    142                         Py_ssize_t base_size = b->b_size - offset;
    143                         if (base_size < 0)
    144                                 base_size = 0;
    145                         if (size == Py_END_OF_BUFFER || size > base_size)
    146                                 size = base_size;
    147                 }
    148                 offset += b->b_offset;
    149                 base = b->b_base;
    150         }
    151         return buffer_from_memory(base, size, offset, NULL, readonly);
     133    if (offset < 0) {
     134        PyErr_SetString(PyExc_ValueError,
     135                        "offset must be zero or positive");
     136        return NULL;
     137    }
     138    if ( PyBuffer_Check(base) && (((PyBufferObject *)base)->b_base) ) {
     139        /* another buffer, refer to the base object */
     140        PyBufferObject *b = (PyBufferObject *)base;
     141        if (b->b_size != Py_END_OF_BUFFER) {
     142            Py_ssize_t base_size = b->b_size - offset;
     143            if (base_size < 0)
     144                base_size = 0;
     145            if (size == Py_END_OF_BUFFER || size > base_size)
     146                size = base_size;
     147        }
     148        offset += b->b_offset;
     149        base = b->b_base;
     150    }
     151    return buffer_from_memory(base, size, offset, NULL, readonly);
    152152}
    153153
     
    156156PyBuffer_FromObject(PyObject *base, Py_ssize_t offset, Py_ssize_t size)
    157157{
    158         PyBufferProcs *pb = base->ob_type->tp_as_buffer;
    159 
    160         if ( pb == NULL ||
    161              pb->bf_getreadbuffer == NULL ||
    162              pb->bf_getsegcount == NULL )
    163         {
    164                 PyErr_SetString(PyExc_TypeError, "buffer object expected");
    165                 return NULL;
    166         }
    167 
    168         return buffer_from_object(base, size, offset, 1);
     158    PyBufferProcs *pb = base->ob_type->tp_as_buffer;
     159
     160    if ( pb == NULL ||
     161         pb->bf_getreadbuffer == NULL ||
     162         pb->bf_getsegcount == NULL )
     163    {
     164        PyErr_SetString(PyExc_TypeError, "buffer object expected");
     165        return NULL;
     166    }
     167
     168    return buffer_from_object(base, size, offset, 1);
    169169}
    170170
     
    172172PyBuffer_FromReadWriteObject(PyObject *base, Py_ssize_t offset, Py_ssize_t size)
    173173{
    174         PyBufferProcs *pb = base->ob_type->tp_as_buffer;
    175 
    176         if ( pb == NULL ||
    177              pb->bf_getwritebuffer == NULL ||
    178              pb->bf_getsegcount == NULL )
    179         {
    180                 PyErr_SetString(PyExc_TypeError, "buffer object expected");
    181                 return NULL;
    182         }
    183 
    184         return buffer_from_object(base, size,  offset, 0);
     174    PyBufferProcs *pb = base->ob_type->tp_as_buffer;
     175
     176    if ( pb == NULL ||
     177         pb->bf_getwritebuffer == NULL ||
     178         pb->bf_getsegcount == NULL )
     179    {
     180        PyErr_SetString(PyExc_TypeError, "buffer object expected");
     181        return NULL;
     182    }
     183
     184    return buffer_from_object(base, size,  offset, 0);
    185185}
    186186
     
    188188PyBuffer_FromMemory(void *ptr, Py_ssize_t size)
    189189{
    190         return buffer_from_memory(NULL, size, 0, ptr, 1);
     190    return buffer_from_memory(NULL, size, 0, ptr, 1);
    191191}
    192192
     
    194194PyBuffer_FromReadWriteMemory(void *ptr, Py_ssize_t size)
    195195{
    196         return buffer_from_memory(NULL, size, 0, ptr, 0);
     196    return buffer_from_memory(NULL, size, 0, ptr, 0);
    197197}
    198198
     
    200200PyBuffer_New(Py_ssize_t size)
    201201{
    202         PyObject *o;
    203         PyBufferObject * b;
    204 
    205         if (size < 0) {
    206                 PyErr_SetString(PyExc_ValueError,
    207                                 "size must be zero or positive");
    208                 return NULL;
    209         }
    210         if (sizeof(*b) > PY_SSIZE_T_MAX - size) {
    211                 /* unlikely */
    212                 return PyErr_NoMemory();
    213         }
    214         /* Inline PyObject_New */
    215         o = (PyObject *)PyObject_MALLOC(sizeof(*b) + size);
    216         if ( o == NULL )
    217                 return PyErr_NoMemory();
    218         b = (PyBufferObject *) PyObject_INIT(o, &PyBuffer_Type);
    219 
    220         b->b_base = NULL;
    221         b->b_ptr = (void *)(b + 1);
    222         b->b_size = size;
    223         b->b_offset = 0;
    224         b->b_readonly = 0;
    225         b->b_hash = -1;
    226 
    227         return o;
     202    PyObject *o;
     203    PyBufferObject * b;
     204
     205    if (size < 0) {
     206        PyErr_SetString(PyExc_ValueError,
     207                        "size must be zero or positive");
     208        return NULL;
     209    }
     210    if (sizeof(*b) > PY_SSIZE_T_MAX - size) {
     211        /* unlikely */
     212        return PyErr_NoMemory();
     213    }
     214    /* Inline PyObject_New */
     215    o = (PyObject *)PyObject_MALLOC(sizeof(*b) + size);
     216    if ( o == NULL )
     217        return PyErr_NoMemory();
     218    b = (PyBufferObject *) PyObject_INIT(o, &PyBuffer_Type);
     219
     220    b->b_base = NULL;
     221    b->b_ptr = (void *)(b + 1);
     222    b->b_size = size;
     223    b->b_offset = 0;
     224    b->b_readonly = 0;
     225    b->b_hash = -1;
     226
     227    return o;
    228228}
    229229
     
    233233buffer_new(PyTypeObject *type, PyObject *args, PyObject *kw)
    234234{
    235         PyObject *ob;
    236         Py_ssize_t offset = 0;
    237         Py_ssize_t size = Py_END_OF_BUFFER;
    238 
    239         if (PyErr_WarnPy3k("buffer() not supported in 3.x", 1) < 0)
    240                 return NULL;
    241        
    242         if (!_PyArg_NoKeywords("buffer()", kw))
    243                 return NULL;
    244 
    245         if (!PyArg_ParseTuple(args, "O|nn:buffer", &ob, &offset, &size))
    246             return NULL;
    247         return PyBuffer_FromObject(ob, offset, size);
     235    PyObject *ob;
     236    Py_ssize_t offset = 0;
     237    Py_ssize_t size = Py_END_OF_BUFFER;
     238
     239    if (PyErr_WarnPy3k("buffer() not supported in 3.x", 1) < 0)
     240        return NULL;
     241
     242    if (!_PyArg_NoKeywords("buffer()", kw))
     243        return NULL;
     244
     245    if (!PyArg_ParseTuple(args, "O|nn:buffer", &ob, &offset, &size))
     246        return NULL;
     247    return PyBuffer_FromObject(ob, offset, size);
    248248}
    249249
     
    260260buffer_dealloc(PyBufferObject *self)
    261261{
    262         Py_XDECREF(self->b_base);
    263         PyObject_DEL(self);
     262    Py_XDECREF(self->b_base);
     263    PyObject_DEL(self);
    264264}
    265265
     
    267267buffer_compare(PyBufferObject *self, PyBufferObject *other)
    268268{
    269         void *p1, *p2;
    270         Py_ssize_t len_self, len_other, min_len;
    271         int cmp;
    272 
    273         if (!get_buf(self, &p1, &len_self, ANY_BUFFER))
    274                 return -1;
    275         if (!get_buf(other, &p2, &len_other, ANY_BUFFER))
    276                 return -1;
    277         min_len = (len_self < len_other) ? len_self : len_other;
    278         if (min_len > 0) {
    279                 cmp = memcmp(p1, p2, min_len);
    280                 if (cmp != 0)
    281                         return cmp < 0 ? -1 : 1;
    282         }
    283         return (len_self < len_other) ? -1 : (len_self > len_other) ? 1 : 0;
     269    void *p1, *p2;
     270    Py_ssize_t len_self, len_other, min_len;
     271    int cmp;
     272
     273    if (!get_buf(self, &p1, &len_self, ANY_BUFFER))
     274        return -1;
     275    if (!get_buf(other, &p2, &len_other, ANY_BUFFER))
     276        return -1;
     277    min_len = (len_self < len_other) ? len_self : len_other;
     278    if (min_len > 0) {
     279        cmp = memcmp(p1, p2, min_len);
     280        if (cmp != 0)
     281            return cmp < 0 ? -1 : 1;
     282    }
     283    return (len_self < len_other) ? -1 : (len_self > len_other) ? 1 : 0;
    284284}
    285285
     
    287287buffer_repr(PyBufferObject *self)
    288288{
    289         const char *status = self->b_readonly ? "read-only" : "read-write";
    290 
    291         if ( self->b_base == NULL )
    292                 return PyString_FromFormat("<%s buffer ptr %p, size %zd at %p>",
    293                                            status,
    294                                            self->b_ptr,
    295                                            self->b_size,
    296                                            self);
    297         else
    298                 return PyString_FromFormat(
    299                         "<%s buffer for %p, size %zd, offset %zd at %p>",
    300                         status,
    301                         self->b_base,
    302                         self->b_size,
    303                         self->b_offset,
    304                         self);
     289    const char *status = self->b_readonly ? "read-only" : "read-write";
     290
     291    if ( self->b_base == NULL )
     292        return PyString_FromFormat("<%s buffer ptr %p, size %zd at %p>",
     293                                   status,
     294                                   self->b_ptr,
     295                                   self->b_size,
     296                                   self);
     297    else
     298        return PyString_FromFormat(
     299            "<%s buffer for %p, size %zd, offset %zd at %p>",
     300            status,
     301            self->b_base,
     302            self->b_size,
     303            self->b_offset,
     304            self);
    305305}
    306306
     
    308308buffer_hash(PyBufferObject *self)
    309309{
    310         void *ptr;
    311         Py_ssize_t size;
    312         register Py_ssize_t len;
    313         register unsigned char *p;
    314         register long x;
    315 
    316         if ( self->b_hash != -1 )
    317                 return self->b_hash;
    318 
    319         /* XXX potential bugs here, a readonly buffer does not imply that the
    320          * underlying memory is immutable.  b_readonly is a necessary but not
    321          * sufficient condition for a buffer to be hashable.  Perhaps it would
    322          * be better to only allow hashing if the underlying object is known to
    323          * be immutable (e.g. PyString_Check() is true).  Another idea would
    324          * be to call tp_hash on the underlying object and see if it raises
    325          * an error. */
    326         if ( !self->b_readonly )
    327         {
    328                 PyErr_SetString(PyExc_TypeError,
    329                                 "writable buffers are not hashable");
    330                 return -1;
    331         }
    332 
    333         if (!get_buf(self, &ptr, &size, ANY_BUFFER))
    334                 return -1;
    335         p = (unsigned char *) ptr;
    336         len = size;
    337         x = *p << 7;
    338         while (--len >= 0)
    339                 x = (1000003*x) ^ *p++;
    340         x ^= size;
    341         if (x == -1)
    342                 x = -2;
    343         self->b_hash = x;
    344         return x;
     310    void *ptr;
     311    Py_ssize_t size;
     312    register Py_ssize_t len;
     313    register unsigned char *p;
     314    register long x;
     315
     316    if ( self->b_hash != -1 )
     317        return self->b_hash;
     318
     319    /* XXX potential bugs here, a readonly buffer does not imply that the
     320     * underlying memory is immutable.  b_readonly is a necessary but not
     321     * sufficient condition for a buffer to be hashable.  Perhaps it would
     322     * be better to only allow hashing if the underlying object is known to
     323     * be immutable (e.g. PyString_Check() is true).  Another idea would
     324     * be to call tp_hash on the underlying object and see if it raises
     325     * an error. */
     326    if ( !self->b_readonly )
     327    {
     328        PyErr_SetString(PyExc_TypeError,
     329                        "writable buffers are not hashable");
     330        return -1;
     331    }
     332
     333    if (!get_buf(self, &ptr, &size, ANY_BUFFER))
     334        return -1;
     335    p = (unsigned char *) ptr;
     336    len = size;
     337    /*
     338      We make the hash of the empty buffer be 0, rather than using
     339      (prefix ^ suffix), since this slightly obfuscates the hash secret
     340    */
     341    if (len == 0) {
     342        self->b_hash = 0;
     343        return 0;
     344    }
     345    x = _Py_HashSecret.prefix;
     346    x ^= *p << 7;
     347    while (--len >= 0)
     348        x = (1000003*x) ^ *p++;
     349    x ^= size;
     350    x ^= _Py_HashSecret.suffix;
     351    if (x == -1)
     352        x = -2;
     353    self->b_hash = x;
     354    return x;
    345355}
    346356
     
    348358buffer_str(PyBufferObject *self)
    349359{
    350         void *ptr;
    351         Py_ssize_t size;
    352         if (!get_buf(self, &ptr, &size, ANY_BUFFER))
    353                 return NULL;
    354         return PyString_FromStringAndSize((const char *)ptr, size);
     360    void *ptr;
     361    Py_ssize_t size;
     362    if (!get_buf(self, &ptr, &size, ANY_BUFFER))
     363        return NULL;
     364    return PyString_FromStringAndSize((const char *)ptr, size);
    355365}
    356366
     
    360370buffer_length(PyBufferObject *self)
    361371{
    362         void *ptr;
    363         Py_ssize_t size;
    364         if (!get_buf(self, &ptr, &size, ANY_BUFFER))
    365                 return -1;
    366         return size;
     372    void *ptr;
     373    Py_ssize_t size;
     374    if (!get_buf(self, &ptr, &size, ANY_BUFFER))
     375        return -1;
     376    return size;
    367377}
    368378
     
    370380buffer_concat(PyBufferObject *self, PyObject *other)
    371381{
    372         PyBufferProcs *pb = other->ob_type->tp_as_buffer;
    373         void *ptr1, *ptr2;
    374         char *p;
    375         PyObject *ob;
    376         Py_ssize_t size, count;
    377 
    378         if ( pb == NULL ||
    379              pb->bf_getreadbuffer == NULL ||
    380              pb->bf_getsegcount == NULL )
    381         {
    382                 PyErr_BadArgument();
    383                 return NULL;
    384         }
    385         if ( (*pb->bf_getsegcount)(other, NULL) != 1 )
    386         {
    387                 /* ### use a different exception type/message? */
    388                 PyErr_SetString(PyExc_TypeError,
    389                                 "single-segment buffer object expected");
    390                 return NULL;
    391         }
    392 
    393         if (!get_buf(self, &ptr1, &size, ANY_BUFFER))
    394                 return NULL;
    395  
    396         /* optimize special case */
    397         if ( size == 0 )
    398         {
    399             Py_INCREF(other);
    400             return other;
    401         }
    402 
    403         if ( (count = (*pb->bf_getreadbuffer)(other, 0, &ptr2)) < 0 )
    404                 return NULL;
    405 
    406         assert(count <= PY_SIZE_MAX - size);
    407 
    408         ob = PyString_FromStringAndSize(NULL, size + count);
    409         if ( ob == NULL )
    410                 return NULL;
    411         p = PyString_AS_STRING(ob);
    412         memcpy(p, ptr1, size);
    413         memcpy(p + size, ptr2, count);
    414 
    415         /* there is an extra byte in the string object, so this is safe */
    416         p[size + count] = '\0';
    417 
    418         return ob;
     382    PyBufferProcs *pb = other->ob_type->tp_as_buffer;
     383    void *ptr1, *ptr2;
     384    char *p;
     385    PyObject *ob;
     386    Py_ssize_t size, count;
     387
     388    if ( pb == NULL ||
     389         pb->bf_getreadbuffer == NULL ||
     390         pb->bf_getsegcount == NULL )
     391    {
     392        PyErr_BadArgument();
     393        return NULL;
     394    }
     395    if ( (*pb->bf_getsegcount)(other, NULL) != 1 )
     396    {
     397        /* ### use a different exception type/message? */
     398        PyErr_SetString(PyExc_TypeError,
     399                        "single-segment buffer object expected");
     400        return NULL;
     401    }
     402
     403    if (!get_buf(self, &ptr1, &size, ANY_BUFFER))
     404        return NULL;
     405
     406    /* optimize special case */
     407    if ( size == 0 )
     408    {
     409        Py_INCREF(other);
     410        return other;
     411    }
     412
     413    if ( (count = (*pb->bf_getreadbuffer)(other, 0, &ptr2)) < 0 )
     414        return NULL;
     415
     416    assert(count <= PY_SIZE_MAX - size);
     417
     418    ob = PyString_FromStringAndSize(NULL, size + count);
     419    if ( ob == NULL )
     420        return NULL;
     421    p = PyString_AS_STRING(ob);
     422    memcpy(p, ptr1, size);
     423    memcpy(p + size, ptr2, count);
     424
     425    /* there is an extra byte in the string object, so this is safe */
     426    p[size + count] = '\0';
     427
     428    return ob;
    419429}
    420430
     
    422432buffer_repeat(PyBufferObject *self, Py_ssize_t count)
    423433{
    424         PyObject *ob;
    425         register char *p;
    426         void *ptr;
    427         Py_ssize_t size;
    428 
    429         if ( count < 0 )
    430                 count = 0;
    431         if (!get_buf(self, &ptr, &size, ANY_BUFFER))
    432                 return NULL;
    433         if (count > PY_SSIZE_T_MAX / size) {
    434                 PyErr_SetString(PyExc_MemoryError, "result too large");
    435                 return NULL;
    436         }
    437         ob = PyString_FromStringAndSize(NULL, size * count);
    438         if ( ob == NULL )
    439                 return NULL;
    440 
    441         p = PyString_AS_STRING(ob);
    442         while ( count-- )
    443         {
    444             memcpy(p, ptr, size);
    445             p += size;
    446         }
    447 
    448         /* there is an extra byte in the string object, so this is safe */
    449         *p = '\0';
    450 
    451         return ob;
     434    PyObject *ob;
     435    register char *p;
     436    void *ptr;
     437    Py_ssize_t size;
     438
     439    if ( count < 0 )
     440        count = 0;
     441    if (!get_buf(self, &ptr, &size, ANY_BUFFER))
     442        return NULL;
     443    if (count > PY_SSIZE_T_MAX / size) {
     444        PyErr_SetString(PyExc_MemoryError, "result too large");
     445        return NULL;
     446    }
     447    ob = PyString_FromStringAndSize(NULL, size * count);
     448    if ( ob == NULL )
     449        return NULL;
     450
     451    p = PyString_AS_STRING(ob);
     452    while ( count-- )
     453    {
     454        memcpy(p, ptr, size);
     455        p += size;
     456    }
     457
     458    /* there is an extra byte in the string object, so this is safe */
     459    *p = '\0';
     460
     461    return ob;
    452462}
    453463
     
    455465buffer_item(PyBufferObject *self, Py_ssize_t idx)
    456466{
    457         void *ptr;
    458         Py_ssize_t size;
    459         if (!get_buf(self, &ptr, &size, ANY_BUFFER))
    460                 return NULL;
    461         if ( idx < 0 || idx >= size ) {
    462                 PyErr_SetString(PyExc_IndexError, "buffer index out of range");
    463                 return NULL;
    464         }
    465         return PyString_FromStringAndSize((char *)ptr + idx, 1);
     467    void *ptr;
     468    Py_ssize_t size;
     469    if (!get_buf(self, &ptr, &size, ANY_BUFFER))
     470        return NULL;
     471    if ( idx < 0 || idx >= size ) {
     472        PyErr_SetString(PyExc_IndexError, "buffer index out of range");
     473        return NULL;
     474    }
     475    return PyString_FromStringAndSize((char *)ptr + idx, 1);
    466476}
    467477
     
    469479buffer_slice(PyBufferObject *self, Py_ssize_t left, Py_ssize_t right)
    470480{
    471         void *ptr;
    472         Py_ssize_t size;
    473         if (!get_buf(self, &ptr, &size, ANY_BUFFER))
    474                 return NULL;
    475         if ( left < 0 )
    476                 left = 0;
    477         if ( right < 0 )
    478                 right = 0;
    479         if ( right > size )
    480                 right = size;
    481         if ( right < left )
    482                 right = left;
    483         return PyString_FromStringAndSize((char *)ptr + left,
    484                                           right - left);
     481    void *ptr;
     482    Py_ssize_t size;
     483    if (!get_buf(self, &ptr, &size, ANY_BUFFER))
     484        return NULL;
     485    if ( left < 0 )
     486        left = 0;
     487    if ( right < 0 )
     488        right = 0;
     489    if ( right > size )
     490        right = size;
     491    if ( right < left )
     492        right = left;
     493    return PyString_FromStringAndSize((char *)ptr + left,
     494                                      right - left);
    485495}
    486496
     
    488498buffer_subscript(PyBufferObject *self, PyObject *item)
    489499{
    490         void *p;
    491         Py_ssize_t size;
    492        
    493         if (!get_buf(self, &p, &size, ANY_BUFFER))
    494                 return NULL;
    495         if (PyIndex_Check(item)) {
    496                 Py_ssize_t i = PyNumber_AsSsize_t(item, PyExc_IndexError);
    497                 if (i == -1 && PyErr_Occurred())
    498                         return NULL;
    499                 if (i < 0)
    500                         i += size;
    501                 return buffer_item(self, i);
    502         }
    503         else if (PySlice_Check(item)) {
    504                 Py_ssize_t start, stop, step, slicelength, cur, i;
    505 
    506                 if (PySlice_GetIndicesEx((PySliceObject*)item, size,
    507                                 &start, &stop, &step, &slicelength) < 0) {
    508                         return NULL;
    509                 }
    510 
    511                 if (slicelength <= 0)
    512                         return PyString_FromStringAndSize("", 0);
    513                 else if (step == 1)
    514                         return PyString_FromStringAndSize((char *)p + start,
    515                                                           stop - start);
    516                 else {
    517                         PyObject *result;
    518                         char *source_buf = (char *)p;
    519                         char *result_buf = (char *)PyMem_Malloc(slicelength);
    520 
    521                         if (result_buf == NULL)
    522                                 return PyErr_NoMemory();
    523 
    524                         for (cur = start, i = 0; i < slicelength;
    525                              cur += step, i++) {
    526                                 result_buf[i] = source_buf[cur];
    527                         }
    528 
    529                         result = PyString_FromStringAndSize(result_buf,
    530                                                             slicelength);
    531                         PyMem_Free(result_buf);
    532                         return result;
    533                 }
    534         }
    535         else {
    536                 PyErr_SetString(PyExc_TypeError,
    537                                 "sequence index must be integer");
    538                 return NULL;
    539         }
     500    void *p;
     501    Py_ssize_t size;
     502
     503    if (!get_buf(self, &p, &size, ANY_BUFFER))
     504        return NULL;
     505    if (PyIndex_Check(item)) {
     506        Py_ssize_t i = PyNumber_AsSsize_t(item, PyExc_IndexError);
     507        if (i == -1 && PyErr_Occurred())
     508            return NULL;
     509        if (i < 0)
     510            i += size;
     511        return buffer_item(self, i);
     512    }
     513    else if (PySlice_Check(item)) {
     514        Py_ssize_t start, stop, step, slicelength, cur, i;
     515
     516        if (PySlice_GetIndicesEx((PySliceObject*)item, size,
     517                        &start, &stop, &step, &slicelength) < 0) {
     518            return NULL;
     519        }
     520
     521        if (slicelength <= 0)
     522            return PyString_FromStringAndSize("", 0);
     523        else if (step == 1)
     524            return PyString_FromStringAndSize((char *)p + start,
     525                                              stop - start);
     526        else {
     527            PyObject *result;
     528            char *source_buf = (char *)p;
     529            char *result_buf = (char *)PyMem_Malloc(slicelength);
     530
     531            if (result_buf == NULL)
     532                return PyErr_NoMemory();
     533
     534            for (cur = start, i = 0; i < slicelength;
     535                 cur += step, i++) {
     536                result_buf[i] = source_buf[cur];
     537            }
     538
     539            result = PyString_FromStringAndSize(result_buf,
     540                                                slicelength);
     541            PyMem_Free(result_buf);
     542            return result;
     543        }
     544    }
     545    else {
     546        PyErr_SetString(PyExc_TypeError,
     547                        "sequence index must be integer");
     548        return NULL;
     549    }
    540550}
    541551
     
    543553buffer_ass_item(PyBufferObject *self, Py_ssize_t idx, PyObject *other)
    544554{
    545         PyBufferProcs *pb;
    546         void *ptr1, *ptr2;
    547         Py_ssize_t size;
    548         Py_ssize_t count;
    549 
    550         if ( self->b_readonly ) {
    551                 PyErr_SetString(PyExc_TypeError,
    552                                 "buffer is read-only");
    553                 return -1;
    554         }
    555 
    556         if (!get_buf(self, &ptr1, &size, ANY_BUFFER))
    557                 return -1;
    558 
    559         if (idx < 0 || idx >= size) {
    560                 PyErr_SetString(PyExc_IndexError,
    561                                 "buffer assignment index out of range");
    562                 return -1;
    563         }
    564 
    565         pb = other ? other->ob_type->tp_as_buffer : NULL;
    566         if ( pb == NULL ||
    567              pb->bf_getreadbuffer == NULL ||
    568              pb->bf_getsegcount == NULL )
    569         {
    570                 PyErr_BadArgument();
    571                 return -1;
    572         }
    573         if ( (*pb->bf_getsegcount)(other, NULL) != 1 )
    574         {
    575                 /* ### use a different exception type/message? */
    576                 PyErr_SetString(PyExc_TypeError,
    577                                 "single-segment buffer object expected");
    578                 return -1;
    579         }
    580 
    581         if ( (count = (*pb->bf_getreadbuffer)(other, 0, &ptr2)) < 0 )
    582                 return -1;
    583         if ( count != 1 ) {
    584                 PyErr_SetString(PyExc_TypeError,
    585                                 "right operand must be a single byte");
    586                 return -1;
    587         }
    588 
    589         ((char *)ptr1)[idx] = *(char *)ptr2;
    590         return 0;
     555    PyBufferProcs *pb;
     556    void *ptr1, *ptr2;
     557    Py_ssize_t size;
     558    Py_ssize_t count;
     559
     560    if ( self->b_readonly ) {
     561        PyErr_SetString(PyExc_TypeError,
     562                        "buffer is read-only");
     563        return -1;
     564    }
     565
     566    if (!get_buf(self, &ptr1, &size, ANY_BUFFER))
     567        return -1;
     568
     569    if (idx < 0 || idx >= size) {
     570        PyErr_SetString(PyExc_IndexError,
     571                        "buffer assignment index out of range");
     572        return -1;
     573    }
     574
     575    pb = other ? other->ob_type->tp_as_buffer : NULL;
     576    if ( pb == NULL ||
     577         pb->bf_getreadbuffer == NULL ||
     578         pb->bf_getsegcount == NULL )
     579    {
     580        PyErr_BadArgument();
     581        return -1;
     582    }
     583    if ( (*pb->bf_getsegcount)(other, NULL) != 1 )
     584    {
     585        /* ### use a different exception type/message? */
     586        PyErr_SetString(PyExc_TypeError,
     587                        "single-segment buffer object expected");
     588        return -1;
     589    }
     590
     591    if ( (count = (*pb->bf_getreadbuffer)(other, 0, &ptr2)) < 0 )
     592        return -1;
     593    if ( count != 1 ) {
     594        PyErr_SetString(PyExc_TypeError,
     595                        "right operand must be a single byte");
     596        return -1;
     597    }
     598
     599    ((char *)ptr1)[idx] = *(char *)ptr2;
     600    return 0;
    591601}
    592602
     
    594604buffer_ass_slice(PyBufferObject *self, Py_ssize_t left, Py_ssize_t right, PyObject *other)
    595605{
    596         PyBufferProcs *pb;
    597         void *ptr1, *ptr2;
    598         Py_ssize_t size;
    599         Py_ssize_t slice_len;
    600         Py_ssize_t count;
    601 
    602         if ( self->b_readonly ) {
    603                 PyErr_SetString(PyExc_TypeError,
    604                                 "buffer is read-only");
    605                 return -1;
    606         }
    607 
    608         pb = other ? other->ob_type->tp_as_buffer : NULL;
    609         if ( pb == NULL ||
    610              pb->bf_getreadbuffer == NULL ||
    611              pb->bf_getsegcount == NULL )
    612         {
    613                 PyErr_BadArgument();
    614                 return -1;
    615         }
    616         if ( (*pb->bf_getsegcount)(other, NULL) != 1 )
    617         {
    618                 /* ### use a different exception type/message? */
    619                 PyErr_SetString(PyExc_TypeError,
    620                                 "single-segment buffer object expected");
    621                 return -1;
    622         }
    623         if (!get_buf(self, &ptr1, &size, ANY_BUFFER))
    624                 return -1;
    625         if ( (count = (*pb->bf_getreadbuffer)(other, 0, &ptr2)) < 0 )
    626                 return -1;
    627 
    628         if ( left < 0 )
    629                 left = 0;
    630         else if ( left > size )
    631                 left = size;
    632         if ( right < left )
    633                 right = left;
    634         else if ( right > size )
    635                 right = size;
    636         slice_len = right - left;
    637 
    638         if ( count != slice_len ) {
    639                 PyErr_SetString(
    640                         PyExc_TypeError,
    641                         "right operand length must match slice length");
    642                 return -1;
    643         }
    644 
    645         if ( slice_len )
    646             memcpy((char *)ptr1 + left, ptr2, slice_len);
    647 
    648         return 0;
     606    PyBufferProcs *pb;
     607    void *ptr1, *ptr2;
     608    Py_ssize_t size;
     609    Py_ssize_t slice_len;
     610    Py_ssize_t count;
     611
     612    if ( self->b_readonly ) {
     613        PyErr_SetString(PyExc_TypeError,
     614                        "buffer is read-only");
     615        return -1;
     616    }
     617
     618    pb = other ? other->ob_type->tp_as_buffer : NULL;
     619    if ( pb == NULL ||
     620         pb->bf_getreadbuffer == NULL ||
     621         pb->bf_getsegcount == NULL )
     622    {
     623        PyErr_BadArgument();
     624        return -1;
     625    }
     626    if ( (*pb->bf_getsegcount)(other, NULL) != 1 )
     627    {
     628        /* ### use a different exception type/message? */
     629        PyErr_SetString(PyExc_TypeError,
     630                        "single-segment buffer object expected");
     631        return -1;
     632    }
     633    if (!get_buf(self, &ptr1, &size, ANY_BUFFER))
     634        return -1;
     635    if ( (count = (*pb->bf_getreadbuffer)(other, 0, &ptr2)) < 0 )
     636        return -1;
     637
     638    if ( left < 0 )
     639        left = 0;
     640    else if ( left > size )
     641        left = size;
     642    if ( right < left )
     643        right = left;
     644    else if ( right > size )
     645        right = size;
     646    slice_len = right - left;
     647
     648    if ( count != slice_len ) {
     649        PyErr_SetString(
     650            PyExc_TypeError,
     651            "right operand length must match slice length");
     652        return -1;
     653    }
     654
     655    if ( slice_len )
     656        memcpy((char *)ptr1 + left, ptr2, slice_len);
     657
     658    return 0;
    649659}
    650660
     
    652662buffer_ass_subscript(PyBufferObject *self, PyObject *item, PyObject *value)
    653663{
    654         PyBufferProcs *pb;
    655         void *ptr1, *ptr2;
    656         Py_ssize_t selfsize;
    657         Py_ssize_t othersize;
    658 
    659         if ( self->b_readonly ) {
    660                 PyErr_SetString(PyExc_TypeError,
    661                                 "buffer is read-only");
    662                 return -1;
    663         }
    664 
    665         pb = value ? value->ob_type->tp_as_buffer : NULL;
    666         if ( pb == NULL ||
    667              pb->bf_getreadbuffer == NULL ||
    668              pb->bf_getsegcount == NULL )
    669         {
    670                 PyErr_BadArgument();
    671                 return -1;
    672         }
    673         if ( (*pb->bf_getsegcount)(value, NULL) != 1 )
    674         {
    675                 /* ### use a different exception type/message? */
    676                 PyErr_SetString(PyExc_TypeError,
    677                                 "single-segment buffer object expected");
    678                 return -1;
    679         }
    680         if (!get_buf(self, &ptr1, &selfsize, ANY_BUFFER))
    681                 return -1;
    682         if (PyIndex_Check(item)) {
    683                 Py_ssize_t i = PyNumber_AsSsize_t(item, PyExc_IndexError);
    684                 if (i == -1 && PyErr_Occurred())
    685                         return -1;
    686                 if (i < 0)
    687                         i += selfsize;
    688                 return buffer_ass_item(self, i, value);
    689         }
    690         else if (PySlice_Check(item)) {
    691                 Py_ssize_t start, stop, step, slicelength;
    692                
    693                 if (PySlice_GetIndicesEx((PySliceObject *)item, selfsize,
    694                                 &start, &stop, &step, &slicelength) < 0)
    695                         return -1;
    696 
    697                 if ((othersize = (*pb->bf_getreadbuffer)(value, 0, &ptr2)) < 0)
    698                         return -1;
    699 
    700                 if (othersize != slicelength) {
    701                         PyErr_SetString(
    702                                 PyExc_TypeError,
    703                                 "right operand length must match slice length");
    704                         return -1;
    705                 }
    706 
    707                 if (slicelength == 0)
    708                         return 0;
    709                 else if (step == 1) {
    710                         memcpy((char *)ptr1 + start, ptr2, slicelength);
    711                         return 0;
    712                 }
    713                 else {
    714                         Py_ssize_t cur, i;
    715                        
    716                         for (cur = start, i = 0; i < slicelength;
    717                              cur += step, i++) {
    718                                 ((char *)ptr1)[cur] = ((char *)ptr2)[i];
    719                         }
    720 
    721                         return 0;
    722                 }
    723         } else {
    724                 PyErr_SetString(PyExc_TypeError,
    725                                 "buffer indices must be integers");
    726                 return -1;
    727         }
     664    PyBufferProcs *pb;
     665    void *ptr1, *ptr2;
     666    Py_ssize_t selfsize;
     667    Py_ssize_t othersize;
     668
     669    if ( self->b_readonly ) {
     670        PyErr_SetString(PyExc_TypeError,
     671                        "buffer is read-only");
     672        return -1;
     673    }
     674
     675    pb = value ? value->ob_type->tp_as_buffer : NULL;
     676    if ( pb == NULL ||
     677         pb->bf_getreadbuffer == NULL ||
     678         pb->bf_getsegcount == NULL )
     679    {
     680        PyErr_BadArgument();
     681        return -1;
     682    }
     683    if ( (*pb->bf_getsegcount)(value, NULL) != 1 )
     684    {
     685        /* ### use a different exception type/message? */
     686        PyErr_SetString(PyExc_TypeError,
     687                        "single-segment buffer object expected");
     688        return -1;
     689    }
     690    if (!get_buf(self, &ptr1, &selfsize, ANY_BUFFER))
     691        return -1;
     692    if (PyIndex_Check(item)) {
     693        Py_ssize_t i = PyNumber_AsSsize_t(item, PyExc_IndexError);
     694        if (i == -1 && PyErr_Occurred())
     695            return -1;
     696        if (i < 0)
     697            i += selfsize;
     698        return buffer_ass_item(self, i, value);
     699    }
     700    else if (PySlice_Check(item)) {
     701        Py_ssize_t start, stop, step, slicelength;
     702
     703        if (PySlice_GetIndicesEx((PySliceObject *)item, selfsize,
     704                        &start, &stop, &step, &slicelength) < 0)
     705            return -1;
     706
     707        if ((othersize = (*pb->bf_getreadbuffer)(value, 0, &ptr2)) < 0)
     708            return -1;
     709
     710        if (othersize != slicelength) {
     711            PyErr_SetString(
     712                PyExc_TypeError,
     713                "right operand length must match slice length");
     714            return -1;
     715        }
     716
     717        if (slicelength == 0)
     718            return 0;
     719        else if (step == 1) {
     720            memcpy((char *)ptr1 + start, ptr2, slicelength);
     721            return 0;
     722        }
     723        else {
     724            Py_ssize_t cur, i;
     725
     726            for (cur = start, i = 0; i < slicelength;
     727                 cur += step, i++) {
     728                ((char *)ptr1)[cur] = ((char *)ptr2)[i];
     729            }
     730
     731            return 0;
     732        }
     733    } else {
     734        PyErr_SetString(PyExc_TypeError,
     735                        "buffer indices must be integers");
     736        return -1;
     737    }
    728738}
    729739
     
    733743buffer_getreadbuf(PyBufferObject *self, Py_ssize_t idx, void **pp)
    734744{
    735         Py_ssize_t size;
    736         if ( idx != 0 ) {
    737                 PyErr_SetString(PyExc_SystemError,
    738                                 "accessing non-existent buffer segment");
    739                 return -1;
    740         }
    741         if (!get_buf(self, pp, &size, READ_BUFFER))
    742                 return -1;
    743         return size;
     745    Py_ssize_t size;
     746    if ( idx != 0 ) {
     747        PyErr_SetString(PyExc_SystemError,
     748                        "accessing non-existent buffer segment");
     749        return -1;
     750    }
     751    if (!get_buf(self, pp, &size, READ_BUFFER))
     752        return -1;
     753    return size;
    744754}
    745755
     
    747757buffer_getwritebuf(PyBufferObject *self, Py_ssize_t idx, void **pp)
    748758{
    749         Py_ssize_t size;
    750 
    751         if ( self->b_readonly )
    752         {
    753                 PyErr_SetString(PyExc_TypeError, "buffer is read-only");
    754                 return -1;
    755         }
    756 
    757         if ( idx != 0 ) {
    758                 PyErr_SetString(PyExc_SystemError,
    759                                 "accessing non-existent buffer segment");
    760                 return -1;
    761         }
    762         if (!get_buf(self, pp, &size, WRITE_BUFFER))
    763                 return -1;
    764         return size;
     759    Py_ssize_t size;
     760
     761    if ( self->b_readonly )
     762    {
     763        PyErr_SetString(PyExc_TypeError, "buffer is read-only");
     764        return -1;
     765    }
     766
     767    if ( idx != 0 ) {
     768        PyErr_SetString(PyExc_SystemError,
     769                        "accessing non-existent buffer segment");
     770        return -1;
     771    }
     772    if (!get_buf(self, pp, &size, WRITE_BUFFER))
     773        return -1;
     774    return size;
    765775}
    766776
     
    768778buffer_getsegcount(PyBufferObject *self, Py_ssize_t *lenp)
    769779{
    770         void *ptr;
    771         Py_ssize_t size;
    772         if (!get_buf(self, &ptr, &size, ANY_BUFFER))
    773                 return -1;
    774         if (lenp)
    775                 *lenp = size;
    776         return 1;
     780    void *ptr;
     781    Py_ssize_t size;
     782    if (!get_buf(self, &ptr, &size, ANY_BUFFER))
     783        return -1;
     784    if (lenp)
     785        *lenp = size;
     786    return 1;
    777787}
    778788
     
    780790buffer_getcharbuf(PyBufferObject *self, Py_ssize_t idx, const char **pp)
    781791{
    782         void *ptr;
    783         Py_ssize_t size;
    784         if ( idx != 0 ) {
    785                 PyErr_SetString(PyExc_SystemError,
    786                                 "accessing non-existent buffer segment");
    787                 return -1;
    788         }
    789         if (!get_buf(self, &ptr, &size, CHAR_BUFFER))
    790                 return -1;
    791         *pp = (const char *)ptr;
    792         return size;
     792    void *ptr;
     793    Py_ssize_t size;
     794    if ( idx != 0 ) {
     795        PyErr_SetString(PyExc_SystemError,
     796                        "accessing non-existent buffer segment");
     797        return -1;
     798    }
     799    if (!get_buf(self, &ptr, &size, CHAR_BUFFER))
     800        return -1;
     801    *pp = (const char *)ptr;
     802    return size;
     803}
     804
     805static int buffer_getbuffer(PyBufferObject *self, Py_buffer *buf, int flags)
     806{
     807    void *ptr;
     808    Py_ssize_t size;
     809    if (!get_buf(self, &ptr, &size, ANY_BUFFER))
     810        return -1;
     811    return PyBuffer_FillInfo(buf, (PyObject*)self, ptr, size,
     812                             self->b_readonly, flags);
    793813}
    794814
    795815static PySequenceMethods buffer_as_sequence = {
    796         (lenfunc)buffer_length, /*sq_length*/
    797         (binaryfunc)buffer_concat, /*sq_concat*/
    798         (ssizeargfunc)buffer_repeat, /*sq_repeat*/
    799         (ssizeargfunc)buffer_item, /*sq_item*/
    800         (ssizessizeargfunc)buffer_slice, /*sq_slice*/
    801         (ssizeobjargproc)buffer_ass_item, /*sq_ass_item*/
    802         (ssizessizeobjargproc)buffer_ass_slice, /*sq_ass_slice*/
     816    (lenfunc)buffer_length, /*sq_length*/
     817    (binaryfunc)buffer_concat, /*sq_concat*/
     818    (ssizeargfunc)buffer_repeat, /*sq_repeat*/
     819    (ssizeargfunc)buffer_item, /*sq_item*/
     820    (ssizessizeargfunc)buffer_slice, /*sq_slice*/
     821    (ssizeobjargproc)buffer_ass_item, /*sq_ass_item*/
     822    (ssizessizeobjargproc)buffer_ass_slice, /*sq_ass_slice*/
    803823};
    804824
    805825static PyMappingMethods buffer_as_mapping = {
    806         (lenfunc)buffer_length,
    807         (binaryfunc)buffer_subscript,
    808         (objobjargproc)buffer_ass_subscript,
     826    (lenfunc)buffer_length,
     827    (binaryfunc)buffer_subscript,
     828    (objobjargproc)buffer_ass_subscript,
    809829};
    810830
    811831static PyBufferProcs buffer_as_buffer = {
    812         (readbufferproc)buffer_getreadbuf,
    813         (writebufferproc)buffer_getwritebuf,
    814         (segcountproc)buffer_getsegcount,
    815         (charbufferproc)buffer_getcharbuf,
     832    (readbufferproc)buffer_getreadbuf,
     833    (writebufferproc)buffer_getwritebuf,
     834    (segcountproc)buffer_getsegcount,
     835    (charbufferproc)buffer_getcharbuf,
     836    (getbufferproc)buffer_getbuffer,
    816837};
    817838
    818839PyTypeObject PyBuffer_Type = {
    819         PyVarObject_HEAD_INIT(&PyType_Type, 0)
    820         "buffer",
    821         sizeof(PyBufferObject),
    822         0,
    823         (destructor)buffer_dealloc,             /* tp_dealloc */
    824         0,                                      /* tp_print */
    825         0,                                      /* tp_getattr */
    826         0,                                      /* tp_setattr */
    827         (cmpfunc)buffer_compare,                /* tp_compare */
    828         (reprfunc)buffer_repr,                  /* tp_repr */
    829         0,                                      /* tp_as_number */
    830         &buffer_as_sequence,                    /* tp_as_sequence */
    831         &buffer_as_mapping,                     /* tp_as_mapping */
    832         (hashfunc)buffer_hash,                  /* tp_hash */
    833         0,                                      /* tp_call */
    834         (reprfunc)buffer_str,                   /* tp_str */
    835         PyObject_GenericGetAttr,                /* tp_getattro */
    836         0,                                      /* tp_setattro */
    837         &buffer_as_buffer,                      /* tp_as_buffer */
    838         Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GETCHARBUFFER, /* tp_flags */
    839         buffer_doc,                             /* tp_doc */
    840         0,                                      /* tp_traverse */
    841         0,                                      /* tp_clear */
    842         0,                                      /* tp_richcompare */
    843         0,                                      /* tp_weaklistoffset */
    844         0,                                      /* tp_iter */
    845         0,                                      /* tp_iternext */
    846         0,                                      /* tp_methods */       
    847         0,                                      /* tp_members */
    848         0,                                      /* tp_getset */
    849         0,                                      /* tp_base */
    850         0,                                      /* tp_dict */
    851         0,                                      /* tp_descr_get */
    852         0,                                      /* tp_descr_set */
    853         0,                                      /* tp_dictoffset */
    854         0,                                      /* tp_init */
    855         0,                                      /* tp_alloc */
    856         buffer_new,                             /* tp_new */
     840    PyVarObject_HEAD_INIT(&PyType_Type, 0)
     841    "buffer",
     842    sizeof(PyBufferObject),
     843    0,
     844    (destructor)buffer_dealloc,                 /* tp_dealloc */
     845    0,                                          /* tp_print */
     846    0,                                          /* tp_getattr */
     847    0,                                          /* tp_setattr */
     848    (cmpfunc)buffer_compare,                    /* tp_compare */
     849    (reprfunc)buffer_repr,                      /* tp_repr */
     850    0,                                          /* tp_as_number */
     851    &buffer_as_sequence,                        /* tp_as_sequence */
     852    &buffer_as_mapping,                         /* tp_as_mapping */
     853    (hashfunc)buffer_hash,                      /* tp_hash */
     854    0,                                          /* tp_call */
     855    (reprfunc)buffer_str,                       /* tp_str */
     856    PyObject_GenericGetAttr,                    /* tp_getattro */
     857    0,                                          /* tp_setattro */
     858    &buffer_as_buffer,                          /* tp_as_buffer */
     859    Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GETCHARBUFFER | Py_TPFLAGS_HAVE_NEWBUFFER, /* tp_flags */
     860    buffer_doc,                                 /* tp_doc */
     861    0,                                          /* tp_traverse */
     862    0,                                          /* tp_clear */
     863    0,                                          /* tp_richcompare */
     864    0,                                          /* tp_weaklistoffset */
     865    0,                                          /* tp_iter */
     866    0,                                          /* tp_iternext */
     867    0,                                          /* tp_methods */
     868    0,                                          /* tp_members */
     869    0,                                          /* tp_getset */
     870    0,                                          /* tp_base */
     871    0,                                          /* tp_dict */
     872    0,                                          /* tp_descr_get */
     873    0,                                          /* tp_descr_set */
     874    0,                                          /* tp_dictoffset */
     875    0,                                          /* tp_init */
     876    0,                                          /* tp_alloc */
     877    buffer_new,                                 /* tp_new */
    857878};
Note: See TracChangeset for help on using the changeset viewer.