~ubuntu-branches/ubuntu/trusty/python3.4/trusty-proposed

« back to all changes in this revision

Viewing changes to Modules/_io/bytesio.c

  • Committer: Package Import Robot
  • Author(s): Matthias Klose
  • Date: 2013-11-25 09:44:27 UTC
  • Revision ID: package-import@ubuntu.com-20131125094427-lzxj8ap5w01lmo7f
Tags: upstream-3.4~b1
ImportĀ upstreamĀ versionĀ 3.4~b1

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
#include "Python.h"
 
2
#include "structmember.h"       /* for offsetof() */
 
3
#include "_iomodule.h"
 
4
 
 
5
typedef struct {
 
6
    PyObject_HEAD
 
7
    char *buf;
 
8
    Py_ssize_t pos;
 
9
    Py_ssize_t string_size;
 
10
    size_t buf_size;
 
11
    PyObject *dict;
 
12
    PyObject *weakreflist;
 
13
    Py_ssize_t exports;
 
14
} bytesio;
 
15
 
 
16
typedef struct {
 
17
    PyObject_HEAD
 
18
    bytesio *source;
 
19
} bytesiobuf;
 
20
 
 
21
 
 
22
#define CHECK_CLOSED(self)                                  \
 
23
    if ((self)->buf == NULL) {                              \
 
24
        PyErr_SetString(PyExc_ValueError,                   \
 
25
                        "I/O operation on closed file.");   \
 
26
        return NULL;                                        \
 
27
    }
 
28
 
 
29
#define CHECK_EXPORTS(self) \
 
30
    if ((self)->exports > 0) { \
 
31
        PyErr_SetString(PyExc_BufferError, \
 
32
                        "Existing exports of data: object cannot be re-sized"); \
 
33
        return NULL; \
 
34
    }
 
35
 
 
36
 
 
37
/* Internal routine to get a line from the buffer of a BytesIO
 
38
   object. Returns the length between the current position to the
 
39
   next newline character. */
 
40
static Py_ssize_t
 
41
get_line(bytesio *self, char **output)
 
42
{
 
43
    char *n;
 
44
    const char *str_end;
 
45
    Py_ssize_t len;
 
46
 
 
47
    assert(self->buf != NULL);
 
48
 
 
49
    /* Move to the end of the line, up to the end of the string, s. */
 
50
    str_end = self->buf + self->string_size;
 
51
    for (n = self->buf + self->pos;
 
52
         n < str_end && *n != '\n';
 
53
         n++);
 
54
 
 
55
    /* Skip the newline character */
 
56
    if (n < str_end)
 
57
        n++;
 
58
 
 
59
    /* Get the length from the current position to the end of the line. */
 
60
    len = n - (self->buf + self->pos);
 
61
    *output = self->buf + self->pos;
 
62
 
 
63
    assert(len >= 0);
 
64
    assert(self->pos < PY_SSIZE_T_MAX - len);
 
65
    self->pos += len;
 
66
 
 
67
    return len;
 
68
}
 
69
 
 
70
/* Internal routine for changing the size of the buffer of BytesIO objects.
 
71
   The caller should ensure that the 'size' argument is non-negative.  Returns
 
72
   0 on success, -1 otherwise. */
 
73
static int
 
74
resize_buffer(bytesio *self, size_t size)
 
75
{
 
76
    /* Here, unsigned types are used to avoid dealing with signed integer
 
77
       overflow, which is undefined in C. */
 
78
    size_t alloc = self->buf_size;
 
79
    char *new_buf = NULL;
 
80
 
 
81
    assert(self->buf != NULL);
 
82
 
 
83
    /* For simplicity, stay in the range of the signed type. Anyway, Python
 
84
       doesn't allow strings to be longer than this. */
 
85
    if (size > PY_SSIZE_T_MAX)
 
86
        goto overflow;
 
87
 
 
88
    if (size < alloc / 2) {
 
89
        /* Major downsize; resize down to exact size. */
 
90
        alloc = size + 1;
 
91
    }
 
92
    else if (size < alloc) {
 
93
        /* Within allocated size; quick exit */
 
94
        return 0;
 
95
    }
 
96
    else if (size <= alloc * 1.125) {
 
97
        /* Moderate upsize; overallocate similar to list_resize() */
 
98
        alloc = size + (size >> 3) + (size < 9 ? 3 : 6);
 
99
    }
 
100
    else {
 
101
        /* Major upsize; resize up to exact size */
 
102
        alloc = size + 1;
 
103
    }
 
104
 
 
105
    if (alloc > ((size_t)-1) / sizeof(char))
 
106
        goto overflow;
 
107
    new_buf = (char *)PyMem_Realloc(self->buf, alloc * sizeof(char));
 
108
    if (new_buf == NULL) {
 
109
        PyErr_NoMemory();
 
110
        return -1;
 
111
    }
 
112
    self->buf_size = alloc;
 
113
    self->buf = new_buf;
 
114
 
 
115
    return 0;
 
116
 
 
117
  overflow:
 
118
    PyErr_SetString(PyExc_OverflowError,
 
119
                    "new buffer size too large");
 
120
    return -1;
 
121
}
 
122
 
 
123
/* Internal routine for writing a string of bytes to the buffer of a BytesIO
 
124
   object. Returns the number of bytes written, or -1 on error. */
 
125
static Py_ssize_t
 
126
write_bytes(bytesio *self, const char *bytes, Py_ssize_t len)
 
