Commit f055372d f055372d64373ee24823e5789e23f902f48011b0 by Sergey Poznyakoff

filter stream: make sure all input data get processed.

* include/mailutils/filter.h (MU_FILTER_MAX_AGAIN): Add a comment.
* libmailutils/stream/fltstream.c (filter_read): Use
mu_debug on the filter.error level, instead of plain mu_error.
If the xcoder returns OK and does not consume all input when
processing the last buffer, assume mu_filter_again.
Fix loop condition.
(filter_write_internal): Use
mu_debug on the filter.error level, instead of plain mu_error.
1 parent c522de11
......@@ -62,6 +62,8 @@ enum mu_filter_result
mu_filter_again
};
/* An xcode function is not allowed to return mu_filter_again more
than MU_FILTER_MAX_AGAIN times in a sequence. */
#define MU_FILTER_MAX_AGAIN 5
typedef int (*mu_filter_new_data_t) (void **, int, int argc,
......
......@@ -172,18 +172,13 @@ filter_read (mu_stream_t stream, char *buf, size_t size, size_t *pret)
if (++again > MU_FILTER_MAX_AGAIN)
{
/* FIXME: What filter? Need some id. */
mu_error (_("filter returned `again' too many times"));
mu_debug (MU_DEBCAT_FILTER, MU_DEBUG_ERROR,
(_("filter returned `again' too many times")));
again = 0;
}
break;
case mu_filter_ok:
again = 0;
if (cmd == mu_filter_lastbuf || iobuf.eof)
{
fs->fltflag |= _MU_FILTER_EOF;
stop = 1;
}
break;
case mu_filter_failure:
......@@ -207,6 +202,37 @@ filter_read (mu_stream_t stream, char *buf, size_t size, size_t *pret)
/* iobuf.isize contains number of bytes read from input */
MFB_advance_pos (&fs->inbuf, iobuf.isize);
if (res == mu_filter_ok)
{
if (iobuf.eof)
{
fs->fltflag |= _MU_FILTER_EOF;
stop = 1;
}
else if (cmd == mu_filter_lastbuf)
{
if (MFB_RDBYTES (fs->inbuf))
{
/* If xcoder has not consumed all input, try again */
if (++again > MU_FILTER_MAX_AGAIN)
{
/* FIXME: What filter? Need some id. */
mu_debug (MU_DEBCAT_FILTER, MU_DEBUG_ERROR,
(_("filter returned `again' too many times")));
stop = 1;
}
}
else
{
fs->fltflag |= _MU_FILTER_EOF;
stop = 1;
}
}
else
again = 0;
}
}
rdsize = size - total;
......@@ -217,7 +243,7 @@ filter_read (mu_stream_t stream, char *buf, size_t size, size_t *pret)
total += rdsize;
}
while (!stop && (total < size || again));
while (!stop && total < size);
*pret = total;
return 0;
......@@ -278,7 +304,8 @@ filter_write_internal (mu_stream_t stream, enum mu_filter_command cmd,
if (++again > MU_FILTER_MAX_AGAIN)
{
/* FIXME: What filter? Need some id. */
mu_error (_("filter returned `again' too many times"));
mu_debug (MU_DEBCAT_FILTER, MU_DEBUG_ERROR,
(_("filter returned `again' too many times")));
again = 0;
}
break;
......