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

Python code coverage for Modules/_io/bufferedio.c

#countcontent
1n/a/*
2n/a An implementation of Buffered I/O as defined by PEP 3116 - "New I/O"
3n/a
4n/a Classes defined here: BufferedIOBase, BufferedReader, BufferedWriter,
5n/a BufferedRandom.
6n/a
7n/a Written by Amaury Forgeot d'Arc and Antoine Pitrou
8n/a*/
9n/a
10n/a#define PY_SSIZE_T_CLEAN
11n/a#include "Python.h"
12n/a#include "structmember.h"
13n/a#include "pythread.h"
14n/a#include "_iomodule.h"
15n/a
16n/a/*[clinic input]
17n/amodule _io
18n/aclass _io._BufferedIOBase "PyObject *" "&PyBufferedIOBase_Type"
19n/aclass _io._Buffered "buffered *" "&PyBufferedIOBase_Type"
20n/aclass _io.BufferedReader "buffered *" "&PyBufferedReader_Type"
21n/aclass _io.BufferedWriter "buffered *" "&PyBufferedWriter_Type"
22n/aclass _io.BufferedRWPair "rwpair *" "&PyBufferedRWPair_Type"
23n/aclass _io.BufferedRandom "buffered *" "&PyBufferedRandom_Type"
24n/a[clinic start generated code]*/
25n/a/*[clinic end generated code: output=da39a3ee5e6b4b0d input=59460b9c5639984d]*/
26n/a
27n/a/*[python input]
28n/aclass io_ssize_t_converter(CConverter):
29n/a type = 'Py_ssize_t'
30n/a converter = '_PyIO_ConvertSsize_t'
31n/a[python start generated code]*/
32n/a/*[python end generated code: output=da39a3ee5e6b4b0d input=d0a811d3cbfd1b33]*/
33n/a
34n/a_Py_IDENTIFIER(close);
35n/a_Py_IDENTIFIER(_dealloc_warn);
36n/a_Py_IDENTIFIER(flush);
37n/a_Py_IDENTIFIER(isatty);
38n/a_Py_IDENTIFIER(mode);
39n/a_Py_IDENTIFIER(name);
40n/a_Py_IDENTIFIER(peek);
41n/a_Py_IDENTIFIER(read);
42n/a_Py_IDENTIFIER(read1);
43n/a_Py_IDENTIFIER(readable);
44n/a_Py_IDENTIFIER(readinto);
45n/a_Py_IDENTIFIER(readinto1);
46n/a_Py_IDENTIFIER(writable);
47n/a_Py_IDENTIFIER(write);
48n/a
49n/a/*
50n/a * BufferedIOBase class, inherits from IOBase.
51n/a */
52n/aPyDoc_STRVAR(bufferediobase_doc,
53n/a "Base class for buffered IO objects.\n"
54n/a "\n"
55n/a "The main difference with RawIOBase is that the read() method\n"
56n/a "supports omitting the size argument, and does not have a default\n"
57n/a "implementation that defers to readinto().\n"
58n/a "\n"
59n/a "In addition, read(), readinto() and write() may raise\n"
60n/a "BlockingIOError if the underlying raw stream is in non-blocking\n"
61n/a "mode and not ready; unlike their raw counterparts, they will never\n"
62n/a "return None.\n"
63n/a "\n"
64n/a "A typical implementation should not inherit from a RawIOBase\n"
65n/a "implementation, but wrap one.\n"
66n/a );
67n/a
68n/astatic PyObject *
69n/a_bufferediobase_readinto_generic(PyObject *self, Py_buffer *buffer, char readinto1)
70n/a{
71n/a Py_ssize_t len;
72n/a PyObject *data;
73n/a
74n/a data = _PyObject_CallMethodId(self,
75n/a readinto1 ? &PyId_read1 : &PyId_read,
76n/a "n", buffer->len);
77n/a if (data == NULL)
78n/a return NULL;
79n/a
80n/a if (!PyBytes_Check(data)) {
81n/a Py_DECREF(data);
82n/a PyErr_SetString(PyExc_TypeError, "read() should return bytes");
83n/a return NULL;
84n/a }
85n/a
86n/a len = Py_SIZE(data);
87n/a if (len > buffer->len) {
88n/a PyErr_Format(PyExc_ValueError,
89n/a "read() returned too much data: "
90n/a "%zd bytes requested, %zd returned",
91n/a buffer->len, len);
92n/a Py_DECREF(data);
93n/a return NULL;
94n/a }
95n/a memcpy(buffer->buf, PyBytes_AS_STRING(data), len);
96n/a
97n/a Py_DECREF(data);
98n/a
99n/a return PyLong_FromSsize_t(len);
100n/a}
101n/a
102n/a/*[clinic input]
103n/a_io._BufferedIOBase.readinto
104n/a buffer: Py_buffer(accept={rwbuffer})
105n/a /
106n/a[clinic start generated code]*/
107n/a
108n/astatic PyObject *
109n/a_io__BufferedIOBase_readinto_impl(PyObject *self, Py_buffer *buffer)
110n/a/*[clinic end generated code: output=8c8cda6684af8038 input=00a6b9a38f29830a]*/
111n/a{
112n/a return _bufferediobase_readinto_generic(self, buffer, 0);
113n/a}
114n/a
115n/a/*[clinic input]
116n/a_io._BufferedIOBase.readinto1
117n/a buffer: Py_buffer(accept={rwbuffer})
118n/a /
119n/a[clinic start generated code]*/
120n/a
121n/astatic PyObject *
122n/a_io__BufferedIOBase_readinto1_impl(PyObject *self, Py_buffer *buffer)
123n/a/*[clinic end generated code: output=358623e4fd2b69d3 input=ebad75b4aadfb9be]*/
124n/a{
125n/a return _bufferediobase_readinto_generic(self, buffer, 1);
126n/a}
127n/a
128n/astatic PyObject *
129n/abufferediobase_unsupported(const char *message)
130n/a{
131n/a _PyIO_State *state = IO_STATE();
132n/a if (state != NULL)
133n/a PyErr_SetString(state->unsupported_operation, message);
134n/a return NULL;
135n/a}
136n/a
137n/a/*[clinic input]
138n/a_io._BufferedIOBase.detach
139n/a
140n/aDisconnect this buffer from its underlying raw stream and return it.
141n/a
142n/aAfter the raw stream has been detached, the buffer is in an unusable
143n/astate.
144n/a[clinic start generated code]*/
145n/a
146n/astatic PyObject *
147n/a_io__BufferedIOBase_detach_impl(PyObject *self)
148n/a/*[clinic end generated code: output=754977c8d10ed88c input=822427fb58fe4169]*/
149n/a{
150n/a return bufferediobase_unsupported("detach");
151n/a}
152n/a
153n/aPyDoc_STRVAR(bufferediobase_read_doc,
154n/a "Read and return up to n bytes.\n"
155n/a "\n"
156n/a "If the argument is omitted, None, or negative, reads and\n"
157n/a "returns all data until EOF.\n"
158n/a "\n"
159n/a "If the argument is positive, and the underlying raw stream is\n"
160n/a "not 'interactive', multiple raw reads may be issued to satisfy\n"
161n/a "the byte count (unless EOF is reached first). But for\n"
162n/a "interactive raw streams (as well as sockets and pipes), at most\n"
163n/a "one raw read will be issued, and a short result does not imply\n"
164n/a "that EOF is imminent.\n"
165n/a "\n"
166n/a "Returns an empty bytes object on EOF.\n"
167n/a "\n"
168n/a "Returns None if the underlying raw stream was open in non-blocking\n"
169n/a "mode and no data is available at the moment.\n");
170n/a
171n/astatic PyObject *
172n/abufferediobase_read(PyObject *self, PyObject *args)
173n/a{
174n/a return bufferediobase_unsupported("read");
175n/a}
176n/a
177n/aPyDoc_STRVAR(bufferediobase_read1_doc,
178n/a "Read and return up to n bytes, with at most one read() call\n"
179n/a "to the underlying raw stream. A short result does not imply\n"
180n/a "that EOF is imminent.\n"
181n/a "\n"
182n/a "Returns an empty bytes object on EOF.\n");
183n/a
184n/astatic PyObject *
185n/abufferediobase_read1(PyObject *self, PyObject *args)
186n/a{
187n/a return bufferediobase_unsupported("read1");
188n/a}
189n/a
190n/aPyDoc_STRVAR(bufferediobase_write_doc,
191n/a "Write the given buffer to the IO stream.\n"
192n/a "\n"
193n/a "Returns the number of bytes written, which is always the length of b\n"
194n/a "in bytes.\n"
195n/a "\n"
196n/a "Raises BlockingIOError if the buffer is full and the\n"
197n/a "underlying raw stream cannot accept more data at the moment.\n");
198n/a
199n/astatic PyObject *
200n/abufferediobase_write(PyObject *self, PyObject *args)
201n/a{
202n/a return bufferediobase_unsupported("write");
203n/a}
204n/a
205n/a
206n/atypedef struct {
207n/a PyObject_HEAD
208n/a
209n/a PyObject *raw;
210n/a int ok; /* Initialized? */
211n/a int detached;
212n/a int readable;
213n/a int writable;
214n/a char finalizing;
215n/a
216n/a /* True if this is a vanilla Buffered object (rather than a user derived
217n/a class) *and* the raw stream is a vanilla FileIO object. */
218n/a int fast_closed_checks;
219n/a
220n/a /* Absolute position inside the raw stream (-1 if unknown). */
221n/a Py_off_t abs_pos;
222n/a
223n/a /* A static buffer of size `buffer_size` */
224n/a char *buffer;
225n/a /* Current logical position in the buffer. */
226n/a Py_off_t pos;
227n/a /* Position of the raw stream in the buffer. */
228n/a Py_off_t raw_pos;
229n/a
230n/a /* Just after the last buffered byte in the buffer, or -1 if the buffer
231n/a isn't ready for reading. */
232n/a Py_off_t read_end;
233n/a
234n/a /* Just after the last byte actually written */
235n/a Py_off_t write_pos;
236n/a /* Just after the last byte waiting to be written, or -1 if the buffer
237n/a isn't ready for writing. */
238n/a Py_off_t write_end;
239n/a
240n/a#ifdef WITH_THREAD
241n/a PyThread_type_lock lock;
242n/a volatile long owner;
243n/a#endif
244n/a
245n/a Py_ssize_t buffer_size;
246n/a Py_ssize_t buffer_mask;
247n/a
248n/a PyObject *dict;
249n/a PyObject *weakreflist;
250n/a} buffered;
251n/a
252n/a/*
253n/a Implementation notes:
254n/a
255n/a * BufferedReader, BufferedWriter and BufferedRandom try to share most
256n/a methods (this is helped by the members `readable` and `writable`, which
257n/a are initialized in the respective constructors)
258n/a * They also share a single buffer for reading and writing. This enables
259n/a interleaved reads and writes without flushing. It also makes the logic
260n/a a bit trickier to get right.
261n/a * The absolute position of the raw stream is cached, if possible, in the
262n/a `abs_pos` member. It must be updated every time an operation is done
263n/a on the raw stream. If not sure, it can be reinitialized by calling
264n/a _buffered_raw_tell(), which queries the raw stream (_buffered_raw_seek()
265n/a also does it). To read it, use RAW_TELL().
266n/a * Three helpers, _bufferedreader_raw_read, _bufferedwriter_raw_write and
267n/a _bufferedwriter_flush_unlocked do a lot of useful housekeeping.
268n/a
269n/a NOTE: we should try to maintain block alignment of reads and writes to the
270n/a raw stream (according to the buffer size), but for now it is only done
271n/a in read() and friends.
272n/a
273n/a*/
274n/a
275n/a/* These macros protect the buffered object against concurrent operations. */
276n/a
277n/a#ifdef WITH_THREAD
278n/a
279n/astatic int
280n/a_enter_buffered_busy(buffered *self)
281n/a{
282n/a int relax_locking;
283n/a PyLockStatus st;
284n/a if (self->owner == PyThread_get_thread_ident()) {
285n/a PyErr_Format(PyExc_RuntimeError,
286n/a "reentrant call inside %R", self);
287n/a return 0;
288n/a }
289n/a relax_locking = (_Py_Finalizing != NULL);
290n/a Py_BEGIN_ALLOW_THREADS
291n/a if (!relax_locking)
292n/a st = PyThread_acquire_lock(self->lock, 1);
293n/a else {
294n/a /* When finalizing, we don't want a deadlock to happen with daemon
295n/a * threads abruptly shut down while they owned the lock.
296n/a * Therefore, only wait for a grace period (1 s.).
297n/a * Note that non-daemon threads have already exited here, so this
298n/a * shouldn't affect carefully written threaded I/O code.
299n/a */
300n/a st = PyThread_acquire_lock_timed(self->lock, (PY_TIMEOUT_T)1e6, 0);
301n/a }
302n/a Py_END_ALLOW_THREADS
303n/a if (relax_locking && st != PY_LOCK_ACQUIRED) {
304n/a PyObject *msgobj = PyUnicode_FromFormat(
305n/a "could not acquire lock for %A at interpreter "
306n/a "shutdown, possibly due to daemon threads",
307n/a (PyObject *) self);
308n/a const char *msg = PyUnicode_AsUTF8(msgobj);
309n/a Py_FatalError(msg);
310n/a }
311n/a return 1;
312n/a}
313n/a
314n/a#define ENTER_BUFFERED(self) \
315n/a ( (PyThread_acquire_lock(self->lock, 0) ? \
316n/a 1 : _enter_buffered_busy(self)) \
317n/a && (self->owner = PyThread_get_thread_ident(), 1) )
318n/a
319n/a#define LEAVE_BUFFERED(self) \
320n/a do { \
321n/a self->owner = 0; \
322n/a PyThread_release_lock(self->lock); \
323n/a } while(0);
324n/a
325n/a#else
326n/a#define ENTER_BUFFERED(self) 1
327n/a#define LEAVE_BUFFERED(self)
328n/a#endif
329n/a
330n/a#define CHECK_INITIALIZED(self) \
331n/a if (self->ok <= 0) { \
332n/a if (self->detached) { \
333n/a PyErr_SetString(PyExc_ValueError, \
334n/a "raw stream has been detached"); \
335n/a } else { \
336n/a PyErr_SetString(PyExc_ValueError, \
337n/a "I/O operation on uninitialized object"); \
338n/a } \
339n/a return NULL; \
340n/a }
341n/a
342n/a#define CHECK_INITIALIZED_INT(self) \
343n/a if (self->ok <= 0) { \
344n/a if (self->detached) { \
345n/a PyErr_SetString(PyExc_ValueError, \
346n/a "raw stream has been detached"); \
347n/a } else { \
348n/a PyErr_SetString(PyExc_ValueError, \
349n/a "I/O operation on uninitialized object"); \
350n/a } \
351n/a return -1; \
352n/a }
353n/a
354n/a#define IS_CLOSED(self) \
355n/a (self->fast_closed_checks \
356n/a ? _PyFileIO_closed(self->raw) \
357n/a : buffered_closed(self))
358n/a
359n/a#define CHECK_CLOSED(self, error_msg) \
360n/a if (IS_CLOSED(self)) { \
361n/a PyErr_SetString(PyExc_ValueError, error_msg); \
362n/a return NULL; \
363n/a }
364n/a
365n/a
366n/a#define VALID_READ_BUFFER(self) \
367n/a (self->readable && self->read_end != -1)
368n/a
369n/a#define VALID_WRITE_BUFFER(self) \
370n/a (self->writable && self->write_end != -1)
371n/a
372n/a#define ADJUST_POSITION(self, _new_pos) \
373n/a do { \
374n/a self->pos = _new_pos; \
375n/a if (VALID_READ_BUFFER(self) && self->read_end < self->pos) \
376n/a self->read_end = self->pos; \
377n/a } while(0)
378n/a
379n/a#define READAHEAD(self) \
380n/a ((self->readable && VALID_READ_BUFFER(self)) \
381n/a ? (self->read_end - self->pos) : 0)
382n/a
383n/a#define RAW_OFFSET(self) \
384n/a (((VALID_READ_BUFFER(self) || VALID_WRITE_BUFFER(self)) \
385n/a && self->raw_pos >= 0) ? self->raw_pos - self->pos : 0)
386n/a
387n/a#define RAW_TELL(self) \
388n/a (self->abs_pos != -1 ? self->abs_pos : _buffered_raw_tell(self))
389n/a
390n/a#define MINUS_LAST_BLOCK(self, size) \
391n/a (self->buffer_mask ? \
392n/a (size & ~self->buffer_mask) : \
393n/a (self->buffer_size * (size / self->buffer_size)))
394n/a
395n/a
396n/astatic void
397n/abuffered_dealloc(buffered *self)
398n/a{
399n/a self->finalizing = 1;
400n/a if (_PyIOBase_finalize((PyObject *) self) < 0)
401n/a return;
402n/a _PyObject_GC_UNTRACK(self);
403n/a self->ok = 0;
404n/a if (self->weakreflist != NULL)
405n/a PyObject_ClearWeakRefs((PyObject *)self);
406n/a Py_CLEAR(self->raw);
407n/a if (self->buffer) {
408n/a PyMem_Free(self->buffer);
409n/a self->buffer = NULL;
410n/a }
411n/a#ifdef WITH_THREAD
412n/a if (self->lock) {
413n/a PyThread_free_lock(self->lock);
414n/a self->lock = NULL;
415n/a }
416n/a#endif
417n/a Py_CLEAR(self->dict);
418n/a Py_TYPE(self)->tp_free((PyObject *)self);
419n/a}
420n/a
421n/astatic PyObject *
422n/abuffered_sizeof(buffered *self, void *unused)
423n/a{
424n/a Py_ssize_t res;
425n/a
426n/a res = _PyObject_SIZE(Py_TYPE(self));
427n/a if (self->buffer)
428n/a res += self->buffer_size;
429n/a return PyLong_FromSsize_t(res);
430n/a}
431n/a
432n/astatic int
433n/abuffered_traverse(buffered *self, visitproc visit, void *arg)
434n/a{
435n/a Py_VISIT(self->raw);
436n/a Py_VISIT(self->dict);
437n/a return 0;
438n/a}
439n/a
440n/astatic int
441n/abuffered_clear(buffered *self)
442n/a{
443n/a self->ok = 0;
444n/a Py_CLEAR(self->raw);
445n/a Py_CLEAR(self->dict);
446n/a return 0;
447n/a}
448n/a
449n/a/* Because this can call arbitrary code, it shouldn't be called when
450n/a the refcount is 0 (that is, not directly from tp_dealloc unless
451n/a the refcount has been temporarily re-incremented). */
452n/astatic PyObject *
453n/abuffered_dealloc_warn(buffered *self, PyObject *source)
454n/a{
455n/a if (self->ok && self->raw) {
456n/a PyObject *r;
457n/a r = _PyObject_CallMethodIdObjArgs(self->raw, &PyId__dealloc_warn,
458n/a source, NULL);
459n/a if (r)
460n/a Py_DECREF(r);
461n/a else
462n/a PyErr_Clear();
463n/a }
464n/a Py_RETURN_NONE;
465n/a}
466n/a
467n/a/*
468n/a * _BufferedIOMixin methods
469n/a * This is not a class, just a collection of methods that will be reused
470n/a * by BufferedReader and BufferedWriter
471n/a */
472n/a
473n/a/* Flush and close */
474n/a
475n/astatic PyObject *
476n/abuffered_simple_flush(buffered *self, PyObject *args)
477n/a{
478n/a CHECK_INITIALIZED(self)
479n/a return PyObject_CallMethodObjArgs(self->raw, _PyIO_str_flush, NULL);
480n/a}
481n/a
482n/astatic int
483n/abuffered_closed(buffered *self)
484n/a{
485n/a int closed;
486n/a PyObject *res;
487n/a CHECK_INITIALIZED_INT(self)
488n/a res = PyObject_GetAttr(self->raw, _PyIO_str_closed);
489n/a if (res == NULL)
490n/a return -1;
491n/a closed = PyObject_IsTrue(res);
492n/a Py_DECREF(res);
493n/a return closed;
494n/a}
495n/a
496n/astatic PyObject *
497n/abuffered_closed_get(buffered *self, void *context)
498n/a{
499n/a CHECK_INITIALIZED(self)
500n/a return PyObject_GetAttr(self->raw, _PyIO_str_closed);
501n/a}
502n/a
503n/astatic PyObject *
504n/abuffered_close(buffered *self, PyObject *args)
505n/a{
506n/a PyObject *res = NULL, *exc = NULL, *val, *tb;
507n/a int r;
508n/a
509n/a CHECK_INITIALIZED(self)
510n/a if (!ENTER_BUFFERED(self))
511n/a return NULL;
512n/a
513n/a r = buffered_closed(self);
514n/a if (r < 0)
515n/a goto end;
516n/a if (r > 0) {
517n/a res = Py_None;
518n/a Py_INCREF(res);
519n/a goto end;
520n/a }
521n/a
522n/a if (self->finalizing) {
523n/a PyObject *r = buffered_dealloc_warn(self, (PyObject *) self);
524n/a if (r)
525n/a Py_DECREF(r);
526n/a else
527n/a PyErr_Clear();
528n/a }
529n/a /* flush() will most probably re-take the lock, so drop it first */
530n/a LEAVE_BUFFERED(self)
531n/a res = PyObject_CallMethodObjArgs((PyObject *)self, _PyIO_str_flush, NULL);
532n/a if (!ENTER_BUFFERED(self))
533n/a return NULL;
534n/a if (res == NULL)
535n/a PyErr_Fetch(&exc, &val, &tb);
536n/a else
537n/a Py_DECREF(res);
538n/a
539n/a res = PyObject_CallMethodObjArgs(self->raw, _PyIO_str_close, NULL);
540n/a
541n/a if (self->buffer) {
542n/a PyMem_Free(self->buffer);
543n/a self->buffer = NULL;
544n/a }
545n/a
546n/a if (exc != NULL) {
547n/a _PyErr_ChainExceptions(exc, val, tb);
548n/a Py_CLEAR(res);
549n/a }
550n/a
551n/aend:
552n/a LEAVE_BUFFERED(self)
553n/a return res;
554n/a}
555n/a
556n/a/* detach */
557n/a
558n/astatic PyObject *
559n/abuffered_detach(buffered *self, PyObject *args)
560n/a{
561n/a PyObject *raw, *res;
562n/a CHECK_INITIALIZED(self)
563n/a res = PyObject_CallMethodObjArgs((PyObject *)self, _PyIO_str_flush, NULL);
564n/a if (res == NULL)
565n/a return NULL;
566n/a Py_DECREF(res);
567n/a raw = self->raw;
568n/a self->raw = NULL;
569n/a self->detached = 1;
570n/a self->ok = 0;
571n/a return raw;
572n/a}
573n/a
574n/a/* Inquiries */
575n/a
576n/astatic PyObject *
577n/abuffered_seekable(buffered *self, PyObject *args)
578n/a{
579n/a CHECK_INITIALIZED(self)
580n/a return PyObject_CallMethodObjArgs(self->raw, _PyIO_str_seekable, NULL);
581n/a}
582n/a
583n/astatic PyObject *
584n/abuffered_readable(buffered *self, PyObject *args)
585n/a{
586n/a CHECK_INITIALIZED(self)
587n/a return PyObject_CallMethodObjArgs(self->raw, _PyIO_str_readable, NULL);
588n/a}
589n/a
590n/astatic PyObject *
591n/abuffered_writable(buffered *self, PyObject *args)
592n/a{
593n/a CHECK_INITIALIZED(self)
594n/a return PyObject_CallMethodObjArgs(self->raw, _PyIO_str_writable, NULL);
595n/a}
596n/a
597n/astatic PyObject *
598n/abuffered_name_get(buffered *self, void *context)
599n/a{
600n/a CHECK_INITIALIZED(self)
601n/a return _PyObject_GetAttrId(self->raw, &PyId_name);
602n/a}
603n/a
604n/astatic PyObject *
605n/abuffered_mode_get(buffered *self, void *context)
606n/a{
607n/a CHECK_INITIALIZED(self)
608n/a return _PyObject_GetAttrId(self->raw, &PyId_mode);
609n/a}
610n/a
611n/a/* Lower-level APIs */
612n/a
613n/astatic PyObject *
614n/abuffered_fileno(buffered *self, PyObject *args)
615n/a{
616n/a CHECK_INITIALIZED(self)
617n/a return PyObject_CallMethodObjArgs(self->raw, _PyIO_str_fileno, NULL);
618n/a}
619n/a
620n/astatic PyObject *
621n/abuffered_isatty(buffered *self, PyObject *args)
622n/a{
623n/a CHECK_INITIALIZED(self)
624n/a return PyObject_CallMethodObjArgs(self->raw, _PyIO_str_isatty, NULL);
625n/a}
626n/a
627n/a/* Serialization */
628n/a
629n/astatic PyObject *
630n/abuffered_getstate(buffered *self, PyObject *args)
631n/a{
632n/a PyErr_Format(PyExc_TypeError,
633n/a "cannot serialize '%s' object", Py_TYPE(self)->tp_name);
634n/a return NULL;
635n/a}
636n/a
637n/a/* Forward decls */
638n/astatic PyObject *
639n/a_bufferedwriter_flush_unlocked(buffered *);
640n/astatic Py_ssize_t
641n/a_bufferedreader_fill_buffer(buffered *self);
642n/astatic void
643n/a_bufferedreader_reset_buf(buffered *self);
644n/astatic void
645n/a_bufferedwriter_reset_buf(buffered *self);
646n/astatic PyObject *
647n/a_bufferedreader_peek_unlocked(buffered *self);
648n/astatic PyObject *
649n/a_bufferedreader_read_all(buffered *self);
650n/astatic PyObject *
651n/a_bufferedreader_read_fast(buffered *self, Py_ssize_t);
652n/astatic PyObject *
653n/a_bufferedreader_read_generic(buffered *self, Py_ssize_t);
654n/astatic Py_ssize_t
655n/a_bufferedreader_raw_read(buffered *self, char *start, Py_ssize_t len);
656n/a
657n/a/*
658n/a * Helpers
659n/a */
660n/a
661n/a/* Sets the current error to BlockingIOError */
662n/astatic void
663n/a_set_BlockingIOError(const char *msg, Py_ssize_t written)
664n/a{
665n/a PyObject *err;
666n/a PyErr_Clear();
667n/a err = PyObject_CallFunction(PyExc_BlockingIOError, "isn",
668n/a errno, msg, written);
669n/a if (err)
670n/a PyErr_SetObject(PyExc_BlockingIOError, err);
671n/a Py_XDECREF(err);
672n/a}
673n/a
674n/a/* Returns the address of the `written` member if a BlockingIOError was
675n/a raised, NULL otherwise. The error is always re-raised. */
676n/astatic Py_ssize_t *
677n/a_buffered_check_blocking_error(void)
678n/a{
679n/a PyObject *t, *v, *tb;
680n/a PyOSErrorObject *err;
681n/a
682n/a PyErr_Fetch(&t, &v, &tb);
683n/a if (v == NULL || !PyErr_GivenExceptionMatches(v, PyExc_BlockingIOError)) {
684n/a PyErr_Restore(t, v, tb);
685n/a return NULL;
686n/a }
687n/a err = (PyOSErrorObject *) v;
688n/a /* TODO: sanity check (err->written >= 0) */
689n/a PyErr_Restore(t, v, tb);
690n/a return &err->written;
691n/a}
692n/a
693n/astatic Py_off_t
694n/a_buffered_raw_tell(buffered *self)
695n/a{
696n/a Py_off_t n;
697n/a PyObject *res;
698n/a res = PyObject_CallMethodObjArgs(self->raw, _PyIO_str_tell, NULL);
699n/a if (res == NULL)
700n/a return -1;
701n/a n = PyNumber_AsOff_t(res, PyExc_ValueError);
702n/a Py_DECREF(res);
703n/a if (n < 0) {
704n/a if (!PyErr_Occurred())
705n/a PyErr_Format(PyExc_IOError,
706n/a "Raw stream returned invalid position %" PY_PRIdOFF,
707n/a (PY_OFF_T_COMPAT)n);
708n/a return -1;
709n/a }
710n/a self->abs_pos = n;
711n/a return n;
712n/a}
713n/a
714n/astatic Py_off_t
715n/a_buffered_raw_seek(buffered *self, Py_off_t target, int whence)
716n/a{
717n/a PyObject *res, *posobj, *whenceobj;
718n/a Py_off_t n;
719n/a
720n/a posobj = PyLong_FromOff_t(target);
721n/a if (posobj == NULL)
722n/a return -1;
723n/a whenceobj = PyLong_FromLong(whence);
724n/a if (whenceobj == NULL) {
725n/a Py_DECREF(posobj);
726n/a return -1;
727n/a }
728n/a res = PyObject_CallMethodObjArgs(self->raw, _PyIO_str_seek,
729n/a posobj, whenceobj, NULL);
730n/a Py_DECREF(posobj);
731n/a Py_DECREF(whenceobj);
732n/a if (res == NULL)
733n/a return -1;
734n/a n = PyNumber_AsOff_t(res, PyExc_ValueError);
735n/a Py_DECREF(res);
736n/a if (n < 0) {
737n/a if (!PyErr_Occurred())
738n/a PyErr_Format(PyExc_IOError,
739n/a "Raw stream returned invalid position %" PY_PRIdOFF,
740n/a (PY_OFF_T_COMPAT)n);
741n/a return -1;
742n/a }
743n/a self->abs_pos = n;
744n/a return n;
745n/a}
746n/a
747n/astatic int
748n/a_buffered_init(buffered *self)
749n/a{
750n/a Py_ssize_t n;
751n/a if (self->buffer_size <= 0) {
752n/a PyErr_SetString(PyExc_ValueError,
753n/a "buffer size must be strictly positive");
754n/a return -1;
755n/a }
756n/a if (self->buffer)
757n/a PyMem_Free(self->buffer);
758n/a self->buffer = PyMem_Malloc(self->buffer_size);
759n/a if (self->buffer == NULL) {
760n/a PyErr_NoMemory();
761n/a return -1;
762n/a }
763n/a#ifdef WITH_THREAD
764n/a if (self->lock)
765n/a PyThread_free_lock(self->lock);
766n/a self->lock = PyThread_allocate_lock();
767n/a if (self->lock == NULL) {
768n/a PyErr_SetString(PyExc_RuntimeError, "can't allocate read lock");
769n/a return -1;
770n/a }
771n/a self->owner = 0;
772n/a#endif
773n/a /* Find out whether buffer_size is a power of 2 */
774n/a /* XXX is this optimization useful? */
775n/a for (n = self->buffer_size - 1; n & 1; n >>= 1)
776n/a ;
777n/a if (n == 0)
778n/a self->buffer_mask = self->buffer_size - 1;
779n/a else
780n/a self->buffer_mask = 0;
781n/a if (_buffered_raw_tell(self) == -1)
782n/a PyErr_Clear();
783n/a return 0;
784n/a}
785n/a
786n/a/* Return 1 if an EnvironmentError with errno == EINTR is set (and then
787n/a clears the error indicator), 0 otherwise.
788n/a Should only be called when PyErr_Occurred() is true.
789n/a*/
790n/aint
791n/a_PyIO_trap_eintr(void)
792n/a{
793n/a static PyObject *eintr_int = NULL;
794n/a PyObject *typ, *val, *tb;
795n/a PyEnvironmentErrorObject *env_err;
796n/a
797n/a if (eintr_int == NULL) {
798n/a eintr_int = PyLong_FromLong(EINTR);
799n/a assert(eintr_int != NULL);
800n/a }
801n/a if (!PyErr_ExceptionMatches(PyExc_EnvironmentError))
802n/a return 0;
803n/a PyErr_Fetch(&typ, &val, &tb);
804n/a PyErr_NormalizeException(&typ, &val, &tb);
805n/a env_err = (PyEnvironmentErrorObject *) val;
806n/a assert(env_err != NULL);
807n/a if (env_err->myerrno != NULL &&
808n/a PyObject_RichCompareBool(env_err->myerrno, eintr_int, Py_EQ) > 0) {
809n/a Py_DECREF(typ);
810n/a Py_DECREF(val);
811n/a Py_XDECREF(tb);
812n/a return 1;
813n/a }
814n/a /* This silences any error set by PyObject_RichCompareBool() */
815n/a PyErr_Restore(typ, val, tb);
816n/a return 0;
817n/a}
818n/a
819n/a/*
820n/a * Shared methods and wrappers
821n/a */
822n/a
823n/astatic PyObject *
824n/abuffered_flush_and_rewind_unlocked(buffered *self)
825n/a{
826n/a PyObject *res;
827n/a
828n/a res = _bufferedwriter_flush_unlocked(self);
829n/a if (res == NULL)
830n/a return NULL;
831n/a Py_DECREF(res);
832n/a
833n/a if (self->readable) {
834n/a /* Rewind the raw stream so that its position corresponds to
835n/a the current logical position. */
836n/a Py_off_t n;
837n/a n = _buffered_raw_seek(self, -RAW_OFFSET(self), 1);
838n/a _bufferedreader_reset_buf(self);
839n/a if (n == -1)
840n/a return NULL;
841n/a }
842n/a Py_RETURN_NONE;
843n/a}
844n/a
845n/astatic PyObject *
846n/abuffered_flush(buffered *self, PyObject *args)
847n/a{
848n/a PyObject *res;
849n/a
850n/a CHECK_INITIALIZED(self)
851n/a CHECK_CLOSED(self, "flush of closed file")
852n/a
853n/a if (!ENTER_BUFFERED(self))
854n/a return NULL;
855n/a res = buffered_flush_and_rewind_unlocked(self);
856n/a LEAVE_BUFFERED(self)
857n/a
858n/a return res;
859n/a}
860n/a
861n/a/*[clinic input]
862n/a_io._Buffered.peek
863n/a size: Py_ssize_t = 0
864n/a /
865n/a
866n/a[clinic start generated code]*/
867n/a
868n/astatic PyObject *
869n/a_io__Buffered_peek_impl(buffered *self, Py_ssize_t size)
870n/a/*[clinic end generated code: output=ba7a097ca230102b input=37ffb97d06ff4adb]*/
871n/a{
872n/a PyObject *res = NULL;
873n/a
874n/a CHECK_INITIALIZED(self)
875n/a CHECK_CLOSED(self, "peek of closed file")
876n/a
877n/a if (!ENTER_BUFFERED(self))
878n/a return NULL;
879n/a
880n/a if (self->writable) {
881n/a res = buffered_flush_and_rewind_unlocked(self);
882n/a if (res == NULL)
883n/a goto end;
884n/a Py_CLEAR(res);
885n/a }
886n/a res = _bufferedreader_peek_unlocked(self);
887n/a
888n/aend:
889n/a LEAVE_BUFFERED(self)
890n/a return res;
891n/a}
892n/a
893n/a/*[clinic input]
894n/a_io._Buffered.read
895n/a size as n: io_ssize_t = -1
896n/a /
897n/a[clinic start generated code]*/
898n/a
899n/astatic PyObject *
900n/a_io__Buffered_read_impl(buffered *self, Py_ssize_t n)
901n/a/*[clinic end generated code: output=f41c78bb15b9bbe9 input=c0939ec7f9e9354f]*/
902n/a{
903n/a PyObject *res;
904n/a
905n/a CHECK_INITIALIZED(self)
906n/a if (n < -1) {
907n/a PyErr_SetString(PyExc_ValueError,
908n/a "read length must be non-negative or -1");
909n/a return NULL;
910n/a }
911n/a
912n/a CHECK_CLOSED(self, "read of closed file")
913n/a
914n/a if (n == -1) {
915n/a /* The number of bytes is unspecified, read until the end of stream */
916n/a if (!ENTER_BUFFERED(self))
917n/a return NULL;
918n/a res = _bufferedreader_read_all(self);
919n/a }
920n/a else {
921n/a res = _bufferedreader_read_fast(self, n);
922n/a if (res != Py_None)
923n/a return res;
924n/a Py_DECREF(res);
925n/a if (!ENTER_BUFFERED(self))
926n/a return NULL;
927n/a res = _bufferedreader_read_generic(self, n);
928n/a }
929n/a
930n/a LEAVE_BUFFERED(self)
931n/a return res;
932n/a}
933n/a
934n/a/*[clinic input]
935n/a_io._Buffered.read1
936n/a size as n: Py_ssize_t = -1
937n/a /
938n/a[clinic start generated code]*/
939n/a
940n/astatic PyObject *
941n/a_io__Buffered_read1_impl(buffered *self, Py_ssize_t n)
942n/a/*[clinic end generated code: output=bcc4fb4e54d103a3 input=7d22de9630b61774]*/
943n/a{
944n/a Py_ssize_t have, r;
945n/a PyObject *res = NULL;
946n/a
947n/a CHECK_INITIALIZED(self)
948n/a if (n < 0) {
949n/a n = self->buffer_size;
950n/a }
951n/a
952n/a CHECK_CLOSED(self, "read of closed file")
953n/a
954n/a if (n == 0)
955n/a return PyBytes_FromStringAndSize(NULL, 0);
956n/a
957n/a /* Return up to n bytes. If at least one byte is buffered, we
958n/a only return buffered bytes. Otherwise, we do one raw read. */
959n/a
960n/a have = Py_SAFE_DOWNCAST(READAHEAD(self), Py_off_t, Py_ssize_t);
961n/a if (have > 0) {
962n/a n = Py_MIN(have, n);
963n/a res = _bufferedreader_read_fast(self, n);
964n/a assert(res != Py_None);
965n/a return res;
966n/a }
967n/a res = PyBytes_FromStringAndSize(NULL, n);
968n/a if (res == NULL)
969n/a return NULL;
970n/a if (!ENTER_BUFFERED(self)) {
971n/a Py_DECREF(res);
972n/a return NULL;
973n/a }
974n/a _bufferedreader_reset_buf(self);
975n/a r = _bufferedreader_raw_read(self, PyBytes_AS_STRING(res), n);
976n/a LEAVE_BUFFERED(self)
977n/a if (r == -1) {
978n/a Py_DECREF(res);
979n/a return NULL;
980n/a }
981n/a if (r == -2)
982n/a r = 0;
983n/a if (n > r)
984n/a _PyBytes_Resize(&res, r);
985n/a return res;
986n/a}
987n/a
988n/astatic PyObject *
989n/a_buffered_readinto_generic(buffered *self, Py_buffer *buffer, char readinto1)
990n/a{
991n/a Py_ssize_t n, written = 0, remaining;
992n/a PyObject *res = NULL;
993n/a
994n/a CHECK_INITIALIZED(self)
995n/a
996n/a n = Py_SAFE_DOWNCAST(READAHEAD(self), Py_off_t, Py_ssize_t);
997n/a if (n > 0) {
998n/a if (n >= buffer->len) {
999n/a memcpy(buffer->buf, self->buffer + self->pos, buffer->len);
1000n/a self->pos += buffer->len;
1001n/a return PyLong_FromSsize_t(buffer->len);
1002n/a }
1003n/a memcpy(buffer->buf, self->buffer + self->pos, n);
1004n/a self->pos += n;
1005n/a written = n;
1006n/a }
1007n/a
1008n/a if (!ENTER_BUFFERED(self))
1009n/a return NULL;
1010n/a
1011n/a if (self->writable) {
1012n/a res = buffered_flush_and_rewind_unlocked(self);
1013n/a if (res == NULL)
1014n/a goto end;
1015n/a Py_CLEAR(res);
1016n/a }
1017n/a
1018n/a _bufferedreader_reset_buf(self);
1019n/a self->pos = 0;
1020n/a
1021n/a for (remaining = buffer->len - written;
1022n/a remaining > 0;
1023n/a written += n, remaining -= n) {
1024n/a /* If remaining bytes is larger than internal buffer size, copy
1025n/a * directly into caller's buffer. */
1026n/a if (remaining > self->buffer_size) {
1027n/a n = _bufferedreader_raw_read(self, (char *) buffer->buf + written,
1028n/a remaining);
1029n/a }
1030n/a
1031n/a /* In readinto1 mode, we do not want to fill the internal
1032n/a buffer if we already have some data to return */
1033n/a else if (!(readinto1 && written)) {
1034n/a n = _bufferedreader_fill_buffer(self);
1035n/a if (n > 0) {
1036n/a if (n > remaining)
1037n/a n = remaining;
1038n/a memcpy((char *) buffer->buf + written,
1039n/a self->buffer + self->pos, n);
1040n/a self->pos += n;
1041n/a continue; /* short circuit */
1042n/a }
1043n/a }
1044n/a else
1045n/a n = 0;
1046n/a
1047n/a if (n == 0 || (n == -2 && written > 0))
1048n/a break;
1049n/a if (n < 0) {
1050n/a if (n == -2) {
1051n/a Py_INCREF(Py_None);
1052n/a res = Py_None;
1053n/a }
1054n/a goto end;
1055n/a }
1056n/a
1057n/a /* At most one read in readinto1 mode */
1058n/a if (readinto1) {
1059n/a written += n;
1060n/a break;
1061n/a }
1062n/a }
1063n/a res = PyLong_FromSsize_t(written);
1064n/a
1065n/aend:
1066n/a LEAVE_BUFFERED(self);
1067n/a return res;
1068n/a}
1069n/a
1070n/a/*[clinic input]
1071n/a_io._Buffered.readinto
1072n/a buffer: Py_buffer(accept={rwbuffer})
1073n/a /
1074n/a[clinic start generated code]*/
1075n/a
1076n/astatic PyObject *
1077n/a_io__Buffered_readinto_impl(buffered *self, Py_buffer *buffer)
1078n/a/*[clinic end generated code: output=bcb376580b1d8170 input=ed6b98b7a20a3008]*/
1079n/a{
1080n/a return _buffered_readinto_generic(self, buffer, 0);
1081n/a}
1082n/a
1083n/a/*[clinic input]
1084n/a_io._Buffered.readinto1
1085n/a buffer: Py_buffer(accept={rwbuffer})
1086n/a /
1087n/a[clinic start generated code]*/
1088n/a
1089n/astatic PyObject *
1090n/a_io__Buffered_readinto1_impl(buffered *self, Py_buffer *buffer)
1091n/a/*[clinic end generated code: output=6e5c6ac5868205d6 input=4455c5d55fdf1687]*/
1092n/a{
1093n/a return _buffered_readinto_generic(self, buffer, 1);
1094n/a}
1095n/a
1096n/a
1097n/astatic PyObject *
1098n/a_buffered_readline(buffered *self, Py_ssize_t limit)
1099n/a{
1100n/a PyObject *res = NULL;
1101n/a PyObject *chunks = NULL;
1102n/a Py_ssize_t n, written = 0;
1103n/a const char *start, *s, *end;
1104n/a
1105n/a CHECK_CLOSED(self, "readline of closed file")
1106n/a
1107n/a /* First, try to find a line in the buffer. This can run unlocked because
1108n/a the calls to the C API are simple enough that they can't trigger
1109n/a any thread switch. */
1110n/a n = Py_SAFE_DOWNCAST(READAHEAD(self), Py_off_t, Py_ssize_t);
1111n/a if (limit >= 0 && n > limit)
1112n/a n = limit;
1113n/a start = self->buffer + self->pos;
1114n/a s = memchr(start, '\n', n);
1115n/a if (s != NULL) {
1116n/a res = PyBytes_FromStringAndSize(start, s - start + 1);
1117n/a if (res != NULL)
1118n/a self->pos += s - start + 1;
1119n/a goto end_unlocked;
1120n/a }
1121n/a if (n == limit) {
1122n/a res = PyBytes_FromStringAndSize(start, n);
1123n/a if (res != NULL)
1124n/a self->pos += n;
1125n/a goto end_unlocked;
1126n/a }
1127n/a
1128n/a if (!ENTER_BUFFERED(self))
1129n/a goto end_unlocked;
1130n/a
1131n/a /* Now we try to get some more from the raw stream */
1132n/a chunks = PyList_New(0);
1133n/a if (chunks == NULL)
1134n/a goto end;
1135n/a if (n > 0) {
1136n/a res = PyBytes_FromStringAndSize(start, n);
1137n/a if (res == NULL)
1138n/a goto end;
1139n/a if (PyList_Append(chunks, res) < 0) {
1140n/a Py_CLEAR(res);
1141n/a goto end;
1142n/a }
1143n/a Py_CLEAR(res);
1144n/a written += n;
1145n/a self->pos += n;
1146n/a if (limit >= 0)
1147n/a limit -= n;
1148n/a }
1149n/a if (self->writable) {
1150n/a PyObject *r = buffered_flush_and_rewind_unlocked(self);
1151n/a if (r == NULL)
1152n/a goto end;
1153n/a Py_DECREF(r);
1154n/a }
1155n/a
1156n/a for (;;) {
1157n/a _bufferedreader_reset_buf(self);
1158n/a n = _bufferedreader_fill_buffer(self);
1159n/a if (n == -1)
1160n/a goto end;
1161n/a if (n <= 0)
1162n/a break;
1163n/a if (limit >= 0 && n > limit)
1164n/a n = limit;
1165n/a start = self->buffer;
1166n/a end = start + n;
1167n/a s = start;
1168n/a while (s < end) {
1169n/a if (*s++ == '\n') {
1170n/a res = PyBytes_FromStringAndSize(start, s - start);
1171n/a if (res == NULL)
1172n/a goto end;
1173n/a self->pos = s - start;
1174n/a goto found;
1175n/a }
1176n/a }
1177n/a res = PyBytes_FromStringAndSize(start, n);
1178n/a if (res == NULL)
1179n/a goto end;
1180n/a if (n == limit) {
1181n/a self->pos = n;
1182n/a break;
1183n/a }
1184n/a if (PyList_Append(chunks, res) < 0) {
1185n/a Py_CLEAR(res);
1186n/a goto end;
1187n/a }
1188n/a Py_CLEAR(res);
1189n/a written += n;
1190n/a if (limit >= 0)
1191n/a limit -= n;
1192n/a }
1193n/afound:
1194n/a if (res != NULL && PyList_Append(chunks, res) < 0) {
1195n/a Py_CLEAR(res);
1196n/a goto end;
1197n/a }
1198n/a Py_XSETREF(res, _PyBytes_Join(_PyIO_empty_bytes, chunks));
1199n/a
1200n/aend:
1201n/a LEAVE_BUFFERED(self)
1202n/aend_unlocked:
1203n/a Py_XDECREF(chunks);
1204n/a return res;
1205n/a}
1206n/a
1207n/a/*[clinic input]
1208n/a_io._Buffered.readline
1209n/a size: io_ssize_t = -1
1210n/a /
1211n/a[clinic start generated code]*/
1212n/a
1213n/astatic PyObject *
1214n/a_io__Buffered_readline_impl(buffered *self, Py_ssize_t size)
1215n/a/*[clinic end generated code: output=24dd2aa6e33be83c input=ff1e0df821cb4e5c]*/
1216n/a{
1217n/a CHECK_INITIALIZED(self)
1218n/a return _buffered_readline(self, size);
1219n/a}
1220n/a
1221n/a
1222n/astatic PyObject *
1223n/abuffered_tell(buffered *self, PyObject *args)
1224n/a{
1225n/a Py_off_t pos;
1226n/a
1227n/a CHECK_INITIALIZED(self)
1228n/a pos = _buffered_raw_tell(self);
1229n/a if (pos == -1)
1230n/a return NULL;
1231n/a pos -= RAW_OFFSET(self);
1232n/a /* TODO: sanity check (pos >= 0) */
1233n/a return PyLong_FromOff_t(pos);
1234n/a}
1235n/a
1236n/a/*[clinic input]
1237n/a_io._Buffered.seek
1238n/a target as targetobj: object
1239n/a whence: int = 0
1240n/a /
1241n/a[clinic start generated code]*/
1242n/a
1243n/astatic PyObject *
1244n/a_io__Buffered_seek_impl(buffered *self, PyObject *targetobj, int whence)
1245n/a/*[clinic end generated code: output=7ae0e8dc46efdefb input=a9c4920bfcba6163]*/
1246n/a{
1247n/a Py_off_t target, n;
1248n/a PyObject *res = NULL;
1249n/a
1250n/a CHECK_INITIALIZED(self)
1251n/a
1252n/a /* Do some error checking instead of trusting OS 'seek()'
1253n/a ** error detection, just in case.
1254n/a */
1255n/a if ((whence < 0 || whence >2)
1256n/a#ifdef SEEK_HOLE
1257n/a && (whence != SEEK_HOLE)
1258n/a#endif
1259n/a#ifdef SEEK_DATA
1260n/a && (whence != SEEK_DATA)
1261n/a#endif
1262n/a ) {
1263n/a PyErr_Format(PyExc_ValueError,
1264n/a "whence value %d unsupported", whence);
1265n/a return NULL;
1266n/a }
1267n/a
1268n/a CHECK_CLOSED(self, "seek of closed file")
1269n/a
1270n/a if (_PyIOBase_check_seekable(self->raw, Py_True) == NULL)
1271n/a return NULL;
1272n/a
1273n/a target = PyNumber_AsOff_t(targetobj, PyExc_ValueError);
1274n/a if (target == -1 && PyErr_Occurred())
1275n/a return NULL;
1276n/a
1277n/a /* SEEK_SET and SEEK_CUR are special because we could seek inside the
1278n/a buffer. Other whence values must be managed without this optimization.
1279n/a Some Operating Systems can provide additional values, like
1280n/a SEEK_HOLE/SEEK_DATA. */
1281n/a if (((whence == 0) || (whence == 1)) && self->readable) {
1282n/a Py_off_t current, avail;
1283n/a /* Check if seeking leaves us inside the current buffer,
1284n/a so as to return quickly if possible. Also, we needn't take the
1285n/a lock in this fast path.
1286n/a Don't know how to do that when whence == 2, though. */
1287n/a /* NOTE: RAW_TELL() can release the GIL but the object is in a stable
1288n/a state at this point. */
1289n/a current = RAW_TELL(self);
1290n/a avail = READAHEAD(self);
1291n/a if (avail > 0) {
1292n/a Py_off_t offset;
1293n/a if (whence == 0)
1294n/a offset = target - (current - RAW_OFFSET(self));
1295n/a else
1296n/a offset = target;
1297n/a if (offset >= -self->pos && offset <= avail) {
1298n/a self->pos += offset;
1299n/a return PyLong_FromOff_t(current - avail + offset);
1300n/a }
1301n/a }
1302n/a }
1303n/a
1304n/a if (!ENTER_BUFFERED(self))
1305n/a return NULL;
1306n/a
1307n/a /* Fallback: invoke raw seek() method and clear buffer */
1308n/a if (self->writable) {
1309n/a res = _bufferedwriter_flush_unlocked(self);
1310n/a if (res == NULL)
1311n/a goto end;
1312n/a Py_CLEAR(res);
1313n/a _bufferedwriter_reset_buf(self);
1314n/a }
1315n/a
1316n/a /* TODO: align on block boundary and read buffer if needed? */
1317n/a if (whence == 1)
1318n/a target -= RAW_OFFSET(self);
1319n/a n = _buffered_raw_seek(self, target, whence);
1320n/a if (n == -1)
1321n/a goto end;
1322n/a self->raw_pos = -1;
1323n/a res = PyLong_FromOff_t(n);
1324n/a if (res != NULL && self->readable)
1325n/a _bufferedreader_reset_buf(self);
1326n/a
1327n/aend:
1328n/a LEAVE_BUFFERED(self)
1329n/a return res;
1330n/a}
1331n/a
1332n/a/*[clinic input]
1333n/a_io._Buffered.truncate
1334n/a pos: object = None
1335n/a /
1336n/a[clinic start generated code]*/
1337n/a
1338n/astatic PyObject *
1339n/a_io__Buffered_truncate_impl(buffered *self, PyObject *pos)
1340n/a/*[clinic end generated code: output=667ca03c60c270de input=8a1be34d57cca2d3]*/
1341n/a{
1342n/a PyObject *res = NULL;
1343n/a
1344n/a CHECK_INITIALIZED(self)
1345n/a if (!ENTER_BUFFERED(self))
1346n/a return NULL;
1347n/a
1348n/a if (self->writable) {
1349n/a res = buffered_flush_and_rewind_unlocked(self);
1350n/a if (res == NULL)
1351n/a goto end;
1352n/a Py_CLEAR(res);
1353n/a }
1354n/a res = PyObject_CallMethodObjArgs(self->raw, _PyIO_str_truncate, pos, NULL);
1355n/a if (res == NULL)
1356n/a goto end;
1357n/a /* Reset cached position */
1358n/a if (_buffered_raw_tell(self) == -1)
1359n/a PyErr_Clear();
1360n/a
1361n/aend:
1362n/a LEAVE_BUFFERED(self)
1363n/a return res;
1364n/a}
1365n/a
1366n/astatic PyObject *
1367n/abuffered_iternext(buffered *self)
1368n/a{
1369n/a PyObject *line;
1370n/a PyTypeObject *tp;
1371n/a
1372n/a CHECK_INITIALIZED(self);
1373n/a
1374n/a tp = Py_TYPE(self);
1375n/a if (tp == &PyBufferedReader_Type ||
1376n/a tp == &PyBufferedRandom_Type) {
1377n/a /* Skip method call overhead for speed */
1378n/a line = _buffered_readline(self, -1);
1379n/a }
1380n/a else {
1381n/a line = PyObject_CallMethodObjArgs((PyObject *)self,
1382n/a _PyIO_str_readline, NULL);
1383n/a if (line && !PyBytes_Check(line)) {
1384n/a PyErr_Format(PyExc_IOError,
1385n/a "readline() should have returned a bytes object, "
1386n/a "not '%.200s'", Py_TYPE(line)->tp_name);
1387n/a Py_DECREF(line);
1388n/a return NULL;
1389n/a }
1390n/a }
1391n/a
1392n/a if (line == NULL)
1393n/a return NULL;
1394n/a
1395n/a if (PyBytes_GET_SIZE(line) == 0) {
1396n/a /* Reached EOF or would have blocked */
1397n/a Py_DECREF(line);
1398n/a return NULL;
1399n/a }
1400n/a
1401n/a return line;
1402n/a}
1403n/a
1404n/astatic PyObject *
1405n/abuffered_repr(buffered *self)
1406n/a{
1407n/a PyObject *nameobj, *res;
1408n/a
1409n/a nameobj = _PyObject_GetAttrId((PyObject *) self, &PyId_name);
1410n/a if (nameobj == NULL) {
1411n/a if (PyErr_ExceptionMatches(PyExc_Exception))
1412n/a PyErr_Clear();
1413n/a else
1414n/a return NULL;
1415n/a res = PyUnicode_FromFormat("<%s>", Py_TYPE(self)->tp_name);
1416n/a }
1417n/a else {
1418n/a res = PyUnicode_FromFormat("<%s name=%R>",
1419n/a Py_TYPE(self)->tp_name, nameobj);
1420n/a Py_DECREF(nameobj);
1421n/a }
1422n/a return res;
1423n/a}
1424n/a
1425n/a/*
1426n/a * class BufferedReader
1427n/a */
1428n/a
1429n/astatic void _bufferedreader_reset_buf(buffered *self)
1430n/a{
1431n/a self->read_end = -1;
1432n/a}
1433n/a
1434n/a/*[clinic input]
1435n/a_io.BufferedReader.__init__
1436n/a raw: object
1437n/a buffer_size: Py_ssize_t(c_default="DEFAULT_BUFFER_SIZE") = DEFAULT_BUFFER_SIZE
1438n/a
1439n/aCreate a new buffered reader using the given readable raw IO object.
1440n/a[clinic start generated code]*/
1441n/a
1442n/astatic int
1443n/a_io_BufferedReader___init___impl(buffered *self, PyObject *raw,
1444n/a Py_ssize_t buffer_size)
1445n/a/*[clinic end generated code: output=cddcfefa0ed294c4 input=fb887e06f11b4e48]*/
1446n/a{
1447n/a self->ok = 0;
1448n/a self->detached = 0;
1449n/a
1450n/a if (_PyIOBase_check_readable(raw, Py_True) == NULL)
1451n/a return -1;
1452n/a
1453n/a Py_INCREF(raw);
1454n/a Py_XSETREF(self->raw, raw);
1455n/a self->buffer_size = buffer_size;
1456n/a self->readable = 1;
1457n/a self->writable = 0;
1458n/a
1459n/a if (_buffered_init(self) < 0)
1460n/a return -1;
1461n/a _bufferedreader_reset_buf(self);
1462n/a
1463n/a self->fast_closed_checks = (Py_TYPE(self) == &PyBufferedReader_Type &&
1464n/a Py_TYPE(raw) == &PyFileIO_Type);
1465n/a
1466n/a self->ok = 1;
1467n/a return 0;
1468n/a}
1469n/a
1470n/astatic Py_ssize_t
1471n/a_bufferedreader_raw_read(buffered *self, char *start, Py_ssize_t len)
1472n/a{
1473n/a Py_buffer buf;
1474n/a PyObject *memobj, *res;
1475n/a Py_ssize_t n;
1476n/a /* NOTE: the buffer needn't be released as its object is NULL. */
1477n/a if (PyBuffer_FillInfo(&buf, NULL, start, len, 0, PyBUF_CONTIG) == -1)
1478n/a return -1;
1479n/a memobj = PyMemoryView_FromBuffer(&buf);
1480n/a if (memobj == NULL)
1481n/a return -1;
1482n/a /* NOTE: PyErr_SetFromErrno() calls PyErr_CheckSignals() when EINTR
1483n/a occurs so we needn't do it ourselves.
1484n/a We then retry reading, ignoring the signal if no handler has
1485n/a raised (see issue #10956).
1486n/a */
1487n/a do {
1488n/a res = PyObject_CallMethodObjArgs(self->raw, _PyIO_str_readinto, memobj, NULL);
1489n/a } while (res == NULL && _PyIO_trap_eintr());
1490n/a Py_DECREF(memobj);
1491n/a if (res == NULL)
1492n/a return -1;
1493n/a if (res == Py_None) {
1494n/a /* Non-blocking stream would have blocked. Special return code! */
1495n/a Py_DECREF(res);
1496n/a return -2;
1497n/a }
1498n/a n = PyNumber_AsSsize_t(res, PyExc_ValueError);
1499n/a Py_DECREF(res);
1500n/a if (n < 0 || n > len) {
1501n/a PyErr_Format(PyExc_IOError,
1502n/a "raw readinto() returned invalid length %zd "
1503n/a "(should have been between 0 and %zd)", n, len);
1504n/a return -1;
1505n/a }
1506n/a if (n > 0 && self->abs_pos != -1)
1507n/a self->abs_pos += n;
1508n/a return n;
1509n/a}
1510n/a
1511n/astatic Py_ssize_t
1512n/a_bufferedreader_fill_buffer(buffered *self)
1513n/a{
1514n/a Py_ssize_t start, len, n;
1515n/a if (VALID_READ_BUFFER(self))
1516n/a start = Py_SAFE_DOWNCAST(self->read_end, Py_off_t, Py_ssize_t);
1517n/a else
1518n/a start = 0;
1519n/a len = self->buffer_size - start;
1520n/a n = _bufferedreader_raw_read(self, self->buffer + start, len);
1521n/a if (n <= 0)
1522n/a return n;
1523n/a self->read_end = start + n;
1524n/a self->raw_pos = start + n;
1525n/a return n;
1526n/a}
1527n/a
1528n/astatic PyObject *
1529n/a_bufferedreader_read_all(buffered *self)
1530n/a{
1531n/a Py_ssize_t current_size;
1532n/a PyObject *res = NULL, *data = NULL, *tmp = NULL, *chunks = NULL;
1533n/a
1534n/a /* First copy what we have in the current buffer. */
1535n/a current_size = Py_SAFE_DOWNCAST(READAHEAD(self), Py_off_t, Py_ssize_t);
1536n/a if (current_size) {
1537n/a data = PyBytes_FromStringAndSize(
1538n/a self->buffer + self->pos, current_size);
1539n/a if (data == NULL)
1540n/a return NULL;
1541n/a self->pos += current_size;
1542n/a }
1543n/a /* We're going past the buffer's bounds, flush it */
1544n/a if (self->writable) {
1545n/a tmp = buffered_flush_and_rewind_unlocked(self);
1546n/a if (tmp == NULL)
1547n/a goto cleanup;
1548n/a Py_CLEAR(tmp);
1549n/a }
1550n/a _bufferedreader_reset_buf(self);
1551n/a
1552n/a if (PyObject_HasAttr(self->raw, _PyIO_str_readall)) {
1553n/a tmp = PyObject_CallMethodObjArgs(self->raw, _PyIO_str_readall, NULL);
1554n/a if (tmp == NULL)
1555n/a goto cleanup;
1556n/a if (tmp != Py_None && !PyBytes_Check(tmp)) {
1557n/a PyErr_SetString(PyExc_TypeError, "readall() should return bytes");
1558n/a goto cleanup;
1559n/a }
1560n/a if (tmp == Py_None) {
1561n/a if (current_size == 0) {
1562n/a res = Py_None;
1563n/a goto cleanup;
1564n/a } else {
1565n/a res = data;
1566n/a goto cleanup;
1567n/a }
1568n/a }
1569n/a else if (current_size) {
1570n/a PyBytes_Concat(&data, tmp);
1571n/a res = data;
1572n/a goto cleanup;
1573n/a }
1574n/a else {
1575n/a res = tmp;
1576n/a goto cleanup;
1577n/a }
1578n/a }
1579n/a
1580n/a chunks = PyList_New(0);
1581n/a if (chunks == NULL)
1582n/a goto cleanup;
1583n/a
1584n/a while (1) {
1585n/a if (data) {
1586n/a if (PyList_Append(chunks, data) < 0)
1587n/a goto cleanup;
1588n/a Py_CLEAR(data);
1589n/a }
1590n/a
1591n/a /* Read until EOF or until read() would block. */
1592n/a data = PyObject_CallMethodObjArgs(self->raw, _PyIO_str_read, NULL);
1593n/a if (data == NULL)
1594n/a goto cleanup;
1595n/a if (data != Py_None && !PyBytes_Check(data)) {
1596n/a PyErr_SetString(PyExc_TypeError, "read() should return bytes");
1597n/a goto cleanup;
1598n/a }
1599n/a if (data == Py_None || PyBytes_GET_SIZE(data) == 0) {
1600n/a if (current_size == 0) {
1601n/a res = data;
1602n/a goto cleanup;
1603n/a }
1604n/a else {
1605n/a tmp = _PyBytes_Join(_PyIO_empty_bytes, chunks);
1606n/a res = tmp;
1607n/a goto cleanup;
1608n/a }
1609n/a }
1610n/a current_size += PyBytes_GET_SIZE(data);
1611n/a if (self->abs_pos != -1)
1612n/a self->abs_pos += PyBytes_GET_SIZE(data);
1613n/a }
1614n/acleanup:
1615n/a /* res is either NULL or a borrowed ref */
1616n/a Py_XINCREF(res);
1617n/a Py_XDECREF(data);
1618n/a Py_XDECREF(tmp);
1619n/a Py_XDECREF(chunks);
1620n/a return res;
1621n/a}
1622n/a
1623n/a/* Read n bytes from the buffer if it can, otherwise return None.
1624n/a This function is simple enough that it can run unlocked. */
1625n/astatic PyObject *
1626n/a_bufferedreader_read_fast(buffered *self, Py_ssize_t n)
1627n/a{
1628n/a Py_ssize_t current_size;
1629n/a
1630n/a current_size = Py_SAFE_DOWNCAST(READAHEAD(self), Py_off_t, Py_ssize_t);
1631n/a if (n <= current_size) {
1632n/a /* Fast path: the data to read is fully buffered. */
1633n/a PyObject *res = PyBytes_FromStringAndSize(self->buffer + self->pos, n);
1634n/a if (res != NULL)
1635n/a self->pos += n;
1636n/a return res;
1637n/a }
1638n/a Py_RETURN_NONE;
1639n/a}
1640n/a
1641n/a/* Generic read function: read from the stream until enough bytes are read,
1642n/a * or until an EOF occurs or until read() would block.
1643n/a */
1644n/astatic PyObject *
1645n/a_bufferedreader_read_generic(buffered *self, Py_ssize_t n)
1646n/a{
1647n/a PyObject *res = NULL;
1648n/a Py_ssize_t current_size, remaining, written;
1649n/a char *out;
1650n/a
1651n/a current_size = Py_SAFE_DOWNCAST(READAHEAD(self), Py_off_t, Py_ssize_t);
1652n/a if (n <= current_size)
1653n/a return _bufferedreader_read_fast(self, n);
1654n/a
1655n/a res = PyBytes_FromStringAndSize(NULL, n);
1656n/a if (res == NULL)
1657n/a goto error;
1658n/a out = PyBytes_AS_STRING(res);
1659n/a remaining = n;
1660n/a written = 0;
1661n/a if (current_size > 0) {
1662n/a memcpy(out, self->buffer + self->pos, current_size);
1663n/a remaining -= current_size;
1664n/a written += current_size;
1665n/a self->pos += current_size;
1666n/a }
1667n/a /* Flush the write buffer if necessary */
1668n/a if (self->writable) {
1669n/a PyObject *r = buffered_flush_and_rewind_unlocked(self);
1670n/a if (r == NULL)
1671n/a goto error;
1672n/a Py_DECREF(r);
1673n/a }
1674n/a _bufferedreader_reset_buf(self);
1675n/a while (remaining > 0) {
1676n/a /* We want to read a whole block at the end into buffer.
1677n/a If we had readv() we could do this in one pass. */
1678n/a Py_ssize_t r = MINUS_LAST_BLOCK(self, remaining);
1679n/a if (r == 0)
1680n/a break;
1681n/a r = _bufferedreader_raw_read(self, out + written, r);
1682n/a if (r == -1)
1683n/a goto error;
1684n/a if (r == 0 || r == -2) {
1685n/a /* EOF occurred or read() would block. */
1686n/a if (r == 0 || written > 0) {
1687n/a if (_PyBytes_Resize(&res, written))
1688n/a goto error;
1689n/a return res;
1690n/a }
1691n/a Py_DECREF(res);
1692n/a Py_RETURN_NONE;
1693n/a }
1694n/a remaining -= r;
1695n/a written += r;
1696n/a }
1697n/a assert(remaining <= self->buffer_size);
1698n/a self->pos = 0;
1699n/a self->raw_pos = 0;
1700n/a self->read_end = 0;
1701n/a /* NOTE: when the read is satisfied, we avoid issuing any additional
1702n/a reads, which could block indefinitely (e.g. on a socket).
1703n/a See issue #9550. */
1704n/a while (remaining > 0 && self->read_end < self->buffer_size) {
1705n/a Py_ssize_t r = _bufferedreader_fill_buffer(self);
1706n/a if (r == -1)
1707n/a goto error;
1708n/a if (r == 0 || r == -2) {
1709n/a /* EOF occurred or read() would block. */
1710n/a if (r == 0 || written > 0) {
1711n/a if (_PyBytes_Resize(&res, written))
1712n/a goto error;
1713n/a return res;
1714n/a }
1715n/a Py_DECREF(res);
1716n/a Py_RETURN_NONE;
1717n/a }
1718n/a if (remaining > r) {
1719n/a memcpy(out + written, self->buffer + self->pos, r);
1720n/a written += r;
1721n/a self->pos += r;
1722n/a remaining -= r;
1723n/a }
1724n/a else if (remaining > 0) {
1725n/a memcpy(out + written, self->buffer + self->pos, remaining);
1726n/a written += remaining;
1727n/a self->pos += remaining;
1728n/a remaining = 0;
1729n/a }
1730n/a if (remaining == 0)
1731n/a break;
1732n/a }
1733n/a
1734n/a return res;
1735n/a
1736n/aerror:
1737n/a Py_XDECREF(res);
1738n/a return NULL;
1739n/a}
1740n/a
1741n/astatic PyObject *
1742n/a_bufferedreader_peek_unlocked(buffered *self)
1743n/a{
1744n/a Py_ssize_t have, r;
1745n/a
1746n/a have = Py_SAFE_DOWNCAST(READAHEAD(self), Py_off_t, Py_ssize_t);
1747n/a /* Constraints:
1748n/a 1. we don't want to advance the file position.
1749n/a 2. we don't want to lose block alignment, so we can't shift the buffer
1750n/a to make some place.
1751n/a Therefore, we either return `have` bytes (if > 0), or a full buffer.
1752n/a */
1753n/a if (have > 0) {
1754n/a return PyBytes_FromStringAndSize(self->buffer + self->pos, have);
1755n/a }
1756n/a
1757n/a /* Fill the buffer from the raw stream, and copy it to the result. */
1758n/a _bufferedreader_reset_buf(self);
1759n/a r = _bufferedreader_fill_buffer(self);
1760n/a if (r == -1)
1761n/a return NULL;
1762n/a if (r == -2)
1763n/a r = 0;
1764n/a self->pos = 0;
1765n/a return PyBytes_FromStringAndSize(self->buffer, r);
1766n/a}
1767n/a
1768n/a
1769n/a
1770n/a/*
1771n/a * class BufferedWriter
1772n/a */
1773n/astatic void
1774n/a_bufferedwriter_reset_buf(buffered *self)
1775n/a{
1776n/a self->write_pos = 0;
1777n/a self->write_end = -1;
1778n/a}
1779n/a
1780n/a/*[clinic input]
1781n/a_io.BufferedWriter.__init__
1782n/a raw: object
1783n/a buffer_size: Py_ssize_t(c_default="DEFAULT_BUFFER_SIZE") = DEFAULT_BUFFER_SIZE
1784n/a
1785n/aA buffer for a writeable sequential RawIO object.
1786n/a
1787n/aThe constructor creates a BufferedWriter for the given writeable raw
1788n/astream. If the buffer_size is not given, it defaults to
1789n/aDEFAULT_BUFFER_SIZE.
1790n/a[clinic start generated code]*/
1791n/a
1792n/astatic int
1793n/a_io_BufferedWriter___init___impl(buffered *self, PyObject *raw,
1794n/a Py_ssize_t buffer_size)
1795n/a/*[clinic end generated code: output=c8942a020c0dee64 input=914be9b95e16007b]*/
1796n/a{
1797n/a self->ok = 0;
1798n/a self->detached = 0;
1799n/a
1800n/a if (_PyIOBase_check_writable(raw, Py_True) == NULL)
1801n/a return -1;
1802n/a
1803n/a Py_INCREF(raw);
1804n/a Py_XSETREF(self->raw, raw);
1805n/a self->readable = 0;
1806n/a self->writable = 1;
1807n/a
1808n/a self->buffer_size = buffer_size;
1809n/a if (_buffered_init(self) < 0)
1810n/a return -1;
1811n/a _bufferedwriter_reset_buf(self);
1812n/a self->pos = 0;
1813n/a
1814n/a self->fast_closed_checks = (Py_TYPE(self) == &PyBufferedWriter_Type &&
1815n/a Py_TYPE(raw) == &PyFileIO_Type);
1816n/a
1817n/a self->ok = 1;
1818n/a return 0;
1819n/a}
1820n/a
1821n/astatic Py_ssize_t
1822n/a_bufferedwriter_raw_write(buffered *self, char *start, Py_ssize_t len)
1823n/a{
1824n/a Py_buffer buf;
1825n/a PyObject *memobj, *res;
1826n/a Py_ssize_t n;
1827n/a int errnum;
1828n/a /* NOTE: the buffer needn't be released as its object is NULL. */
1829n/a if (PyBuffer_FillInfo(&buf, NULL, start, len, 1, PyBUF_CONTIG_RO) == -1)
1830n/a return -1;
1831n/a memobj = PyMemoryView_FromBuffer(&buf);
1832n/a if (memobj == NULL)
1833n/a return -1;
1834n/a /* NOTE: PyErr_SetFromErrno() calls PyErr_CheckSignals() when EINTR
1835n/a occurs so we needn't do it ourselves.
1836n/a We then retry writing, ignoring the signal if no handler has
1837n/a raised (see issue #10956).
1838n/a */
1839n/a do {
1840n/a errno = 0;
1841n/a res = PyObject_CallMethodObjArgs(self->raw, _PyIO_str_write, memobj, NULL);
1842n/a errnum = errno;
1843n/a } while (res == NULL && _PyIO_trap_eintr());
1844n/a Py_DECREF(memobj);
1845n/a if (res == NULL)
1846n/a return -1;
1847n/a if (res == Py_None) {
1848n/a /* Non-blocking stream would have blocked. Special return code!
1849n/a Being paranoid we reset errno in case it is changed by code
1850n/a triggered by a decref. errno is used by _set_BlockingIOError(). */
1851n/a Py_DECREF(res);
1852n/a errno = errnum;
1853n/a return -2;
1854n/a }
1855n/a n = PyNumber_AsSsize_t(res, PyExc_ValueError);
1856n/a Py_DECREF(res);
1857n/a if (n < 0 || n > len) {
1858n/a PyErr_Format(PyExc_IOError,
1859n/a "raw write() returned invalid length %zd "
1860n/a "(should have been between 0 and %zd)", n, len);
1861n/a return -1;
1862n/a }
1863n/a if (n > 0 && self->abs_pos != -1)
1864n/a self->abs_pos += n;
1865n/a return n;
1866n/a}
1867n/a
1868n/a/* `restore_pos` is 1 if we need to restore the raw stream position at
1869n/a the end, 0 otherwise. */
1870n/astatic PyObject *
1871n/a_bufferedwriter_flush_unlocked(buffered *self)
1872n/a{
1873n/a Py_ssize_t written = 0;
1874n/a Py_off_t n, rewind;
1875n/a
1876n/a if (!VALID_WRITE_BUFFER(self) || self->write_pos == self->write_end)
1877n/a goto end;
1878n/a /* First, rewind */
1879n/a rewind = RAW_OFFSET(self) + (self->pos - self->write_pos);
1880n/a if (rewind != 0) {
1881n/a n = _buffered_raw_seek(self, -rewind, 1);
1882n/a if (n < 0) {
1883n/a goto error;
1884n/a }
1885n/a self->raw_pos -= rewind;
1886n/a }
1887n/a while (self->write_pos < self->write_end) {
1888n/a n = _bufferedwriter_raw_write(self,
1889n/a self->buffer + self->write_pos,
1890n/a Py_SAFE_DOWNCAST(self->write_end - self->write_pos,
1891n/a Py_off_t, Py_ssize_t));
1892n/a if (n == -1) {
1893n/a goto error;
1894n/a }
1895n/a else if (n == -2) {
1896n/a _set_BlockingIOError("write could not complete without blocking",
1897n/a 0);
1898n/a goto error;
1899n/a }
1900n/a self->write_pos += n;
1901n/a self->raw_pos = self->write_pos;
1902n/a written += Py_SAFE_DOWNCAST(n, Py_off_t, Py_ssize_t);
1903n/a /* Partial writes can return successfully when interrupted by a
1904n/a signal (see write(2)). We must run signal handlers before
1905n/a blocking another time, possibly indefinitely. */
1906n/a if (PyErr_CheckSignals() < 0)
1907n/a goto error;
1908n/a }
1909n/a
1910n/a _bufferedwriter_reset_buf(self);
1911n/a
1912n/aend:
1913n/a Py_RETURN_NONE;
1914n/a
1915n/aerror:
1916n/a return NULL;
1917n/a}
1918n/a
1919n/a/*[clinic input]
1920n/a_io.BufferedWriter.write
1921n/a buffer: Py_buffer
1922n/a /
1923n/a[clinic start generated code]*/
1924n/a
1925n/astatic PyObject *
1926n/a_io_BufferedWriter_write_impl(buffered *self, Py_buffer *buffer)
1927n/a/*[clinic end generated code: output=7f8d1365759bfc6b input=dd87dd85fc7f8850]*/
1928n/a{
1929n/a PyObject *res = NULL;
1930n/a Py_ssize_t written, avail, remaining;
1931n/a Py_off_t offset;
1932n/a
1933n/a CHECK_INITIALIZED(self)
1934n/a if (IS_CLOSED(self)) {
1935n/a PyErr_SetString(PyExc_ValueError, "write to closed file");
1936n/a return NULL;
1937n/a }
1938n/a
1939n/a if (!ENTER_BUFFERED(self))
1940n/a return NULL;
1941n/a
1942n/a /* Fast path: the data to write can be fully buffered. */
1943n/a if (!VALID_READ_BUFFER(self) && !VALID_WRITE_BUFFER(self)) {
1944n/a self->pos = 0;
1945n/a self->raw_pos = 0;
1946n/a }
1947n/a avail = Py_SAFE_DOWNCAST(self->buffer_size - self->pos, Py_off_t, Py_ssize_t);
1948n/a if (buffer->len <= avail) {
1949n/a memcpy(self->buffer + self->pos, buffer->buf, buffer->len);
1950n/a if (!VALID_WRITE_BUFFER(self) || self->write_pos > self->pos) {
1951n/a self->write_pos = self->pos;
1952n/a }
1953n/a ADJUST_POSITION(self, self->pos + buffer->len);
1954n/a if (self->pos > self->write_end)
1955n/a self->write_end = self->pos;
1956n/a written = buffer->len;
1957n/a goto end;
1958n/a }
1959n/a
1960n/a /* First write the current buffer */
1961n/a res = _bufferedwriter_flush_unlocked(self);
1962n/a if (res == NULL) {
1963n/a Py_ssize_t *w = _buffered_check_blocking_error();
1964n/a if (w == NULL)
1965n/a goto error;
1966n/a if (self->readable)
1967n/a _bufferedreader_reset_buf(self);
1968n/a /* Make some place by shifting the buffer. */
1969n/a assert(VALID_WRITE_BUFFER(self));
1970n/a memmove(self->buffer, self->buffer + self->write_pos,
1971n/a Py_SAFE_DOWNCAST(self->write_end - self->write_pos,
1972n/a Py_off_t, Py_ssize_t));
1973n/a self->write_end -= self->write_pos;
1974n/a self->raw_pos -= self->write_pos;
1975n/a self->pos -= self->write_pos;
1976n/a self->write_pos = 0;
1977n/a avail = Py_SAFE_DOWNCAST(self->buffer_size - self->write_end,
1978n/a Py_off_t, Py_ssize_t);
1979n/a if (buffer->len <= avail) {
1980n/a /* Everything can be buffered */
1981n/a PyErr_Clear();
1982n/a memcpy(self->buffer + self->write_end, buffer->buf, buffer->len);
1983n/a self->write_end += buffer->len;
1984n/a self->pos += buffer->len;
1985n/a written = buffer->len;
1986n/a goto end;
1987n/a }
1988n/a /* Buffer as much as possible. */
1989n/a memcpy(self->buffer + self->write_end, buffer->buf, avail);
1990n/a self->write_end += avail;
1991n/a self->pos += avail;
1992n/a /* XXX Modifying the existing exception e using the pointer w
1993n/a will change e.characters_written but not e.args[2].
1994n/a Therefore we just replace with a new error. */
1995n/a _set_BlockingIOError("write could not complete without blocking",
1996n/a avail);
1997n/a goto error;
1998n/a }
1999n/a Py_CLEAR(res);
2000n/a
2001n/a /* Adjust the raw stream position if it is away from the logical stream
2002n/a position. This happens if the read buffer has been filled but not
2003n/a modified (and therefore _bufferedwriter_flush_unlocked() didn't rewind
2004n/a the raw stream by itself).
2005n/a Fixes issue #6629.
2006n/a */
2007n/a offset = RAW_OFFSET(self);
2008n/a if (offset != 0) {
2009n/a if (_buffered_raw_seek(self, -offset, 1) < 0)
2010n/a goto error;
2011n/a self->raw_pos -= offset;
2012n/a }
2013n/a
2014n/a /* Then write buf itself. At this point the buffer has been emptied. */
2015n/a remaining = buffer->len;
2016n/a written = 0;
2017n/a while (remaining > self->buffer_size) {
2018n/a Py_ssize_t n = _bufferedwriter_raw_write(
2019n/a self, (char *) buffer->buf + written, buffer->len - written);
2020n/a if (n == -1) {
2021n/a goto error;
2022n/a } else if (n == -2) {
2023n/a /* Write failed because raw file is non-blocking */
2024n/a if (remaining > self->buffer_size) {
2025n/a /* Can't buffer everything, still buffer as much as possible */
2026n/a memcpy(self->buffer,
2027n/a (char *) buffer->buf + written, self->buffer_size);
2028n/a self->raw_pos = 0;
2029n/a ADJUST_POSITION(self, self->buffer_size);
2030n/a self->write_end = self->buffer_size;
2031n/a written += self->buffer_size;
2032n/a _set_BlockingIOError("write could not complete without "
2033n/a "blocking", written);
2034n/a goto error;
2035n/a }
2036n/a PyErr_Clear();
2037n/a break;
2038n/a }
2039n/a written += n;
2040n/a remaining -= n;
2041n/a /* Partial writes can return successfully when interrupted by a
2042n/a signal (see write(2)). We must run signal handlers before
2043n/a blocking another time, possibly indefinitely. */
2044n/a if (PyErr_CheckSignals() < 0)
2045n/a goto error;
2046n/a }
2047n/a if (self->readable)
2048n/a _bufferedreader_reset_buf(self);
2049n/a if (remaining > 0) {
2050n/a memcpy(self->buffer, (char *) buffer->buf + written, remaining);
2051n/a written += remaining;
2052n/a }
2053n/a self->write_pos = 0;
2054n/a /* TODO: sanity check (remaining >= 0) */
2055n/a self->write_end = remaining;
2056n/a ADJUST_POSITION(self, remaining);
2057n/a self->raw_pos = 0;
2058n/a
2059n/aend:
2060n/a res = PyLong_FromSsize_t(written);
2061n/a
2062n/aerror:
2063n/a LEAVE_BUFFERED(self)
2064n/a return res;
2065n/a}
2066n/a
2067n/a
2068n/a
2069n/a/*
2070n/a * BufferedRWPair
2071n/a */
2072n/a
2073n/a/* XXX The usefulness of this (compared to having two separate IO objects) is
2074n/a * questionable.
2075n/a */
2076n/a
2077n/atypedef struct {
2078n/a PyObject_HEAD
2079n/a buffered *reader;
2080n/a buffered *writer;
2081n/a PyObject *dict;
2082n/a PyObject *weakreflist;
2083n/a} rwpair;
2084n/a
2085n/a/*[clinic input]
2086n/a_io.BufferedRWPair.__init__
2087n/a reader: object
2088n/a writer: object
2089n/a buffer_size: Py_ssize_t(c_default="DEFAULT_BUFFER_SIZE") = DEFAULT_BUFFER_SIZE
2090n/a /
2091n/a
2092n/aA buffered reader and writer object together.
2093n/a
2094n/aA buffered reader object and buffered writer object put together to
2095n/aform a sequential IO object that can read and write. This is typically
2096n/aused with a socket or two-way pipe.
2097n/a
2098n/areader and writer are RawIOBase objects that are readable and
2099n/awriteable respectively. If the buffer_size is omitted it defaults to
2100n/aDEFAULT_BUFFER_SIZE.
2101n/a[clinic start generated code]*/
2102n/a
2103n/astatic int
2104n/a_io_BufferedRWPair___init___impl(rwpair *self, PyObject *reader,
2105n/a PyObject *writer, Py_ssize_t buffer_size)
2106n/a/*[clinic end generated code: output=327e73d1aee8f984 input=620d42d71f33a031]*/
2107n/a{
2108n/a if (_PyIOBase_check_readable(reader, Py_True) == NULL)
2109n/a return -1;
2110n/a if (_PyIOBase_check_writable(writer, Py_True) == NULL)
2111n/a return -1;
2112n/a
2113n/a self->reader = (buffered *) PyObject_CallFunction(
2114n/a (PyObject *) &PyBufferedReader_Type, "On", reader, buffer_size);
2115n/a if (self->reader == NULL)
2116n/a return -1;
2117n/a
2118n/a self->writer = (buffered *) PyObject_CallFunction(
2119n/a (PyObject *) &PyBufferedWriter_Type, "On", writer, buffer_size);
2120n/a if (self->writer == NULL) {
2121n/a Py_CLEAR(self->reader);
2122n/a return -1;
2123n/a }
2124n/a
2125n/a return 0;
2126n/a}
2127n/a
2128n/astatic int
2129n/abufferedrwpair_traverse(rwpair *self, visitproc visit, void *arg)
2130n/a{
2131n/a Py_VISIT(self->dict);
2132n/a return 0;
2133n/a}
2134n/a
2135n/astatic int
2136n/abufferedrwpair_clear(rwpair *self)
2137n/a{
2138n/a Py_CLEAR(self->reader);
2139n/a Py_CLEAR(self->writer);
2140n/a Py_CLEAR(self->dict);
2141n/a return 0;
2142n/a}
2143n/a
2144n/astatic void
2145n/abufferedrwpair_dealloc(rwpair *self)
2146n/a{
2147n/a _PyObject_GC_UNTRACK(self);
2148n/a if (self->weakreflist != NULL)
2149n/a PyObject_ClearWeakRefs((PyObject *)self);
2150n/a Py_CLEAR(self->reader);
2151n/a Py_CLEAR(self->writer);
2152n/a Py_CLEAR(self->dict);
2153n/a Py_TYPE(self)->tp_free((PyObject *) self);
2154n/a}
2155n/a
2156n/astatic PyObject *
2157n/a_forward_call(buffered *self, _Py_Identifier *name, PyObject *args)
2158n/a{
2159n/a PyObject *func, *ret;
2160n/a if (self == NULL) {
2161n/a PyErr_SetString(PyExc_ValueError,
2162n/a "I/O operation on uninitialized object");
2163n/a return NULL;
2164n/a }
2165n/a
2166n/a func = _PyObject_GetAttrId((PyObject *)self, name);
2167n/a if (func == NULL) {
2168n/a PyErr_SetString(PyExc_AttributeError, name->string);
2169n/a return NULL;
2170n/a }
2171n/a
2172n/a ret = PyObject_CallObject(func, args);
2173n/a Py_DECREF(func);
2174n/a return ret;
2175n/a}
2176n/a
2177n/astatic PyObject *
2178n/abufferedrwpair_read(rwpair *self, PyObject *args)
2179n/a{
2180n/a return _forward_call(self->reader, &PyId_read, args);
2181n/a}
2182n/a
2183n/astatic PyObject *
2184n/abufferedrwpair_peek(rwpair *self, PyObject *args)
2185n/a{
2186n/a return _forward_call(self->reader, &PyId_peek, args);
2187n/a}
2188n/a
2189n/astatic PyObject *
2190n/abufferedrwpair_read1(rwpair *self, PyObject *args)
2191n/a{
2192n/a return _forward_call(self->reader, &PyId_read1, args);
2193n/a}
2194n/a
2195n/astatic PyObject *
2196n/abufferedrwpair_readinto(rwpair *self, PyObject *args)
2197n/a{
2198n/a return _forward_call(self->reader, &PyId_readinto, args);
2199n/a}
2200n/a
2201n/astatic PyObject *
2202n/abufferedrwpair_readinto1(rwpair *self, PyObject *args)
2203n/a{
2204n/a return _forward_call(self->reader, &PyId_readinto1, args);
2205n/a}
2206n/a
2207n/astatic PyObject *
2208n/abufferedrwpair_write(rwpair *self, PyObject *args)
2209n/a{
2210n/a return _forward_call(self->writer, &PyId_write, args);
2211n/a}
2212n/a
2213n/astatic PyObject *
2214n/abufferedrwpair_flush(rwpair *self, PyObject *args)
2215n/a{
2216n/a return _forward_call(self->writer, &PyId_flush, args);
2217n/a}
2218n/a
2219n/astatic PyObject *
2220n/abufferedrwpair_readable(rwpair *self, PyObject *args)
2221n/a{
2222n/a return _forward_call(self->reader, &PyId_readable, args);
2223n/a}
2224n/a
2225n/astatic PyObject *
2226n/abufferedrwpair_writable(rwpair *self, PyObject *args)
2227n/a{
2228n/a return _forward_call(self->writer, &PyId_writable, args);
2229n/a}
2230n/a
2231n/astatic PyObject *
2232n/abufferedrwpair_close(rwpair *self, PyObject *args)
2233n/a{
2234n/a PyObject *exc = NULL, *val, *tb;
2235n/a PyObject *ret = _forward_call(self->writer, &PyId_close, args);
2236n/a if (ret == NULL)
2237n/a PyErr_Fetch(&exc, &val, &tb);
2238n/a else
2239n/a Py_DECREF(ret);
2240n/a ret = _forward_call(self->reader, &PyId_close, args);
2241n/a if (exc != NULL) {
2242n/a _PyErr_ChainExceptions(exc, val, tb);
2243n/a Py_CLEAR(ret);
2244n/a }
2245n/a return ret;
2246n/a}
2247n/a
2248n/astatic PyObject *
2249n/abufferedrwpair_isatty(rwpair *self, PyObject *args)
2250n/a{
2251n/a PyObject *ret = _forward_call(self->writer, &PyId_isatty, args);
2252n/a
2253n/a if (ret != Py_False) {
2254n/a /* either True or exception */
2255n/a return ret;
2256n/a }
2257n/a Py_DECREF(ret);
2258n/a
2259n/a return _forward_call(self->reader, &PyId_isatty, args);
2260n/a}
2261n/a
2262n/astatic PyObject *
2263n/abufferedrwpair_closed_get(rwpair *self, void *context)
2264n/a{
2265n/a if (self->writer == NULL) {
2266n/a PyErr_SetString(PyExc_RuntimeError,
2267n/a "the BufferedRWPair object is being garbage-collected");
2268n/a return NULL;
2269n/a }
2270n/a return PyObject_GetAttr((PyObject *) self->writer, _PyIO_str_closed);
2271n/a}
2272n/a
2273n/a
2274n/a
2275n/a/*
2276n/a * BufferedRandom
2277n/a */
2278n/a
2279n/a/*[clinic input]
2280n/a_io.BufferedRandom.__init__
2281n/a raw: object
2282n/a buffer_size: Py_ssize_t(c_default="DEFAULT_BUFFER_SIZE") = DEFAULT_BUFFER_SIZE
2283n/a
2284n/aA buffered interface to random access streams.
2285n/a
2286n/aThe constructor creates a reader and writer for a seekable stream,
2287n/araw, given in the first argument. If the buffer_size is omitted it
2288n/adefaults to DEFAULT_BUFFER_SIZE.
2289n/a[clinic start generated code]*/
2290n/a
2291n/astatic int
2292n/a_io_BufferedRandom___init___impl(buffered *self, PyObject *raw,
2293n/a Py_ssize_t buffer_size)
2294n/a/*[clinic end generated code: output=d3d64eb0f64e64a3 input=a4e818fb86d0e50c]*/
2295n/a{
2296n/a self->ok = 0;
2297n/a self->detached = 0;
2298n/a
2299n/a if (_PyIOBase_check_seekable(raw, Py_True) == NULL)
2300n/a return -1;
2301n/a if (_PyIOBase_check_readable(raw, Py_True) == NULL)
2302n/a return -1;
2303n/a if (_PyIOBase_check_writable(raw, Py_True) == NULL)
2304n/a return -1;
2305n/a
2306n/a Py_INCREF(raw);
2307n/a Py_XSETREF(self->raw, raw);
2308n/a self->buffer_size = buffer_size;
2309n/a self->readable = 1;
2310n/a self->writable = 1;
2311n/a
2312n/a if (_buffered_init(self) < 0)
2313n/a return -1;
2314n/a _bufferedreader_reset_buf(self);
2315n/a _bufferedwriter_reset_buf(self);
2316n/a self->pos = 0;
2317n/a
2318n/a self->fast_closed_checks = (Py_TYPE(self) == &PyBufferedRandom_Type &&
2319n/a Py_TYPE(raw) == &PyFileIO_Type);
2320n/a
2321n/a self->ok = 1;
2322n/a return 0;
2323n/a}
2324n/a
2325n/a#include "clinic/bufferedio.c.h"
2326n/a
2327n/a
2328n/astatic PyMethodDef bufferediobase_methods[] = {
2329n/a _IO__BUFFEREDIOBASE_DETACH_METHODDEF
2330n/a {"read", bufferediobase_read, METH_VARARGS, bufferediobase_read_doc},
2331n/a {"read1", bufferediobase_read1, METH_VARARGS, bufferediobase_read1_doc},
2332n/a _IO__BUFFEREDIOBASE_READINTO_METHODDEF
2333n/a _IO__BUFFEREDIOBASE_READINTO1_METHODDEF
2334n/a {"write", bufferediobase_write, METH_VARARGS, bufferediobase_write_doc},
2335n/a {NULL, NULL}
2336n/a};
2337n/a
2338n/aPyTypeObject PyBufferedIOBase_Type = {
2339n/a PyVarObject_HEAD_INIT(NULL, 0)
2340n/a "_io._BufferedIOBase", /*tp_name*/
2341n/a 0, /*tp_basicsize*/
2342n/a 0, /*tp_itemsize*/
2343n/a 0, /*tp_dealloc*/
2344n/a 0, /*tp_print*/
2345n/a 0, /*tp_getattr*/
2346n/a 0, /*tp_setattr*/
2347n/a 0, /*tp_compare */
2348n/a 0, /*tp_repr*/
2349n/a 0, /*tp_as_number*/
2350n/a 0, /*tp_as_sequence*/
2351n/a 0, /*tp_as_mapping*/
2352n/a 0, /*tp_hash */
2353n/a 0, /*tp_call*/
2354n/a 0, /*tp_str*/
2355n/a 0, /*tp_getattro*/
2356n/a 0, /*tp_setattro*/
2357n/a 0, /*tp_as_buffer*/
2358n/a Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE
2359n/a | Py_TPFLAGS_HAVE_FINALIZE, /*tp_flags*/
2360n/a bufferediobase_doc, /* tp_doc */
2361n/a 0, /* tp_traverse */
2362n/a 0, /* tp_clear */
2363n/a 0, /* tp_richcompare */
2364n/a 0, /* tp_weaklistoffset */
2365n/a 0, /* tp_iter */
2366n/a 0, /* tp_iternext */
2367n/a bufferediobase_methods, /* tp_methods */
2368n/a 0, /* tp_members */
2369n/a 0, /* tp_getset */
2370n/a &PyIOBase_Type, /* tp_base */
2371n/a 0, /* tp_dict */
2372n/a 0, /* tp_descr_get */
2373n/a 0, /* tp_descr_set */
2374n/a 0, /* tp_dictoffset */
2375n/a 0, /* tp_init */
2376n/a 0, /* tp_alloc */
2377n/a 0, /* tp_new */
2378n/a 0, /* tp_free */
2379n/a 0, /* tp_is_gc */
2380n/a 0, /* tp_bases */
2381n/a 0, /* tp_mro */
2382n/a 0, /* tp_cache */
2383n/a 0, /* tp_subclasses */
2384n/a 0, /* tp_weaklist */
2385n/a 0, /* tp_del */
2386n/a 0, /* tp_version_tag */
2387n/a 0, /* tp_finalize */
2388n/a};
2389n/a
2390n/a
2391n/astatic PyMethodDef bufferedreader_methods[] = {
2392n/a /* BufferedIOMixin methods */
2393n/a {"detach", (PyCFunction)buffered_detach, METH_NOARGS},
2394n/a {"flush", (PyCFunction)buffered_simple_flush, METH_NOARGS},
2395n/a {"close", (PyCFunction)buffered_close, METH_NOARGS},
2396n/a {"seekable", (PyCFunction)buffered_seekable, METH_NOARGS},
2397n/a {"readable", (PyCFunction)buffered_readable, METH_NOARGS},
2398n/a {"fileno", (PyCFunction)buffered_fileno, METH_NOARGS},
2399n/a {"isatty", (PyCFunction)buffered_isatty, METH_NOARGS},
2400n/a {"_dealloc_warn", (PyCFunction)buffered_dealloc_warn, METH_O},
2401n/a {"__getstate__", (PyCFunction)buffered_getstate, METH_NOARGS},
2402n/a
2403n/a _IO__BUFFERED_READ_METHODDEF
2404n/a _IO__BUFFERED_PEEK_METHODDEF
2405n/a _IO__BUFFERED_READ1_METHODDEF
2406n/a _IO__BUFFERED_READINTO_METHODDEF
2407n/a _IO__BUFFERED_READINTO1_METHODDEF
2408n/a _IO__BUFFERED_READLINE_METHODDEF
2409n/a _IO__BUFFERED_SEEK_METHODDEF
2410n/a {"tell", (PyCFunction)buffered_tell, METH_NOARGS},
2411n/a _IO__BUFFERED_TRUNCATE_METHODDEF
2412n/a {"__sizeof__", (PyCFunction)buffered_sizeof, METH_NOARGS},
2413n/a {NULL, NULL}
2414n/a};
2415n/a
2416n/astatic PyMemberDef bufferedreader_members[] = {
2417n/a {"raw", T_OBJECT, offsetof(buffered, raw), READONLY},
2418n/a {"_finalizing", T_BOOL, offsetof(buffered, finalizing), 0},
2419n/a {NULL}
2420n/a};
2421n/a
2422n/astatic PyGetSetDef bufferedreader_getset[] = {
2423n/a {"closed", (getter)buffered_closed_get, NULL, NULL},
2424n/a {"name", (getter)buffered_name_get, NULL, NULL},
2425n/a {"mode", (getter)buffered_mode_get, NULL, NULL},
2426n/a {NULL}
2427n/a};
2428n/a
2429n/a
2430n/aPyTypeObject PyBufferedReader_Type = {
2431n/a PyVarObject_HEAD_INIT(NULL, 0)
2432n/a "_io.BufferedReader", /*tp_name*/
2433n/a sizeof(buffered), /*tp_basicsize*/
2434n/a 0, /*tp_itemsize*/
2435n/a (destructor)buffered_dealloc, /*tp_dealloc*/
2436n/a 0, /*tp_print*/
2437n/a 0, /*tp_getattr*/
2438n/a 0, /*tp_setattr*/
2439n/a 0, /*tp_compare */
2440n/a (reprfunc)buffered_repr, /*tp_repr*/
2441n/a 0, /*tp_as_number*/
2442n/a 0, /*tp_as_sequence*/
2443n/a 0, /*tp_as_mapping*/
2444n/a 0, /*tp_hash */
2445n/a 0, /*tp_call*/
2446n/a 0, /*tp_str*/
2447n/a 0, /*tp_getattro*/
2448n/a 0, /*tp_setattro*/
2449n/a 0, /*tp_as_buffer*/
2450n/a Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE
2451n/a | Py_TPFLAGS_HAVE_GC | Py_TPFLAGS_HAVE_FINALIZE, /*tp_flags*/
2452n/a _io_BufferedReader___init____doc__, /* tp_doc */
2453n/a (traverseproc)buffered_traverse, /* tp_traverse */
2454n/a (inquiry)buffered_clear, /* tp_clear */
2455n/a 0, /* tp_richcompare */
2456n/a offsetof(buffered, weakreflist), /*tp_weaklistoffset*/
2457n/a 0, /* tp_iter */
2458n/a (iternextfunc)buffered_iternext, /* tp_iternext */
2459n/a bufferedreader_methods, /* tp_methods */
2460n/a bufferedreader_members, /* tp_members */
2461n/a bufferedreader_getset, /* tp_getset */
2462n/a 0, /* tp_base */
2463n/a 0, /* tp_dict */
2464n/a 0, /* tp_descr_get */
2465n/a 0, /* tp_descr_set */
2466n/a offsetof(buffered, dict), /* tp_dictoffset */
2467n/a _io_BufferedReader___init__, /* tp_init */
2468n/a 0, /* tp_alloc */
2469n/a PyType_GenericNew, /* tp_new */
2470n/a 0, /* tp_free */
2471n/a 0, /* tp_is_gc */
2472n/a 0, /* tp_bases */
2473n/a 0, /* tp_mro */
2474n/a 0, /* tp_cache */
2475n/a 0, /* tp_subclasses */
2476n/a 0, /* tp_weaklist */
2477n/a 0, /* tp_del */
2478n/a 0, /* tp_version_tag */
2479n/a 0, /* tp_finalize */
2480n/a};
2481n/a
2482n/a
2483n/astatic PyMethodDef bufferedwriter_methods[] = {
2484n/a /* BufferedIOMixin methods */
2485n/a {"close", (PyCFunction)buffered_close, METH_NOARGS},
2486n/a {"detach", (PyCFunction)buffered_detach, METH_NOARGS},
2487n/a {"seekable", (PyCFunction)buffered_seekable, METH_NOARGS},
2488n/a {"writable", (PyCFunction)buffered_writable, METH_NOARGS},
2489n/a {"fileno", (PyCFunction)buffered_fileno, METH_NOARGS},
2490n/a {"isatty", (PyCFunction)buffered_isatty, METH_NOARGS},
2491n/a {"_dealloc_warn", (PyCFunction)buffered_dealloc_warn, METH_O},
2492n/a {"__getstate__", (PyCFunction)buffered_getstate, METH_NOARGS},
2493n/a
2494n/a _IO_BUFFEREDWRITER_WRITE_METHODDEF
2495n/a _IO__BUFFERED_TRUNCATE_METHODDEF
2496n/a {"flush", (PyCFunction)buffered_flush, METH_NOARGS},
2497n/a _IO__BUFFERED_SEEK_METHODDEF
2498n/a {"tell", (PyCFunction)buffered_tell, METH_NOARGS},
2499n/a {"__sizeof__", (PyCFunction)buffered_sizeof, METH_NOARGS},
2500n/a {NULL, NULL}
2501n/a};
2502n/a
2503n/astatic PyMemberDef bufferedwriter_members[] = {
2504n/a {"raw", T_OBJECT, offsetof(buffered, raw), READONLY},
2505n/a {"_finalizing", T_BOOL, offsetof(buffered, finalizing), 0},
2506n/a {NULL}
2507n/a};
2508n/a
2509n/astatic PyGetSetDef bufferedwriter_getset[] = {
2510n/a {"closed", (getter)buffered_closed_get, NULL, NULL},
2511n/a {"name", (getter)buffered_name_get, NULL, NULL},
2512n/a {"mode", (getter)buffered_mode_get, NULL, NULL},
2513n/a {NULL}
2514n/a};
2515n/a
2516n/a
2517n/aPyTypeObject PyBufferedWriter_Type = {
2518n/a PyVarObject_HEAD_INIT(NULL, 0)
2519n/a "_io.BufferedWriter", /*tp_name*/
2520n/a sizeof(buffered), /*tp_basicsize*/
2521n/a 0, /*tp_itemsize*/
2522n/a (destructor)buffered_dealloc, /*tp_dealloc*/
2523n/a 0, /*tp_print*/
2524n/a 0, /*tp_getattr*/
2525n/a 0, /*tp_setattr*/
2526n/a 0, /*tp_compare */
2527n/a (reprfunc)buffered_repr, /*tp_repr*/
2528n/a 0, /*tp_as_number*/
2529n/a 0, /*tp_as_sequence*/
2530n/a 0, /*tp_as_mapping*/
2531n/a 0, /*tp_hash */
2532n/a 0, /*tp_call*/
2533n/a 0, /*tp_str*/
2534n/a 0, /*tp_getattro*/
2535n/a 0, /*tp_setattro*/
2536n/a 0, /*tp_as_buffer*/
2537n/a Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE
2538n/a | Py_TPFLAGS_HAVE_GC | Py_TPFLAGS_HAVE_FINALIZE, /*tp_flags*/
2539n/a _io_BufferedWriter___init____doc__, /* tp_doc */
2540n/a (traverseproc)buffered_traverse, /* tp_traverse */
2541n/a (inquiry)buffered_clear, /* tp_clear */
2542n/a 0, /* tp_richcompare */
2543n/a offsetof(buffered, weakreflist), /*tp_weaklistoffset*/
2544n/a 0, /* tp_iter */
2545n/a 0, /* tp_iternext */
2546n/a bufferedwriter_methods, /* tp_methods */
2547n/a bufferedwriter_members, /* tp_members */
2548n/a bufferedwriter_getset, /* tp_getset */
2549n/a 0, /* tp_base */
2550n/a 0, /* tp_dict */
2551n/a 0, /* tp_descr_get */
2552n/a 0, /* tp_descr_set */
2553n/a offsetof(buffered, dict), /* tp_dictoffset */
2554n/a _io_BufferedWriter___init__, /* tp_init */
2555n/a 0, /* tp_alloc */
2556n/a PyType_GenericNew, /* tp_new */
2557n/a 0, /* tp_free */
2558n/a 0, /* tp_is_gc */
2559n/a 0, /* tp_bases */
2560n/a 0, /* tp_mro */
2561n/a 0, /* tp_cache */
2562n/a 0, /* tp_subclasses */
2563n/a 0, /* tp_weaklist */
2564n/a 0, /* tp_del */
2565n/a 0, /* tp_version_tag */
2566n/a 0, /* tp_finalize */
2567n/a};
2568n/a
2569n/a
2570n/astatic PyMethodDef bufferedrwpair_methods[] = {
2571n/a {"read", (PyCFunction)bufferedrwpair_read, METH_VARARGS},
2572n/a {"peek", (PyCFunction)bufferedrwpair_peek, METH_VARARGS},
2573n/a {"read1", (PyCFunction)bufferedrwpair_read1, METH_VARARGS},
2574n/a {"readinto", (PyCFunction)bufferedrwpair_readinto, METH_VARARGS},
2575n/a {"readinto1", (PyCFunction)bufferedrwpair_readinto1, METH_VARARGS},
2576n/a
2577n/a {"write", (PyCFunction)bufferedrwpair_write, METH_VARARGS},
2578n/a {"flush", (PyCFunction)bufferedrwpair_flush, METH_NOARGS},
2579n/a
2580n/a {"readable", (PyCFunction)bufferedrwpair_readable, METH_NOARGS},
2581n/a {"writable", (PyCFunction)bufferedrwpair_writable, METH_NOARGS},
2582n/a
2583n/a {"close", (PyCFunction)bufferedrwpair_close, METH_NOARGS},
2584n/a {"isatty", (PyCFunction)bufferedrwpair_isatty, METH_NOARGS},
2585n/a
2586n/a {"__getstate__", (PyCFunction)buffered_getstate, METH_NOARGS},
2587n/a
2588n/a {NULL, NULL}
2589n/a};
2590n/a
2591n/astatic PyGetSetDef bufferedrwpair_getset[] = {
2592n/a {"closed", (getter)bufferedrwpair_closed_get, NULL, NULL},
2593n/a {NULL}
2594n/a};
2595n/a
2596n/aPyTypeObject PyBufferedRWPair_Type = {
2597n/a PyVarObject_HEAD_INIT(NULL, 0)
2598n/a "_io.BufferedRWPair", /*tp_name*/
2599n/a sizeof(rwpair), /*tp_basicsize*/
2600n/a 0, /*tp_itemsize*/
2601n/a (destructor)bufferedrwpair_dealloc, /*tp_dealloc*/
2602n/a 0, /*tp_print*/
2603n/a 0, /*tp_getattr*/
2604n/a 0, /*tp_setattr*/
2605n/a 0, /*tp_compare */
2606n/a 0, /*tp_repr*/
2607n/a 0, /*tp_as_number*/
2608n/a 0, /*tp_as_sequence*/
2609n/a 0, /*tp_as_mapping*/
2610n/a 0, /*tp_hash */
2611n/a 0, /*tp_call*/
2612n/a 0, /*tp_str*/
2613n/a 0, /*tp_getattro*/
2614n/a 0, /*tp_setattro*/
2615n/a 0, /*tp_as_buffer*/
2616n/a Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE
2617n/a | Py_TPFLAGS_HAVE_GC | Py_TPFLAGS_HAVE_FINALIZE, /* tp_flags */
2618n/a _io_BufferedRWPair___init____doc__, /* tp_doc */
2619n/a (traverseproc)bufferedrwpair_traverse, /* tp_traverse */
2620n/a (inquiry)bufferedrwpair_clear, /* tp_clear */
2621n/a 0, /* tp_richcompare */
2622n/a offsetof(rwpair, weakreflist), /*tp_weaklistoffset*/
2623n/a 0, /* tp_iter */
2624n/a 0, /* tp_iternext */
2625n/a bufferedrwpair_methods, /* tp_methods */
2626n/a 0, /* tp_members */
2627n/a bufferedrwpair_getset, /* tp_getset */
2628n/a 0, /* tp_base */
2629n/a 0, /* tp_dict */
2630n/a 0, /* tp_descr_get */
2631n/a 0, /* tp_descr_set */
2632n/a offsetof(rwpair, dict), /* tp_dictoffset */
2633n/a _io_BufferedRWPair___init__, /* tp_init */
2634n/a 0, /* tp_alloc */
2635n/a PyType_GenericNew, /* tp_new */
2636n/a 0, /* tp_free */
2637n/a 0, /* tp_is_gc */
2638n/a 0, /* tp_bases */
2639n/a 0, /* tp_mro */
2640n/a 0, /* tp_cache */
2641n/a 0, /* tp_subclasses */
2642n/a 0, /* tp_weaklist */
2643n/a 0, /* tp_del */
2644n/a 0, /* tp_version_tag */
2645n/a 0, /* tp_finalize */
2646n/a};
2647n/a
2648n/a
2649n/astatic PyMethodDef bufferedrandom_methods[] = {
2650n/a /* BufferedIOMixin methods */
2651n/a {"close", (PyCFunction)buffered_close, METH_NOARGS},
2652n/a {"detach", (PyCFunction)buffered_detach, METH_NOARGS},
2653n/a {"seekable", (PyCFunction)buffered_seekable, METH_NOARGS},
2654n/a {"readable", (PyCFunction)buffered_readable, METH_NOARGS},
2655n/a {"writable", (PyCFunction)buffered_writable, METH_NOARGS},
2656n/a {"fileno", (PyCFunction)buffered_fileno, METH_NOARGS},
2657n/a {"isatty", (PyCFunction)buffered_isatty, METH_NOARGS},
2658n/a {"_dealloc_warn", (PyCFunction)buffered_dealloc_warn, METH_O},
2659n/a {"__getstate__", (PyCFunction)buffered_getstate, METH_NOARGS},
2660n/a
2661n/a {"flush", (PyCFunction)buffered_flush, METH_NOARGS},
2662n/a
2663n/a _IO__BUFFERED_SEEK_METHODDEF
2664n/a {"tell", (PyCFunction)buffered_tell, METH_NOARGS},
2665n/a _IO__BUFFERED_TRUNCATE_METHODDEF
2666n/a _IO__BUFFERED_READ_METHODDEF
2667n/a _IO__BUFFERED_READ1_METHODDEF
2668n/a _IO__BUFFERED_READINTO_METHODDEF
2669n/a _IO__BUFFERED_READINTO1_METHODDEF
2670n/a _IO__BUFFERED_READLINE_METHODDEF
2671n/a _IO__BUFFERED_PEEK_METHODDEF
2672n/a _IO_BUFFEREDWRITER_WRITE_METHODDEF
2673n/a {"__sizeof__", (PyCFunction)buffered_sizeof, METH_NOARGS},
2674n/a {NULL, NULL}
2675n/a};
2676n/a
2677n/astatic PyMemberDef bufferedrandom_members[] = {
2678n/a {"raw", T_OBJECT, offsetof(buffered, raw), READONLY},
2679n/a {"_finalizing", T_BOOL, offsetof(buffered, finalizing), 0},
2680n/a {NULL}
2681n/a};
2682n/a
2683n/astatic PyGetSetDef bufferedrandom_getset[] = {
2684n/a {"closed", (getter)buffered_closed_get, NULL, NULL},
2685n/a {"name", (getter)buffered_name_get, NULL, NULL},
2686n/a {"mode", (getter)buffered_mode_get, NULL, NULL},
2687n/a {NULL}
2688n/a};
2689n/a
2690n/a
2691n/aPyTypeObject PyBufferedRandom_Type = {
2692n/a PyVarObject_HEAD_INIT(NULL, 0)
2693n/a "_io.BufferedRandom", /*tp_name*/
2694n/a sizeof(buffered), /*tp_basicsize*/
2695n/a 0, /*tp_itemsize*/
2696n/a (destructor)buffered_dealloc, /*tp_dealloc*/
2697n/a 0, /*tp_print*/
2698n/a 0, /*tp_getattr*/
2699n/a 0, /*tp_setattr*/
2700n/a 0, /*tp_compare */
2701n/a (reprfunc)buffered_repr, /*tp_repr*/
2702n/a 0, /*tp_as_number*/
2703n/a 0, /*tp_as_sequence*/
2704n/a 0, /*tp_as_mapping*/
2705n/a 0, /*tp_hash */
2706n/a 0, /*tp_call*/
2707n/a 0, /*tp_str*/
2708n/a 0, /*tp_getattro*/
2709n/a 0, /*tp_setattro*/
2710n/a 0, /*tp_as_buffer*/
2711n/a Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE
2712n/a | Py_TPFLAGS_HAVE_GC | Py_TPFLAGS_HAVE_FINALIZE, /*tp_flags*/
2713n/a _io_BufferedRandom___init____doc__, /* tp_doc */
2714n/a (traverseproc)buffered_traverse, /* tp_traverse */
2715n/a (inquiry)buffered_clear, /* tp_clear */
2716n/a 0, /* tp_richcompare */
2717n/a offsetof(buffered, weakreflist), /*tp_weaklistoffset*/
2718n/a 0, /* tp_iter */
2719n/a (iternextfunc)buffered_iternext, /* tp_iternext */
2720n/a bufferedrandom_methods, /* tp_methods */
2721n/a bufferedrandom_members, /* tp_members */
2722n/a bufferedrandom_getset, /* tp_getset */
2723n/a 0, /* tp_base */
2724n/a 0, /*tp_dict*/
2725n/a 0, /* tp_descr_get */
2726n/a 0, /* tp_descr_set */
2727n/a offsetof(buffered, dict), /*tp_dictoffset*/
2728n/a _io_BufferedRandom___init__, /* tp_init */
2729n/a 0, /* tp_alloc */
2730n/a PyType_GenericNew, /* tp_new */
2731n/a 0, /* tp_free */
2732n/a 0, /* tp_is_gc */
2733n/a 0, /* tp_bases */
2734n/a 0, /* tp_mro */
2735n/a 0, /* tp_cache */
2736n/a 0, /* tp_subclasses */
2737n/a 0, /* tp_weaklist */
2738n/a 0, /* tp_del */
2739n/a 0, /* tp_version_tag */
2740n/a 0, /* tp_finalize */
2741n/a};