127
{
 
128
    assert(self->buf != NULL);
 
129
    assert(self->pos >= 0);
 
130
    assert(len >= 0);
 
131
 
 
132
    if ((size_t)self->pos + len > self->buf_size) {
 
133
        if (resize_buffer(self, (size_t)self->pos + len) < 0)
 
134
            return -1;
 
135
    }
 
136
 
 
137
    if (self->pos > self->string_size) {
 
138
        /* In case of overseek, pad with null bytes the buffer region between
 
139
           the end of stream and the current position.
 
140
 
 
141
          0   lo      string_size                           hi
 
142
          |   |<---used--->|<----------available----------->|
 
143
          |   |            <--to pad-->|<---to write--->    |
 
144
          0   buf                   position
 
145
        */
 
146
        memset(self->buf + self->string_size, '\0',
 
147
               (self->pos - self->string_size) * sizeof(char));
 
148
    }
 
149
 
 
150
    /* Copy the data to the internal buffer, overwriting some of the existing
 
151
       data if self->pos < self->string_size. */
 
152
    memcpy(self->buf + self->pos, bytes, len);
 
153
    self->pos += len;
 
154
 
 
155
    /* Set the new length of the internal string if it has changed. */
 
156
    if (self->string_size < self->pos) {
 
157
        self->string_size = self->pos;
 
158
    }
 
159
 
 
160
    return len;
 
161
}
 
162
 
 
163
static PyObject *
 
164
bytesio_get_closed(bytesio *self)
 
165
{
 
166
    if (self->buf == NULL) {
 
167
        Py_RETURN_TRUE;
 
168
    }
 
169
    else {
 
170
        Py_RETURN_FALSE;
 
171
    }
 
172
}
 
173
 
 
174
PyDoc_STRVAR(readable_doc,
 
175
"readable() -> bool. Returns True if the IO object can be read.");
 
176
 
 
177
PyDoc_STRVAR(writable_doc,
 
178
"writable() -> bool. Returns True if the IO object can be written.");
 
179
 
 
180
PyDoc_STRVAR(seekable_doc,
 
181
"seekable() -> bool. Returns True if the IO object can be seeked.");
 
182
 
 
183
/* Generic getter for the writable, readable and seekable properties */
 
184
static PyObject *
 
185
return_not_closed(bytesio *self)
 
186
{
 
187
    CHECK_CLOSED(self);
 
188
    Py_RETURN_TRUE;
 
189
}
 
190
 
 
191
PyDoc_STRVAR(flush_doc,
 
192
"flush() -> None.  Does nothing.");
 
193
 
 
194
static PyObject *
 
195
bytesio_flush(bytesio *self)
 
196
{
 
197
    CHECK_CLOSED(self);
 
198
    Py_RETURN_NONE;
 
199
}
 
200
 
 
201
PyDoc_STRVAR(getbuffer_doc,
 
202
"getbuffer() -> bytes.\n"
 
203
"\n"
 
204
"Get a read-write view over the contents of the BytesIO object.");
 
205
 
 
206
static PyObject *
 
207
bytesio_getbuffer(bytesio *self)
 
208
{
 
209
    PyTypeObject *type = &_PyBytesIOBuffer_Type;
 
210
    bytesiobuf *buf;
 
211
    PyObject *view;
 
212
 
 
213
    CHECK_CLOSED(self);
 
214
 
 
215
    buf = (bytesiobuf *) type->tp_alloc(type, 0);
 
216
    if (buf == NULL)
 
217
        return NULL;
 
218
    Py_INCREF(self);
 
219
    buf->source = self;
 
220
    view = PyMemoryView_FromObject((PyObject *) buf);
 
221
    Py_DECREF(buf);
 
222
    return view;
 
223
}
 
224
 
 
225
PyDoc_STRVAR(getval_doc,
 
226
"getvalue() -> bytes.\n"
 
227
"\n"
 
228
"Retrieve the entire contents of the BytesIO object.");
 
229
 
 
230
static PyObject *
 
231
bytesio_getvalue(bytesio *self)
 
232
{
 
233
    CHECK_CLOSED(self);
 
234
    return PyBytes_FromStringAndSize(self->buf, self->string_size);
 
235
}
 
236
 
 
237
PyDoc_STRVAR(isatty_doc,
 
238
"isatty() -> False.\n"
 
239
"\n"
 
240
"Always returns False since BytesIO objects are not connected\n"
 
241
"to a tty-like device.");
 
242
 
 
243
static PyObject *
 
244
bytesio_isatty(bytesio *self)
 
245
{
 
246
    CHECK_CLOSED(self);
 
247
    Py_RETURN_FALSE;
 
248
}
 
249
 
 
250
PyDoc_STRVAR(tell_doc,
 
251
"tell() -> current file position, an integer\n");
 
252
 
 
253
static PyObject *
 
254
bytesio_tell(bytesio *self)
 
255
{
 
256
    CHECK_CLOSED(self);
 
257
    return PyLong_FromSsize_t(self->pos);
 
258
}
 
259
 
 
260
PyDoc_STRVAR(read_doc,
 
261
"read([size]) -> read at most size bytes, returned as a string.\n"
 
262
"\n"
 
263
"If the size argument is negative, read until EOF is reached.\n"
 
264
"Return an empty string at EOF.");
 
265
 
 
266
static PyObject *
 
267
bytesio_read(bytesio *self, PyObject *args)
 
