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) ...@@ -116,7 +116,7 @@ main (int argc, char **argv)
116 MU_ASSERT (mu_mailbox_open (mbox, MU_STREAM_RDWR)); 116 MU_ASSERT (mu_mailbox_open (mbox, MU_STREAM_RDWR));
117 117
118 /* Iterate through the entire message set. */ 118 /* Iterate through the entire message set. */
119 mu_mailbox_messages_count (mbox, &count); 119 MU_ASSERT (mu_mailbox_messages_count (mbox, &count));
120 120
121 for (i = 1; i <= count; ++i) 121 for (i = 1; i <= count; ++i)
122 { 122 {
......
...@@ -24,8 +24,12 @@ ...@@ -24,8 +24,12 @@
24 24
25 #define _MU_STR_INTERN_MASK 0xf0000000 25 #define _MU_STR_INTERN_MASK 0xf0000000
26 26
27 #define _MU_STR_EVENT_SET 1 27 #define _MU_STR_EVENT_SETFLAG 0
28 #define _MU_STR_EVENT_CLR 2 28 #define _MU_STR_EVENT_CLRFLAG 1
29 #define _MU_STR_EVENT_FILLBUF 2
30 #define _MU_STR_EVENT_FLUSHBUF 3
31
32 #define _MU_STR_EVMASK(n) (1<<(n))
29 33
30 struct _mu_stream 34 struct _mu_stream
31 { 35 {
...@@ -35,7 +39,7 @@ struct _mu_stream ...@@ -35,7 +39,7 @@ struct _mu_stream
35 size_t bufsize; 39 size_t bufsize;
36 char *buffer; 40 char *buffer;
37 size_t level; 41 size_t level;
38 char *cur; 42 size_t pos;
39 43
40 int flags; 44 int flags;
41 mu_off_t offset; 45 mu_off_t offset;
...@@ -57,7 +61,7 @@ struct _mu_stream ...@@ -57,7 +61,7 @@ struct _mu_stream
57 int (*truncate) (struct _mu_stream *, mu_off_t); 61 int (*truncate) (struct _mu_stream *, mu_off_t);
58 int (*shutdown) (struct _mu_stream *, int); 62 int (*shutdown) (struct _mu_stream *, int);
59 63
60 void (*event_cb) (struct _mu_stream *, int, int); 64 void (*event_cb) (struct _mu_stream *, int code, unsigned long, void *);
61 int event_mask; 65 int event_mask;
62 66
63 const char *(*error_string) (struct _mu_stream *, int); 67 const char *(*error_string) (struct _mu_stream *, int);
...@@ -65,11 +69,6 @@ struct _mu_stream ...@@ -65,11 +69,6 @@ struct _mu_stream
65 }; 69 };
66 70
67 mu_stream_t _mu_stream_create (size_t size, int flags); 71 mu_stream_t _mu_stream_create (size_t size, int flags);
68 int mu_stream_read_unbuffered (mu_stream_t stream, void *buf, size_t size,
69 int full_read, size_t *pnread);
70 int mu_stream_write_unbuffered (mu_stream_t stream,
71 const void *buf, size_t size,
72 int full_write, size_t *pnwritten);
73 72
74 void _mu_stream_cleareof (mu_stream_t str); 73 void _mu_stream_cleareof (mu_stream_t str);
75 void _mu_stream_seteof (mu_stream_t str); 74 void _mu_stream_seteof (mu_stream_t str);
......
...@@ -41,10 +41,12 @@ struct mu_pop3_stream ...@@ -41,10 +41,12 @@ struct mu_pop3_stream
41 struct mu_buffer_query oldbuf; 41 struct mu_buffer_query oldbuf;
42 }; 42 };
43 43
44 /* Called on _MU_STR_EVENT_SETFLAG */
44 static void 45 static void
45 _pop3_event_cb (mu_stream_t str, int ev, int flags) 46 _pop3_event_cb (mu_stream_t str, int ev, unsigned long flags,
47 void *ptr MU_ARG_UNUSED)
46 { 48 {
47 if (ev == _MU_STR_EVENT_SET) 49 if (flags & _MU_STR_EOF)
48 { 50 {
49 mu_transport_t trans[2]; 51 mu_transport_t trans[2];
50 52
...@@ -78,7 +80,7 @@ mu_pop3_filter_create (mu_stream_t *pstream, mu_stream_t stream) ...@@ -78,7 +80,7 @@ mu_pop3_filter_create (mu_stream_t *pstream, mu_stream_t stream)
78 mu_stream_t str = *pstream; 80 mu_stream_t str = *pstream;
79 81
80 str->event_cb = _pop3_event_cb; 82 str->event_cb = _pop3_event_cb;
81 str->event_mask = _MU_STR_EOF; 83 str->event_mask = _MU_STR_EVMASK(_MU_STR_EVENT_SETFLAG);
82 84
83 sp->oldbuf.type = MU_TRANSPORT_OUTPUT; 85 sp->oldbuf.type = MU_TRANSPORT_OUTPUT;
84 if (mu_stream_ioctl (sp->pop3->carrier, MU_IOCTL_GET_TRANSPORT_BUFFER, 86 if (mu_stream_ioctl (sp->pop3->carrier, MU_IOCTL_GET_TRANSPORT_BUFFER,
......
...@@ -27,7 +27,7 @@ mail_test -noprompt "quit" \ ...@@ -27,7 +27,7 @@ mail_test -noprompt "quit" \
27 # Start again using the same mailbox 27 # Start again using the same mailbox
28 mail_start -reuse-spool "--file=%mbox1" 28 mail_start -reuse-spool "--file=%mbox1"
29 # Go to the last message and do delete 4 times 29 # Go to the last message and do delete 4 times
30 mail_command "4" 30 mail_command "3"
31 mail_command "delete" 31 mail_command "delete"
32 mail_command "delete" 32 mail_command "delete"
33 mail_command "delete" 33 mail_command "delete"
......
...@@ -244,6 +244,9 @@ _base64_encoder (void *xd MU_ARG_UNUSED, ...@@ -244,6 +244,9 @@ _base64_encoder (void *xd MU_ARG_UNUSED,
244 pad = 0; 244 pad = 0;
245 } 245 }
246 246
247 /* Consumed may grow bigger than isize if cmd is mu_filter_lastbuf */
248 if (consumed > iobuf->isize)
249 consumed = iobuf->isize;
247 iobuf->isize = consumed; 250 iobuf->isize = consumed;
248 iobuf->osize = nbytes; 251 iobuf->osize = nbytes;
249 return mu_filter_ok; 252 return mu_filter_ok;
......
...@@ -236,6 +236,7 @@ mu_iostream_create (mu_stream_t *pref, mu_stream_t in, mu_stream_t out) ...@@ -236,6 +236,7 @@ mu_iostream_create (mu_stream_t *pref, mu_stream_t in, mu_stream_t out)
236 return ENOMEM; 236 return ENOMEM;
237 237
238 sp->stream.read = _iostream_read; 238 sp->stream.read = _iostream_read;
239 if (in->readdelim)
239 sp->stream.readdelim = _iostream_readdelim; 240 sp->stream.readdelim = _iostream_readdelim;
240 sp->stream.write = _iostream_write; 241 sp->stream.write = _iostream_write;
241 sp->stream.flush = _iostream_flush; 242 sp->stream.flush = _iostream_flush;
......
...@@ -279,6 +279,7 @@ mu_streamref_create_abridged (mu_stream_t *pref, mu_stream_t str, ...@@ -279,6 +279,7 @@ mu_streamref_create_abridged (mu_stream_t *pref, mu_stream_t str,
279 mu_stream_ref (str); 279 mu_stream_ref (str);
280 280
281 sp->stream.read = _streamref_read; 281 sp->stream.read = _streamref_read;
282 if (str->readdelim)
282 sp->stream.readdelim = _streamref_readdelim; 283 sp->stream.readdelim = _streamref_readdelim;
283 sp->stream.write = _streamref_write; 284 sp->stream.write = _streamref_write;
284 sp->stream.flush = _streamref_flush; 285 sp->stream.flush = _streamref_flush;
......
...@@ -167,21 +167,28 @@ print_transcript (struct _mu_xscript_stream *str, int flag, ...@@ -167,21 +167,28 @@ print_transcript (struct _mu_xscript_stream *str, int flag,
167 } 167 }
168 } 168 }
169 169
170 static int 170 static void
171 _xscript_read (struct _mu_stream *str, char *buf, size_t bufsize, 171 _xscript_event_cb (mu_stream_t str, int ev, unsigned long size, void *ptr)
172 size_t *pnread)
173 { 172 {
174 struct _mu_xscript_stream *sp = (struct _mu_xscript_stream *)str; 173 struct _mu_xscript_stream *sp = (struct _mu_xscript_stream *)str;
175 size_t nbytes;
176 int rc = mu_stream_read (sp->transport, buf, bufsize, &nbytes);
177 174
178 if (rc == 0) 175 switch (ev)
179 { 176 {
180 print_transcript (sp, TRANS_READ, buf, nbytes); 177 case _MU_STR_EVENT_FILLBUF:
181 if (pnread) 178 print_transcript (sp, TRANS_READ, ptr, size);
182 *pnread = nbytes; 179 break;
180
181 case _MU_STR_EVENT_FLUSHBUF:
182 print_transcript (sp, TRANS_WRITE, ptr, size);
183 } 183 }
184 return rc; 184 }
185
186 static int
187 _xscript_read (struct _mu_stream *str, char *buf, size_t bufsize,
188 size_t *pnread)
189 {
190 struct _mu_xscript_stream *sp = (struct _mu_xscript_stream *)str;
191 return mu_stream_read (sp->transport, buf, bufsize, pnread);
185 } 192 }
186 193
187 static int 194 static int
...@@ -189,15 +196,7 @@ _xscript_readdelim (struct _mu_stream *str, char *buf, size_t bufsize, ...@@ -189,15 +196,7 @@ _xscript_readdelim (struct _mu_stream *str, char *buf, size_t bufsize,
189 int delim, size_t *pnread) 196 int delim, size_t *pnread)
190 { 197 {
191 struct _mu_xscript_stream *sp = (struct _mu_xscript_stream *)str; 198 struct _mu_xscript_stream *sp = (struct _mu_xscript_stream *)str;
192 size_t nread; 199 return mu_stream_readdelim (sp->transport, buf, bufsize, delim, pnread);
193 int rc = mu_stream_readdelim (sp->transport, buf, bufsize, delim, &nread);
194 if (rc == 0)
195 {
196 print_transcript (sp, TRANS_READ, buf, nread);
197 if (pnread)
198 *pnread = nread;
199 }
200 return rc;
201 } 200 }
202 201
203 static int 202 static int
...@@ -205,11 +204,7 @@ _xscript_write (struct _mu_stream *str, const char *buf, size_t bufsize, ...@@ -205,11 +204,7 @@ _xscript_write (struct _mu_stream *str, const char *buf, size_t bufsize,
205 size_t *pnwrite) 204 size_t *pnwrite)
206 { 205 {
207 struct _mu_xscript_stream *sp = (struct _mu_xscript_stream *)str; 206 struct _mu_xscript_stream *sp = (struct _mu_xscript_stream *)str;
208 int rc = mu_stream_write (sp->transport, buf, bufsize, pnwrite); 207 return mu_stream_write (sp->transport, buf, bufsize, pnwrite);
209
210 if (rc == 0)
211 print_transcript (sp, TRANS_WRITE, buf, pnwrite ? *pnwrite : bufsize);
212 return rc;
213 } 208 }
214 209
215 static int 210 static int
...@@ -318,7 +313,6 @@ _xscript_ctl (struct _mu_stream *str, int op, void *arg) ...@@ -318,7 +313,6 @@ _xscript_ctl (struct _mu_stream *str, int op, void *arg)
318 case MU_IOCTL_GET_TRANSPORT_BUFFER: 313 case MU_IOCTL_GET_TRANSPORT_BUFFER:
319 case MU_IOCTL_SET_TRANSPORT_BUFFER: 314 case MU_IOCTL_SET_TRANSPORT_BUFFER:
320 { 315 {
321 struct mu_transport_buffer_query *qp = arg;
322 if (!sp->transport) 316 if (!sp->transport)
323 return EINVAL; 317 return EINVAL;
324 return mu_stream_ioctl (sp->transport, op, arg); 318 return mu_stream_ioctl (sp->transport, op, arg);
...@@ -391,6 +385,7 @@ mu_xscript_stream_create(mu_stream_t *pref, mu_stream_t transport, ...@@ -391,6 +385,7 @@ mu_xscript_stream_create(mu_stream_t *pref, mu_stream_t transport,
391 return ENOMEM; 385 return ENOMEM;
392 386
393 sp->stream.read = _xscript_read; 387 sp->stream.read = _xscript_read;
388 if (transport->readdelim)
394 sp->stream.readdelim = _xscript_readdelim; 389 sp->stream.readdelim = _xscript_readdelim;
395 sp->stream.write = _xscript_write; 390 sp->stream.write = _xscript_write;
396 sp->stream.flush = _xscript_flush; 391 sp->stream.flush = _xscript_flush;
...@@ -404,7 +399,9 @@ mu_xscript_stream_create(mu_stream_t *pref, mu_stream_t transport, ...@@ -404,7 +399,9 @@ mu_xscript_stream_create(mu_stream_t *pref, mu_stream_t transport,
404 sp->stream.truncate = _xscript_truncate; 399 sp->stream.truncate = _xscript_truncate;
405 sp->stream.shutdown = _xscript_shutdown; 400 sp->stream.shutdown = _xscript_shutdown;
406 sp->stream.error_string = _xscript_error_string; 401 sp->stream.error_string = _xscript_error_string;
407 402 sp->stream.event_cb = _xscript_event_cb;
403 sp->stream.event_mask = _MU_STR_EVMASK(_MU_STR_EVENT_FILLBUF) |
404 _MU_STR_EVMASK(_MU_STR_EVENT_FLUSHBUF);
408 if (!(flags & MU_STREAM_AUTOCLOSE)) 405 if (!(flags & MU_STREAM_AUTOCLOSE))
409 { 406 {
410 mu_stream_ref (transport); 407 mu_stream_ref (transport);
......