ยปCore Development>Code coverage>Modules/_io/bytesio.c

Python code coverage for Modules/_io/bytesio.c

#countcontent
1n/a#include "Python.h"
2n/a#include "structmember.h" /* for offsetof() */
3n/a#include "_iomodule.h"
4n/a
5n/a/*[clinic input]
6n/amodule _io
7n/aclass _io.BytesIO "bytesio *" "&PyBytesIO_Type"
8n/a[clinic start generated code]*/
9n/a/*[clinic end generated code: output=da39a3ee5e6b4b0d input=7f50ec034f5c0b26]*/
10n/a
11n/atypedef struct {
12n/a PyObject_HEAD
13n/a PyObject *buf;
14n/a Py_ssize_t pos;
15n/a Py_ssize_t string_size;
16n/a PyObject *dict;
17n/a PyObject *weakreflist;
18n/a Py_ssize_t exports;
19n/a} bytesio;
20n/a
21n/atypedef struct {
22n/a PyObject_HEAD
23n/a bytesio *source;
24n/a} bytesiobuf;
25n/a
26n/a/* The bytesio object can be in three states:
27n/a * Py_REFCNT(buf) == 1, exports == 0.
28n/a * Py_REFCNT(buf) > 1. exports == 0,
29n/a first modification or export causes the internal buffer copying.
30n/a * exports > 0. Py_REFCNT(buf) == 1, any modifications are forbidden.
31n/a*/
32n/a
33n/a#define CHECK_CLOSED(self) \
34n/a if ((self)->buf == NULL) { \
35n/a PyErr_SetString(PyExc_ValueError, \
36n/a "I/O operation on closed file."); \
37n/a return NULL; \
38n/a }
39n/a
40n/a#define CHECK_EXPORTS(self) \
41n/a if ((self)->exports > 0) { \
42n/a PyErr_SetString(PyExc_BufferError, \
43n/a "Existing exports of data: object cannot be re-sized"); \
44n/a return NULL; \
45n/a }
46n/a
47n/a#define SHARED_BUF(self) (Py_REFCNT((self)->buf) > 1)
48n/a
49n/a
50n/a/* Internal routine to get a line from the buffer of a BytesIO
51n/a object. Returns the length between the current position to the
52n/a next newline character. */
53n/astatic Py_ssize_t
54n/ascan_eol(bytesio *self, Py_ssize_t len)
55n/a{
56n/a const char *start, *n;
57n/a Py_ssize_t maxlen;
58n/a
59n/a assert(self->buf != NULL);
60n/a assert(self->pos >= 0);
61n/a
62n/a if (self->pos >= self->string_size)
63n/a return 0;
64n/a
65n/a /* Move to the end of the line, up to the end of the string, s. */
66n/a maxlen = self->string_size - self->pos;
67n/a if (len < 0 || len > maxlen)
68n/a len = maxlen;
69n/a
70n/a if (len) {
71n/a start = PyBytes_AS_STRING(self->buf) + self->pos;
72n/a n = memchr(start, '\n', len);
73n/a if (n)
74n/a /* Get the length from the current position to the end of
75n/a the line. */
76n/a len = n - start + 1;
77n/a }
78n/a assert(len >= 0);
79n/a assert(self->pos < PY_SSIZE_T_MAX - len);
80n/a
81n/a return len;
82n/a}
83n/a
84n/a/* Internal routine for detaching the shared buffer of BytesIO objects.
85n/a The caller should ensure that the 'size' argument is non-negative and
86n/a not lesser than self->string_size. Returns 0 on success, -1 otherwise. */
87n/astatic int
88n/aunshare_buffer(bytesio *self, size_t size)
89n/a{
90n/a PyObject *new_buf;
91n/a assert(SHARED_BUF(self));
92n/a assert(self->exports == 0);
93n/a assert(size >= (size_t)self->string_size);
94n/a new_buf = PyBytes_FromStringAndSize(NULL, size);
95n/a if (new_buf == NULL)
96n/a return -1;
97n/a memcpy(PyBytes_AS_STRING(new_buf), PyBytes_AS_STRING(self->buf),
98n/a self->string_size);
99n/a Py_SETREF(self->buf, new_buf);
100n/a return 0;
101n/a}
102n/a
103n/a/* Internal routine for changing the size of the buffer of BytesIO objects.
104n/a The caller should ensure that the 'size' argument is non-negative. Returns
105n/a 0 on success, -1 otherwise. */
106n/astatic int
107n/aresize_buffer(bytesio *self, size_t size)
108n/a{
109n/a /* Here, unsigned types are used to avoid dealing with signed integer
110n/a overflow, which is undefined in C. */
111n/a size_t alloc = PyBytes_GET_SIZE(self->buf);
112n/a
113n/a assert(self->buf != NULL);
114n/a
115n/a /* For simplicity, stay in the range of the signed type. Anyway, Python
116n/a doesn't allow strings to be longer than this. */
117n/a if (size > PY_SSIZE_T_MAX)
118n/a goto overflow;
119n/a
120n/a if (size < alloc / 2) {
121n/a /* Major downsize; resize down to exact size. */
122n/a alloc = size + 1;
123n/a }
124n/a else if (size < alloc) {
125n/a /* Within allocated size; quick exit */
126n/a return 0;
127n/a }
128n/a else if (size <= alloc * 1.125) {
129n/a /* Moderate upsize; overallocate similar to list_resize() */
130n/a alloc = size + (size >> 3) + (size < 9 ? 3 : 6);
131n/a }
132n/a else {
133n/a /* Major upsize; resize up to exact size */
134n/a alloc = size + 1;
135n/a }
136n/a
137n/a if (alloc > ((size_t)-1) / sizeof(char))
138n/a goto overflow;
139n/a
140n/a if (SHARED_BUF(self)) {
141n/a if (unshare_buffer(self, alloc) < 0)
142n/a return -1;
143n/a }
144n/a else {
145n/a if (_PyBytes_Resize(&self->buf, alloc) < 0)
146n/a return -1;
147n/a }
148n/a
149n/a return 0;
150n/a
151n/a overflow:
152n/a PyErr_SetString(PyExc_OverflowError,
153n/a "new buffer size too large");
154n/a return -1;
155n/a}
156n/a
157n/a/* Internal routine for writing a string of bytes to the buffer of a BytesIO
158n/a object. Returns the number of bytes written, or -1 on error. */
159n/astatic Py_ssize_t
160n/awrite_bytes(bytesio *self, const char *bytes, Py_ssize_t len)
161n/a{
162n/a size_t endpos;
163n/a assert(self->buf != NULL);
164n/a assert(self->pos >= 0);
165n/a assert(len >= 0);
166n/a
167n/a endpos = (size_t)self->pos + len;
168n/a if (endpos > (size_t)PyBytes_GET_SIZE(self->buf)) {
169n/a if (resize_buffer(self, endpos) < 0)
170n/a return -1;
171n/a }
172n/a else if (SHARED_BUF(self)) {
173n/a if (unshare_buffer(self, Py_MAX(endpos, (size_t)self->string_size)) < 0)
174n/a return -1;
175n/a }
176n/a
177n/a if (self->pos > self->string_size) {
178n/a /* In case of overseek, pad with null bytes the buffer region between
179n/a the end of stream and the current position.
180n/a
181n/a 0 lo string_size hi
182n/a | |<---used--->|<----------available----------->|
183n/a | | <--to pad-->|<---to write---> |
184n/a 0 buf position
185n/a */
186n/a memset(PyBytes_AS_STRING(self->buf) + self->string_size, '\0',
187n/a (self->pos - self->string_size) * sizeof(char));
188n/a }
189n/a
190n/a /* Copy the data to the internal buffer, overwriting some of the existing
191n/a data if self->pos < self->string_size. */
192n/a memcpy(PyBytes_AS_STRING(self->buf) + self->pos, bytes, len);
193n/a self->pos = endpos;
194n/a
195n/a /* Set the new length of the internal string if it has changed. */
196n/a if ((size_t)self->string_size < endpos) {
197n/a self->string_size = endpos;
198n/a }
199n/a
200n/a return len;
201n/a}
202n/a
203n/astatic PyObject *
204n/abytesio_get_closed(bytesio *self)
205n/a{
206n/a if (self->buf == NULL) {
207n/a Py_RETURN_TRUE;
208n/a }
209n/a else {
210n/a Py_RETURN_FALSE;
211n/a }
212n/a}
213n/a
214n/a/*[clinic input]
215n/a_io.BytesIO.readable
216n/a
217n/aReturns True if the IO object can be read.
218n/a[clinic start generated code]*/
219n/a
220n/astatic PyObject *
221n/a_io_BytesIO_readable_impl(bytesio *self)
222n/a/*[clinic end generated code: output=4e93822ad5b62263 input=96c5d0cccfb29f5c]*/
223n/a{
224n/a CHECK_CLOSED(self);
225n/a Py_RETURN_TRUE;
226n/a}
227n/a
228n/a/*[clinic input]
229n/a_io.BytesIO.writable
230n/a
231n/aReturns True if the IO object can be written.
232n/a[clinic start generated code]*/
233n/a
234n/astatic PyObject *
235n/a_io_BytesIO_writable_impl(bytesio *self)
236n/a/*[clinic end generated code: output=64ff6a254b1150b8 input=700eed808277560a]*/
237n/a{
238n/a CHECK_CLOSED(self);
239n/a Py_RETURN_TRUE;
240n/a}
241n/a
242n/a/*[clinic input]
243n/a_io.BytesIO.seekable
244n/a
245n/aReturns True if the IO object can be seeked.
246n/a[clinic start generated code]*/
247n/a
248n/astatic PyObject *
249n/a_io_BytesIO_seekable_impl(bytesio *self)
250n/a/*[clinic end generated code: output=6b417f46dcc09b56 input=9421f65627a344dd]*/
251n/a{
252n/a CHECK_CLOSED(self);
253n/a Py_RETURN_TRUE;
254n/a}
255n/a
256n/a/*[clinic input]
257n/a_io.BytesIO.flush
258n/a
259n/aDoes nothing.
260n/a[clinic start generated code]*/
261n/a
262n/astatic PyObject *
263n/a_io_BytesIO_flush_impl(bytesio *self)
264n/a/*[clinic end generated code: output=187e3d781ca134a0 input=561ea490be4581a7]*/
265n/a{
266n/a CHECK_CLOSED(self);
267n/a Py_RETURN_NONE;
268n/a}
269n/a
270n/a/*[clinic input]
271n/a_io.BytesIO.getbuffer
272n/a
273n/aGet a read-write view over the contents of the BytesIO object.
274n/a[clinic start generated code]*/
275n/a
276n/astatic PyObject *
277n/a_io_BytesIO_getbuffer_impl(bytesio *self)
278n/a/*[clinic end generated code: output=72cd7c6e13aa09ed input=8f738ef615865176]*/
279n/a{
280n/a PyTypeObject *type = &_PyBytesIOBuffer_Type;
281n/a bytesiobuf *buf;
282n/a PyObject *view;
283n/a
284n/a CHECK_CLOSED(self);
285n/a
286n/a buf = (bytesiobuf *) type->tp_alloc(type, 0);
287n/a if (buf == NULL)
288n/a return NULL;
289n/a Py_INCREF(self);
290n/a buf->source = self;
291n/a view = PyMemoryView_FromObject((PyObject *) buf);
292n/a Py_DECREF(buf);
293n/a return view;
294n/a}
295n/a
296n/a/*[clinic input]
297n/a_io.BytesIO.getvalue
298n/a
299n/aRetrieve the entire contents of the BytesIO object.
300n/a[clinic start generated code]*/
301n/a
302n/astatic PyObject *
303n/a_io_BytesIO_getvalue_impl(bytesio *self)
304n/a/*[clinic end generated code: output=b3f6a3233c8fd628 input=4b403ac0af3973ed]*/
305n/a{
306n/a CHECK_CLOSED(self);
307n/a if (self->string_size <= 1 || self->exports > 0)
308n/a return PyBytes_FromStringAndSize(PyBytes_AS_STRING(self->buf),
309n/a self->string_size);
310n/a
311n/a if (self->string_size != PyBytes_GET_SIZE(self->buf)) {
312n/a if (SHARED_BUF(self)) {
313n/a if (unshare_buffer(self, self->string_size) < 0)
314n/a return NULL;
315n/a }
316n/a else {
317n/a if (_PyBytes_Resize(&self->buf, self->string_size) < 0)
318n/a return NULL;
319n/a }
320n/a }
321n/a Py_INCREF(self->buf);
322n/a return self->buf;
323n/a}
324n/a
325n/a/*[clinic input]
326n/a_io.BytesIO.isatty
327n/a
328n/aAlways returns False.
329n/a
330n/aBytesIO objects are not connected to a TTY-like device.
331n/a[clinic start generated code]*/
332n/a
333n/astatic PyObject *
334n/a_io_BytesIO_isatty_impl(bytesio *self)
335n/a/*[clinic end generated code: output=df67712e669f6c8f input=6f97f0985d13f827]*/
336n/a{
337n/a CHECK_CLOSED(self);
338n/a Py_RETURN_FALSE;
339n/a}
340n/a
341n/a/*[clinic input]
342n/a_io.BytesIO.tell
343n/a
344n/aCurrent file position, an integer.
345n/a[clinic start generated code]*/
346n/a
347n/astatic PyObject *
348n/a_io_BytesIO_tell_impl(bytesio *self)
349n/a/*[clinic end generated code: output=b54b0f93cd0e5e1d input=b106adf099cb3657]*/
350n/a{
351n/a CHECK_CLOSED(self);
352n/a return PyLong_FromSsize_t(self->pos);
353n/a}
354n/a
355n/astatic PyObject *
356n/aread_bytes(bytesio *self, Py_ssize_t size)
357n/a{
358n/a char *output;
359n/a
360n/a assert(self->buf != NULL);
361n/a assert(size <= self->string_size);
362n/a if (size > 1 &&
363n/a self->pos == 0 && size == PyBytes_GET_SIZE(self->buf) &&
364n/a self->exports == 0) {
365n/a self->pos += size;
366n/a Py_INCREF(self->buf);
367n/a return self->buf;
368n/a }
369n/a
370n/a output = PyBytes_AS_STRING(self->buf) + self->pos;
371n/a self->pos += size;
372n/a return PyBytes_FromStringAndSize(output, size);
373n/a}
374n/a
375n/a/*[clinic input]
376n/a_io.BytesIO.read
377n/a size as arg: object = None
378n/a /
379n/a
380n/aRead at most size bytes, returned as a bytes object.
381n/a
382n/aIf the size argument is negative, read until EOF is reached.
383n/aReturn an empty bytes object at EOF.
384n/a[clinic start generated code]*/
385n/a
386n/astatic PyObject *
387n/a_io_BytesIO_read_impl(bytesio *self, PyObject *arg)
388n/a/*[clinic end generated code: output=85dacb535c1e1781 input=cc7ba4a797bb1555]*/
389n/a{
390n/a Py_ssize_t size, n;
391n/a
392n/a CHECK_CLOSED(self);
393n/a
394n/a if (PyLong_Check(arg)) {
395n/a size = PyLong_AsSsize_t(arg);
396n/a if (size == -1 && PyErr_Occurred())
397n/a return NULL;
398n/a }
399n/a else if (arg == Py_None) {
400n/a /* Read until EOF is reached, by default. */
401n/a size = -1;
402n/a }
403n/a else {
404n/a PyErr_Format(PyExc_TypeError, "integer argument expected, got '%s'",
405n/a Py_TYPE(arg)->tp_name);
406n/a return NULL;
407n/a }
408n/a
409n/a /* adjust invalid sizes */
410n/a n = self->string_size - self->pos;
411n/a if (size < 0 || size > n) {
412n/a size = n;
413n/a if (size < 0)
414n/a size = 0;
415n/a }
416n/a
417n/a return read_bytes(self, size);
418n/a}
419n/a
420n/a
421n/a/*[clinic input]
422n/a_io.BytesIO.read1
423n/a size: object(c_default="Py_None") = -1
424n/a /
425n/a
426n/aRead at most size bytes, returned as a bytes object.
427n/a
428n/aIf the size argument is negative or omitted, read until EOF is reached.
429n/aReturn an empty bytes object at EOF.
430n/a[clinic start generated code]*/
431n/a
432n/astatic PyObject *
433n/a_io_BytesIO_read1_impl(bytesio *self, PyObject *size)
434n/a/*[clinic end generated code: output=a60d80c84c81a6b8 input=0951874bafee8e80]*/
435n/a{
436n/a return _io_BytesIO_read_impl(self, size);
437n/a}
438n/a
439n/a/*[clinic input]
440n/a_io.BytesIO.readline
441n/a size as arg: object = None
442n/a /
443n/a
444n/aNext line from the file, as a bytes object.
445n/a
446n/aRetain newline. A non-negative size argument limits the maximum
447n/anumber of bytes to return (an incomplete line may be returned then).
448n/aReturn an empty bytes object at EOF.
449n/a[clinic start generated code]*/
450n/a
451n/astatic PyObject *
452n/a_io_BytesIO_readline_impl(bytesio *self, PyObject *arg)
453n/a/*[clinic end generated code: output=1c2115534a4f9276 input=ca31f06de6eab257]*/
454n/a{
455n/a Py_ssize_t size, n;
456n/a
457n/a CHECK_CLOSED(self);
458n/a
459n/a if (PyLong_Check(arg)) {
460n/a size = PyLong_AsSsize_t(arg);
461n/a if (size == -1 && PyErr_Occurred())
462n/a return NULL;
463n/a }
464n/a else if (arg == Py_None) {
465n/a /* No size limit, by default. */
466n/a size = -1;
467n/a }
468n/a else {
469n/a PyErr_Format(PyExc_TypeError, "integer argument expected, got '%s'",
470n/a Py_TYPE(arg)->tp_name);
471n/a return NULL;
472n/a }
473n/a
474n/a n = scan_eol(self, size);
475n/a
476n/a return read_bytes(self, n);
477n/a}
478n/a
479n/a/*[clinic input]
480n/a_io.BytesIO.readlines
481n/a size as arg: object = None
482n/a /
483n/a
484n/aList of bytes objects, each a line from the file.
485n/a
486n/aCall readline() repeatedly and return a list of the lines so read.
487n/aThe optional size argument, if given, is an approximate bound on the
488n/atotal number of bytes in the lines returned.
489n/a[clinic start generated code]*/
490n/a
491n/astatic PyObject *
492n/a_io_BytesIO_readlines_impl(bytesio *self, PyObject *arg)
493n/a/*[clinic end generated code: output=09b8e34c880808ff input=691aa1314f2c2a87]*/
494n/a{
495n/a Py_ssize_t maxsize, size, n;
496n/a PyObject *result, *line;
497n/a char *output;
498n/a
499n/a CHECK_CLOSED(self);
500n/a
501n/a if (PyLong_Check(arg)) {
502n/a maxsize = PyLong_AsSsize_t(arg);
503n/a if (maxsize == -1 && PyErr_Occurred())
504n/a return NULL;
505n/a }
506n/a else if (arg == Py_None) {
507n/a /* No size limit, by default. */
508n/a maxsize = -1;
509n/a }
510n/a else {
511n/a PyErr_Format(PyExc_TypeError, "integer argument expected, got '%s'",
512n/a Py_TYPE(arg)->tp_name);
513n/a return NULL;
514n/a }
515n/a
516n/a size = 0;
517n/a result = PyList_New(0);
518n/a if (!result)
519n/a return NULL;
520n/a
521n/a output = PyBytes_AS_STRING(self->buf) + self->pos;
522n/a while ((n = scan_eol(self, -1)) != 0) {
523n/a self->pos += n;
524n/a line = PyBytes_FromStringAndSize(output, n);
525n/a if (!line)
526n/a goto on_error;
527n/a if (PyList_Append(result, line) == -1) {
528n/a Py_DECREF(line);
529n/a goto on_error;
530n/a }
531n/a Py_DECREF(line);
532n/a size += n;
533n/a if (maxsize > 0 && size >= maxsize)
534n/a break;
535n/a output += n;
536n/a }
537n/a return result;
538n/a
539n/a on_error:
540n/a Py_DECREF(result);
541n/a return NULL;
542n/a}
543n/a
544n/a/*[clinic input]
545n/a_io.BytesIO.readinto
546n/a buffer: Py_buffer(accept={rwbuffer})
547n/a /
548n/a
549n/aRead bytes into buffer.
550n/a
551n/aReturns number of bytes read (0 for EOF), or None if the object
552n/ais set not to block and has no data to read.
553n/a[clinic start generated code]*/
554n/a
555n/astatic PyObject *
556n/a_io_BytesIO_readinto_impl(bytesio *self, Py_buffer *buffer)
557n/a/*[clinic end generated code: output=a5d407217dcf0639 input=1424d0fdce857919]*/
558n/a{
559n/a Py_ssize_t len, n;
560n/a
561n/a CHECK_CLOSED(self);
562n/a
563n/a /* adjust invalid sizes */
564n/a len = buffer->len;
565n/a n = self->string_size - self->pos;
566n/a if (len > n) {
567n/a len = n;
568n/a if (len < 0)
569n/a len = 0;
570n/a }
571n/a
572n/a memcpy(buffer->buf, PyBytes_AS_STRING(self->buf) + self->pos, len);
573n/a assert(self->pos + len < PY_SSIZE_T_MAX);
574n/a assert(len >= 0);
575n/a self->pos += len;
576n/a
577n/a return PyLong_FromSsize_t(len);
578n/a}
579n/a
580n/a/*[clinic input]
581n/a_io.BytesIO.truncate
582n/a size as arg: object = None
583n/a /
584n/a
585n/aTruncate the file to at most size bytes.
586n/a
587n/aSize defaults to the current file position, as returned by tell().
588n/aThe current file position is unchanged. Returns the new size.
589n/a[clinic start generated code]*/
590n/a
591n/astatic PyObject *
592n/a_io_BytesIO_truncate_impl(bytesio *self, PyObject *arg)
593n/a/*[clinic end generated code: output=81e6be60e67ddd66 input=11ed1966835462ba]*/
594n/a{
595n/a Py_ssize_t size;
596n/a
597n/a CHECK_CLOSED(self);
598n/a CHECK_EXPORTS(self);
599n/a
600n/a if (PyLong_Check(arg)) {
601n/a size = PyLong_AsSsize_t(arg);
602n/a if (size == -1 && PyErr_Occurred())
603n/a return NULL;
604n/a }
605n/a else if (arg == Py_None) {
606n/a /* Truncate to current position if no argument is passed. */
607n/a size = self->pos;
608n/a }
609n/a else {
610n/a PyErr_Format(PyExc_TypeError, "integer argument expected, got '%s'",
611n/a Py_TYPE(arg)->tp_name);
612n/a return NULL;
613n/a }
614n/a
615n/a if (size < 0) {
616n/a PyErr_Format(PyExc_ValueError,
617n/a "negative size value %zd", size);
618n/a return NULL;
619n/a }
620n/a
621n/a if (size < self->string_size) {
622n/a self->string_size = size;
623n/a if (resize_buffer(self, size) < 0)
624n/a return NULL;
625n/a }
626n/a
627n/a return PyLong_FromSsize_t(size);
628n/a}
629n/a
630n/astatic PyObject *
631n/abytesio_iternext(bytesio *self)
632n/a{
633n/a Py_ssize_t n;
634n/a
635n/a CHECK_CLOSED(self);
636n/a
637n/a n = scan_eol(self, -1);
638n/a
639n/a if (n == 0)
640n/a return NULL;
641n/a
642n/a return read_bytes(self, n);
643n/a}
644n/a
645n/a/*[clinic input]
646n/a_io.BytesIO.seek
647n/a pos: Py_ssize_t
648n/a whence: int = 0
649n/a /
650n/a
651n/aChange stream position.
652n/a
653n/aSeek to byte offset pos relative to position indicated by whence:
654n/a 0 Start of stream (the default). pos should be >= 0;
655n/a 1 Current position - pos may be negative;
656n/a 2 End of stream - pos usually negative.
657n/aReturns the new absolute position.
658n/a[clinic start generated code]*/
659n/a
660n/astatic PyObject *
661n/a_io_BytesIO_seek_impl(bytesio *self, Py_ssize_t pos, int whence)
662n/a/*[clinic end generated code: output=c26204a68e9190e4 input=1e875e6ebc652948]*/
663n/a{
664n/a CHECK_CLOSED(self);
665n/a
666n/a if (pos < 0 && whence == 0) {
667n/a PyErr_Format(PyExc_ValueError,
668n/a "negative seek value %zd", pos);
669n/a return NULL;
670n/a }
671n/a
672n/a /* whence = 0: offset relative to beginning of the string.
673n/a whence = 1: offset relative to current position.
674n/a whence = 2: offset relative the end of the string. */
675n/a if (whence == 1) {
676n/a if (pos > PY_SSIZE_T_MAX - self->pos) {
677n/a PyErr_SetString(PyExc_OverflowError,
678n/a "new position too large");
679n/a return NULL;
680n/a }
681n/a pos += self->pos;
682n/a }
683n/a else if (whence == 2) {
684n/a if (pos > PY_SSIZE_T_MAX - self->string_size) {
685n/a PyErr_SetString(PyExc_OverflowError,
686n/a "new position too large");
687n/a return NULL;
688n/a }
689n/a pos += self->string_size;
690n/a }
691n/a else if (whence != 0) {
692n/a PyErr_Format(PyExc_ValueError,
693n/a "invalid whence (%i, should be 0, 1 or 2)", whence);
694n/a return NULL;
695n/a }
696n/a
697n/a if (pos < 0)
698n/a pos = 0;
699n/a self->pos = pos;
700n/a
701n/a return PyLong_FromSsize_t(self->pos);
702n/a}
703n/a
704n/a/*[clinic input]
705n/a_io.BytesIO.write
706n/a b: object
707n/a /
708n/a
709n/aWrite bytes to file.
710n/a
711n/aReturn the number of bytes written.
712n/a[clinic start generated code]*/
713n/a
714n/astatic PyObject *
715n/a_io_BytesIO_write(bytesio *self, PyObject *b)
716n/a/*[clinic end generated code: output=53316d99800a0b95 input=f5ec7c8c64ed720a]*/
717n/a{
718n/a Py_ssize_t n = 0;
719n/a Py_buffer buf;
720n/a
721n/a CHECK_CLOSED(self);
722n/a CHECK_EXPORTS(self);
723n/a
724n/a if (PyObject_GetBuffer(b, &buf, PyBUF_CONTIG_RO) < 0)
725n/a return NULL;
726n/a
727n/a if (buf.len != 0)
728n/a n = write_bytes(self, buf.buf, buf.len);
729n/a
730n/a PyBuffer_Release(&buf);
731n/a return n >= 0 ? PyLong_FromSsize_t(n) : NULL;
732n/a}
733n/a
734n/a/*[clinic input]
735n/a_io.BytesIO.writelines
736n/a lines: object
737n/a /
738n/a
739n/aWrite lines to the file.
740n/a
741n/aNote that newlines are not added. lines can be any iterable object
742n/aproducing bytes-like objects. This is equivalent to calling write() for
743n/aeach element.
744n/a[clinic start generated code]*/
745n/a
746n/astatic PyObject *
747n/a_io_BytesIO_writelines(bytesio *self, PyObject *lines)
748n/a/*[clinic end generated code: output=7f33aa3271c91752 input=e972539176fc8fc1]*/
749n/a{
750n/a PyObject *it, *item;
751n/a PyObject *ret;
752n/a
753n/a CHECK_CLOSED(self);
754n/a
755n/a it = PyObject_GetIter(lines);
756n/a if (it == NULL)
757n/a return NULL;
758n/a
759n/a while ((item = PyIter_Next(it)) != NULL) {
760n/a ret = _io_BytesIO_write(self, item);
761n/a Py_DECREF(item);
762n/a if (ret == NULL) {
763n/a Py_DECREF(it);
764n/a return NULL;
765n/a }
766n/a Py_DECREF(ret);
767n/a }
768n/a Py_DECREF(it);
769n/a
770n/a /* See if PyIter_Next failed */
771n/a if (PyErr_Occurred())
772n/a return NULL;
773n/a
774n/a Py_RETURN_NONE;
775n/a}
776n/a
777n/a/*[clinic input]
778n/a_io.BytesIO.close
779n/a
780n/aDisable all I/O operations.
781n/a[clinic start generated code]*/
782n/a
783n/astatic PyObject *
784n/a_io_BytesIO_close_impl(bytesio *self)
785n/a/*[clinic end generated code: output=1471bb9411af84a0 input=37e1f55556e61f60]*/
786n/a{
787n/a CHECK_EXPORTS(self);
788n/a Py_CLEAR(self->buf);
789n/a Py_RETURN_NONE;
790n/a}
791n/a
792n/a/* Pickling support.
793n/a
794n/a Note that only pickle protocol 2 and onward are supported since we use
795n/a extended __reduce__ API of PEP 307 to make BytesIO instances picklable.
796n/a
797n/a Providing support for protocol < 2 would require the __reduce_ex__ method
798n/a which is notably long-winded when defined properly.
799n/a
800n/a For BytesIO, the implementation would similar to one coded for
801n/a object.__reduce_ex__, but slightly less general. To be more specific, we
802n/a could call bytesio_getstate directly and avoid checking for the presence of
803n/a a fallback __reduce__ method. However, we would still need a __newobj__
804n/a function to use the efficient instance representation of PEP 307.
805n/a */
806n/a
807n/astatic PyObject *
808n/abytesio_getstate(bytesio *self)
809n/a{
810n/a PyObject *initvalue = _io_BytesIO_getvalue_impl(self);
811n/a PyObject *dict;
812n/a PyObject *state;
813n/a
814n/a if (initvalue == NULL)
815n/a return NULL;
816n/a if (self->dict == NULL) {
817n/a Py_INCREF(Py_None);
818n/a dict = Py_None;
819n/a }
820n/a else {
821n/a dict = PyDict_Copy(self->dict);
822n/a if (dict == NULL) {
823n/a Py_DECREF(initvalue);
824n/a return NULL;
825n/a }
826n/a }
827n/a
828n/a state = Py_BuildValue("(OnN)", initvalue, self->pos, dict);
829n/a Py_DECREF(initvalue);
830n/a return state;
831n/a}
832n/a
833n/astatic PyObject *
834n/abytesio_setstate(bytesio *self, PyObject *state)
835n/a{
836n/a PyObject *result;
837n/a PyObject *position_obj;
838n/a PyObject *dict;
839n/a Py_ssize_t pos;
840n/a
841n/a assert(state != NULL);
842n/a
843n/a /* We allow the state tuple to be longer than 3, because we may need
844n/a someday to extend the object's state without breaking
845n/a backward-compatibility. */
846n/a if (!PyTuple_Check(state) || Py_SIZE(state) < 3) {
847n/a PyErr_Format(PyExc_TypeError,
848n/a "%.200s.__setstate__ argument should be 3-tuple, got %.200s",
849n/a Py_TYPE(self)->tp_name, Py_TYPE(state)->tp_name);
850n/a return NULL;
851n/a }
852n/a CHECK_EXPORTS(self);
853n/a /* Reset the object to its default state. This is only needed to handle
854n/a the case of repeated calls to __setstate__. */
855n/a self->string_size = 0;
856n/a self->pos = 0;
857n/a
858n/a /* Set the value of the internal buffer. If state[0] does not support the
859n/a buffer protocol, bytesio_write will raise the appropriate TypeError. */
860n/a result = _io_BytesIO_write(self, PyTuple_GET_ITEM(state, 0));
861n/a if (result == NULL)
862n/a return NULL;
863n/a Py_DECREF(result);
864n/a
865n/a /* Set carefully the position value. Alternatively, we could use the seek
866n/a method instead of modifying self->pos directly to better protect the
867n/a object internal state against errneous (or malicious) inputs. */
868n/a position_obj = PyTuple_GET_ITEM(state, 1);
869n/a if (!PyLong_Check(position_obj)) {
870n/a PyErr_Format(PyExc_TypeError,
871n/a "second item of state must be an integer, not %.200s",
872n/a Py_TYPE(position_obj)->tp_name);
873n/a return NULL;
874n/a }
875n/a pos = PyLong_AsSsize_t(position_obj);
876n/a if (pos == -1 && PyErr_Occurred())
877n/a return NULL;
878n/a if (pos < 0) {
879n/a PyErr_SetString(PyExc_ValueError,
880n/a "position value cannot be negative");
881n/a return NULL;
882n/a }
883n/a self->pos = pos;
884n/a
885n/a /* Set the dictionary of the instance variables. */
886n/a dict = PyTuple_GET_ITEM(state, 2);
887n/a if (dict != Py_None) {
888n/a if (!PyDict_Check(dict)) {
889n/a PyErr_Format(PyExc_TypeError,
890n/a "third item of state should be a dict, got a %.200s",
891n/a Py_TYPE(dict)->tp_name);
892n/a return NULL;
893n/a }
894n/a if (self->dict) {
895n/a /* Alternatively, we could replace the internal dictionary
896n/a completely. However, it seems more practical to just update it. */
897n/a if (PyDict_Update(self->dict, dict) < 0)
898n/a return NULL;
899n/a }
900n/a else {
901n/a Py_INCREF(dict);
902n/a self->dict = dict;
903n/a }
904n/a }
905n/a
906n/a Py_RETURN_NONE;
907n/a}
908n/a
909n/astatic void
910n/abytesio_dealloc(bytesio *self)
911n/a{
912n/a _PyObject_GC_UNTRACK(self);
913n/a if (self->exports > 0) {
914n/a PyErr_SetString(PyExc_SystemError,
915n/a "deallocated BytesIO object has exported buffers");
916n/a PyErr_Print();
917n/a }
918n/a Py_CLEAR(self->buf);
919n/a Py_CLEAR(self->dict);
920n/a if (self->weakreflist != NULL)
921n/a PyObject_ClearWeakRefs((PyObject *) self);
922n/a Py_TYPE(self)->tp_free(self);
923n/a}
924n/a
925n/astatic PyObject *
926n/abytesio_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
927n/a{
928n/a bytesio *self;
929n/a
930n/a assert(type != NULL && type->tp_alloc != NULL);
931n/a self = (bytesio *)type->tp_alloc(type, 0);
932n/a if (self == NULL)
933n/a return NULL;
934n/a
935n/a /* tp_alloc initializes all the fields to zero. So we don't have to
936n/a initialize them here. */
937n/a
938n/a self->buf = PyBytes_FromStringAndSize(NULL, 0);
939n/a if (self->buf == NULL) {
940n/a Py_DECREF(self);
941n/a return PyErr_NoMemory();
942n/a }
943n/a
944n/a return (PyObject *)self;
945n/a}
946n/a
947n/a/*[clinic input]
948n/a_io.BytesIO.__init__
949n/a initial_bytes as initvalue: object(c_default="NULL") = b''
950n/a
951n/aBuffered I/O implementation using an in-memory bytes buffer.
952n/a[clinic start generated code]*/
953n/a
954n/astatic int
955n/a_io_BytesIO___init___impl(bytesio *self, PyObject *initvalue)
956n/a/*[clinic end generated code: output=65c0c51e24c5b621 input=aac7f31b67bf0fb6]*/
957n/a{
958n/a /* In case, __init__ is called multiple times. */
959n/a self->string_size = 0;
960n/a self->pos = 0;
961n/a
962n/a if (self->exports > 0) {
963n/a PyErr_SetString(PyExc_BufferError,
964n/a "Existing exports of data: object cannot be re-sized");
965n/a return -1;
966n/a }
967n/a if (initvalue && initvalue != Py_None) {
968n/a if (PyBytes_CheckExact(initvalue)) {
969n/a Py_INCREF(initvalue);
970n/a Py_XSETREF(self->buf, initvalue);
971n/a self->string_size = PyBytes_GET_SIZE(initvalue);
972n/a }
973n/a else {
974n/a PyObject *res;
975n/a res = _io_BytesIO_write(self, initvalue);
976n/a if (res == NULL)
977n/a return -1;
978n/a Py_DECREF(res);
979n/a self->pos = 0;
980n/a }
981n/a }
982n/a
983n/a return 0;
984n/a}
985n/a
986n/astatic PyObject *
987n/abytesio_sizeof(bytesio *self, void *unused)
988n/a{
989n/a Py_ssize_t res;
990n/a
991n/a res = _PyObject_SIZE(Py_TYPE(self));
992n/a if (self->buf && !SHARED_BUF(self))
993n/a res += _PySys_GetSizeOf(self->buf);
994n/a return PyLong_FromSsize_t(res);
995n/a}
996n/a
997n/astatic int
998n/abytesio_traverse(bytesio *self, visitproc visit, void *arg)
999n/a{
1000n/a Py_VISIT(self->dict);
1001n/a return 0;
1002n/a}
1003n/a
1004n/astatic int
1005n/abytesio_clear(bytesio *self)
1006n/a{
1007n/a Py_CLEAR(self->dict);
1008n/a return 0;
1009n/a}
1010n/a
1011n/a
1012n/a#include "clinic/bytesio.c.h"
1013n/a
1014n/astatic PyGetSetDef bytesio_getsetlist[] = {
1015n/a {"closed", (getter)bytesio_get_closed, NULL,
1016n/a "True if the file is closed."},
1017n/a {NULL}, /* sentinel */
1018n/a};
1019n/a
1020n/astatic struct PyMethodDef bytesio_methods[] = {
1021n/a _IO_BYTESIO_READABLE_METHODDEF
1022n/a _IO_BYTESIO_SEEKABLE_METHODDEF
1023n/a _IO_BYTESIO_WRITABLE_METHODDEF
1024n/a _IO_BYTESIO_CLOSE_METHODDEF
1025n/a _IO_BYTESIO_FLUSH_METHODDEF
1026n/a _IO_BYTESIO_ISATTY_METHODDEF
1027n/a _IO_BYTESIO_TELL_METHODDEF
1028n/a _IO_BYTESIO_WRITE_METHODDEF
1029n/a _IO_BYTESIO_WRITELINES_METHODDEF
1030n/a _IO_BYTESIO_READ1_METHODDEF
1031n/a _IO_BYTESIO_READINTO_METHODDEF
1032n/a _IO_BYTESIO_READLINE_METHODDEF
1033n/a _IO_BYTESIO_READLINES_METHODDEF
1034n/a _IO_BYTESIO_READ_METHODDEF
1035n/a _IO_BYTESIO_GETBUFFER_METHODDEF
1036n/a _IO_BYTESIO_GETVALUE_METHODDEF
1037n/a _IO_BYTESIO_SEEK_METHODDEF
1038n/a _IO_BYTESIO_TRUNCATE_METHODDEF
1039n/a {"__getstate__", (PyCFunction)bytesio_getstate, METH_NOARGS, NULL},
1040n/a {"__setstate__", (PyCFunction)bytesio_setstate, METH_O, NULL},
1041n/a {"__sizeof__", (PyCFunction)bytesio_sizeof, METH_NOARGS, NULL},
1042n/a {NULL, NULL} /* sentinel */
1043n/a};
1044n/a
1045n/aPyTypeObject PyBytesIO_Type = {
1046n/a PyVarObject_HEAD_INIT(NULL, 0)
1047n/a "_io.BytesIO", /*tp_name*/
1048n/a sizeof(bytesio), /*tp_basicsize*/
1049n/a 0, /*tp_itemsize*/
1050n/a (destructor)bytesio_dealloc, /*tp_dealloc*/
1051n/a 0, /*tp_print*/
1052n/a 0, /*tp_getattr*/
1053n/a 0, /*tp_setattr*/
1054n/a 0, /*tp_reserved*/
1055n/a 0, /*tp_repr*/
1056n/a 0, /*tp_as_number*/
1057n/a 0, /*tp_as_sequence*/
1058n/a 0, /*tp_as_mapping*/
1059n/a 0, /*tp_hash*/
1060n/a 0, /*tp_call*/
1061n/a 0, /*tp_str*/
1062n/a 0, /*tp_getattro*/
1063n/a 0, /*tp_setattro*/
1064n/a 0, /*tp_as_buffer*/
1065n/a Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE |
1066n/a Py_TPFLAGS_HAVE_GC, /*tp_flags*/
1067n/a _io_BytesIO___init____doc__, /*tp_doc*/
1068n/a (traverseproc)bytesio_traverse, /*tp_traverse*/
1069n/a (inquiry)bytesio_clear, /*tp_clear*/
1070n/a 0, /*tp_richcompare*/
1071n/a offsetof(bytesio, weakreflist), /*tp_weaklistoffset*/
1072n/a PyObject_SelfIter, /*tp_iter*/
1073n/a (iternextfunc)bytesio_iternext, /*tp_iternext*/
1074n/a bytesio_methods, /*tp_methods*/
1075n/a 0, /*tp_members*/
1076n/a bytesio_getsetlist, /*tp_getset*/
1077n/a 0, /*tp_base*/
1078n/a 0, /*tp_dict*/
1079n/a 0, /*tp_descr_get*/
1080n/a 0, /*tp_descr_set*/
1081n/a offsetof(bytesio, dict), /*tp_dictoffset*/
1082n/a _io_BytesIO___init__, /*tp_init*/
1083n/a 0, /*tp_alloc*/
1084n/a bytesio_new, /*tp_new*/
1085n/a};
1086n/a
1087n/a
1088n/a/*
1089n/a * Implementation of the small intermediate object used by getbuffer().
1090n/a * getbuffer() returns a memoryview over this object, which should make it
1091n/a * invisible from Python code.
1092n/a */
1093n/a
1094n/astatic int
1095n/abytesiobuf_getbuffer(bytesiobuf *obj, Py_buffer *view, int flags)
1096n/a{
1097n/a bytesio *b = (bytesio *) obj->source;
1098n/a
1099n/a if (view == NULL) {
1100n/a PyErr_SetString(PyExc_BufferError,
1101n/a "bytesiobuf_getbuffer: view==NULL argument is obsolete");
1102n/a return -1;
1103n/a }
1104n/a if (SHARED_BUF(b)) {
1105n/a if (unshare_buffer(b, b->string_size) < 0)
1106n/a return -1;
1107n/a }
1108n/a
1109n/a /* cannot fail if view != NULL and readonly == 0 */
1110n/a (void)PyBuffer_FillInfo(view, (PyObject*)obj,
1111n/a PyBytes_AS_STRING(b->buf), b->string_size,
1112n/a 0, flags);
1113n/a b->exports++;
1114n/a return 0;
1115n/a}
1116n/a
1117n/astatic void
1118n/abytesiobuf_releasebuffer(bytesiobuf *obj, Py_buffer *view)
1119n/a{
1120n/a bytesio *b = (bytesio *) obj->source;
1121n/a b->exports--;
1122n/a}
1123n/a
1124n/astatic int
1125n/abytesiobuf_traverse(bytesiobuf *self, visitproc visit, void *arg)
1126n/a{
1127n/a Py_VISIT(self->source);
1128n/a return 0;
1129n/a}
1130n/a
1131n/astatic void
1132n/abytesiobuf_dealloc(bytesiobuf *self)
1133n/a{
1134n/a Py_CLEAR(self->source);
1135n/a Py_TYPE(self)->tp_free(self);
1136n/a}
1137n/a
1138n/astatic PyBufferProcs bytesiobuf_as_buffer = {
1139n/a (getbufferproc) bytesiobuf_getbuffer,
1140n/a (releasebufferproc) bytesiobuf_releasebuffer,
1141n/a};
1142n/a
1143n/aPyTypeObject _PyBytesIOBuffer_Type = {
1144n/a PyVarObject_HEAD_INIT(NULL, 0)
1145n/a "_io._BytesIOBuffer", /*tp_name*/
1146n/a sizeof(bytesiobuf), /*tp_basicsize*/
1147n/a 0, /*tp_itemsize*/
1148n/a (destructor)bytesiobuf_dealloc, /*tp_dealloc*/
1149n/a 0, /*tp_print*/
1150n/a 0, /*tp_getattr*/
1151n/a 0, /*tp_setattr*/
1152n/a 0, /*tp_reserved*/
1153n/a 0, /*tp_repr*/
1154n/a 0, /*tp_as_number*/
1155n/a 0, /*tp_as_sequence*/
1156n/a 0, /*tp_as_mapping*/
1157n/a 0, /*tp_hash*/
1158n/a 0, /*tp_call*/
1159n/a 0, /*tp_str*/
1160n/a 0, /*tp_getattro*/
1161n/a 0, /*tp_setattro*/
1162n/a &bytesiobuf_as_buffer, /*tp_as_buffer*/
1163n/a Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC, /*tp_flags*/
1164n/a 0, /*tp_doc*/
1165n/a (traverseproc)bytesiobuf_traverse, /*tp_traverse*/
1166n/a 0, /*tp_clear*/
1167n/a 0, /*tp_richcompare*/
1168n/a 0, /*tp_weaklistoffset*/
1169n/a 0, /*tp_iter*/
1170n/a 0, /*tp_iternext*/
1171n/a 0, /*tp_methods*/
1172n/a 0, /*tp_members*/
1173n/a 0, /*tp_getset*/
1174n/a 0, /*tp_base*/
1175n/a 0, /*tp_dict*/
1176n/a 0, /*tp_descr_get*/
1177n/a 0, /*tp_descr_set*/
1178n/a 0, /*tp_dictoffset*/
1179n/a 0, /*tp_init*/
1180n/a 0, /*tp_alloc*/
1181n/a 0, /*tp_new*/
1182n/a};