268
{
 
269
    Py_ssize_t size, n;
 
270
    char *output;
 
271
    PyObject *arg = Py_None;
 
272
 
 
273
    CHECK_CLOSED(self);
 
274
 
 
275
    if (!PyArg_ParseTuple(args, "|O:read", &arg))
 
276
        return NULL;
 
277
 
 
278
    if (PyLong_Check(arg)) {
 
279
        size = PyLong_AsSsize_t(arg);
 
280
        if (size == -1 && PyErr_Occurred())
 
281
            return NULL;
 
282
    }
 
283
    else if (arg == Py_None) {
 
284
        /* Read until EOF is reached, by default. */
 
285
        size = -1;
 
286
    }
 
287
    else {
 
288
        PyErr_Format(PyExc_TypeError, "integer argument expected, got '%s'",
 
289
                     Py_TYPE(arg)->tp_name);
 
290
        return NULL;
 
291
    }
 
292
 
 
293
    /* adjust invalid sizes */
 
294
    n = self->string_size - self->pos;
 
295
    if (size < 0 || size > n) {
 
296
        size = n;
 
297
        if (size < 0)
 
298
            size = 0;
 
299
    }
 
300
 
 
301
    assert(self->buf != NULL);
 
302
    output = self->buf + self->pos;
 
303
    self->pos += size;
 
304
 
 
305
    return PyBytes_FromStringAndSize(output, size);
 
306
}
 
307
 
 
308
 
 
309
PyDoc_STRVAR(read1_doc,
 
310
"read1(size) -> read at most size bytes, returned as a string.\n"
 
311
"\n"
 
312
"If the size argument is negative or omitted, read until EOF is reached.\n"
 
313
"Return an empty string at EOF.");
 
314
 
 
315
static PyObject *
 
316
bytesio_read1(bytesio *self, PyObject *n)
 
317
{
 
318
    PyObject *arg, *res;
 
319
 
 
320
    arg = PyTuple_Pack(1, n);
 
321
    if (arg == NULL)
 
322
        return NULL;
 
323
    res  = bytesio_read(self, arg);
 
324
    Py_DECREF(arg);
 
325
    return res;
 
326
}
 
327
 
 
328
PyDoc_STRVAR(readline_doc,
 
329
"readline([size]) -> next line from the file, as a string.\n"
 
330
"\n"
 
331
"Retain newline.  A non-negative size argument limits the maximum\n"
 
332
"number of bytes to return (an incomplete line may be returned then).\n"
 
333
"Return an empty string at EOF.\n");
 
334
 
 
335
static PyObject *
 
336
bytesio_readline(bytesio *self, PyObject *args)
 
337
{
 
338
    Py_ssize_t size, n;
 
339
    char *output;
 
340
    PyObject *arg = Py_None;
 
341
 
 
342
    CHECK_CLOSED(self);
 
343
 
 
344
    if (!PyArg_ParseTuple(args, "|O:readline", &arg))
 
345
        return NULL;
 
346
 
 
347
    if (PyLong_Check(arg)) {
 
348
        size = PyLong_AsSsize_t(arg);
 
349
        if (size == -1 && PyErr_Occurred())
 
350
            return NULL;
 
351
    }
 
352
    else if (arg == Py_None) {
 
353
        /* No size limit, by default. */
 
354
        size = -1;
 
355
    }
 
356
    else {
 
357
        PyErr_Format(PyExc_TypeError, "integer argument expected, got '%s'",
 
358
                     Py_TYPE(arg)->tp_name);
 
359
        return NULL;
 
360
    }
 
361
 
 
362
    n = get_line(self, &output);
 
363
 
 
364
    if (size >= 0 && size < n) {
 
365
        size = n - size;
 
366
        n -= size;
 
367
        self->pos -= size;
 
368
    }
 
369
 
 
370
    return PyBytes_FromStringAndSize(output, n);
 
371
}
 
372
 
 
373
PyDoc_STRVAR(readlines_doc,
 
374
"readlines([size]) -> list of strings, each a line from the file.\n"
 
375
"\n"
 
376
"Call readline() repeatedly and return a list of the lines so read.\n"
 
377
"The optional size argument, if given, is an approximate bound on the\n"
 
378
"total number of bytes in the lines returned.\n");
 
379
 
 
380
static PyObject *
 
381
bytesio_readlines(bytesio *self, PyObject *args)
 
