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.
Showing
1 changed file
with
95 additions
and
66 deletions
... | @@ -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 | } |
234 | if (wrsize) | 235 | if (!(flags & _MU_STR_FLUSH_KEEP)) |
235 | memmove (stream->buffer, start, wrsize); | 236 | { |
236 | else | 237 | if (wrsize) |
237 | _stream_clrflag (stream, _MU_STR_DIRTY); | 238 | memmove (stream->buffer, start, wrsize); |
238 | stream->level = stream->pos = wrsize; | 239 | else |
239 | return 0; | 240 | _stream_clrflag (stream, _MU_STR_DIRTY); |
241 | stream->offset += stream->level - wrsize; | ||
242 | stream->level = stream->pos = wrsize; | ||
243 | return 0; | ||
244 | } | ||
240 | } | 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)) |
245 | stream->pos = stream->level = 0; | 250 | { |
251 | stream->offset += stream->level; | ||
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; |
424 | rc = stream->seek (stream, offset, &stream->offset); | 432 | if (stream->offset != offset) |
425 | if (rc == ESPIPE) | 433 | { |
426 | return rc; | 434 | rc = stream->seek (stream, offset, &stream->offset); |
427 | if (rc) | 435 | if (rc == ESPIPE) |
428 | return mu_stream_seterr (stream, rc, 1); | 436 | return rc; |
437 | if (rc) | ||
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; |
... | @@ -585,44 +596,42 @@ _stream_read_unbuffered (mu_stream_t stream, void *buf, size_t size, | ... | @@ -585,44 +596,42 @@ _stream_read_unbuffered (mu_stream_t stream, void *buf, size_t size, |
585 | return 0; | 596 | return 0; |
586 | } | 597 | } |
587 | 598 | ||
588 | if (full_read) | 599 | if (full_read) |
589 | { | 600 | { |
590 | size_t rdbytes; | 601 | size_t rdbytes; |
591 | 602 | ||
592 | nread = 0; | 603 | nread = 0; |
593 | while (size > 0 | 604 | while (size > 0 |
594 | && (rc = stream->read (stream, buf, size, &rdbytes)) == 0) | 605 | && (rc = stream->read (stream, buf, size, &rdbytes)) == 0) |
595 | { | 606 | { |
596 | if (rdbytes == 0) | 607 | if (rdbytes == 0) |
597 | { | 608 | { |
598 | _stream_setflag (stream, _MU_STR_EOF); | ||
599 | break; | ||
600 | } | ||
601 | buf += rdbytes; | ||
602 | nread += rdbytes; | ||
603 | size -= rdbytes; | ||
604 | stream->bytes_in += rdbytes; | ||
605 | |||
606 | } | ||
607 | if (size && rc) | ||
608 | rc = mu_stream_seterr (stream, rc, 0); | ||
609 | } | ||
610 | else | ||
611 | { | ||
612 | rc = stream->read (stream, buf, size, &nread); | ||
613 | if (rc == 0) | ||
614 | { | ||
615 | if (nread == 0) | ||
616 | _stream_setflag (stream, _MU_STR_EOF); | 609 | _stream_setflag (stream, _MU_STR_EOF); |
617 | stream->bytes_in += nread; | 610 | break; |
618 | } | 611 | } |
619 | mu_stream_seterr (stream, rc, rc != 0); | 612 | buf += rdbytes; |
620 | } | 613 | nread += rdbytes; |
621 | stream->offset += nread; | 614 | size -= rdbytes; |
622 | if (pnread) | 615 | stream->bytes_in += rdbytes; |
623 | *pnread = nread; | 616 | } |
624 | 617 | if (size && rc) | |
625 | return rc; | 618 | rc = mu_stream_seterr (stream, rc, 0); |
619 | } | ||
620 | else | ||
621 | { | ||
622 | rc = stream->read (stream, buf, size, &nread); | ||
623 | if (rc == 0) | ||
624 | { | ||
625 | if (nread == 0) | ||
626 | _stream_setflag (stream, _MU_STR_EOF); | ||
627 | stream->bytes_in += nread; | ||
628 | } | ||
629 | mu_stream_seterr (stream, rc, rc != 0); | ||
630 | } | ||
631 | if (pnread) | ||
632 | *pnread = nread; | ||
633 | |||
634 | return rc; | ||
626 | } | 635 | } |
627 | 636 | ||
628 | static int | 637 | static int |
... | @@ -657,7 +666,7 @@ _stream_write_unbuffered (mu_stream_t stream, | ... | @@ -657,7 +666,7 @@ _stream_write_unbuffered (mu_stream_t stream, |
657 | nwritten = 0; | 666 | nwritten = 0; |
658 | while (size > 0 | 667 | while (size > 0 |
659 | && (rc = stream->write (stream, bufp, size, &wrbytes)) | 668 | && (rc = stream->write (stream, bufp, size, &wrbytes)) |
660 | == 0) | 669 | == 0) |
661 | { | 670 | { |
662 | if (wrbytes == 0) | 671 | if (wrbytes == 0) |
663 | { | 672 | { |
... | @@ -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) |
962 | rc = _stream_write_unbuffered (stream, buf, size, | 985 | { |
963 | !pnwritten, pnwritten); | 986 | size_t nwritten; |
987 | rc = _stream_write_unbuffered (stream, buf, size, | ||
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; | ... | ... |
-
Please register or sign in to post a comment