Commit 8c76d675 8c76d675333b70a0887de506073d64cd2c14643a by Sergey Poznyakoff

Optimize stream seeks and I/O. Expand stream event handlers. Rewrite xscript stream.

* include/mailutils/sys/stream.h (_MU_STR_EVENT_SET): Rename
to _MU_STR_EVENT_SET.
(_MU_STR_EVENT_CLR): Rename to _MU_STR_EVENT_CLRFLAG.
(_MU_STR_EVENT_FILLBUF, _MU_STR_EVENT_FLUSHBUF): New event codes.
(_MU_STR_EVMASK): New macro.
(_mu_stream) <cur>: Replace with pos, indicating current position
in the buffer.
(event_cb): Change signature.
(mu_stream_read_unbuffered): Remove.
(mu_stream_write_unbuffered): Remove.

* mailbox/iostream.c (mu_iostream_create): Provide the readdelim method
only if the underlying input transpor stream provides it.
* mailbox/streamref.c (mu_streamref_create_abridged): Likewise.

* mailbox/stream.c (_stream_event): New macro.
(mu_stream_read_unbuffered): Rename to static _stream_read_unbuffered.
(mu_stream_write_unbuffered): Rename to static _stream_write_unbuffered.
(_stream_advance_buffer, _stream_buffer_offset)
(_stream_orig_level): Remove macros.
(_stream_buffer_freespace): Rewrite.
(_stream_curp): New macro.
(_stream_fill_buffer): Make sure the `offset' indicates the offset
int the transport, corresponding to the beginning of the current
buffer.
(_stream_flush_buffer): Essentially rewritten.
(mu_stream_seek): Reflect changes to the _mu_stream structure. Optimize
calls to the seek method.
(_stream_skip_input_bytes): Likewise.
(mu_stream_read, _stream_scandelim, mu_stream_write): Rewrite using
new _mu_stream structure.

* mailbox/xscript-stream.c: Rewrite using stream events.

* mailbox/base64.c (_base64_encoder): Bugfix.

* libproto/pop/pop3_stream.c (_pop3_event_cb): Update signature to
match the changes above.
* examples/mimetest.c (main): Add more error checking.
* mail/testsuite/mail/write.exp: Minor fix.
1 parent fd032c6f
......@@ -116,7 +116,7 @@ main (int argc, char **argv)
MU_ASSERT (mu_mailbox_open (mbox, MU_STREAM_RDWR));
/* Iterate through the entire message set. */
mu_mailbox_messages_count (mbox, &count);
MU_ASSERT (mu_mailbox_messages_count (mbox, &count));
for (i = 1; i <= count; ++i)
{
......
......@@ -24,8 +24,12 @@
#define _MU_STR_INTERN_MASK 0xf0000000
#define _MU_STR_EVENT_SET 1
#define _MU_STR_EVENT_CLR 2
#define _MU_STR_EVENT_SETFLAG 0
#define _MU_STR_EVENT_CLRFLAG 1
#define _MU_STR_EVENT_FILLBUF 2
#define _MU_STR_EVENT_FLUSHBUF 3
#define _MU_STR_EVMASK(n) (1<<(n))
struct _mu_stream
{
......@@ -35,7 +39,7 @@ struct _mu_stream
size_t bufsize;
char *buffer;
size_t level;
char *cur;
size_t pos;
int flags;
mu_off_t offset;
......@@ -57,7 +61,7 @@ struct _mu_stream
int (*truncate) (struct _mu_stream *, mu_off_t);
int (*shutdown) (struct _mu_stream *, int);
void (*event_cb) (struct _mu_stream *, int, int);
void (*event_cb) (struct _mu_stream *, int code, unsigned long, void *);
int event_mask;
const char *(*error_string) (struct _mu_stream *, int);
......@@ -65,11 +69,6 @@ struct _mu_stream
};
mu_stream_t _mu_stream_create (size_t size, int flags);
int mu_stream_read_unbuffered (mu_stream_t stream, void *buf, size_t size,
int full_read, size_t *pnread);
int mu_stream_write_unbuffered (mu_stream_t stream,
const void *buf, size_t size,
int full_write, size_t *pnwritten);
void _mu_stream_cleareof (mu_stream_t str);
void _mu_stream_seteof (mu_stream_t str);
......
......@@ -41,10 +41,12 @@ struct mu_pop3_stream
struct mu_buffer_query oldbuf;
};
/* Called on _MU_STR_EVENT_SETFLAG */
static void
_pop3_event_cb (mu_stream_t str, int ev, int flags)
_pop3_event_cb (mu_stream_t str, int ev, unsigned long flags,
void *ptr MU_ARG_UNUSED)
{
if (ev == _MU_STR_EVENT_SET)
if (flags & _MU_STR_EOF)
{
mu_transport_t trans[2];
......@@ -78,7 +80,7 @@ mu_pop3_filter_create (mu_stream_t *pstream, mu_stream_t stream)
mu_stream_t str = *pstream;
str->event_cb = _pop3_event_cb;
str->event_mask = _MU_STR_EOF;
str->event_mask = _MU_STR_EVMASK(_MU_STR_EVENT_SETFLAG);
sp->oldbuf.type = MU_TRANSPORT_OUTPUT;
if (mu_stream_ioctl (sp->pop3->carrier, MU_IOCTL_GET_TRANSPORT_BUFFER,
......
......@@ -27,7 +27,7 @@ mail_test -noprompt "quit" \
# Start again using the same mailbox
mail_start -reuse-spool "--file=%mbox1"
# Go to the last message and do delete 4 times
mail_command "4"
mail_command "3"
mail_command "delete"
mail_command "delete"
mail_command "delete"
......
......@@ -244,6 +244,9 @@ _base64_encoder (void *xd MU_ARG_UNUSED,
pad = 0;
}
/* Consumed may grow bigger than isize if cmd is mu_filter_lastbuf */
if (consumed > iobuf->isize)
consumed = iobuf->isize;
iobuf->isize = consumed;
iobuf->osize = nbytes;
return mu_filter_ok;
......
......@@ -236,7 +236,8 @@ mu_iostream_create (mu_stream_t *pref, mu_stream_t in, mu_stream_t out)
return ENOMEM;
sp->stream.read = _iostream_read;
sp->stream.readdelim = _iostream_readdelim;
if (in->readdelim)
sp->stream.readdelim = _iostream_readdelim;
sp->stream.write = _iostream_write;
sp->stream.flush = _iostream_flush;
sp->stream.open = _iostream_open;
......
......@@ -279,7 +279,8 @@ mu_streamref_create_abridged (mu_stream_t *pref, mu_stream_t str,
mu_stream_ref (str);
sp->stream.read = _streamref_read;
sp->stream.readdelim = _streamref_readdelim;
if (str->readdelim)
sp->stream.readdelim = _streamref_readdelim;
sp->stream.write = _streamref_write;
sp->stream.flush = _streamref_flush;
sp->stream.open = _streamref_open;
......
......@@ -167,21 +167,28 @@ print_transcript (struct _mu_xscript_stream *str, int flag,
}
}
static int
_xscript_read (struct _mu_stream *str, char *buf, size_t bufsize,
size_t *pnread)
static void
_xscript_event_cb (mu_stream_t str, int ev, unsigned long size, void *ptr)
{
struct _mu_xscript_stream *sp = (struct _mu_xscript_stream *)str;
size_t nbytes;
int rc = mu_stream_read (sp->transport, buf, bufsize, &nbytes);
if (rc == 0)
switch (ev)
{
print_transcript (sp, TRANS_READ, buf, nbytes);
if (pnread)
*pnread = nbytes;
case _MU_STR_EVENT_FILLBUF:
print_transcript (sp, TRANS_READ, ptr, size);
break;
case _MU_STR_EVENT_FLUSHBUF:
print_transcript (sp, TRANS_WRITE, ptr, size);
}
return rc;
}
static int
_xscript_read (struct _mu_stream *str, char *buf, size_t bufsize,
size_t *pnread)
{
struct _mu_xscript_stream *sp = (struct _mu_xscript_stream *)str;
return mu_stream_read (sp->transport, buf, bufsize, pnread);
}
static int
......@@ -189,15 +196,7 @@ _xscript_readdelim (struct _mu_stream *str, char *buf, size_t bufsize,
int delim, size_t *pnread)
{
struct _mu_xscript_stream *sp = (struct _mu_xscript_stream *)str;
size_t nread;
int rc = mu_stream_readdelim (sp->transport, buf, bufsize, delim, &nread);
if (rc == 0)
{
print_transcript (sp, TRANS_READ, buf, nread);
if (pnread)
*pnread = nread;
}
return rc;
return mu_stream_readdelim (sp->transport, buf, bufsize, delim, pnread);
}
static int
......@@ -205,11 +204,7 @@ _xscript_write (struct _mu_stream *str, const char *buf, size_t bufsize,
size_t *pnwrite)
{
struct _mu_xscript_stream *sp = (struct _mu_xscript_stream *)str;
int rc = mu_stream_write (sp->transport, buf, bufsize, pnwrite);
if (rc == 0)
print_transcript (sp, TRANS_WRITE, buf, pnwrite ? *pnwrite : bufsize);
return rc;
return mu_stream_write (sp->transport, buf, bufsize, pnwrite);
}
static int
......@@ -318,7 +313,6 @@ _xscript_ctl (struct _mu_stream *str, int op, void *arg)
case MU_IOCTL_GET_TRANSPORT_BUFFER:
case MU_IOCTL_SET_TRANSPORT_BUFFER:
{
struct mu_transport_buffer_query *qp = arg;
if (!sp->transport)
return EINVAL;
return mu_stream_ioctl (sp->transport, op, arg);
......@@ -391,7 +385,8 @@ mu_xscript_stream_create(mu_stream_t *pref, mu_stream_t transport,
return ENOMEM;
sp->stream.read = _xscript_read;
sp->stream.readdelim = _xscript_readdelim;
if (transport->readdelim)
sp->stream.readdelim = _xscript_readdelim;
sp->stream.write = _xscript_write;
sp->stream.flush = _xscript_flush;
sp->stream.open = _xscript_open;
......@@ -404,7 +399,9 @@ mu_xscript_stream_create(mu_stream_t *pref, mu_stream_t transport,
sp->stream.truncate = _xscript_truncate;
sp->stream.shutdown = _xscript_shutdown;
sp->stream.error_string = _xscript_error_string;
sp->stream.event_cb = _xscript_event_cb;
sp->stream.event_mask = _MU_STR_EVMASK(_MU_STR_EVENT_FILLBUF) |
_MU_STR_EVMASK(_MU_STR_EVENT_FLUSHBUF);
if (!(flags & MU_STREAM_AUTOCLOSE))
{
mu_stream_ref (transport);
......