1 /***********************************************************
2 Copyright 1991-1995 by Stichting Mathematisch Centrum, Amsterdam,
7 Permission to use, copy, modify, and distribute this software and its
8 documentation for any purpose and without fee is hereby granted,
9 provided that the above copyright notice appear in all copies and that
10 both that copyright notice and this permission notice appear in
11 supporting documentation, and that the names of Stichting Mathematisch
12 Centrum or CWI or Corporation for National Research Initiatives or
13 CNRI not be used in advertising or publicity pertaining to
14 distribution of the software without specific, written prior
17 While CWI is the initial source for this software, a modified version
18 is made available by the Corporation for National Research Initiatives
19 (CNRI) at the Internet address ftp://ftp.python.org.
21 STICHTING MATHEMATISCH CENTRUM AND CNRI DISCLAIM ALL WARRANTIES WITH
22 REGARD TO THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF
23 MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL STICHTING MATHEMATISCH
24 CENTRUM OR CNRI BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL
25 DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR
26 PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
27 TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
28 PERFORMANCE OF THIS SOFTWARE.
30 ******************************************************************/
32 /* Buffer object implementation */
50 _PyBuffer_FromMemory(base
, ptr
, size
, readonly
)
59 PyErr_SetString(PyExc_ValueError
,
60 "size must be zero or positive");
64 b
= PyObject_NEW(PyBufferObject
, &PyBuffer_Type
);
72 b
->b_readonly
= readonly
;
77 return (PyObject
*) b
;
81 _PyBuffer_FromObject(base
, offset
, size
, proc
, readonly
)
85 getreadbufferproc proc
;
88 PyBufferProcs
*pb
= base
->ob_type
->tp_as_buffer
;
93 PyErr_SetString(PyExc_ValueError
,
94 "offset must be zero or positive");
98 if ( (*pb
->bf_getsegcount
)(base
, NULL
) != 1 )
100 PyErr_SetString(PyExc_TypeError
,
101 "single-segment buffer object expected");
104 if ( (count
= (*proc
)(base
, 0, &p
)) < 0 )
107 /* apply constraints to the start/end */
108 if ( size
== Py_END_OF_BUFFER
|| size
< 0 )
110 if ( offset
> count
)
112 if ( offset
+ size
> count
)
113 size
= count
- offset
;
115 /* if the base object is another buffer, then "deref" it */
116 if ( PyBuffer_Check(base
) )
117 base
= ((PyBufferObject
*)base
)->b_base
;
119 return _PyBuffer_FromMemory(base
, (char *)p
+ offset
, size
, readonly
);
124 PyBuffer_FromObject(base
, offset
, size
)
129 PyBufferProcs
*pb
= base
->ob_type
->tp_as_buffer
;
132 pb
->bf_getreadbuffer
== NULL
||
133 pb
->bf_getsegcount
== NULL
)
135 PyErr_SetString(PyExc_TypeError
, "buffer object expected");
139 return _PyBuffer_FromObject(base
, offset
, size
,
140 pb
->bf_getreadbuffer
, 1);
144 PyBuffer_FromReadWriteObject(base
, offset
, size
)
149 PyBufferProcs
*pb
= base
->ob_type
->tp_as_buffer
;
152 pb
->bf_getwritebuffer
== NULL
||
153 pb
->bf_getsegcount
== NULL
)
155 PyErr_SetString(PyExc_TypeError
, "buffer object expected");
159 return _PyBuffer_FromObject(base
, offset
, size
,
160 (getreadbufferproc
)pb
->bf_getwritebuffer
,
165 PyBuffer_FromMemory(ptr
, size
)
169 return _PyBuffer_FromMemory(NULL
, ptr
, size
, 1);
173 PyBuffer_FromReadWriteMemory(ptr
, size
)
177 return _PyBuffer_FromMemory(NULL
, ptr
, size
, 0);
187 PyErr_SetString(PyExc_ValueError
,
188 "size must be zero or positive");
191 b
= (PyBufferObject
*)malloc(sizeof(*b
) + size
);
193 return PyErr_NoMemory();
194 b
->ob_type
= &PyBuffer_Type
;
195 _Py_NewReference((PyObject
*)b
);
198 b
->b_ptr
= (void *)(b
+ 1);
205 return (PyObject
*) b
;
212 PyBufferObject
*self
;
214 Py_XDECREF(self
->b_base
);
219 buffer_compare(self
, other
)
220 PyBufferObject
*self
;
221 PyBufferObject
*other
;
223 int len_self
= self
->b_size
;
224 int len_other
= other
->b_size
;
225 int min_len
= (len_self
< len_other
) ? len_self
: len_other
;
228 cmp
= memcmp(self
->b_ptr
, other
->b_ptr
, min_len
);
232 return (len_self
< len_other
) ? -1 : (len_self
> len_other
) ? 1 : 0;
237 PyBufferObject
*self
;
240 char *status
= self
->b_readonly
? "read-only" : "read-write";
242 if ( self
->b_base
== NULL
)
244 sprintf(buf
, "<%s buffer ptr %lx, size %d at %lx>",
252 sprintf(buf
, "<%s buffer for %lx, ptr %lx, size %d at %lx>",
260 return PyString_FromString(buf
);
265 PyBufferObject
*self
;
268 register unsigned char *p
;
272 if ( self
->b_hash
!= -1 )
276 if ( !self
->b_readonly
)
278 /* ### use different wording, since this is conditional? */
279 PyErr_SetString(PyExc_TypeError
, "unhashable type");
284 p
= (unsigned char *) self
->b_ptr
;
287 x
= (1000003*x
) ^ *p
++;
299 PyBufferObject
*self
;
301 return PyString_FromStringAndSize(self
->b_ptr
, self
->b_size
);
304 /* Sequence methods */
308 PyBufferObject
*self
;
314 buffer_concat(self
, other
)
315 PyBufferObject
*self
;
318 PyBufferProcs
*pb
= other
->ob_type
->tp_as_buffer
;
325 pb
->bf_getreadbuffer
== NULL
||
326 pb
->bf_getsegcount
== NULL
)
331 if ( (*pb
->bf_getsegcount
)(other
, NULL
) != 1 )
333 /* ### use a different exception type/message? */
334 PyErr_SetString(PyExc_TypeError
,
335 "single-segment buffer object expected");
339 /* optimize special case */
340 if ( self
->b_size
== 0 )
346 if ( (count
= (*pb
->bf_getreadbuffer
)(other
, 0, &p2
)) < 0 )
349 /* optimize special case */
353 return (PyObject
*)self
;
356 ob
= PyString_FromStringAndSize(NULL
, self
->b_size
+ count
);
357 p1
= PyString_AS_STRING(ob
);
358 memcpy(p1
, self
->b_ptr
, self
->b_size
);
359 memcpy(p1
+ self
->b_size
, p2
, count
);
361 /* there is an extra byte in the string object, so this is safe */
362 p1
[self
->b_size
+ count
] = '\0';
368 buffer_repeat(self
, count
)
369 PyBufferObject
*self
;
374 void *ptr
= self
->b_ptr
;
375 int size
= self
->b_size
;
379 ob
= PyString_FromStringAndSize(NULL
, size
* count
);
383 p
= PyString_AS_STRING(ob
);
386 memcpy(p
, ptr
, size
);
390 /* there is an extra byte in the string object, so this is safe */
397 buffer_item(self
, idx
)
398 PyBufferObject
*self
;
401 if ( idx
< 0 || idx
>= self
->b_size
)
403 PyErr_SetString(PyExc_IndexError
, "buffer index out of range");
406 return PyString_FromStringAndSize((char *)self
->b_ptr
+ idx
, 1);
410 buffer_slice(self
, left
, right
)
411 PyBufferObject
*self
;
419 if ( right
> self
->b_size
)
420 right
= self
->b_size
;
421 if ( left
== 0 && right
== self
->b_size
)
425 return (PyObject
*)self
;
429 return PyString_FromStringAndSize((char *)self
->b_ptr
+ left
,
434 buffer_ass_item(self
, idx
, other
)
435 PyBufferObject
*self
;
443 if ( self
->b_readonly
) {
444 PyErr_SetString(PyExc_TypeError
,
445 "buffer is read-only");
449 if (idx
< 0 || idx
>= self
->b_size
) {
450 PyErr_SetString(PyExc_IndexError
,
451 "buffer assignment index out of range");
455 pb
= other
? other
->ob_type
->tp_as_buffer
: NULL
;
457 pb
->bf_getreadbuffer
== NULL
||
458 pb
->bf_getsegcount
== NULL
)
463 if ( (*pb
->bf_getsegcount
)(other
, NULL
) != 1 )
465 /* ### use a different exception type/message? */
466 PyErr_SetString(PyExc_TypeError
,
467 "single-segment buffer object expected");
471 if ( (count
= (*pb
->bf_getreadbuffer
)(other
, 0, &p
)) < 0 )
474 PyErr_SetString(PyExc_TypeError
,
475 "right operand must be a single byte");
479 ((char *)self
->b_ptr
)[idx
] = *(char *)p
;
484 buffer_ass_slice(self
, left
, right
, other
)
485 PyBufferObject
*self
;
495 if ( self
->b_readonly
) {
496 PyErr_SetString(PyExc_TypeError
,
497 "buffer is read-only");
501 pb
= other
? other
->ob_type
->tp_as_buffer
: NULL
;
503 pb
->bf_getreadbuffer
== NULL
||
504 pb
->bf_getsegcount
== NULL
)
509 if ( (*pb
->bf_getsegcount
)(other
, NULL
) != 1 )
511 /* ### use a different exception type/message? */
512 PyErr_SetString(PyExc_TypeError
,
513 "single-segment buffer object expected");
516 if ( (count
= (*pb
->bf_getreadbuffer
)(other
, 0, &p
)) < 0 )
521 else if ( left
> self
->b_size
)
525 else if ( right
> self
->b_size
)
526 right
= self
->b_size
;
527 slice_len
= right
- left
;
529 if ( count
!= slice_len
) {
532 "right operand length must match slice length");
537 memcpy((char *)self
->b_ptr
+ left
, p
, slice_len
);
545 buffer_getreadbuf(self
, idx
, pp
)
546 PyBufferObject
*self
;
551 PyErr_SetString(PyExc_SystemError
,
552 "accessing non-existent buffer segment");
560 buffer_getwritebuf(self
, idx
, pp
)
561 PyBufferObject
*self
;
565 if ( self
->b_readonly
)
567 PyErr_SetString(PyExc_TypeError
, "buffer is read-only");
570 return buffer_getreadbuf(self
, idx
, pp
);
574 buffer_getsegcount(self
, lenp
)
575 PyBufferObject
*self
;
579 *lenp
= self
->b_size
;
584 buffer_getcharbuf(self
, idx
, pp
)
585 PyBufferObject
*self
;
590 PyErr_SetString(PyExc_SystemError
,
591 "accessing non-existent buffer segment");
594 *pp
= (const char *)self
->b_ptr
;
599 static PySequenceMethods buffer_as_sequence
= {
600 (inquiry
)buffer_length
, /*sq_length*/
601 (binaryfunc
)buffer_concat
, /*sq_concat*/
602 (intargfunc
)buffer_repeat
, /*sq_repeat*/
603 (intargfunc
)buffer_item
, /*sq_item*/
604 (intintargfunc
)buffer_slice
, /*sq_slice*/
605 (intobjargproc
)buffer_ass_item
, /*sq_ass_item*/
606 (intintobjargproc
)buffer_ass_slice
, /*sq_ass_slice*/
609 static PyBufferProcs buffer_as_buffer
= {
610 (getreadbufferproc
)buffer_getreadbuf
,
611 (getwritebufferproc
)buffer_getwritebuf
,
612 (getsegcountproc
)buffer_getsegcount
,
613 (getcharbufferproc
)buffer_getcharbuf
,
616 PyTypeObject PyBuffer_Type
= {
617 PyObject_HEAD_INIT(&PyType_Type
)
620 sizeof(PyBufferObject
),
622 (destructor
)buffer_dealloc
, /*tp_dealloc*/
626 (cmpfunc
)buffer_compare
, /*tp_compare*/
627 (reprfunc
)buffer_repr
, /*tp_repr*/
629 &buffer_as_sequence
, /*tp_as_sequence*/
631 (hashfunc
)buffer_hash
, /*tp_hash*/
633 (reprfunc
)buffer_str
, /*tp_str*/
636 &buffer_as_buffer
, /*tp_as_buffer*/
637 Py_TPFLAGS_DEFAULT
, /*tp_flags*/