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
46 additions
and
17 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 | } |
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; | ... | ... |
-
Please register or sign in to post a comment