382
{
 
383
    Py_ssize_t maxsize, size, n;
 
384
    PyObject *result, *line;
 
385
    char *output;
 
386
    PyObject *arg = Py_None;
 
387
 
 
388
    CHECK_CLOSED(self);
 
389
 
 
390
    if (!PyArg_ParseTuple(args, "|O:readlines", &arg))
 
391
        return NULL;
 
392
 
 
393
    if (PyLong_Check(arg)) {
 
394
        maxsize = PyLong_AsSsize_t(arg);
 
395
        if (maxsize == -1 && PyErr_Occurred())
 
396
            return NULL;
 
397
    }
 
398
    else if (arg == Py_None) {
 
399
        /* No size limit, by default. */
 
400
        maxsize = -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
    size = 0;
 
409
    result = PyList_New(0);
 
410
    if (!result)
 
411
        return NULL;
 
412
 
 
413
    while ((n = get_line(self, &output)) != 0) {
 
414
        line = PyBytes_FromStringAndSize(output, n);
 
415
        if (!line)
 
416
            goto on_error;
 
417
        if (PyList_Append(result, line) == -1) {
 
418
            Py_DECREF(line);
 
419
            goto on_error;
 
420
        }
 
421
        Py_DECREF(line);
 
422
        size += n;
 
423
        if (maxsize > 0 && size >= maxsize)
 
424
            break;
 
425
    }
 
426
    return result;
 
427
 
 
428
  on_error:
 
429
    Py_DECREF(result);
 
430
    return NULL;
 
431
}
 
432
 
 
433
PyDoc_STRVAR(readinto_doc,
 
434
"readinto(bytearray) -> int.  Read up to len(b) bytes into b.\n"
 
435
"\n"
 
436
"Returns number of bytes read (0 for EOF), or None if the object\n"
 
437
"is set not to block as has no data to read.");
 
438
 
 
439
static PyObject *
 
440
bytesio_readinto(bytesio *self, PyObject *buffer)
 
441
{
 
442
    void *raw_buffer;
 
443
    Py_ssize_t len, n;
 
444
 
 
445
    CHECK_CLOSED(self);
 
446
 
 
447
    if (PyObject_AsWriteBuffer(buffer, &raw_buffer, &len) == -1)
 
448
        return NULL;
 
449
 
 
450
    /* adjust invalid sizes */
 
451
    n = self->string_size - self->pos;
 
452
    if (len > n) {
 
453
        len = n;
 
454
        if (len < 0)
 
455
            len = 0;
 
456
    }
 
457
 
 
458
    memcpy(raw_buffer, self->buf + self->pos, len);
 
459
    assert(self->pos + len < PY_SSIZE_T_MAX);
 
460
    assert(len >= 0);
 
461
    self->pos += len;
 
462
 
 
463
    return PyLong_FromSsize_t(len);
 
464
}
 
465
 
 
466
PyDoc_STRVAR(truncate_doc,
 
467
"truncate([size]) -> int.  Truncate the file to at most size bytes.\n"
 
468
"\n"
 
469
"Size defaults to the current file position, as returned by tell().\n"
 
470
"The current file position is unchanged.  Returns the new size.\n");
 
471
 
 
472
static PyObject *
 
473
bytesio_truncate(bytesio *self, PyObject *args)
 
474
{
 
475
    Py_ssize_t size;
 
476
    PyObject *arg = Py_None;
 
477
 
 
478
    CHECK_CLOSED(self);
 
479
    CHECK_EXPORTS(self);
 
480
 
 
481
    if (!PyArg_ParseTuple(args, "|O:truncate", &arg))
 
482
        return NULL;
 
483
 
 
484
    if (PyLong_Check(arg)) {
 
485
        size = PyLong_AsSsize_t(arg);
 
486
        if (size == -1 && PyErr_Occurred())
 
487
            return NULL;
 
488
    }
 
489
    else if (arg == Py_None) {
 
490
        /* Truncate to current position if no argument is passed. */
 
491
        size = self->pos;
 
492
    }
 
493
    else {
 
494
        PyErr_Format(PyExc_TypeError, "integer argument expected, got '%s'",
 
495
                     Py_TYPE(arg)->tp_name);
 
496
        return NULL;
 
497
    }
 
498
 
 
499
    if (size < 0) {
 
500
        PyErr_Format(PyExc_ValueError,
 
501
                     "negative size value %zd", size);
 
502
        return NULL;
 
503
    }
 
504
 
 
505
    if (size < self->string_size) {
 
506
        self->string_size = size;
 
507
        if (resize_buffer(self, size) < 0)
 
508
            return NULL;
 
509
    }
 
510
 
 
511
    return PyLong_FromSsize_t(size);
 
512
}
 
513
 
 
514
static PyObject *
 
515
bytesio_iternext(bytesio *self)
 
516
{
 
517
    char *next;
 
518
    Py_ssize_t n;
 
519
 
 
520
    CHECK_CLOSED(self);
 
521
 
 
522
    n = get_line(self, &next);
 
523
 
 
524
    if (!next || n == 0)
 
525
        return NULL;
 
526
 
 
527
    return PyBytes_FromStringAndSize(next, n);
 
528
}
 
529
 
 
530
PyDoc_STRVAR(seek_doc,
 
531
"seek(pos, whence=0) -> int.  Change stream position.\n"
 
532
"\n"
 
533
"Seek to byte offset pos relative to position indicated by whence:\n"
 
534
"     0  Start of stream (the default).  pos should be >= 0;\n"
 
535
"     1  Current position - pos may be negative;\n"
 
536
"     2  End of stream - pos usually negative.\n"
 
537
"Returns the new absolute position.");
 
538
 
 
539
static PyObject *
 
540
bytesio_seek(bytesio *self, PyObject *args)
 
541
{
 
542
    Py_ssize_t pos;
 
543
    int mode = 0;
 
544
 
 
545
    CHECK_CLOSED(self);
 
546
 
 
547
    if (!PyArg_ParseTuple(args, "n|i:seek", &pos, &mode))
 
548
        return NULL;
 
549
 
 
550
    if (pos < 0 && mode == 0) {
 
551
        PyErr_Format(PyExc_ValueError,
 
552
                     "negative seek value %zd", pos);
 
553
        return NULL;
 
554
    }
 
555
 
 
556
    /* mode 0: offset relative to beginning of the string.
 
557
       mode 1: offset relative to current position.
 
558
       mode 2: offset relative the end of the string. */
 
559
    if (mode == 1) {
 
560
        if (pos > PY_SSIZE_T_MAX - self->pos) {
 
561
            PyErr_SetString(PyExc_OverflowError,
 
562
                            "new position too large");
 
563
            return NULL;
 
564
        }
 
565
        pos += self->pos;
 
566
    }
 
567
    else if (mode == 2) {
 
568
        if (pos > PY_SSIZE_T_MAX - self->string_size) {
 
569
            PyErr_SetString(PyExc_OverflowError,
 
570
                            "new position too large");
 
571
            return NULL;
 
572
        }
 
573
        pos += self->string_size;
 
574
    }
 
575
    else if (mode != 0) {
 
576
        PyErr_Format(PyExc_ValueError,
 
577
                     "invalid whence (%i, should be 0, 1 or 2)", mode);
 
578
        return NULL;
 
579
    }
 
580
 
 
581
    if (pos < 0)
 
582
        pos = 0;
 
583
    self->pos = pos;
 
584
 
 
585
    return PyLong_FromSsize_t(self->pos);
 
586
}
 
587
 
 
588
PyDoc_STRVAR(write_doc,
 
589
"write(bytes) -> int.  Write bytes to file.\n"
 
590
"\n"
 
591
"Return the number of bytes written.");
 
592
 
 
593
static PyObject *
 
594
bytesio_write(bytesio *self, PyObject *obj)
 
595
{
 
596
    Py_ssize_t n = 0;
 
597
    Py_buffer buf;
 
598
    PyObject *result = NULL;
 
599
 
 
600
    CHECK_CLOSED(self);
 
601
    CHECK_EXPORTS(self);
 
602
 
 
603
    if (PyObject_GetBuffer(obj, &buf, PyBUF_CONTIG_RO) < 0)
 
604
        return NULL;
 
605
 
 
606
    if (buf.len != 0)
 
607
        n = write_bytes(self, buf.buf, buf.len);
 
608
    if (n >= 0)
 
609
        result = PyLong_FromSsize_t(n);
 
610
 
 
611
    PyBuffer_Release(&buf);
 
612
    return result;
 
613
}
 
614
 
 
615
PyDoc_STRVAR(writelines_doc,
 
616
"writelines(sequence_of_strings) -> None.  Write strings to the file.\n"
 
617
"\n"
 
618
"Note that newlines are not added.  The sequence can be any iterable\n"
 
619
"object producing strings. This is equivalent to calling write() for\n"
 
620
"each string.");
 
621
 
 
622
static PyObject *
 
623
bytesio_writelines(bytesio *self, PyObject *v)
 
624
{
 
625
    PyObject *it, *item;
 
626
    PyObject *ret;
 
627
 
 
628
    CHECK_CLOSED(self);
 
629
 
 
630
    it = PyObject_GetIter(v);
 
631
    if (it == NULL)
 
632
        return NULL;
 
633
 
 
634
    while ((item = PyIter_Next(it)) != NULL) {
 
635
        ret = bytesio_write(self, item);
 
636
        Py_DECREF(item);
 
637
        if (ret == NULL) {
 
638
            Py_DECREF(it);
 
639
            return NULL;
 
640
        }
 
641
        Py_DECREF(ret);
 
642
    }
 
643
    Py_DECREF(it);
 
644
 
 
645
    /* See if PyIter_Next failed */
 
646
    if (PyErr_Occurred())
 
647
        return NULL;
 
648
 
 
649
    Py_RETURN_NONE;
 
650
}
 
651
 
 
652
PyDoc_STRVAR(close_doc,
 
653
"close() -> None.  Disable all I/O operations.");
 
654
 
 
655
static PyObject *
 
656
bytesio_close(bytesio *self)
 
657
{
 
658
    if (self->buf != NULL) {
 
659
        PyMem_Free(self->buf);
 
660
        self->buf = NULL;
 
661
    }
 
662
    Py_RETURN_NONE;
 
663
}
 
664
 
 
665
/* Pickling support.
 
666
 
 
667
   Note that only pickle protocol 2 and onward are supported since we use
 
668
   extended __reduce__ API of PEP 307 to make BytesIO instances picklable.
 
669
 
 
670
   Providing support for protocol < 2 would require the __reduce_ex__ method
 
671
   which is notably long-winded when defined properly.
 
672
 
 
673
   For BytesIO, the implementation would similar to one coded for
 
674
   object.__reduce_ex__, but slightly less general. To be more specific, we
 
675
   could call bytesio_getstate directly and avoid checking for the presence of
 
676
   a fallback __reduce__ method. However, we would still need a __newobj__
 
677
   function to use the efficient instance representation of PEP 307.
 
678
 */
 
679
 
 
680
static PyObject *
 
681
bytesio_getstate(bytesio *self)
 
682
{
 
683
    PyObject *initvalue = bytesio_getvalue(self);
 
684
    PyObject *dict;
 
685
    PyObject *state;
 
686
 
 
687
    if (initvalue == NULL)
 
688
        return NULL;
 
689
    if (self->dict == NULL) {
 
690
        Py_INCREF(Py_None);
 
691
        dict = Py_None;
 
692
    }
 
693
    else {
 
694
        dict = PyDict_Copy(self->dict);
 
695
        if (dict == NULL) {
 
696
            Py_DECREF(initvalue);
 
697
            return NULL;
 
698
        }
 
699
    }
 
700
 
 
701
    state = Py_BuildValue("(OnN)", initvalue, self->pos, dict);
 
702
    Py_DECREF(initvalue);
 
703
    return state;
 
704
}
 
705
 
 
706
static PyObject *
 
707
bytesio_setstate(bytesio *self, PyObject *state)
 
708
{
 
709
    PyObject *result;
 
710
    PyObject *position_obj;
 
711
    PyObject *dict;
 
712
    Py_ssize_t pos;
 
713
 
 
714
    assert(state != NULL);
 
715
 
 
716
    /* We allow the state tuple to be longer than 3, because we may need
 
717
       someday to extend the object's state without breaking
 
718
       backward-compatibility. */
 
719
    if (!PyTuple_Check(state) || Py_SIZE(state) < 3) {
 
720
        PyErr_Format(PyExc_TypeError,
 
721
                     "%.200s.__setstate__ argument should be 3-tuple, got %.200s",
 
722
                     Py_TYPE(self)->tp_name, Py_TYPE(state)->tp_name);
 
723
        return NULL;
 
724
    }
 
725
    CHECK_EXPORTS(self);
 
726
    /* Reset the object to its default state. This is only needed to handle
 
727
       the case of repeated calls to __setstate__. */
 
728
    self->string_size = 0;
 
729
    self->pos = 0;
 
730
 
 
731
    /* Set the value of the internal buffer. If state[0] does not support the
 
732
       buffer protocol, bytesio_write will raise the appropriate TypeError. */
 
733
    result = bytesio_write(self, PyTuple_GET_ITEM(state, 0));
 
734
    if (result == NULL)
 
735
        return NULL;
 
736
    Py_DECREF(result);
 
737
 
 
738
    /* Set carefully the position value. Alternatively, we could use the seek
 
739
       method instead of modifying self->pos directly to better protect the
 
740
       object internal state against errneous (or malicious) inputs. */
 
741
    position_obj = PyTuple_GET_ITEM(state, 1);
 
742
    if (!PyLong_Check(position_obj)) {
 
743
        PyErr_Format(PyExc_TypeError,
 
744
                     "second item of state must be an integer, not %.200s",
 
745
                     Py_TYPE(position_obj)->tp_name);
 
746
        return NULL;
 
747
    }
 
748
    pos = PyLong_AsSsize_t(position_obj);
 
749
    if (pos == -1 && PyErr_Occurred())
 
750
        return NULL;
 
751
    if (pos < 0) {
 
752
        PyErr_SetString(PyExc_ValueError,
 
753
                        "position value cannot be negative");
 
754
        return NULL;
 
755
    }
 
756
    self->pos = pos;
 
757
 
 
758
    /* Set the dictionary of the instance variables. */
 
759
    dict = PyTuple_GET_ITEM(state, 2);
 
760
    if (dict != Py_None) {
 
761
        if (!PyDict_Check(dict)) {
 
762
            PyErr_Format(PyExc_TypeError,
 
763
                         "third item of state should be a dict, got a %.200s",
 
764
                         Py_TYPE(dict)->tp_name);
 
765
            return NULL;
 
766
        }
 
767
        if (self->dict) {
 
768
            /* Alternatively, we could replace the internal dictionary
 
769
               completely. However, it seems more practical to just update it. */
 
770
            if (PyDict_Update(self->dict, dict) < 0)
 
771
                return NULL;
 
772
        }
 
773
        else {
 
774
            Py_INCREF(dict);
 
775
            self->dict = dict;
 
776
        }
 
777
    }
 
778
 
 
779
    Py_RETURN_NONE;
 
780
}
 
781
 
 
782
static void
 
783
bytesio_dealloc(bytesio *self)
 
784
{
 
785
    _PyObject_GC_UNTRACK(self);
 
786
    if (self->exports > 0) {
 
787
        PyErr_SetString(PyExc_SystemError,
 
788
                        "deallocated BytesIO object has exported buffers");
 
789
        PyErr_Print();
 
790
    }
 
791
    if (self->buf != NULL) {
 
792
        PyMem_Free(self->buf);
 
793
        self->buf = NULL;
 
794
    }
 
795
    Py_CLEAR(self->dict);
 
796
    if (self->weakreflist != NULL)
 
797
        PyObject_ClearWeakRefs((PyObject *) self);
 
798
    Py_TYPE(self)->tp_free(self);
 
799
}
 
800
 
 
801
static PyObject *
 
802
bytesio_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
 
803
{
 
804
    bytesio *self;
 
805
 
 
806
    assert(type != NULL && type->tp_alloc != NULL);
 
807
    self = (bytesio *)type->tp_alloc(type, 0);
 
808
    if (self == NULL)
 
809
        return NULL;
 
810
 
 
811
    /* tp_alloc initializes all the fields to zero. So we don't have to
 
812
       initialize them here. */
 
813
 
 
814
    self->buf = (char *)PyMem_Malloc(0);
 
815
    if (self->buf == NULL) {
 
816
        Py_DECREF(self);
 
817
        return PyErr_NoMemory();
 
818
    }
 
819
 
 
820
    return (PyObject *)self;
 
821
}
 
822
 
 
823
static int
 
824
bytesio_init(bytesio *self, PyObject *args, PyObject *kwds)
 
825
{
 
826
    char *kwlist[] = {"initial_bytes", NULL};
 
827
    PyObject *initvalue = NULL;
 
828
 
 
829
    if (!PyArg_ParseTupleAndKeywords(args, kwds, "|O:BytesIO", kwlist,
 
830
                                     &initvalue))
 
831
        return -1;
 
832
 
 
833
    /* In case, __init__ is called multiple times. */
 
834
    self->string_size = 0;
 
835
    self->pos = 0;
 
836
 
 
837
    if (initvalue && initvalue != Py_None) {
 
838
        PyObject *res;
 
839
        res = bytesio_write(self, initvalue);
 
840
        if (res == NULL)
 
841
            return -1;
 
842
        Py_DECREF(res);
 
843
        self->pos = 0;
 
844
    }
 
845
 
 
846
    return 0;
 
847
}
 
848
 
 
849
static PyObject *
 
850
bytesio_sizeof(bytesio *self, void *unused)
 
851
{
 
852
    Py_ssize_t res;
 
853
 
 
854
    res = sizeof(bytesio);
 
855
    if (self->buf)
 
856
        res += self->buf_size;
 
857
    return PyLong_FromSsize_t(res);
 
858
}
 
859
 
 
860
static int
 
861
bytesio_traverse(bytesio *self, visitproc visit, void *arg)
 
862
{
 
863
    Py_VISIT(self->dict);
 
864
    return 0;
 
865
}
 
866
 
 
867
static int
 
868
bytesio_clear(bytesio *self)
 
869
{
 
870
    Py_CLEAR(self->dict);
 
871
    return 0;
 
872
}
 
873
 
 
874
 
 
875
static PyGetSetDef bytesio_getsetlist[] = {
 
876
    {"closed",  (getter)bytesio_get_closed, NULL,
 
877
     "True if the file is closed."},
 
878
    {NULL},            /* sentinel */
 
879
};
 
880
 
 
881
static struct PyMethodDef bytesio_methods[] = {
 
882
    {"readable",   (PyCFunction)return_not_closed,  METH_NOARGS, readable_doc},
 
883
    {"seekable",   (PyCFunction)return_not_closed,  METH_NOARGS, seekable_doc},
 
884
    {"writable",   (PyCFunction)return_not_closed,  METH_NOARGS, writable_doc},
 
885
    {"close",      (PyCFunction)bytesio_close,      METH_NOARGS, close_doc},
 
886
    {"flush",      (PyCFunction)bytesio_flush,      METH_NOARGS, flush_doc},
 
887
    {"isatty",     (PyCFunction)bytesio_isatty,     METH_NOARGS, isatty_doc},
 
888
    {"tell",       (PyCFunction)bytesio_tell,       METH_NOARGS, tell_doc},
 
889
    {"write",      (PyCFunction)bytesio_write,      METH_O, write_doc},
 
890
    {"writelines", (PyCFunction)bytesio_writelines, METH_O, writelines_doc},
 
891
    {"read1",      (PyCFunction)bytesio_read1,      METH_O, read1_doc},
 
892
    {"readinto",   (PyCFunction)bytesio_readinto,   METH_O, readinto_doc},
 
893
    {"readline",   (PyCFunction)bytesio_readline,   METH_VARARGS, readline_doc},
 
894
    {"readlines",  (PyCFunction)bytesio_readlines,  METH_VARARGS, readlines_doc},
 
895
    {"read",       (PyCFunction)bytesio_read,       METH_VARARGS, read_doc},
 
896
    {"getbuffer",  (PyCFunction)bytesio_getbuffer,  METH_NOARGS,  getbuffer_doc},
 
897
    {"getvalue",   (PyCFunction)bytesio_getvalue,   METH_NOARGS,  getval_doc},
 
898
    {"seek",       (PyCFunction)bytesio_seek,       METH_VARARGS, seek_doc},
 
899
    {"truncate",   (PyCFunction)bytesio_truncate,   METH_VARARGS, truncate_doc},
 
900
    {"__getstate__",  (PyCFunction)bytesio_getstate,  METH_NOARGS, NULL},
 
901
    {"__setstate__",  (PyCFunction)bytesio_setstate,  METH_O, NULL},
 
902
    {"__sizeof__", (PyCFunction)bytesio_sizeof,     METH_NOARGS, NULL},
 
903
    {NULL, NULL}        /* sentinel */
 
904
};
 
905
 
 
906
PyDoc_STRVAR(bytesio_doc,
 
907
"BytesIO([buffer]) -> object\n"
 
908
"\n"
 
909
"Create a buffered I/O implementation using an in-memory bytes\n"
 
910
"buffer, ready for reading and writing.");
 
911
 
 
912
PyTypeObject PyBytesIO_Type = {
 
913
    PyVarObject_HEAD_INIT(NULL, 0)
 
914
    "_io.BytesIO",                             /*tp_name*/
 
915
    sizeof(bytesio),                     /*tp_basicsize*/
 
916
    0,                                         /*tp_itemsize*/
 
917
    (destructor)bytesio_dealloc,               /*tp_dealloc*/
 
918
    0,                                         /*tp_print*/
 
919
    0,                                         /*tp_getattr*/
 
920
    0,                                         /*tp_setattr*/
 
921
    0,                                         /*tp_reserved*/
 
922
    0,                                         /*tp_repr*/
 
923
    0,                                         /*tp_as_number*/
 
924
    0,                                         /*tp_as_sequence*/
 
925
    0,                                         /*tp_as_mapping*/
 
926
    0,                                         /*tp_hash*/
 
927
    0,                                         /*tp_call*/
 
928
    0,                                         /*tp_str*/
 
929
    0,                                         /*tp_getattro*/
 
930
    0,                                         /*tp_setattro*/
 
931
    0,                                         /*tp_as_buffer*/
 
932
    Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE |
 
933
    Py_TPFLAGS_HAVE_GC,                        /*tp_flags*/
 
934
    bytesio_doc,                               /*tp_doc*/
 
935
    (traverseproc)bytesio_traverse,            /*tp_traverse*/
 
936
    (inquiry)bytesio_clear,                    /*tp_clear*/
 
937
    0,                                         /*tp_richcompare*/
 
938
    offsetof(bytesio, weakreflist),      /*tp_weaklistoffset*/
 
939
    PyObject_SelfIter,                         /*tp_iter*/
 
940
    (iternextfunc)bytesio_iternext,            /*tp_iternext*/
 
941
    bytesio_methods,                           /*tp_methods*/
 
942
    0,                                         /*tp_members*/
 
943
    bytesio_getsetlist,                        /*tp_getset*/
 
944
    0,                                         /*tp_base*/
 
945
    0,                                         /*tp_dict*/
 
946
    0,                                         /*tp_descr_get*/
 
947
    0,                                         /*tp_descr_set*/
 
948
    offsetof(bytesio, dict),             /*tp_dictoffset*/
 
949
    (initproc)bytesio_init,                    /*tp_init*/
 
950
    0,                                         /*tp_alloc*/
 
951
    bytesio_new,                               /*tp_new*/
 
952
};
 
953
 
 
954
 
 
955
/*
 
956
 * Implementation of the small intermediate object used by getbuffer().
 
957
 * getbuffer() returns a memoryview over this object, which should make it
 
958
 * invisible from Python code.
 
959
 */
 
960
 
 
961
static int
 
962
bytesiobuf_getbuffer(bytesiobuf *obj, Py_buffer *view, int flags)
 
963
{
 
964
    int ret;
 
965
    bytesio *b = (bytesio *) obj->source;
 
966
    if (view == NULL) {
 
967
        b->exports++;
 
968
        return 0;
 
969
    }
 
970
    ret = PyBuffer_FillInfo(view, (PyObject*)obj, b->buf, b->string_size,
 
971
                            0, flags);
 
972
    if (ret >= 0) {
 
973
        b->exports++;
 
974
    }
 
975
    return ret;
 
976
}
 
977
 
 
978
static void
 
979
bytesiobuf_releasebuffer(bytesiobuf *obj, Py_buffer *view)
 
980
{
 
981
    bytesio *b = (bytesio *) obj->source;
 
982
    b->exports--;
 
983
}
 
984
 
 
985
static int
 
986
bytesiobuf_traverse(bytesiobuf *self, visitproc visit, void *arg)
 
987
{
 
988
    Py_VISIT(self->source);
 
989
    return 0;
 
990
}
 
991
 
 
992
static void
 
993
bytesiobuf_dealloc(bytesiobuf *self)
 
994
{
 
995
    Py_CLEAR(self->source);
 
996
    Py_TYPE(self)->tp_free(self);
 
997
}
 
998
 
 
999
static PyBufferProcs bytesiobuf_as_buffer = {
 
1000
    (getbufferproc) bytesiobuf_getbuffer,
 
1001
    (releasebufferproc) bytesiobuf_releasebuffer,
 
1002
};
 
1003
 
 
1004
PyTypeObject _PyBytesIOBuffer_Type = {
 
1005
    PyVarObject_HEAD_INIT(NULL, 0)
 
1006
    "_io._BytesIOBuffer",                      /*tp_name*/
 
1007
    sizeof(bytesiobuf),                        /*tp_basicsize*/
 
1008
    0,                                         /*tp_itemsize*/
 
1009
    (destructor)bytesiobuf_dealloc,            /*tp_dealloc*/
 
1010
    0,                                         /*tp_print*/
 
1011
    0,                                         /*tp_getattr*/
 
1012
    0,                                         /*tp_setattr*/
 
1013
    0,                                         /*tp_reserved*/
 
1014
    0,                                         /*tp_repr*/
 
1015
    0,                                         /*tp_as_number*/
 
1016
    0,                                         /*tp_as_sequence*/
 
1017
    0,                                         /*tp_as_mapping*/
 
1018
    0,                                         /*tp_hash*/
 
1019
    0,                                         /*tp_call*/
 
1020
    0,                                         /*tp_str*/
 
1021
    0,                                         /*tp_getattro*/
 
1022
    0,                                         /*tp_setattro*/
 
1023
    &bytesiobuf_as_buffer,                     /*tp_as_buffer*/
 
1024
    Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC,   /*tp_flags*/
 
1025
    0,                                         /*tp_doc*/
 
1026
    (traverseproc)bytesiobuf_traverse,         /*tp_traverse*/
 
1027
    0,                                         /*tp_clear*/
 
1028
    0,                                         /*tp_richcompare*/
 
1029
    0,                                         /*tp_weaklistoffset*/
 
1030
    0,                                         /*tp_iter*/
 
1031
    0,                                         /*tp_iternext*/
 
1032
    0,                                         /*tp_methods*/
 
1033
    0,                                         /*tp_members*/
 
1034
    0,                                         /*tp_getset*/
 
1035
    0,                                         /*tp_base*/
 
1036
    0,                                         /*tp_dict*/
 
1037
    0,                                         /*tp_descr_get*/
 
1038
    0,                                         /*tp_descr_set*/
 
1039
    0,                                         /*tp_dictoffset*/
 
1040
    0,                                         /*tp_init*/
 
1041
    0,                                         /*tp_alloc*/
 
1042
    0,                                         /*tp_new*/
 
1043
};