blob: d07da084213797141c2cb85d751973be378c03b4 [file] [log] [blame]
Alexandre Vassalotti77250f42008-05-06 19:48:38 +00001#include "Python.h"
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002#include "structmember.h" /* for offsetof() */
3#include "_iomodule.h"
Alexandre Vassalotti77250f42008-05-06 19:48:38 +00004
5typedef struct {
6 PyObject_HEAD
7 char *buf;
8 Py_ssize_t pos;
9 Py_ssize_t string_size;
10 size_t buf_size;
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +000011 PyObject *dict;
12 PyObject *weakreflist;
Antoine Pitrou972ee132010-09-06 18:48:21 +000013 Py_ssize_t exports;
Antoine Pitroucc66a732014-07-29 19:41:11 -040014 /** If `initvalue' != NULL, `buf' is a read-only pointer into the PyBytes
15 * referenced by `initvalue'. It must be copied prior to mutation, and
16 * released during finalization */
17 PyObject *initvalue;
Benjamin Peterson680bf1a2009-06-12 02:07:12 +000018} bytesio;
Alexandre Vassalotti77250f42008-05-06 19:48:38 +000019
Antoine Pitrou972ee132010-09-06 18:48:21 +000020typedef struct {
21 PyObject_HEAD
22 bytesio *source;
23} bytesiobuf;
24
25
Antoine Pitroucc66a732014-07-29 19:41:11 -040026#define CHECK_CLOSED(self, ret) \
Alexandre Vassalotti77250f42008-05-06 19:48:38 +000027 if ((self)->buf == NULL) { \
28 PyErr_SetString(PyExc_ValueError, \
29 "I/O operation on closed file."); \
Antoine Pitroucc66a732014-07-29 19:41:11 -040030 return ret; \
Alexandre Vassalotti77250f42008-05-06 19:48:38 +000031 }
32
Antoine Pitrou972ee132010-09-06 18:48:21 +000033#define CHECK_EXPORTS(self) \
34 if ((self)->exports > 0) { \
35 PyErr_SetString(PyExc_BufferError, \
36 "Existing exports of data: object cannot be re-sized"); \
37 return NULL; \
38 }
39
Antoine Pitroucc66a732014-07-29 19:41:11 -040040/* Ensure we have a buffer suitable for writing, in the case that an initvalue
41 * object was provided, and we're currently borrowing its buffer. `size'
42 * indicates the new buffer size allocated as part of unsharing, to avoid a
43 * redundant reallocation caused by any subsequent mutation. `truncate'
44 * indicates whether truncation should occur if `size` < self->string_size.
45 *
46 * Do nothing if the buffer wasn't shared. Returns 0 on success, or sets an
47 * exception and returns -1 on failure. Existing state is preserved on failure.
48 */
49static int
50unshare(bytesio *self, size_t preferred_size, int truncate)
51{
52 if (self->initvalue) {
53 Py_ssize_t copy_size;
54 char *new_buf;
55
56 if((! truncate) && preferred_size < self->string_size) {
57 preferred_size = self->string_size;
58 }
59
60 new_buf = (char *)PyMem_Malloc(preferred_size);
61 if (new_buf == NULL) {
62 PyErr_NoMemory();
63 return -1;
64 }
65
66 copy_size = self->string_size;
67 if (copy_size > preferred_size) {
68 copy_size = preferred_size;
69 }
70
71 memcpy(new_buf, self->buf, copy_size);
72 Py_CLEAR(self->initvalue);
73 self->buf = new_buf;
74 self->buf_size = preferred_size;
75 self->string_size = (Py_ssize_t) copy_size;
76 }
77 return 0;
78}
Antoine Pitrou972ee132010-09-06 18:48:21 +000079
Alexandre Vassalotti77250f42008-05-06 19:48:38 +000080/* Internal routine to get a line from the buffer of a BytesIO
81 object. Returns the length between the current position to the
82 next newline character. */
83static Py_ssize_t
Serhiy Storchakad7728ca2014-08-14 22:26:38 +030084scan_eol(bytesio *self, Py_ssize_t len)
Alexandre Vassalotti77250f42008-05-06 19:48:38 +000085{
Serhiy Storchakad7728ca2014-08-14 22:26:38 +030086 const char *start, *n;
87 Py_ssize_t maxlen;
Alexandre Vassalotti77250f42008-05-06 19:48:38 +000088
89 assert(self->buf != NULL);
90
91 /* Move to the end of the line, up to the end of the string, s. */
Serhiy Storchakad7728ca2014-08-14 22:26:38 +030092 start = self->buf + self->pos;
93 maxlen = self->string_size - self->pos;
94 if (len < 0 || len > maxlen)
95 len = maxlen;
Alexandre Vassalotti77250f42008-05-06 19:48:38 +000096
Serhiy Storchakad7728ca2014-08-14 22:26:38 +030097 if (len) {
98 n = memchr(start, '\n', len);
99 if (n)
100 /* Get the length from the current position to the end of
101 the line. */
102 len = n - start + 1;
103 }
Alexandre Vassalotti77250f42008-05-06 19:48:38 +0000104 assert(len >= 0);
105 assert(self->pos < PY_SSIZE_T_MAX - len);
Alexandre Vassalotti77250f42008-05-06 19:48:38 +0000106
107 return len;
108}
109
110/* Internal routine for changing the size of the buffer of BytesIO objects.
111 The caller should ensure that the 'size' argument is non-negative. Returns
112 0 on success, -1 otherwise. */
113static int
Benjamin Peterson680bf1a2009-06-12 02:07:12 +0000114resize_buffer(bytesio *self, size_t size)
Alexandre Vassalotti77250f42008-05-06 19:48:38 +0000115{
116 /* Here, unsigned types are used to avoid dealing with signed integer
117 overflow, which is undefined in C. */
118 size_t alloc = self->buf_size;
119 char *new_buf = NULL;
120
121 assert(self->buf != NULL);
122
123 /* For simplicity, stay in the range of the signed type. Anyway, Python
124 doesn't allow strings to be longer than this. */
125 if (size > PY_SSIZE_T_MAX)
126 goto overflow;
127
128 if (size < alloc / 2) {
129 /* Major downsize; resize down to exact size. */
130 alloc = size + 1;
131 }
132 else if (size < alloc) {
133 /* Within allocated size; quick exit */
134 return 0;
135 }
136 else if (size <= alloc * 1.125) {
137 /* Moderate upsize; overallocate similar to list_resize() */
138 alloc = size + (size >> 3) + (size < 9 ? 3 : 6);
139 }
140 else {
141 /* Major upsize; resize up to exact size */
142 alloc = size + 1;
143 }
144
145 if (alloc > ((size_t)-1) / sizeof(char))
146 goto overflow;
147 new_buf = (char *)PyMem_Realloc(self->buf, alloc * sizeof(char));
148 if (new_buf == NULL) {
149 PyErr_NoMemory();
150 return -1;
151 }
152 self->buf_size = alloc;
153 self->buf = new_buf;
154
155 return 0;
156
157 overflow:
158 PyErr_SetString(PyExc_OverflowError,
159 "new buffer size too large");
160 return -1;
161}
162
163/* Internal routine for writing a string of bytes to the buffer of a BytesIO
Antoine Pitrou1d857452012-09-05 20:11:49 +0200164 object. Returns the number of bytes written, or -1 on error. */
Alexandre Vassalotti77250f42008-05-06 19:48:38 +0000165static Py_ssize_t
Benjamin Peterson680bf1a2009-06-12 02:07:12 +0000166write_bytes(bytesio *self, const char *bytes, Py_ssize_t len)
Alexandre Vassalotti77250f42008-05-06 19:48:38 +0000167{
Antoine Pitroucc66a732014-07-29 19:41:11 -0400168 size_t desired;
169
Alexandre Vassalotti77250f42008-05-06 19:48:38 +0000170 assert(self->buf != NULL);
171 assert(self->pos >= 0);
172 assert(len >= 0);
173
Antoine Pitroucc66a732014-07-29 19:41:11 -0400174 desired = (size_t)self->pos + len;
175 if (unshare(self, desired, 0) < 0) {
176 return -1;
177 }
178
179 if (desired > self->buf_size) {
Alexandre Vassalotti1bfe9dc82008-05-07 01:44:31 +0000180 if (resize_buffer(self, (size_t)self->pos + len) < 0)
Alexandre Vassalotti77250f42008-05-06 19:48:38 +0000181 return -1;
182 }
183
184 if (self->pos > self->string_size) {
185 /* In case of overseek, pad with null bytes the buffer region between
186 the end of stream and the current position.
187
188 0 lo string_size hi
189 | |<---used--->|<----------available----------->|
190 | | <--to pad-->|<---to write---> |
191 0 buf position
192 */
193 memset(self->buf + self->string_size, '\0',
194 (self->pos - self->string_size) * sizeof(char));
195 }
196
197 /* Copy the data to the internal buffer, overwriting some of the existing
198 data if self->pos < self->string_size. */
199 memcpy(self->buf + self->pos, bytes, len);
200 self->pos += len;
201
202 /* Set the new length of the internal string if it has changed. */
203 if (self->string_size < self->pos) {
204 self->string_size = self->pos;
205 }
206
207 return len;
208}
209
Antoine Pitroucc66a732014-07-29 19:41:11 -0400210/* Release or free any existing buffer, and place the BytesIO in the closed
211 * state. */
212static void
213reset(bytesio *self)
214{
215 if (self->initvalue) {
216 Py_CLEAR(self->initvalue);
217 } else if (self->buf) {
218 PyMem_Free(self->buf);
219 }
220 self->buf = NULL;
221 self->string_size = 0;
222 self->pos = 0;
223}
224
225/* Reinitialize with a new heap-allocated buffer of size `size`. Returns 0 on
226 * success, or sets an exception and returns -1 on failure. Existing state is
227 * preserved on failure. */
228static int
229reinit_private(bytesio *self, Py_ssize_t size)
230{
231 char *tmp = (char *)PyMem_Malloc(size);
232 if (tmp == NULL) {
233 PyErr_NoMemory();
234 return -1;
235 }
236 reset(self);
237 self->buf = tmp;
238 self->buf_size = size;
239 return 0;
240}
241
242/* Internal version of BytesIO.__init__; resets the object to its initial
243 * (closed) state before repopulating it, optionally by sharing a PyBytes
244 * buffer provided by `initvalue'. Returns 0 on success, or sets an exception
245 * and returns -1 on failure. */
246static int
247reinit(bytesio *self, PyObject *initvalue)
248{
249 CHECK_CLOSED(self, -1);
250
251 if (initvalue == NULL || initvalue == Py_None) {
252 if (reinit_private(self, 0) < 0) {
253 return -1;
254 }
255 } else if (PyBytes_CheckExact(initvalue)) {
256 reset(self);
257 Py_INCREF(initvalue);
258 self->initvalue = initvalue;
259 self->buf = PyBytes_AS_STRING(initvalue);
260 self->buf_size = PyBytes_GET_SIZE(initvalue);
261 self->string_size = PyBytes_GET_SIZE(initvalue);
262 } else {
263 Py_buffer buf;
264 if (PyObject_GetBuffer(initvalue, &buf, PyBUF_CONTIG_RO) < 0) {
265 return -1;
266 }
267 if (reinit_private(self, buf.len) < 0) {
268 PyBuffer_Release(&buf);
269 return -1;
270 }
271 memcpy(self->buf, buf.buf, buf.len);
272 self->string_size = buf.len;
273 PyBuffer_Release(&buf);
274 }
275 return 0;
276}
277
Alexandre Vassalotti77250f42008-05-06 19:48:38 +0000278static PyObject *
Benjamin Peterson680bf1a2009-06-12 02:07:12 +0000279bytesio_get_closed(bytesio *self)
Alexandre Vassalotti77250f42008-05-06 19:48:38 +0000280{
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000281 if (self->buf == NULL) {
Alexandre Vassalotti77250f42008-05-06 19:48:38 +0000282 Py_RETURN_TRUE;
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000283 }
284 else {
Alexandre Vassalotti77250f42008-05-06 19:48:38 +0000285 Py_RETURN_FALSE;
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000286 }
Alexandre Vassalotti77250f42008-05-06 19:48:38 +0000287}
288
Antoine Pitrou1d857452012-09-05 20:11:49 +0200289PyDoc_STRVAR(readable_doc,
290"readable() -> bool. Returns True if the IO object can be read.");
291
292PyDoc_STRVAR(writable_doc,
293"writable() -> bool. Returns True if the IO object can be written.");
294
295PyDoc_STRVAR(seekable_doc,
296"seekable() -> bool. Returns True if the IO object can be seeked.");
297
Alexandre Vassalotti77250f42008-05-06 19:48:38 +0000298/* Generic getter for the writable, readable and seekable properties */
299static PyObject *
Antoine Pitrou1d857452012-09-05 20:11:49 +0200300return_not_closed(bytesio *self)
Alexandre Vassalotti77250f42008-05-06 19:48:38 +0000301{
Antoine Pitroucc66a732014-07-29 19:41:11 -0400302 CHECK_CLOSED(self, NULL);
Alexandre Vassalotti77250f42008-05-06 19:48:38 +0000303 Py_RETURN_TRUE;
304}
305
306PyDoc_STRVAR(flush_doc,
307"flush() -> None. Does nothing.");
308
309static PyObject *
Benjamin Peterson680bf1a2009-06-12 02:07:12 +0000310bytesio_flush(bytesio *self)
Alexandre Vassalotti77250f42008-05-06 19:48:38 +0000311{
Antoine Pitroucc66a732014-07-29 19:41:11 -0400312 CHECK_CLOSED(self, NULL);
Alexandre Vassalotti77250f42008-05-06 19:48:38 +0000313 Py_RETURN_NONE;
314}
315
Antoine Pitrou972ee132010-09-06 18:48:21 +0000316PyDoc_STRVAR(getbuffer_doc,
317"getbuffer() -> bytes.\n"
318"\n"
319"Get a read-write view over the contents of the BytesIO object.");
320
321static PyObject *
322bytesio_getbuffer(bytesio *self)
323{
324 PyTypeObject *type = &_PyBytesIOBuffer_Type;
325 bytesiobuf *buf;
326 PyObject *view;
327
Antoine Pitroucc66a732014-07-29 19:41:11 -0400328 CHECK_CLOSED(self, NULL);
Antoine Pitrou972ee132010-09-06 18:48:21 +0000329
330 buf = (bytesiobuf *) type->tp_alloc(type, 0);
331 if (buf == NULL)
332 return NULL;
333 Py_INCREF(self);
334 buf->source = self;
335 view = PyMemoryView_FromObject((PyObject *) buf);
336 Py_DECREF(buf);
337 return view;
338}
339
Alexandre Vassalotti77250f42008-05-06 19:48:38 +0000340PyDoc_STRVAR(getval_doc,
Alexandre Vassalotti10dfc1e2008-05-08 01:34:41 +0000341"getvalue() -> bytes.\n"
Alexandre Vassalotti77250f42008-05-06 19:48:38 +0000342"\n"
343"Retrieve the entire contents of the BytesIO object.");
344
345static PyObject *
Benjamin Peterson680bf1a2009-06-12 02:07:12 +0000346bytesio_getvalue(bytesio *self)
Alexandre Vassalotti77250f42008-05-06 19:48:38 +0000347{
Antoine Pitroucc66a732014-07-29 19:41:11 -0400348 CHECK_CLOSED(self, NULL);
Christian Heimes72b710a2008-05-26 13:28:38 +0000349 return PyBytes_FromStringAndSize(self->buf, self->string_size);
Alexandre Vassalotti77250f42008-05-06 19:48:38 +0000350}
351
352PyDoc_STRVAR(isatty_doc,
353"isatty() -> False.\n"
354"\n"
355"Always returns False since BytesIO objects are not connected\n"
356"to a tty-like device.");
357
358static PyObject *
Benjamin Peterson680bf1a2009-06-12 02:07:12 +0000359bytesio_isatty(bytesio *self)
Alexandre Vassalotti77250f42008-05-06 19:48:38 +0000360{
Antoine Pitroucc66a732014-07-29 19:41:11 -0400361 CHECK_CLOSED(self, NULL);
Alexandre Vassalotti77250f42008-05-06 19:48:38 +0000362 Py_RETURN_FALSE;
363}
364
365PyDoc_STRVAR(tell_doc,
366"tell() -> current file position, an integer\n");
367
368static PyObject *
Benjamin Peterson680bf1a2009-06-12 02:07:12 +0000369bytesio_tell(bytesio *self)
Alexandre Vassalotti77250f42008-05-06 19:48:38 +0000370{
Antoine Pitroucc66a732014-07-29 19:41:11 -0400371 CHECK_CLOSED(self, NULL);
Alexandre Vassalotti77250f42008-05-06 19:48:38 +0000372 return PyLong_FromSsize_t(self->pos);
373}
374
375PyDoc_STRVAR(read_doc,
376"read([size]) -> read at most size bytes, returned as a string.\n"
377"\n"
378"If the size argument is negative, read until EOF is reached.\n"
379"Return an empty string at EOF.");
380
381static PyObject *
Benjamin Peterson680bf1a2009-06-12 02:07:12 +0000382bytesio_read(bytesio *self, PyObject *args)
Alexandre Vassalotti77250f42008-05-06 19:48:38 +0000383{
384 Py_ssize_t size, n;
385 char *output;
386 PyObject *arg = Py_None;
387
Antoine Pitroucc66a732014-07-29 19:41:11 -0400388 CHECK_CLOSED(self, NULL);
Alexandre Vassalotti77250f42008-05-06 19:48:38 +0000389
390 if (!PyArg_ParseTuple(args, "|O:read", &arg))
391 return NULL;
392
393 if (PyLong_Check(arg)) {
394 size = PyLong_AsSsize_t(arg);
Benjamin Petersona8a93042008-09-30 02:18:09 +0000395 if (size == -1 && PyErr_Occurred())
396 return NULL;
Alexandre Vassalotti77250f42008-05-06 19:48:38 +0000397 }
398 else if (arg == Py_None) {
399 /* Read until EOF is reached, by default. */
400 size = -1;
401 }
402 else {
403 PyErr_Format(PyExc_TypeError, "integer argument expected, got '%s'",
404 Py_TYPE(arg)->tp_name);
405 return NULL;
406 }
407
408 /* adjust invalid sizes */
409 n = self->string_size - self->pos;
410 if (size < 0 || size > n) {
411 size = n;
412 if (size < 0)
413 size = 0;
414 }
415
416 assert(self->buf != NULL);
417 output = self->buf + self->pos;
418 self->pos += size;
419
Christian Heimes72b710a2008-05-26 13:28:38 +0000420 return PyBytes_FromStringAndSize(output, size);
Alexandre Vassalotti77250f42008-05-06 19:48:38 +0000421}
422
423
424PyDoc_STRVAR(read1_doc,
425"read1(size) -> read at most size bytes, returned as a string.\n"
426"\n"
427"If the size argument is negative or omitted, read until EOF is reached.\n"
428"Return an empty string at EOF.");
429
430static PyObject *
Benjamin Peterson680bf1a2009-06-12 02:07:12 +0000431bytesio_read1(bytesio *self, PyObject *n)
Alexandre Vassalotti77250f42008-05-06 19:48:38 +0000432{
433 PyObject *arg, *res;
434
435 arg = PyTuple_Pack(1, n);
436 if (arg == NULL)
437 return NULL;
438 res = bytesio_read(self, arg);
439 Py_DECREF(arg);
440 return res;
441}
442
443PyDoc_STRVAR(readline_doc,
444"readline([size]) -> next line from the file, as a string.\n"
445"\n"
446"Retain newline. A non-negative size argument limits the maximum\n"
447"number of bytes to return (an incomplete line may be returned then).\n"
448"Return an empty string at EOF.\n");
449
450static PyObject *
Benjamin Peterson680bf1a2009-06-12 02:07:12 +0000451bytesio_readline(bytesio *self, PyObject *args)
Alexandre Vassalotti77250f42008-05-06 19:48:38 +0000452{
453 Py_ssize_t size, n;
454 char *output;
455 PyObject *arg = Py_None;
456
Antoine Pitroucc66a732014-07-29 19:41:11 -0400457 CHECK_CLOSED(self, NULL);
Alexandre Vassalotti77250f42008-05-06 19:48:38 +0000458
459 if (!PyArg_ParseTuple(args, "|O:readline", &arg))
460 return NULL;
461
462 if (PyLong_Check(arg)) {
463 size = PyLong_AsSsize_t(arg);
Benjamin Petersona8a93042008-09-30 02:18:09 +0000464 if (size == -1 && PyErr_Occurred())
465 return NULL;
Alexandre Vassalotti77250f42008-05-06 19:48:38 +0000466 }
467 else if (arg == Py_None) {
468 /* No size limit, by default. */
469 size = -1;
470 }
471 else {
472 PyErr_Format(PyExc_TypeError, "integer argument expected, got '%s'",
473 Py_TYPE(arg)->tp_name);
474 return NULL;
475 }
476
Serhiy Storchakad7728ca2014-08-14 22:26:38 +0300477 n = scan_eol(self, size);
Alexandre Vassalotti77250f42008-05-06 19:48:38 +0000478
Serhiy Storchakad7728ca2014-08-14 22:26:38 +0300479 output = self->buf + self->pos;
480 self->pos += n;
Christian Heimes72b710a2008-05-26 13:28:38 +0000481 return PyBytes_FromStringAndSize(output, n);
Alexandre Vassalotti77250f42008-05-06 19:48:38 +0000482}
483
484PyDoc_STRVAR(readlines_doc,
485"readlines([size]) -> list of strings, each a line from the file.\n"
486"\n"
487"Call readline() repeatedly and return a list of the lines so read.\n"
488"The optional size argument, if given, is an approximate bound on the\n"
489"total number of bytes in the lines returned.\n");
490
491static PyObject *
Benjamin Peterson680bf1a2009-06-12 02:07:12 +0000492bytesio_readlines(bytesio *self, PyObject *args)
Alexandre Vassalotti77250f42008-05-06 19:48:38 +0000493{
494 Py_ssize_t maxsize, size, n;
495 PyObject *result, *line;
496 char *output;
497 PyObject *arg = Py_None;
498
Antoine Pitroucc66a732014-07-29 19:41:11 -0400499 CHECK_CLOSED(self, NULL);
Alexandre Vassalotti77250f42008-05-06 19:48:38 +0000500
501 if (!PyArg_ParseTuple(args, "|O:readlines", &arg))
502 return NULL;
503
504 if (PyLong_Check(arg)) {
505 maxsize = PyLong_AsSsize_t(arg);
Benjamin Petersona8a93042008-09-30 02:18:09 +0000506 if (maxsize == -1 && PyErr_Occurred())
507 return NULL;
Alexandre Vassalotti77250f42008-05-06 19:48:38 +0000508 }
509 else if (arg == Py_None) {
510 /* No size limit, by default. */
511 maxsize = -1;
512 }
513 else {
514 PyErr_Format(PyExc_TypeError, "integer argument expected, got '%s'",
515 Py_TYPE(arg)->tp_name);
516 return NULL;
517 }
518
519 size = 0;
520 result = PyList_New(0);
521 if (!result)
522 return NULL;
523
Serhiy Storchakad7728ca2014-08-14 22:26:38 +0300524 output = self->buf + self->pos;
525 while ((n = scan_eol(self, -1)) != 0) {
526 self->pos += n;
Christian Heimes72b710a2008-05-26 13:28:38 +0000527 line = PyBytes_FromStringAndSize(output, n);
Alexandre Vassalotti77250f42008-05-06 19:48:38 +0000528 if (!line)
529 goto on_error;
530 if (PyList_Append(result, line) == -1) {
531 Py_DECREF(line);
532 goto on_error;
533 }
534 Py_DECREF(line);
535 size += n;
536 if (maxsize > 0 && size >= maxsize)
537 break;
Serhiy Storchakad7728ca2014-08-14 22:26:38 +0300538 output += n;
Alexandre Vassalotti77250f42008-05-06 19:48:38 +0000539 }
540 return result;
541
542 on_error:
543 Py_DECREF(result);
544 return NULL;
545}
546
547PyDoc_STRVAR(readinto_doc,
Alexandre Vassalotti10dfc1e2008-05-08 01:34:41 +0000548"readinto(bytearray) -> int. Read up to len(b) bytes into b.\n"
Alexandre Vassalotti77250f42008-05-06 19:48:38 +0000549"\n"
550"Returns number of bytes read (0 for EOF), or None if the object\n"
551"is set not to block as has no data to read.");
552
553static PyObject *
Benjamin Peterson680bf1a2009-06-12 02:07:12 +0000554bytesio_readinto(bytesio *self, PyObject *buffer)
Alexandre Vassalotti77250f42008-05-06 19:48:38 +0000555{
556 void *raw_buffer;
Benjamin Petersonfa735552010-11-20 17:24:04 +0000557 Py_ssize_t len, n;
Alexandre Vassalotti77250f42008-05-06 19:48:38 +0000558
Antoine Pitroucc66a732014-07-29 19:41:11 -0400559 CHECK_CLOSED(self, NULL);
Alexandre Vassalotti77250f42008-05-06 19:48:38 +0000560
561 if (PyObject_AsWriteBuffer(buffer, &raw_buffer, &len) == -1)
562 return NULL;
563
Benjamin Petersonfa735552010-11-20 17:24:04 +0000564 /* adjust invalid sizes */
565 n = self->string_size - self->pos;
566 if (len > n) {
567 len = n;
568 if (len < 0)
569 len = 0;
570 }
Alexandre Vassalotti77250f42008-05-06 19:48:38 +0000571
572 memcpy(raw_buffer, self->buf + self->pos, len);
573 assert(self->pos + len < PY_SSIZE_T_MAX);
574 assert(len >= 0);
575 self->pos += len;
576
577 return PyLong_FromSsize_t(len);
578}
579
580PyDoc_STRVAR(truncate_doc,
581"truncate([size]) -> int. Truncate the file to at most size bytes.\n"
582"\n"
583"Size defaults to the current file position, as returned by tell().\n"
Antoine Pitrou905a2ff2010-01-31 22:47:27 +0000584"The current file position is unchanged. Returns the new size.\n");
Alexandre Vassalotti77250f42008-05-06 19:48:38 +0000585
586static PyObject *
Benjamin Peterson680bf1a2009-06-12 02:07:12 +0000587bytesio_truncate(bytesio *self, PyObject *args)
Alexandre Vassalotti77250f42008-05-06 19:48:38 +0000588{
589 Py_ssize_t size;
590 PyObject *arg = Py_None;
591
Antoine Pitroucc66a732014-07-29 19:41:11 -0400592 CHECK_CLOSED(self, NULL);
Antoine Pitrou972ee132010-09-06 18:48:21 +0000593 CHECK_EXPORTS(self);
Alexandre Vassalotti77250f42008-05-06 19:48:38 +0000594
595 if (!PyArg_ParseTuple(args, "|O:truncate", &arg))
596 return NULL;
597
598 if (PyLong_Check(arg)) {
599 size = PyLong_AsSsize_t(arg);
Benjamin Petersona8a93042008-09-30 02:18:09 +0000600 if (size == -1 && PyErr_Occurred())
601 return NULL;
Alexandre Vassalotti77250f42008-05-06 19:48:38 +0000602 }
603 else if (arg == Py_None) {
604 /* Truncate to current position if no argument is passed. */
605 size = self->pos;
606 }
607 else {
608 PyErr_Format(PyExc_TypeError, "integer argument expected, got '%s'",
609 Py_TYPE(arg)->tp_name);
610 return NULL;
611 }
612
613 if (size < 0) {
614 PyErr_Format(PyExc_ValueError,
615 "negative size value %zd", size);
616 return NULL;
617 }
618
Antoine Pitroucc66a732014-07-29 19:41:11 -0400619 if (unshare(self, size, 1) < 0) {
620 return NULL;
621 }
622
Alexandre Vassalotti77250f42008-05-06 19:48:38 +0000623 if (size < self->string_size) {
624 self->string_size = size;
625 if (resize_buffer(self, size) < 0)
626 return NULL;
627 }
Alexandre Vassalotti77250f42008-05-06 19:48:38 +0000628
629 return PyLong_FromSsize_t(size);
630}
631
632static PyObject *
Benjamin Peterson680bf1a2009-06-12 02:07:12 +0000633bytesio_iternext(bytesio *self)
Alexandre Vassalotti77250f42008-05-06 19:48:38 +0000634{
Serhiy Storchakad7728ca2014-08-14 22:26:38 +0300635 const char *next;
Alexandre Vassalotti77250f42008-05-06 19:48:38 +0000636 Py_ssize_t n;
637
Antoine Pitroucc66a732014-07-29 19:41:11 -0400638 CHECK_CLOSED(self, NULL);
Alexandre Vassalotti77250f42008-05-06 19:48:38 +0000639
Serhiy Storchakad7728ca2014-08-14 22:26:38 +0300640 n = scan_eol(self, -1);
Alexandre Vassalotti77250f42008-05-06 19:48:38 +0000641
Serhiy Storchakad7728ca2014-08-14 22:26:38 +0300642 if (n == 0)
Alexandre Vassalotti77250f42008-05-06 19:48:38 +0000643 return NULL;
644
Serhiy Storchakad7728ca2014-08-14 22:26:38 +0300645 next = self->buf + self->pos;
646 self->pos += n;
Christian Heimes72b710a2008-05-26 13:28:38 +0000647 return PyBytes_FromStringAndSize(next, n);
Alexandre Vassalotti77250f42008-05-06 19:48:38 +0000648}
649
650PyDoc_STRVAR(seek_doc,
651"seek(pos, whence=0) -> int. Change stream position.\n"
652"\n"
653"Seek to byte offset pos relative to position indicated by whence:\n"
654" 0 Start of stream (the default). pos should be >= 0;\n"
655" 1 Current position - pos may be negative;\n"
656" 2 End of stream - pos usually negative.\n"
657"Returns the new absolute position.");
658
659static PyObject *
Benjamin Peterson680bf1a2009-06-12 02:07:12 +0000660bytesio_seek(bytesio *self, PyObject *args)
Alexandre Vassalotti77250f42008-05-06 19:48:38 +0000661{
662 Py_ssize_t pos;
663 int mode = 0;
664
Antoine Pitroucc66a732014-07-29 19:41:11 -0400665 CHECK_CLOSED(self, NULL);
Alexandre Vassalotti77250f42008-05-06 19:48:38 +0000666
667 if (!PyArg_ParseTuple(args, "n|i:seek", &pos, &mode))
668 return NULL;
669
670 if (pos < 0 && mode == 0) {
671 PyErr_Format(PyExc_ValueError,
672 "negative seek value %zd", pos);
673 return NULL;
674 }
675
676 /* mode 0: offset relative to beginning of the string.
677 mode 1: offset relative to current position.
678 mode 2: offset relative the end of the string. */
679 if (mode == 1) {
680 if (pos > PY_SSIZE_T_MAX - self->pos) {
681 PyErr_SetString(PyExc_OverflowError,
682 "new position too large");
683 return NULL;
684 }
685 pos += self->pos;
686 }
687 else if (mode == 2) {
688 if (pos > PY_SSIZE_T_MAX - self->string_size) {
689 PyErr_SetString(PyExc_OverflowError,
690 "new position too large");
691 return NULL;
692 }
693 pos += self->string_size;
694 }
695 else if (mode != 0) {
696 PyErr_Format(PyExc_ValueError,
697 "invalid whence (%i, should be 0, 1 or 2)", mode);
698 return NULL;
699 }
700
701 if (pos < 0)
702 pos = 0;
703 self->pos = pos;
704
705 return PyLong_FromSsize_t(self->pos);
706}
707
708PyDoc_STRVAR(write_doc,
Alexandre Vassalotti10dfc1e2008-05-08 01:34:41 +0000709"write(bytes) -> int. Write bytes to file.\n"
Alexandre Vassalotti77250f42008-05-06 19:48:38 +0000710"\n"
711"Return the number of bytes written.");
712
713static PyObject *
Benjamin Peterson680bf1a2009-06-12 02:07:12 +0000714bytesio_write(bytesio *self, PyObject *obj)
Alexandre Vassalotti77250f42008-05-06 19:48:38 +0000715{
Alexandre Vassalotti77250f42008-05-06 19:48:38 +0000716 Py_ssize_t n = 0;
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000717 Py_buffer buf;
718 PyObject *result = NULL;
Alexandre Vassalotti77250f42008-05-06 19:48:38 +0000719
Antoine Pitroucc66a732014-07-29 19:41:11 -0400720 CHECK_CLOSED(self, NULL);
Antoine Pitrou972ee132010-09-06 18:48:21 +0000721 CHECK_EXPORTS(self);
Alexandre Vassalotti77250f42008-05-06 19:48:38 +0000722
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000723 if (PyObject_GetBuffer(obj, &buf, PyBUF_CONTIG_RO) < 0)
Alexandre Vassalotti77250f42008-05-06 19:48:38 +0000724 return NULL;
725
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000726 if (buf.len != 0)
727 n = write_bytes(self, buf.buf, buf.len);
728 if (n >= 0)
729 result = PyLong_FromSsize_t(n);
Alexandre Vassalotti77250f42008-05-06 19:48:38 +0000730
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000731 PyBuffer_Release(&buf);
732 return result;
Alexandre Vassalotti77250f42008-05-06 19:48:38 +0000733}
734
735PyDoc_STRVAR(writelines_doc,
Alexandre Vassalotti7d060892008-05-07 01:47:37 +0000736"writelines(sequence_of_strings) -> None. Write strings to the file.\n"
Alexandre Vassalotti77250f42008-05-06 19:48:38 +0000737"\n"
Alexandre Vassalotti7d060892008-05-07 01:47:37 +0000738"Note that newlines are not added. The sequence can be any iterable\n"
739"object producing strings. This is equivalent to calling write() for\n"
740"each string.");
Alexandre Vassalotti77250f42008-05-06 19:48:38 +0000741
742static PyObject *
Benjamin Peterson680bf1a2009-06-12 02:07:12 +0000743bytesio_writelines(bytesio *self, PyObject *v)
Alexandre Vassalotti77250f42008-05-06 19:48:38 +0000744{
745 PyObject *it, *item;
746 PyObject *ret;
747
Antoine Pitroucc66a732014-07-29 19:41:11 -0400748 CHECK_CLOSED(self, NULL);
Alexandre Vassalotti77250f42008-05-06 19:48:38 +0000749
750 it = PyObject_GetIter(v);
751 if (it == NULL)
752 return NULL;
753
754 while ((item = PyIter_Next(it)) != NULL) {
755 ret = bytesio_write(self, item);
756 Py_DECREF(item);
757 if (ret == NULL) {
758 Py_DECREF(it);
759 return NULL;
760 }
761 Py_DECREF(ret);
762 }
763 Py_DECREF(it);
764
765 /* See if PyIter_Next failed */
766 if (PyErr_Occurred())
767 return NULL;
768
769 Py_RETURN_NONE;
770}
771
772PyDoc_STRVAR(close_doc,
773"close() -> None. Disable all I/O operations.");
774
775static PyObject *
Benjamin Peterson680bf1a2009-06-12 02:07:12 +0000776bytesio_close(bytesio *self)
Alexandre Vassalotti77250f42008-05-06 19:48:38 +0000777{
Antoine Pitroucc66a732014-07-29 19:41:11 -0400778 reset(self);
Alexandre Vassalotti77250f42008-05-06 19:48:38 +0000779 Py_RETURN_NONE;
780}
781
Alexandre Vassalotticf76e1a2009-07-22 03:24:36 +0000782/* Pickling support.
783
784 Note that only pickle protocol 2 and onward are supported since we use
785 extended __reduce__ API of PEP 307 to make BytesIO instances picklable.
786
787 Providing support for protocol < 2 would require the __reduce_ex__ method
788 which is notably long-winded when defined properly.
789
790 For BytesIO, the implementation would similar to one coded for
791 object.__reduce_ex__, but slightly less general. To be more specific, we
792 could call bytesio_getstate directly and avoid checking for the presence of
793 a fallback __reduce__ method. However, we would still need a __newobj__
794 function to use the efficient instance representation of PEP 307.
795 */
796
797static PyObject *
798bytesio_getstate(bytesio *self)
799{
800 PyObject *initvalue = bytesio_getvalue(self);
801 PyObject *dict;
802 PyObject *state;
803
804 if (initvalue == NULL)
805 return NULL;
806 if (self->dict == NULL) {
807 Py_INCREF(Py_None);
808 dict = Py_None;
809 }
810 else {
811 dict = PyDict_Copy(self->dict);
Stefan Krah96efdd42012-09-08 11:12:33 +0200812 if (dict == NULL) {
813 Py_DECREF(initvalue);
Alexandre Vassalotticf76e1a2009-07-22 03:24:36 +0000814 return NULL;
Stefan Krah96efdd42012-09-08 11:12:33 +0200815 }
Alexandre Vassalotticf76e1a2009-07-22 03:24:36 +0000816 }
817
818 state = Py_BuildValue("(OnN)", initvalue, self->pos, dict);
819 Py_DECREF(initvalue);
820 return state;
821}
822
823static PyObject *
824bytesio_setstate(bytesio *self, PyObject *state)
825{
Alexandre Vassalotticf76e1a2009-07-22 03:24:36 +0000826 PyObject *position_obj;
827 PyObject *dict;
828 Py_ssize_t pos;
829
Antoine Pitroucc66a732014-07-29 19:41:11 -0400830 CHECK_EXPORTS(self);
Alexandre Vassalotticf76e1a2009-07-22 03:24:36 +0000831 assert(state != NULL);
832
833 /* We allow the state tuple to be longer than 3, because we may need
834 someday to extend the object's state without breaking
835 backward-compatibility. */
836 if (!PyTuple_Check(state) || Py_SIZE(state) < 3) {
837 PyErr_Format(PyExc_TypeError,
838 "%.200s.__setstate__ argument should be 3-tuple, got %.200s",
839 Py_TYPE(self)->tp_name, Py_TYPE(state)->tp_name);
840 return NULL;
841 }
Alexandre Vassalotticf76e1a2009-07-22 03:24:36 +0000842
Antoine Pitroucc66a732014-07-29 19:41:11 -0400843 /* Reset the object to its default state and set the value of the internal
844 * buffer. If state[0] does not support the buffer protocol, reinit() will
845 * raise the appropriate TypeError. */
846 if (reinit(self, PyTuple_GET_ITEM(state, 0)) < 0) {
Alexandre Vassalotticf76e1a2009-07-22 03:24:36 +0000847 return NULL;
Antoine Pitroucc66a732014-07-29 19:41:11 -0400848 }
Alexandre Vassalotticf76e1a2009-07-22 03:24:36 +0000849
850 /* Set carefully the position value. Alternatively, we could use the seek
851 method instead of modifying self->pos directly to better protect the
852 object internal state against errneous (or malicious) inputs. */
853 position_obj = PyTuple_GET_ITEM(state, 1);
854 if (!PyLong_Check(position_obj)) {
855 PyErr_Format(PyExc_TypeError,
856 "second item of state must be an integer, not %.200s",
857 Py_TYPE(position_obj)->tp_name);
858 return NULL;
859 }
860 pos = PyLong_AsSsize_t(position_obj);
861 if (pos == -1 && PyErr_Occurred())
862 return NULL;
863 if (pos < 0) {
864 PyErr_SetString(PyExc_ValueError,
865 "position value cannot be negative");
866 return NULL;
867 }
868 self->pos = pos;
869
870 /* Set the dictionary of the instance variables. */
871 dict = PyTuple_GET_ITEM(state, 2);
872 if (dict != Py_None) {
873 if (!PyDict_Check(dict)) {
874 PyErr_Format(PyExc_TypeError,
875 "third item of state should be a dict, got a %.200s",
876 Py_TYPE(dict)->tp_name);
877 return NULL;
878 }
879 if (self->dict) {
880 /* Alternatively, we could replace the internal dictionary
881 completely. However, it seems more practical to just update it. */
882 if (PyDict_Update(self->dict, dict) < 0)
883 return NULL;
884 }
885 else {
886 Py_INCREF(dict);
887 self->dict = dict;
888 }
889 }
890
891 Py_RETURN_NONE;
892}
893
Alexandre Vassalotti77250f42008-05-06 19:48:38 +0000894static void
Benjamin Peterson680bf1a2009-06-12 02:07:12 +0000895bytesio_dealloc(bytesio *self)
Alexandre Vassalotti77250f42008-05-06 19:48:38 +0000896{
Alexandre Vassalottifc477042009-07-22 02:24:49 +0000897 _PyObject_GC_UNTRACK(self);
Antoine Pitrou972ee132010-09-06 18:48:21 +0000898 if (self->exports > 0) {
899 PyErr_SetString(PyExc_SystemError,
900 "deallocated BytesIO object has exported buffers");
901 PyErr_Print();
902 }
Antoine Pitroucc66a732014-07-29 19:41:11 -0400903
904 reset(self);
905
Alexandre Vassalottifc477042009-07-22 02:24:49 +0000906 Py_CLEAR(self->dict);
907 if (self->weakreflist != NULL)
908 PyObject_ClearWeakRefs((PyObject *) self);
Alexandre Vassalotti77250f42008-05-06 19:48:38 +0000909 Py_TYPE(self)->tp_free(self);
910}
911
912static PyObject *
913bytesio_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
914{
Benjamin Peterson680bf1a2009-06-12 02:07:12 +0000915 bytesio *self;
Alexandre Vassalotti77250f42008-05-06 19:48:38 +0000916
917 assert(type != NULL && type->tp_alloc != NULL);
Benjamin Peterson680bf1a2009-06-12 02:07:12 +0000918 self = (bytesio *)type->tp_alloc(type, 0);
Alexandre Vassalotti77250f42008-05-06 19:48:38 +0000919 if (self == NULL)
920 return NULL;
921
Alexandre Vassalotticf76e1a2009-07-22 03:24:36 +0000922 /* tp_alloc initializes all the fields to zero. So we don't have to
923 initialize them here. */
924
Alexandre Vassalotti77250f42008-05-06 19:48:38 +0000925 self->buf = (char *)PyMem_Malloc(0);
926 if (self->buf == NULL) {
927 Py_DECREF(self);
928 return PyErr_NoMemory();
929 }
930
931 return (PyObject *)self;
932}
933
934static int
Benjamin Peterson680bf1a2009-06-12 02:07:12 +0000935bytesio_init(bytesio *self, PyObject *args, PyObject *kwds)
Alexandre Vassalotti77250f42008-05-06 19:48:38 +0000936{
Alexandre Vassalottiba5c7432009-08-04 23:19:13 +0000937 char *kwlist[] = {"initial_bytes", NULL};
Alexandre Vassalotti77250f42008-05-06 19:48:38 +0000938 PyObject *initvalue = NULL;
939
Alexandre Vassalottiba5c7432009-08-04 23:19:13 +0000940 if (!PyArg_ParseTupleAndKeywords(args, kwds, "|O:BytesIO", kwlist,
941 &initvalue))
Alexandre Vassalotti77250f42008-05-06 19:48:38 +0000942 return -1;
943
Antoine Pitroucc66a732014-07-29 19:41:11 -0400944 return reinit(self, initvalue);
Alexandre Vassalotti77250f42008-05-06 19:48:38 +0000945}
946
Antoine Pitrou8f328d02012-07-30 00:01:06 +0200947static PyObject *
948bytesio_sizeof(bytesio *self, void *unused)
949{
950 Py_ssize_t res;
951
952 res = sizeof(bytesio);
953 if (self->buf)
954 res += self->buf_size;
955 return PyLong_FromSsize_t(res);
956}
957
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000958static int
Benjamin Peterson680bf1a2009-06-12 02:07:12 +0000959bytesio_traverse(bytesio *self, visitproc visit, void *arg)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000960{
961 Py_VISIT(self->dict);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000962 return 0;
963}
964
965static int
Benjamin Peterson680bf1a2009-06-12 02:07:12 +0000966bytesio_clear(bytesio *self)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000967{
968 Py_CLEAR(self->dict);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000969 return 0;
970}
971
972
Alexandre Vassalotti77250f42008-05-06 19:48:38 +0000973static PyGetSetDef bytesio_getsetlist[] = {
974 {"closed", (getter)bytesio_get_closed, NULL,
975 "True if the file is closed."},
Benjamin Peterson1fea3212009-04-19 03:15:20 +0000976 {NULL}, /* sentinel */
Alexandre Vassalotti77250f42008-05-06 19:48:38 +0000977};
978
979static struct PyMethodDef bytesio_methods[] = {
Antoine Pitrou1d857452012-09-05 20:11:49 +0200980 {"readable", (PyCFunction)return_not_closed, METH_NOARGS, readable_doc},
981 {"seekable", (PyCFunction)return_not_closed, METH_NOARGS, seekable_doc},
982 {"writable", (PyCFunction)return_not_closed, METH_NOARGS, writable_doc},
Alexandre Vassalotti77250f42008-05-06 19:48:38 +0000983 {"close", (PyCFunction)bytesio_close, METH_NOARGS, close_doc},
984 {"flush", (PyCFunction)bytesio_flush, METH_NOARGS, flush_doc},
985 {"isatty", (PyCFunction)bytesio_isatty, METH_NOARGS, isatty_doc},
986 {"tell", (PyCFunction)bytesio_tell, METH_NOARGS, tell_doc},
987 {"write", (PyCFunction)bytesio_write, METH_O, write_doc},
988 {"writelines", (PyCFunction)bytesio_writelines, METH_O, writelines_doc},
989 {"read1", (PyCFunction)bytesio_read1, METH_O, read1_doc},
990 {"readinto", (PyCFunction)bytesio_readinto, METH_O, readinto_doc},
991 {"readline", (PyCFunction)bytesio_readline, METH_VARARGS, readline_doc},
992 {"readlines", (PyCFunction)bytesio_readlines, METH_VARARGS, readlines_doc},
993 {"read", (PyCFunction)bytesio_read, METH_VARARGS, read_doc},
Antoine Pitrou972ee132010-09-06 18:48:21 +0000994 {"getbuffer", (PyCFunction)bytesio_getbuffer, METH_NOARGS, getbuffer_doc},
Antoine Pitroud5c3f6c2010-09-02 19:48:07 +0000995 {"getvalue", (PyCFunction)bytesio_getvalue, METH_NOARGS, getval_doc},
Alexandre Vassalotti77250f42008-05-06 19:48:38 +0000996 {"seek", (PyCFunction)bytesio_seek, METH_VARARGS, seek_doc},
997 {"truncate", (PyCFunction)bytesio_truncate, METH_VARARGS, truncate_doc},
Alexandre Vassalotticf76e1a2009-07-22 03:24:36 +0000998 {"__getstate__", (PyCFunction)bytesio_getstate, METH_NOARGS, NULL},
999 {"__setstate__", (PyCFunction)bytesio_setstate, METH_O, NULL},
Antoine Pitrou8f328d02012-07-30 00:01:06 +02001000 {"__sizeof__", (PyCFunction)bytesio_sizeof, METH_NOARGS, NULL},
Alexandre Vassalotti77250f42008-05-06 19:48:38 +00001001 {NULL, NULL} /* sentinel */
1002};
1003
1004PyDoc_STRVAR(bytesio_doc,
1005"BytesIO([buffer]) -> object\n"
1006"\n"
1007"Create a buffered I/O implementation using an in-memory bytes\n"
1008"buffer, ready for reading and writing.");
1009
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001010PyTypeObject PyBytesIO_Type = {
Alexandre Vassalotti77250f42008-05-06 19:48:38 +00001011 PyVarObject_HEAD_INIT(NULL, 0)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001012 "_io.BytesIO", /*tp_name*/
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001013 sizeof(bytesio), /*tp_basicsize*/
Alexandre Vassalotti77250f42008-05-06 19:48:38 +00001014 0, /*tp_itemsize*/
1015 (destructor)bytesio_dealloc, /*tp_dealloc*/
1016 0, /*tp_print*/
1017 0, /*tp_getattr*/
1018 0, /*tp_setattr*/
Mark Dickinsone94c6792009-02-02 20:36:42 +00001019 0, /*tp_reserved*/
Alexandre Vassalotti77250f42008-05-06 19:48:38 +00001020 0, /*tp_repr*/
1021 0, /*tp_as_number*/
1022 0, /*tp_as_sequence*/
1023 0, /*tp_as_mapping*/
1024 0, /*tp_hash*/
1025 0, /*tp_call*/
1026 0, /*tp_str*/
1027 0, /*tp_getattro*/
1028 0, /*tp_setattro*/
1029 0, /*tp_as_buffer*/
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001030 Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE |
1031 Py_TPFLAGS_HAVE_GC, /*tp_flags*/
Alexandre Vassalotti77250f42008-05-06 19:48:38 +00001032 bytesio_doc, /*tp_doc*/
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001033 (traverseproc)bytesio_traverse, /*tp_traverse*/
1034 (inquiry)bytesio_clear, /*tp_clear*/
Alexandre Vassalotti77250f42008-05-06 19:48:38 +00001035 0, /*tp_richcompare*/
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001036 offsetof(bytesio, weakreflist), /*tp_weaklistoffset*/
Alexandre Vassalotti77250f42008-05-06 19:48:38 +00001037 PyObject_SelfIter, /*tp_iter*/
1038 (iternextfunc)bytesio_iternext, /*tp_iternext*/
1039 bytesio_methods, /*tp_methods*/
1040 0, /*tp_members*/
1041 bytesio_getsetlist, /*tp_getset*/
1042 0, /*tp_base*/
1043 0, /*tp_dict*/
1044 0, /*tp_descr_get*/
1045 0, /*tp_descr_set*/
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001046 offsetof(bytesio, dict), /*tp_dictoffset*/
Alexandre Vassalotti77250f42008-05-06 19:48:38 +00001047 (initproc)bytesio_init, /*tp_init*/
1048 0, /*tp_alloc*/
1049 bytesio_new, /*tp_new*/
1050};
Antoine Pitrou972ee132010-09-06 18:48:21 +00001051
1052
1053/*
1054 * Implementation of the small intermediate object used by getbuffer().
1055 * getbuffer() returns a memoryview over this object, which should make it
1056 * invisible from Python code.
1057 */
1058
1059static int
1060bytesiobuf_getbuffer(bytesiobuf *obj, Py_buffer *view, int flags)
1061{
1062 int ret;
Antoine Pitrou972ee132010-09-06 18:48:21 +00001063 bytesio *b = (bytesio *) obj->source;
1064 if (view == NULL) {
1065 b->exports++;
1066 return 0;
1067 }
Antoine Pitrou972ee132010-09-06 18:48:21 +00001068 ret = PyBuffer_FillInfo(view, (PyObject*)obj, b->buf, b->string_size,
1069 0, flags);
1070 if (ret >= 0) {
1071 b->exports++;
1072 }
1073 return ret;
1074}
1075
1076static void
1077bytesiobuf_releasebuffer(bytesiobuf *obj, Py_buffer *view)
1078{
1079 bytesio *b = (bytesio *) obj->source;
1080 b->exports--;
1081}
1082
1083static int
1084bytesiobuf_traverse(bytesiobuf *self, visitproc visit, void *arg)
1085{
1086 Py_VISIT(self->source);
1087 return 0;
1088}
1089
1090static void
1091bytesiobuf_dealloc(bytesiobuf *self)
1092{
1093 Py_CLEAR(self->source);
1094 Py_TYPE(self)->tp_free(self);
1095}
1096
1097static PyBufferProcs bytesiobuf_as_buffer = {
1098 (getbufferproc) bytesiobuf_getbuffer,
1099 (releasebufferproc) bytesiobuf_releasebuffer,
1100};
1101
1102PyTypeObject _PyBytesIOBuffer_Type = {
1103 PyVarObject_HEAD_INIT(NULL, 0)
1104 "_io._BytesIOBuffer", /*tp_name*/
1105 sizeof(bytesiobuf), /*tp_basicsize*/
1106 0, /*tp_itemsize*/
1107 (destructor)bytesiobuf_dealloc, /*tp_dealloc*/
1108 0, /*tp_print*/
1109 0, /*tp_getattr*/
1110 0, /*tp_setattr*/
1111 0, /*tp_reserved*/
1112 0, /*tp_repr*/
1113 0, /*tp_as_number*/
1114 0, /*tp_as_sequence*/
1115 0, /*tp_as_mapping*/
1116 0, /*tp_hash*/
1117 0, /*tp_call*/
1118 0, /*tp_str*/
1119 0, /*tp_getattro*/
1120 0, /*tp_setattro*/
1121 &bytesiobuf_as_buffer, /*tp_as_buffer*/
1122 Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC, /*tp_flags*/
1123 0, /*tp_doc*/
1124 (traverseproc)bytesiobuf_traverse, /*tp_traverse*/
1125 0, /*tp_clear*/
1126 0, /*tp_richcompare*/
1127 0, /*tp_weaklistoffset*/
1128 0, /*tp_iter*/
1129 0, /*tp_iternext*/
1130 0, /*tp_methods*/
1131 0, /*tp_members*/
1132 0, /*tp_getset*/
1133 0, /*tp_base*/
1134 0, /*tp_dict*/
1135 0, /*tp_descr_get*/
1136 0, /*tp_descr_set*/
1137 0, /*tp_dictoffset*/
1138 0, /*tp_init*/
1139 0, /*tp_alloc*/
1140 0, /*tp_new*/
1141};