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