Commit 96cfdb5e 96cfdb5e8ef877b1f8773e426061ef4d3442997e by Sergey Poznyakoff

Make sure stream->offset points to the position in stream corresponding to the start of the buffer.

* libmailutils/stream/stream.c (_stream_fill_buffer): Keep
track of the current offset.
(mu_stream_seek): avoid unnecessary seeks.
(_stream_skip_input_bytes): Call _stream_flush_buffer before
_stream_fill_buffer.
(_stream_write_unbuffered): Do not modify current offset.
(mu_stream_read,mu_stream_write): For unbuffered streams,
modify current offset after invoking the corresponding I/O
call.
(_stream_scandelim): Call _stream_flush_buffer before
_stream_fill_buffer.
1 parent 78e57f7e
...@@ -110,7 +110,6 @@ _stream_fill_buffer (struct _mu_stream *stream) ...@@ -110,7 +110,6 @@ _stream_fill_buffer (struct _mu_stream *stream)
110 int rc = 0; 110 int rc = 0;
111 char c; 111 char c;
112 112
113 stream->offset += stream->level;
114 switch (stream->buftype) 113 switch (stream->buftype)
115 { 114 {
116 case mu_buffer_none: 115 case mu_buffer_none:
...@@ -127,7 +126,8 @@ _stream_fill_buffer (struct _mu_stream *stream) ...@@ -127,7 +126,8 @@ _stream_fill_buffer (struct _mu_stream *stream)
127 for (n = 0; 126 for (n = 0;
128 n < stream->bufsize 127 n < stream->bufsize
129 && (rc = _stream_read_unbuffered (stream, 128 && (rc = _stream_read_unbuffered (stream,
130 &c, 1, 0, &rdn)) == 0;) 129 &c, 1,
130 0, &rdn)) == 0;)
131 { 131 {
132 if (rdn == 0) 132 if (rdn == 0)
133 { 133 {
...@@ -143,7 +143,6 @@ _stream_fill_buffer (struct _mu_stream *stream) ...@@ -143,7 +143,6 @@ _stream_fill_buffer (struct _mu_stream *stream)
143 } 143 }
144 if (rc == 0) 144 if (rc == 0)
145 { 145 {
146 stream->offset -= stream->level;
147 stream->pos = 0; 146 stream->pos = 0;
148 _stream_event (stream, _MU_STR_EVENT_FILLBUF, 147 _stream_event (stream, _MU_STR_EVENT_FILLBUF,
149 stream->level, _stream_curp (stream)); 148 stream->level, _stream_curp (stream));
...@@ -193,7 +192,8 @@ _stream_flush_buffer (struct _mu_stream *stream, int flags) ...@@ -193,7 +192,8 @@ _stream_flush_buffer (struct _mu_stream *stream, int flags)
193 192
194 case mu_buffer_full: 193 case mu_buffer_full:
195 if ((rc = _stream_write_unbuffered (stream, stream->buffer, 194 if ((rc = _stream_write_unbuffered (stream, stream->buffer,
196 stream->level, 1, NULL))) 195 stream->level,
196 1, NULL)))
197 return rc; 197 return rc;
198 _stream_event (stream, _MU_STR_EVENT_FLUSHBUF, 198 _stream_event (stream, _MU_STR_EVENT_FLUSHBUF,
199 stream->level, stream->buffer); 199 stream->level, stream->buffer);
...@@ -208,7 +208,8 @@ _stream_flush_buffer (struct _mu_stream *stream, int flags) ...@@ -208,7 +208,8 @@ _stream_flush_buffer (struct _mu_stream *stream, int flags)
208 end = memchr (start, '\n', wrsize)) 208 end = memchr (start, '\n', wrsize))
209 { 209 {
210 size_t size = end - start + 1; 210 size_t size = end - start + 1;
211 rc = _stream_write_unbuffered (stream, start, size, 1, NULL); 211 rc = _stream_write_unbuffered (stream, start, size,
212 1, NULL);
212 if (rc) 213 if (rc)
213 return rc; 214 return rc;
214 _stream_event (stream, _MU_STR_EVENT_FLUSHBUF, 215 _stream_event (stream, _MU_STR_EVENT_FLUSHBUF,
...@@ -231,18 +232,26 @@ _stream_flush_buffer (struct _mu_stream *stream, int flags) ...@@ -231,18 +232,26 @@ _stream_flush_buffer (struct _mu_stream *stream, int flags)
231 wrsize, stream->buffer); 232 wrsize, stream->buffer);
232 wrsize = 0; 233 wrsize = 0;
233 } 234 }
235 if (!(flags & _MU_STR_FLUSH_KEEP))
236 {
234 if (wrsize) 237 if (wrsize)
235 memmove (stream->buffer, start, wrsize); 238 memmove (stream->buffer, start, wrsize);
236 else 239 else
237 _stream_clrflag (stream, _MU_STR_DIRTY); 240 _stream_clrflag (stream, _MU_STR_DIRTY);
241 stream->offset += stream->level - wrsize;
238 stream->level = stream->pos = wrsize; 242 stream->level = stream->pos = wrsize;
239 return 0; 243 return 0;
240 } 244 }
245 }
241 _stream_clrflag (stream, _MU_STR_DIRTY); 246 _stream_clrflag (stream, _MU_STR_DIRTY);
242 } 247 }
243 248
244 if (!(flags & _MU_STR_FLUSH_KEEP)) 249 if (!(flags & _MU_STR_FLUSH_KEEP))
250 {
251 stream->offset += stream->level;
245 stream->pos = stream->level = 0; 252 stream->pos = stream->level = 0;
253 }
254
246 return 0; 255 return 0;
247 } 256 }
248 257
...@@ -413,19 +422,21 @@ mu_stream_seek (mu_stream_t stream, mu_off_t offset, int whence, ...@@ -413,19 +422,21 @@ mu_stream_seek (mu_stream_t stream, mu_off_t offset, int whence,
413 return mu_stream_seterr (stream, EINVAL, 1); 422 return mu_stream_seterr (stream, EINVAL, 1);
414 } 423 }
415 424
416 if (stream->buftype == mu_buffer_none ? 425 if (!(stream->buftype == mu_buffer_none ?
417 (offset != stream->offset) 426 (offset == stream->offset)
418 : (stream->level == 0 427 : (stream->offset <= offset &&
419 || offset < stream->offset 428 offset < stream->offset + stream->level)))
420 || offset > stream->offset + stream->level))
421 { 429 {
422 if ((rc = _stream_flush_buffer (stream, _MU_STR_FLUSH_ALL))) 430 if ((rc = _stream_flush_buffer (stream, _MU_STR_FLUSH_ALL)))
423 return rc; 431 return rc;
432 if (stream->offset != offset)
433 {
424 rc = stream->seek (stream, offset, &stream->offset); 434 rc = stream->seek (stream, offset, &stream->offset);
425 if (rc == ESPIPE) 435 if (rc == ESPIPE)
426 return rc; 436 return rc;
427 if (rc) 437 if (rc)
428 return mu_stream_seterr (stream, rc, 1); 438 return mu_stream_seterr (stream, rc, 1);
439 }
429 _mu_stream_cleareof (stream); 440 _mu_stream_cleareof (stream);
430 } 441 }
431 else if (stream->buftype != mu_buffer_none) 442 else if (stream->buftype != mu_buffer_none)
...@@ -476,10 +487,10 @@ _stream_skip_input_bytes (mu_stream_t stream, mu_off_t count, mu_off_t *pres) ...@@ -476,10 +487,10 @@ _stream_skip_input_bytes (mu_stream_t stream, mu_off_t count, mu_off_t *pres)
476 { 487 {
477 for (pos = 0;;) 488 for (pos = 0;;)
478 { 489 {
479 if ((rc = _stream_flush_buffer (stream, _MU_STR_FLUSH_ALL)))
480 return rc;
481 if (stream->pos == stream->level) 490 if (stream->pos == stream->level)
482 { 491 {
492 if ((rc = _stream_flush_buffer (stream, _MU_STR_FLUSH_ALL)))
493 return rc;
483 rc = _stream_fill_buffer (stream); 494 rc = _stream_fill_buffer (stream);
484 if (rc) 495 if (rc)
485 break; 496 break;
...@@ -602,7 +613,6 @@ _stream_read_unbuffered (mu_stream_t stream, void *buf, size_t size, ...@@ -602,7 +613,6 @@ _stream_read_unbuffered (mu_stream_t stream, void *buf, size_t size,
602 nread += rdbytes; 613 nread += rdbytes;
603 size -= rdbytes; 614 size -= rdbytes;
604 stream->bytes_in += rdbytes; 615 stream->bytes_in += rdbytes;
605
606 } 616 }
607 if (size && rc) 617 if (size && rc)
608 rc = mu_stream_seterr (stream, rc, 0); 618 rc = mu_stream_seterr (stream, rc, 0);
...@@ -618,7 +628,6 @@ _stream_read_unbuffered (mu_stream_t stream, void *buf, size_t size, ...@@ -618,7 +628,6 @@ _stream_read_unbuffered (mu_stream_t stream, void *buf, size_t size,
618 } 628 }
619 mu_stream_seterr (stream, rc, rc != 0); 629 mu_stream_seterr (stream, rc, rc != 0);
620 } 630 }
621 stream->offset += nread;
622 if (pnread) 631 if (pnread)
623 *pnread = nread; 632 *pnread = nread;
624 633
...@@ -677,7 +686,6 @@ _stream_write_unbuffered (mu_stream_t stream, ...@@ -677,7 +686,6 @@ _stream_write_unbuffered (mu_stream_t stream,
677 stream->bytes_out += nwritten; 686 stream->bytes_out += nwritten;
678 } 687 }
679 _stream_setflag (stream, _MU_STR_WRT); 688 _stream_setflag (stream, _MU_STR_WRT);
680 stream->offset += nwritten;
681 if (pnwritten) 689 if (pnwritten)
682 *pnwritten = nwritten; 690 *pnwritten = nwritten;
683 mu_stream_seterr (stream, rc, rc != 0); 691 mu_stream_seterr (stream, rc, rc != 0);
...@@ -695,7 +703,14 @@ mu_stream_read (mu_stream_t stream, void *buf, size_t size, size_t *pread) ...@@ -695,7 +703,14 @@ mu_stream_read (mu_stream_t stream, void *buf, size_t size, size_t *pread)
695 } 703 }
696 704
697 if (stream->buftype == mu_buffer_none) 705 if (stream->buftype == mu_buffer_none)
698 return _stream_read_unbuffered (stream, buf, size, !pread, pread); 706 {
707 size_t nread = 0;
708 int rc = _stream_read_unbuffered (stream, buf, size, !pread, &nread);
709 stream->offset += nread;
710 if (pread)
711 *pread = nread;
712 return rc;
713 }
699 else 714 else
700 { 715 {
701 char *bufp = buf; 716 char *bufp = buf;
...@@ -712,6 +727,12 @@ mu_stream_read (mu_stream_t stream, void *buf, size_t size, size_t *pread) ...@@ -712,6 +727,12 @@ mu_stream_read (mu_stream_t stream, void *buf, size_t size, size_t *pread)
712 727
713 if (stream->pos == stream->level) 728 if (stream->pos == stream->level)
714 { 729 {
730 if ((rc = _stream_flush_buffer (stream, _MU_STR_FLUSH_ALL)))
731 {
732 if (nbytes)
733 break;
734 return rc;
735 }
715 if ((rc = _stream_fill_buffer (stream))) 736 if ((rc = _stream_fill_buffer (stream)))
716 { 737 {
717 if (nbytes) 738 if (nbytes)
...@@ -757,6 +778,8 @@ _stream_scandelim (mu_stream_t stream, char *buf, size_t size, int delim, ...@@ -757,6 +778,8 @@ _stream_scandelim (mu_stream_t stream, char *buf, size_t size, int delim,
757 778
758 if (stream->pos == stream->level) 779 if (stream->pos == stream->level)
759 { 780 {
781 if ((rc = _stream_flush_buffer (stream, _MU_STR_FLUSH_ALL)))
782 break;
760 if ((rc = _stream_fill_buffer (stream)) || stream->level == 0) 783 if ((rc = _stream_fill_buffer (stream)) || stream->level == 0)
761 break; 784 break;
762 } 785 }
...@@ -959,8 +982,14 @@ mu_stream_write (mu_stream_t stream, const void *buf, size_t size, ...@@ -959,8 +982,14 @@ mu_stream_write (mu_stream_t stream, const void *buf, size_t size,
959 } 982 }
960 983
961 if (stream->buftype == mu_buffer_none) 984 if (stream->buftype == mu_buffer_none)
985 {
986 size_t nwritten;
962 rc = _stream_write_unbuffered (stream, buf, size, 987 rc = _stream_write_unbuffered (stream, buf, size,
963 !pnwritten, pnwritten); 988 !pnwritten, &nwritten);
989 stream->offset += nwritten;
990 if (pnwritten)
991 *pnwritten = nwritten;
992 }
964 else 993 else
965 { 994 {
966 size_t nbytes = 0; 995 size_t nbytes = 0;
......