blob: d7d2667a3647f35c9f8e4aa513b21d9f743e099d [file] [log] [blame]
Alexandre Vassalotti77250f42008-05-06 19:48:38 +00001#include "Python.h"
2
3typedef struct {
4 PyObject_HEAD
5 char *buf;
6 Py_ssize_t pos;
7 Py_ssize_t string_size;
8 size_t buf_size;
9} BytesIOObject;
10
11#define CHECK_CLOSED(self) \
12 if ((self)->buf == NULL) { \
13 PyErr_SetString(PyExc_ValueError, \
14 "I/O operation on closed file."); \
15 return NULL; \
16 }
17
18/* Internal routine to get a line from the buffer of a BytesIO
19 object. Returns the length between the current position to the
20 next newline character. */
21static Py_ssize_t
22get_line(BytesIOObject *self, char **output)
23{
24 char *n;
25 const char *str_end;
26 Py_ssize_t len;
27
28 assert(self->buf != NULL);
29
30 /* Move to the end of the line, up to the end of the string, s. */
31 str_end = self->buf + self->string_size;
32 for (n = self->buf + self->pos;
33 n < str_end && *n != '\n';
34 n++);
35
36 /* Skip the newline character */
37 if (n < str_end)
38 n++;
39
40 /* Get the length from the current position to the end of the line. */
41 len = n - (self->buf + self->pos);
42 *output = self->buf + self->pos;
43
44 assert(len >= 0);
45 assert(self->pos < PY_SSIZE_T_MAX - len);
46 self->pos += len;
47
48 return len;
49}
50
51/* Internal routine for changing the size of the buffer of BytesIO objects.
52 The caller should ensure that the 'size' argument is non-negative. Returns
53 0 on success, -1 otherwise. */
54static int
55resize_buffer(BytesIOObject *self, size_t size)
56{
57 /* Here, unsigned types are used to avoid dealing with signed integer
58 overflow, which is undefined in C. */
59 size_t alloc = self->buf_size;
60 char *new_buf = NULL;
61
62 assert(self->buf != NULL);
63
64 /* For simplicity, stay in the range of the signed type. Anyway, Python
65 doesn't allow strings to be longer than this. */
66 if (size > PY_SSIZE_T_MAX)
67 goto overflow;
68
69 if (size < alloc / 2) {
70 /* Major downsize; resize down to exact size. */
71 alloc = size + 1;
72 }
73 else if (size < alloc) {
74 /* Within allocated size; quick exit */
75 return 0;
76 }
77 else if (size <= alloc * 1.125) {
78 /* Moderate upsize; overallocate similar to list_resize() */
79 alloc = size + (size >> 3) + (size < 9 ? 3 : 6);
80 }
81 else {
82 /* Major upsize; resize up to exact size */
83 alloc = size + 1;
84 }
85
86 if (alloc > ((size_t)-1) / sizeof(char))
87 goto overflow;
88 new_buf = (char *)PyMem_Realloc(self->buf, alloc * sizeof(char));
89 if (new_buf == NULL) {
90 PyErr_NoMemory();
91 return -1;
92 }
93 self->buf_size = alloc;
94 self->buf = new_buf;
95
96 return 0;
97
98 overflow:
99 PyErr_SetString(PyExc_OverflowError,
100 "new buffer size too large");
101 return -1;
102}
103
104/* Internal routine for writing a string of bytes to the buffer of a BytesIO
105 object. Returns the number of bytes wrote, or -1 on error. */
106static Py_ssize_t
107write_bytes(BytesIOObject *self, const char *bytes, Py_ssize_t len)
108{
109 assert(self->buf != NULL);
110 assert(self->pos >= 0);
111 assert(len >= 0);
112
Alexandre Vassalotti1bfe9dc82008-05-07 01:44:31 +0000113 if ((size_t)self->pos + len > self->buf_size) {
114 if (resize_buffer(self, (size_t)self->pos + len) < 0)
Alexandre Vassalotti77250f42008-05-06 19:48:38 +0000115 return -1;
116 }
117
118 if (self->pos > self->string_size) {
119 /* In case of overseek, pad with null bytes the buffer region between
120 the end of stream and the current position.
121
122 0 lo string_size hi
123 | |<---used--->|<----------available----------->|
124 | | <--to pad-->|<---to write---> |
125 0 buf position
126 */
127 memset(self->buf + self->string_size, '\0',
128 (self->pos - self->string_size) * sizeof(char));
129 }
130
131 /* Copy the data to the internal buffer, overwriting some of the existing
132 data if self->pos < self->string_size. */
133 memcpy(self->buf + self->pos, bytes, len);
134 self->pos += len;
135
136 /* Set the new length of the internal string if it has changed. */
137 if (self->string_size < self->pos) {
138 self->string_size = self->pos;
139 }
140
141 return len;
142}
143
144static PyObject *
145bytesio_get_closed(BytesIOObject *self)
146{
147 if (self->buf == NULL)
148 Py_RETURN_TRUE;
149 else
150 Py_RETURN_FALSE;
151}
152
153/* Generic getter for the writable, readable and seekable properties */
154static PyObject *
155return_true(BytesIOObject *self)
156{
157 Py_RETURN_TRUE;
158}
159
160PyDoc_STRVAR(flush_doc,
161"flush() -> None. Does nothing.");
162
163static PyObject *
164bytesio_flush(BytesIOObject *self)
165{
166 Py_RETURN_NONE;
167}
168
169PyDoc_STRVAR(getval_doc,
Alexandre Vassalotti10dfc1e2008-05-08 01:34:41 +0000170"getvalue() -> bytes.\n"
Alexandre Vassalotti77250f42008-05-06 19:48:38 +0000171"\n"
172"Retrieve the entire contents of the BytesIO object.");
173
174static PyObject *
175bytesio_getvalue(BytesIOObject *self)
176{
177 CHECK_CLOSED(self);
Christian Heimes72b710a2008-05-26 13:28:38 +0000178 return PyBytes_FromStringAndSize(self->buf, self->string_size);
Alexandre Vassalotti77250f42008-05-06 19:48:38 +0000179}
180
181PyDoc_STRVAR(isatty_doc,
182"isatty() -> False.\n"
183"\n"
184"Always returns False since BytesIO objects are not connected\n"
185"to a tty-like device.");
186
187static PyObject *
188bytesio_isatty(BytesIOObject *self)
189{
190 CHECK_CLOSED(self);
191 Py_RETURN_FALSE;
192}
193
194PyDoc_STRVAR(tell_doc,
195"tell() -> current file position, an integer\n");
196
197static PyObject *
198bytesio_tell(BytesIOObject *self)
199{
200 CHECK_CLOSED(self);
201 return PyLong_FromSsize_t(self->pos);
202}
203
204PyDoc_STRVAR(read_doc,
205"read([size]) -> read at most size bytes, returned as a string.\n"
206"\n"
207"If the size argument is negative, read until EOF is reached.\n"
208"Return an empty string at EOF.");
209
210static PyObject *
211bytesio_read(BytesIOObject *self, PyObject *args)
212{
213 Py_ssize_t size, n;
214 char *output;
215 PyObject *arg = Py_None;
216
217 CHECK_CLOSED(self);
218
219 if (!PyArg_ParseTuple(args, "|O:read", &arg))
220 return NULL;
221
222 if (PyLong_Check(arg)) {
223 size = PyLong_AsSsize_t(arg);
224 }
225 else if (arg == Py_None) {
226 /* Read until EOF is reached, by default. */
227 size = -1;
228 }
229 else {
230 PyErr_Format(PyExc_TypeError, "integer argument expected, got '%s'",
231 Py_TYPE(arg)->tp_name);
232 return NULL;
233 }
234
235 /* adjust invalid sizes */
236 n = self->string_size - self->pos;
237 if (size < 0 || size > n) {
238 size = n;
239 if (size < 0)
240 size = 0;
241 }
242
243 assert(self->buf != NULL);
244 output = self->buf + self->pos;
245 self->pos += size;
246
Christian Heimes72b710a2008-05-26 13:28:38 +0000247 return PyBytes_FromStringAndSize(output, size);
Alexandre Vassalotti77250f42008-05-06 19:48:38 +0000248}
249
250
251PyDoc_STRVAR(read1_doc,
252"read1(size) -> read at most size bytes, returned as a string.\n"
253"\n"
254"If the size argument is negative or omitted, read until EOF is reached.\n"
255"Return an empty string at EOF.");
256
257static PyObject *
258bytesio_read1(BytesIOObject *self, PyObject *n)
259{
260 PyObject *arg, *res;
261
262 arg = PyTuple_Pack(1, n);
263 if (arg == NULL)
264 return NULL;
265 res = bytesio_read(self, arg);
266 Py_DECREF(arg);
267 return res;
268}
269
270PyDoc_STRVAR(readline_doc,
271"readline([size]) -> next line from the file, as a string.\n"
272"\n"
273"Retain newline. A non-negative size argument limits the maximum\n"
274"number of bytes to return (an incomplete line may be returned then).\n"
275"Return an empty string at EOF.\n");
276
277static PyObject *
278bytesio_readline(BytesIOObject *self, PyObject *args)
279{
280 Py_ssize_t size, n;
281 char *output;
282 PyObject *arg = Py_None;
283
284 CHECK_CLOSED(self);
285
286 if (!PyArg_ParseTuple(args, "|O:readline", &arg))
287 return NULL;
288
289 if (PyLong_Check(arg)) {
290 size = PyLong_AsSsize_t(arg);
291 }
292 else if (arg == Py_None) {
293 /* No size limit, by default. */
294 size = -1;
295 }
296 else {
297 PyErr_Format(PyExc_TypeError, "integer argument expected, got '%s'",
298 Py_TYPE(arg)->tp_name);
299 return NULL;
300 }
301
302 n = get_line(self, &output);
303
304 if (size >= 0 && size < n) {
305 size = n - size;
306 n -= size;
307 self->pos -= size;
308 }
309
Christian Heimes72b710a2008-05-26 13:28:38 +0000310 return PyBytes_FromStringAndSize(output, n);
Alexandre Vassalotti77250f42008-05-06 19:48:38 +0000311}
312
313PyDoc_STRVAR(readlines_doc,
314"readlines([size]) -> list of strings, each a line from the file.\n"
315"\n"
316"Call readline() repeatedly and return a list of the lines so read.\n"
317"The optional size argument, if given, is an approximate bound on the\n"
318"total number of bytes in the lines returned.\n");
319
320static PyObject *
321bytesio_readlines(BytesIOObject *self, PyObject *args)
322{
323 Py_ssize_t maxsize, size, n;
324 PyObject *result, *line;
325 char *output;
326 PyObject *arg = Py_None;
327
328 CHECK_CLOSED(self);
329
330 if (!PyArg_ParseTuple(args, "|O:readlines", &arg))
331 return NULL;
332
333 if (PyLong_Check(arg)) {
334 maxsize = PyLong_AsSsize_t(arg);
335 }
336 else if (arg == Py_None) {
337 /* No size limit, by default. */
338 maxsize = -1;
339 }
340 else {
341 PyErr_Format(PyExc_TypeError, "integer argument expected, got '%s'",
342 Py_TYPE(arg)->tp_name);
343 return NULL;
344 }
345
346 size = 0;
347 result = PyList_New(0);
348 if (!result)
349 return NULL;
350
351 while ((n = get_line(self, &output)) != 0) {
Christian Heimes72b710a2008-05-26 13:28:38 +0000352 line = PyBytes_FromStringAndSize(output, n);
Alexandre Vassalotti77250f42008-05-06 19:48:38 +0000353 if (!line)
354 goto on_error;
355 if (PyList_Append(result, line) == -1) {
356 Py_DECREF(line);
357 goto on_error;
358 }
359 Py_DECREF(line);
360 size += n;
361 if (maxsize > 0 && size >= maxsize)
362 break;
363 }
364 return result;
365
366 on_error:
367 Py_DECREF(result);
368 return NULL;
369}
370
371PyDoc_STRVAR(readinto_doc,
Alexandre Vassalotti10dfc1e2008-05-08 01:34:41 +0000372"readinto(bytearray) -> int. Read up to len(b) bytes into b.\n"
Alexandre Vassalotti77250f42008-05-06 19:48:38 +0000373"\n"
374"Returns number of bytes read (0 for EOF), or None if the object\n"
375"is set not to block as has no data to read.");
376
377static PyObject *
378bytesio_readinto(BytesIOObject *self, PyObject *buffer)
379{
380 void *raw_buffer;
381 Py_ssize_t len;
382
383 CHECK_CLOSED(self);
384
385 if (PyObject_AsWriteBuffer(buffer, &raw_buffer, &len) == -1)
386 return NULL;
387
388 if (self->pos + len > self->string_size)
389 len = self->string_size - self->pos;
390
391 memcpy(raw_buffer, self->buf + self->pos, len);
392 assert(self->pos + len < PY_SSIZE_T_MAX);
393 assert(len >= 0);
394 self->pos += len;
395
396 return PyLong_FromSsize_t(len);
397}
398
399PyDoc_STRVAR(truncate_doc,
400"truncate([size]) -> int. Truncate the file to at most size bytes.\n"
401"\n"
402"Size defaults to the current file position, as returned by tell().\n"
403"Returns the new size. Imply an absolute seek to the position size.");
404
405static PyObject *
406bytesio_truncate(BytesIOObject *self, PyObject *args)
407{
408 Py_ssize_t size;
409 PyObject *arg = Py_None;
410
411 CHECK_CLOSED(self);
412
413 if (!PyArg_ParseTuple(args, "|O:truncate", &arg))
414 return NULL;
415
416 if (PyLong_Check(arg)) {
417 size = PyLong_AsSsize_t(arg);
418 }
419 else if (arg == Py_None) {
420 /* Truncate to current position if no argument is passed. */
421 size = self->pos;
422 }
423 else {
424 PyErr_Format(PyExc_TypeError, "integer argument expected, got '%s'",
425 Py_TYPE(arg)->tp_name);
426 return NULL;
427 }
428
429 if (size < 0) {
430 PyErr_Format(PyExc_ValueError,
431 "negative size value %zd", size);
432 return NULL;
433 }
434
435 if (size < self->string_size) {
436 self->string_size = size;
437 if (resize_buffer(self, size) < 0)
438 return NULL;
439 }
440 self->pos = size;
441
442 return PyLong_FromSsize_t(size);
443}
444
445static PyObject *
446bytesio_iternext(BytesIOObject *self)
447{
448 char *next;
449 Py_ssize_t n;
450
451 CHECK_CLOSED(self);
452
453 n = get_line(self, &next);
454
455 if (!next || n == 0)
456 return NULL;
457
Christian Heimes72b710a2008-05-26 13:28:38 +0000458 return PyBytes_FromStringAndSize(next, n);
Alexandre Vassalotti77250f42008-05-06 19:48:38 +0000459}
460
461PyDoc_STRVAR(seek_doc,
462"seek(pos, whence=0) -> int. Change stream position.\n"
463"\n"
464"Seek to byte offset pos relative to position indicated by whence:\n"
465" 0 Start of stream (the default). pos should be >= 0;\n"
466" 1 Current position - pos may be negative;\n"
467" 2 End of stream - pos usually negative.\n"
468"Returns the new absolute position.");
469
470static PyObject *
471bytesio_seek(BytesIOObject *self, PyObject *args)
472{
473 Py_ssize_t pos;
474 int mode = 0;
475
476 CHECK_CLOSED(self);
477
478 if (!PyArg_ParseTuple(args, "n|i:seek", &pos, &mode))
479 return NULL;
480
481 if (pos < 0 && mode == 0) {
482 PyErr_Format(PyExc_ValueError,
483 "negative seek value %zd", pos);
484 return NULL;
485 }
486
487 /* mode 0: offset relative to beginning of the string.
488 mode 1: offset relative to current position.
489 mode 2: offset relative the end of the string. */
490 if (mode == 1) {
491 if (pos > PY_SSIZE_T_MAX - self->pos) {
492 PyErr_SetString(PyExc_OverflowError,
493 "new position too large");
494 return NULL;
495 }
496 pos += self->pos;
497 }
498 else if (mode == 2) {
499 if (pos > PY_SSIZE_T_MAX - self->string_size) {
500 PyErr_SetString(PyExc_OverflowError,
501 "new position too large");
502 return NULL;
503 }
504 pos += self->string_size;
505 }
506 else if (mode != 0) {
507 PyErr_Format(PyExc_ValueError,
508 "invalid whence (%i, should be 0, 1 or 2)", mode);
509 return NULL;
510 }
511
512 if (pos < 0)
513 pos = 0;
514 self->pos = pos;
515
516 return PyLong_FromSsize_t(self->pos);
517}
518
519PyDoc_STRVAR(write_doc,
Alexandre Vassalotti10dfc1e2008-05-08 01:34:41 +0000520"write(bytes) -> int. Write bytes to file.\n"
Alexandre Vassalotti77250f42008-05-06 19:48:38 +0000521"\n"
522"Return the number of bytes written.");
523
524static PyObject *
525bytesio_write(BytesIOObject *self, PyObject *obj)
526{
527 const char *bytes;
528 Py_ssize_t size;
529 Py_ssize_t n = 0;
530
531 CHECK_CLOSED(self);
532
533 if (PyObject_AsReadBuffer(obj, (void *)&bytes, &size) < 0)
534 return NULL;
535
536 if (size != 0) {
537 n = write_bytes(self, bytes, size);
538 if (n < 0)
539 return NULL;
540 }
541
542 return PyLong_FromSsize_t(n);
543}
544
545PyDoc_STRVAR(writelines_doc,
Alexandre Vassalotti7d060892008-05-07 01:47:37 +0000546"writelines(sequence_of_strings) -> None. Write strings to the file.\n"
Alexandre Vassalotti77250f42008-05-06 19:48:38 +0000547"\n"
Alexandre Vassalotti7d060892008-05-07 01:47:37 +0000548"Note that newlines are not added. The sequence can be any iterable\n"
549"object producing strings. This is equivalent to calling write() for\n"
550"each string.");
Alexandre Vassalotti77250f42008-05-06 19:48:38 +0000551
552static PyObject *
553bytesio_writelines(BytesIOObject *self, PyObject *v)
554{
555 PyObject *it, *item;
556 PyObject *ret;
557
558 CHECK_CLOSED(self);
559
560 it = PyObject_GetIter(v);
561 if (it == NULL)
562 return NULL;
563
564 while ((item = PyIter_Next(it)) != NULL) {
565 ret = bytesio_write(self, item);
566 Py_DECREF(item);
567 if (ret == NULL) {
568 Py_DECREF(it);
569 return NULL;
570 }
571 Py_DECREF(ret);
572 }
573 Py_DECREF(it);
574
575 /* See if PyIter_Next failed */
576 if (PyErr_Occurred())
577 return NULL;
578
579 Py_RETURN_NONE;
580}
581
582PyDoc_STRVAR(close_doc,
583"close() -> None. Disable all I/O operations.");
584
585static PyObject *
586bytesio_close(BytesIOObject *self)
587{
588 if (self->buf != NULL) {
589 PyMem_Free(self->buf);
590 self->buf = NULL;
591 }
592 Py_RETURN_NONE;
593}
594
595static void
596bytesio_dealloc(BytesIOObject *self)
597{
598 if (self->buf != NULL) {
599 PyMem_Free(self->buf);
600 self->buf = NULL;
601 }
602 Py_TYPE(self)->tp_free(self);
603}
604
605static PyObject *
606bytesio_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
607{
608 BytesIOObject *self;
609
610 assert(type != NULL && type->tp_alloc != NULL);
611 self = (BytesIOObject *)type->tp_alloc(type, 0);
612 if (self == NULL)
613 return NULL;
614
615 self->string_size = 0;
616 self->pos = 0;
617 self->buf_size = 0;
618 self->buf = (char *)PyMem_Malloc(0);
619 if (self->buf == NULL) {
620 Py_DECREF(self);
621 return PyErr_NoMemory();
622 }
623
624 return (PyObject *)self;
625}
626
627static int
628bytesio_init(BytesIOObject *self, PyObject *args, PyObject *kwds)
629{
630 PyObject *initvalue = NULL;
631
632 if (!PyArg_ParseTuple(args, "|O:BytesIO", &initvalue))
633 return -1;
634
635 /* In case, __init__ is called multiple times. */
636 self->string_size = 0;
637 self->pos = 0;
638
639 if (initvalue && initvalue != Py_None) {
640 PyObject *res;
641 res = bytesio_write(self, initvalue);
642 if (res == NULL)
643 return -1;
644 Py_DECREF(res);
645 self->pos = 0;
646 }
647
648 return 0;
649}
650
651static PyGetSetDef bytesio_getsetlist[] = {
652 {"closed", (getter)bytesio_get_closed, NULL,
653 "True if the file is closed."},
654 {0}, /* sentinel */
655};
656
657static struct PyMethodDef bytesio_methods[] = {
658 {"readable", (PyCFunction)return_true, METH_NOARGS, NULL},
659 {"seekable", (PyCFunction)return_true, METH_NOARGS, NULL},
660 {"writable", (PyCFunction)return_true, METH_NOARGS, NULL},
661 {"close", (PyCFunction)bytesio_close, METH_NOARGS, close_doc},
662 {"flush", (PyCFunction)bytesio_flush, METH_NOARGS, flush_doc},
663 {"isatty", (PyCFunction)bytesio_isatty, METH_NOARGS, isatty_doc},
664 {"tell", (PyCFunction)bytesio_tell, METH_NOARGS, tell_doc},
665 {"write", (PyCFunction)bytesio_write, METH_O, write_doc},
666 {"writelines", (PyCFunction)bytesio_writelines, METH_O, writelines_doc},
667 {"read1", (PyCFunction)bytesio_read1, METH_O, read1_doc},
668 {"readinto", (PyCFunction)bytesio_readinto, METH_O, readinto_doc},
669 {"readline", (PyCFunction)bytesio_readline, METH_VARARGS, readline_doc},
670 {"readlines", (PyCFunction)bytesio_readlines, METH_VARARGS, readlines_doc},
671 {"read", (PyCFunction)bytesio_read, METH_VARARGS, read_doc},
672 {"getvalue", (PyCFunction)bytesio_getvalue, METH_VARARGS, getval_doc},
673 {"seek", (PyCFunction)bytesio_seek, METH_VARARGS, seek_doc},
674 {"truncate", (PyCFunction)bytesio_truncate, METH_VARARGS, truncate_doc},
675 {NULL, NULL} /* sentinel */
676};
677
678PyDoc_STRVAR(bytesio_doc,
679"BytesIO([buffer]) -> object\n"
680"\n"
681"Create a buffered I/O implementation using an in-memory bytes\n"
682"buffer, ready for reading and writing.");
683
684static PyTypeObject BytesIO_Type = {
685 PyVarObject_HEAD_INIT(NULL, 0)
686 "_bytesio._BytesIO", /*tp_name*/
687 sizeof(BytesIOObject), /*tp_basicsize*/
688 0, /*tp_itemsize*/
689 (destructor)bytesio_dealloc, /*tp_dealloc*/
690 0, /*tp_print*/
691 0, /*tp_getattr*/
692 0, /*tp_setattr*/
693 0, /*tp_compare*/
694 0, /*tp_repr*/
695 0, /*tp_as_number*/
696 0, /*tp_as_sequence*/
697 0, /*tp_as_mapping*/
698 0, /*tp_hash*/
699 0, /*tp_call*/
700 0, /*tp_str*/
701 0, /*tp_getattro*/
702 0, /*tp_setattro*/
703 0, /*tp_as_buffer*/
704 Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, /*tp_flags*/
705 bytesio_doc, /*tp_doc*/
706 0, /*tp_traverse*/
707 0, /*tp_clear*/
708 0, /*tp_richcompare*/
709 0, /*tp_weaklistoffset*/
710 PyObject_SelfIter, /*tp_iter*/
711 (iternextfunc)bytesio_iternext, /*tp_iternext*/
712 bytesio_methods, /*tp_methods*/
713 0, /*tp_members*/
714 bytesio_getsetlist, /*tp_getset*/
715 0, /*tp_base*/
716 0, /*tp_dict*/
717 0, /*tp_descr_get*/
718 0, /*tp_descr_set*/
719 0, /*tp_dictoffset*/
720 (initproc)bytesio_init, /*tp_init*/
721 0, /*tp_alloc*/
722 bytesio_new, /*tp_new*/
723};
724
Martin v. Löwis1a214512008-06-11 05:26:20 +0000725
726static struct PyModuleDef _bytesiomodule = {
727 PyModuleDef_HEAD_INIT,
728 "_bytesio",
729 NULL,
730 -1,
731 NULL,
732 NULL,
733 NULL,
734 NULL,
735 NULL
736};
737
Alexandre Vassalotti77250f42008-05-06 19:48:38 +0000738PyMODINIT_FUNC
Martin v. Löwis1a214512008-06-11 05:26:20 +0000739PyInit__bytesio(void)
Alexandre Vassalotti77250f42008-05-06 19:48:38 +0000740{
741 PyObject *m;
742
743 if (PyType_Ready(&BytesIO_Type) < 0)
Martin v. Löwis1a214512008-06-11 05:26:20 +0000744 return NULL;
745 m = PyModule_Create(&_bytesiomodule);
Alexandre Vassalotti77250f42008-05-06 19:48:38 +0000746 if (m == NULL)
Martin v. Löwis1a214512008-06-11 05:26:20 +0000747 return NULL;
Alexandre Vassalotti77250f42008-05-06 19:48:38 +0000748 Py_INCREF(&BytesIO_Type);
749 PyModule_AddObject(m, "_BytesIO", (PyObject *)&BytesIO_Type);
Martin v. Löwis1a214512008-06-11 05:26:20 +0000750 return m;
Alexandre Vassalotti77250f42008-05-06 19:48:38 +0000751}