Commit 352c5e92 352c5e92e6d26701fccced669c40409d6010ff10 by Sergey Poznyakoff

Bugfixes in stream-related code.

* mailbox/fltstream.c (filter_read): Do not try to get more input until
the output buffer is drained.
* mailbox/mapfile_stream.c (_mapfile_seek): Fix conditional.
* mailbox/stream.c (_stream_fill_buffer): Fix increment.
(mu_stream_skip_input_bytes): Bugfixes.
1 parent 2203753f
......@@ -117,73 +117,78 @@ filter_read (mu_stream_t stream, char *buf, size_t size, size_t *pret)
while (total < size && cmd != mu_filter_lastbuf)
{
enum mu_filter_result res;
int rc;
size_t rdsize;
if (MFB_RDBYTES (fs->inbuf) < min_input_level)
if (MFB_RDBYTES (fs->outbuf) == 0)
{
rc = MFB_require (&fs->inbuf, min_input_level);
if (rc)
return rc;
rc = mu_stream_read (fs->transport,
MFB_ENDPTR (fs->inbuf),
MFB_FREESIZE (fs->inbuf),
&rdsize);
enum mu_filter_result res;
int rc;
if (MFB_RDBYTES (fs->inbuf) < min_input_level)
{
rc = MFB_require (&fs->inbuf, min_input_level);
if (rc)
return rc;
rc = mu_stream_read (fs->transport,
MFB_ENDPTR (fs->inbuf),
MFB_FREESIZE (fs->inbuf),
&rdsize);
if (rc)
return rc;
if (rdsize == 0 &&
MFB_RDBYTES (fs->outbuf) == 0
&& MFB_RDBYTES (fs->inbuf) == 0)
break;
MFB_advance_level (&fs->inbuf, rdsize);
}
if (min_output_size < MFB_RDBYTES (fs->inbuf))
min_output_size = MFB_RDBYTES (fs->inbuf);
rc = MFB_require (&fs->outbuf, min_output_size);
if (rc)
return rc;
if (rdsize == 0 &&
MFB_RDBYTES (fs->outbuf) == 0 && MFB_RDBYTES (fs->inbuf) == 0)
break;
MFB_advance_level (&fs->inbuf, rdsize);
}
if (min_output_size < MFB_RDBYTES (fs->inbuf))
min_output_size = MFB_RDBYTES (fs->inbuf);
rc = MFB_require (&fs->outbuf, min_output_size);
if (rc)
return rc;
init_iobuf (&iobuf, fs);
init_iobuf (&iobuf, fs);
cmd = mu_stream_eof (fs->transport) ?
mu_filter_lastbuf : mu_filter_xcode;
res = fs->xcode (fs->xdata, cmd, &iobuf);
switch (res)
{
case mu_filter_ok:
if (iobuf.isize == 0 || iobuf.osize == 0)
cmd = mu_stream_eof (fs->transport) ?
mu_filter_lastbuf : mu_filter_xcode;
res = fs->xcode (fs->xdata, cmd, &iobuf);
switch (res)
{
/* FIXME: Hack to handle eventual buggy filters */
if (iobuf.isize == 0)
min_input_level++;
if (iobuf.osize == 0)
min_output_size++;
case mu_filter_ok:
if (iobuf.isize == 0 || iobuf.osize == 0)
{
/* FIXME: Hack to handle eventual buggy filters */
if (iobuf.isize == 0)
min_input_level++;
if (iobuf.osize == 0)
min_output_size++;
continue;
}
if (iobuf.isize > MFB_RDBYTES (fs->inbuf)
|| iobuf.osize > MFB_FREESIZE (fs->outbuf))
return MU_ERR_FAILURE; /* FIXME: special error code? */
break;
case mu_filter_falure:
return iobuf.errcode;
case mu_filter_moreinput:
min_input_level = iobuf.isize;
continue;
case mu_filter_moreoutput:
min_output_size = iobuf.osize;
continue;
}
if (iobuf.isize > MFB_RDBYTES (fs->inbuf)
|| iobuf.osize > MFB_FREESIZE (fs->outbuf))
return MU_ERR_FAILURE; /* FIXME: special error code? */
break;
case mu_filter_falure:
return iobuf.errcode;
case mu_filter_moreinput:
min_input_level = iobuf.isize;
continue;
/* iobuf.osize contains number of bytes written to output */
MFB_advance_level (&fs->outbuf, iobuf.osize);
case mu_filter_moreoutput:
min_output_size = iobuf.osize;
continue;
/* iobuf.isize contains number of bytes read from input */
MFB_advance_pos (&fs->inbuf, iobuf.isize);
}
/* iobuf.osize contains number of bytes written to output */
MFB_advance_level (&fs->outbuf, iobuf.osize);
/* iobuf.isize contains number of bytes read from input */
MFB_advance_pos (&fs->inbuf, iobuf.isize);
rdsize = size - total;
if (rdsize > MFB_RDBYTES (fs->outbuf))
rdsize = MFB_RDBYTES (fs->outbuf);
......
......@@ -316,7 +316,7 @@ _mapfile_seek (struct _mu_stream *str, mu_off_t off, mu_off_t *presult)
{
struct _mu_mapfile_stream *mfs = (struct _mu_mapfile_stream *) str;
if (off < 0 || off >= mfs->size)
if (off < 0 || off > mfs->size)
return ESPIPE;
mfs->offset = off;
*presult = off;
......
......@@ -80,9 +80,9 @@ _stream_fill_buffer (struct _mu_stream *stream)
n < stream->bufsize
&& (rc = mu_stream_read_unbuffered (stream,
&c, 1, 0, &rdn)) == 0
&& rdn; n++)
&& rdn; )
{
stream->buffer[n] = c;
stream->buffer[n++] = c;
if (c == '\n')
break;
}
......@@ -368,10 +368,10 @@ mu_stream_skip_input_bytes (mu_stream_t stream, mu_off_t count, mu_off_t *pres)
}
else
{
if ((rc = _stream_flush_buffer (stream, 1)))
return rc;
for (pos = 0;;)
{
if ((rc = _stream_flush_buffer (stream, 1)))
return rc;
if (stream->level == 0)
{
rc = _stream_fill_buffer (stream);
......@@ -385,11 +385,13 @@ mu_stream_skip_input_bytes (mu_stream_t stream, mu_off_t count, mu_off_t *pres)
}
if (pos <= count && count < pos + stream->level)
{
rc = 0;
stream->cur = stream->buffer + count - pos;
size_t delta = count - pos;
_stream_advance_buffer (stream, delta);
pos = count;
rc = 0;
break;
}
pos += stream->level;
}
}
......