@@ -752,25 +752,38 @@ _trap_eintr(void)
752752 */
753753
754754static PyObject *
755- buffered_flush (buffered * self , PyObject * args )
755+ buffered_flush_and_rewind_unlocked (buffered * self )
756756{
757757 PyObject * res ;
758758
759- CHECK_INITIALIZED (self )
760- CHECK_CLOSED (self , "flush of closed file" )
761-
762- if (!ENTER_BUFFERED (self ))
763- return NULL ;
764759 res = _bufferedwriter_flush_unlocked (self , 0 );
765- if (res != NULL && self -> readable ) {
760+ if (res == NULL )
761+ return NULL ;
762+ Py_DECREF (res );
763+
764+ if (self -> readable ) {
766765 /* Rewind the raw stream so that its position corresponds to
767766 the current logical position. */
768767 Py_off_t n ;
769768 n = _buffered_raw_seek (self , - RAW_OFFSET (self ), 1 );
770- if (n == -1 )
771- Py_CLEAR (res );
772769 _bufferedreader_reset_buf (self );
770+ if (n == -1 )
771+ return NULL ;
773772 }
773+ Py_RETURN_NONE ;
774+ }
775+
776+ static PyObject *
777+ buffered_flush (buffered * self , PyObject * args )
778+ {
779+ PyObject * res ;
780+
781+ CHECK_INITIALIZED (self )
782+ CHECK_CLOSED (self , "flush of closed file" )
783+
784+ if (!ENTER_BUFFERED (self ))
785+ return NULL ;
786+ res = buffered_flush_and_rewind_unlocked (self );
774787 LEAVE_BUFFERED (self )
775788
776789 return res ;
@@ -791,7 +804,7 @@ buffered_peek(buffered *self, PyObject *args)
791804 return NULL ;
792805
793806 if (self -> writable ) {
794- res = _bufferedwriter_flush_unlocked (self , 1 );
807+ res = buffered_flush_and_rewind_unlocked (self );
795808 if (res == NULL )
796809 goto end ;
797810 Py_CLEAR (res );
@@ -826,19 +839,18 @@ buffered_read(buffered *self, PyObject *args)
826839 if (!ENTER_BUFFERED (self ))
827840 return NULL ;
828841 res = _bufferedreader_read_all (self );
829- LEAVE_BUFFERED (self )
830842 }
831843 else {
832844 res = _bufferedreader_read_fast (self , n );
833- if (res == Py_None ) {
834- Py_DECREF (res );
835- if (!ENTER_BUFFERED (self ))
836- return NULL ;
837- res = _bufferedreader_read_generic (self , n );
838- LEAVE_BUFFERED (self )
839- }
845+ if (res != Py_None )
846+ return res ;
847+ Py_DECREF (res );
848+ if (!ENTER_BUFFERED (self ))
849+ return NULL ;
850+ res = _bufferedreader_read_generic (self , n );
840851 }
841852
853+ LEAVE_BUFFERED (self )
842854 return res ;
843855}
844856
@@ -864,13 +876,6 @@ buffered_read1(buffered *self, PyObject *args)
864876 if (!ENTER_BUFFERED (self ))
865877 return NULL ;
866878
867- if (self -> writable ) {
868- res = _bufferedwriter_flush_unlocked (self , 1 );
869- if (res == NULL )
870- goto end ;
871- Py_CLEAR (res );
872- }
873-
874879 /* Return up to n bytes. If at least one byte is buffered, we
875880 only return buffered bytes. Otherwise, we do one raw read. */
876881
@@ -890,6 +895,13 @@ buffered_read1(buffered *self, PyObject *args)
890895 goto end ;
891896 }
892897
898+ if (self -> writable ) {
899+ res = buffered_flush_and_rewind_unlocked (self );
900+ if (res == NULL )
901+ goto end ;
902+ Py_DECREF (res );
903+ }
904+
893905 /* Fill the buffer from the raw stream, and copy it to the result. */
894906 _bufferedreader_reset_buf (self );
895907 r = _bufferedreader_fill_buffer (self );
@@ -912,24 +924,10 @@ buffered_read1(buffered *self, PyObject *args)
912924static PyObject *
913925buffered_readinto (buffered * self , PyObject * args )
914926{
915- PyObject * res = NULL ;
916-
917927 CHECK_INITIALIZED (self )
918928
919- /* TODO: use raw.readinto() instead! */
920- if (self -> writable ) {
921- if (!ENTER_BUFFERED (self ))
922- return NULL ;
923- res = _bufferedwriter_flush_unlocked (self , 0 );
924- LEAVE_BUFFERED (self )
925- if (res == NULL)
926- goto end ;
927- Py_DECREF (res );
928- }
929- res = bufferediobase_readinto ((PyObject * )self , args );
930-
931- end :
932- return res ;
929+ /* TODO: use raw.readinto() (or a direct copy from our buffer) instead! */
930+ return bufferediobase_readinto ((PyObject * )self , args );
933931}
934932
935933static PyObject *
@@ -967,12 +965,6 @@ _buffered_readline(buffered *self, Py_ssize_t limit)
967965 goto end_unlocked ;
968966
969967 /* Now we try to get some more from the raw stream */
970- if (self -> writable ) {
971- res = _bufferedwriter_flush_unlocked (self , 1 );
972- if (res == NULL )
973- goto end ;
974- Py_CLEAR (res );
975- }
976968 chunks = PyList_New (0 );
977969 if (chunks == NULL )
978970 goto end ;
@@ -986,9 +978,16 @@ _buffered_readline(buffered *self, Py_ssize_t limit)
986978 }
987979 Py_CLEAR (res );
988980 written += n ;
981+ self -> pos += n ;
989982 if (limit >= 0 )
990983 limit -= n ;
991984 }
985+ if (self -> writable ) {
986+ PyObject * r = buffered_flush_and_rewind_unlocked (self );
987+ if (r == NULL )
988+ goto end ;
989+ Py_DECREF (r );
990+ }
992991
993992 for (;;) {
994993 _bufferedreader_reset_buf (self );
@@ -1157,20 +1156,11 @@ buffered_truncate(buffered *self, PyObject *args)
11571156 return NULL ;
11581157
11591158 if (self -> writable ) {
1160- res = _bufferedwriter_flush_unlocked (self , 0 );
1159+ res = buffered_flush_and_rewind_unlocked (self );
11611160 if (res == NULL )
11621161 goto end ;
11631162 Py_CLEAR (res );
11641163 }
1165- if (self -> readable ) {
1166- if (pos == Py_None ) {
1167- /* Rewind the raw stream so that its position corresponds to
1168- the current logical position. */
1169- if (_buffered_raw_seek (self , - RAW_OFFSET (self ), 1 ) == -1 )
1170- goto end ;
1171- }
1172- _bufferedreader_reset_buf (self );
1173- }
11741164 res = PyObject_CallMethodObjArgs (self -> raw , _PyIO_str_truncate , pos , NULL );
11751165 if (res == NULL )
11761166 goto end ;
@@ -1367,17 +1357,18 @@ _bufferedreader_read_all(buffered *self)
13671357 Py_DECREF (chunks );
13681358 return NULL ;
13691359 }
1360+ self -> pos += current_size ;
13701361 }
1371- _bufferedreader_reset_buf (self );
13721362 /* We're going past the buffer's bounds, flush it */
13731363 if (self -> writable ) {
1374- res = _bufferedwriter_flush_unlocked (self , 1 );
1364+ res = buffered_flush_and_rewind_unlocked (self );
13751365 if (res == NULL ) {
13761366 Py_DECREF (chunks );
13771367 return NULL ;
13781368 }
13791369 Py_CLEAR (res );
13801370 }
1371+ _bufferedreader_reset_buf (self );
13811372 while (1 ) {
13821373 if (data ) {
13831374 if (PyList_Append (chunks , data ) < 0 ) {
@@ -1460,6 +1451,14 @@ _bufferedreader_read_generic(buffered *self, Py_ssize_t n)
14601451 memcpy (out , self -> buffer + self -> pos , current_size );
14611452 remaining -= current_size ;
14621453 written += current_size ;
1454+ self -> pos += current_size ;
1455+ }
1456+ /* Flush the write buffer if necessary */
1457+ if (self -> writable ) {
1458+ PyObject * r = buffered_flush_and_rewind_unlocked (self );
1459+ if (r == NULL )
1460+ goto error ;
1461+ Py_DECREF (r );
14631462 }
14641463 _bufferedreader_reset_buf (self );
14651464 while (remaining > 0 ) {
0 commit comments