ostream-metawrap.c revision 6759ba36f2bac9e83547cfdcf233382a139f1283
02c335c23bf5fa225a467c19f2c063fb0dc7b8c3Timo Sirainen/* Copyright (c) 2013 Dovecot authors, see the included COPYING file */
ae9691f7ef36d5272d72c90fa51393dfea5dd126Timo Sirainen
ae9691f7ef36d5272d72c90fa51393dfea5dd126Timo Sirainen#include "lib.h"
ae9691f7ef36d5272d72c90fa51393dfea5dd126Timo Sirainen#include "ostream-private.h"
ae9691f7ef36d5272d72c90fa51393dfea5dd126Timo Sirainen#include "ostream-metawrap.h"
ae9691f7ef36d5272d72c90fa51393dfea5dd126Timo Sirainen
ae9691f7ef36d5272d72c90fa51393dfea5dd126Timo Sirainenstruct metawrap_ostream {
2eccb2637d0153bb7f9ad39a70f254cece74342cTimo Sirainen struct ostream_private ostream;
2eccb2637d0153bb7f9ad39a70f254cece74342cTimo Sirainen void (*write_callback)(void *);
7877db7b5daad125b6cb3e015574f33871c9a51bTimo Sirainen void *context;
ae9691f7ef36d5272d72c90fa51393dfea5dd126Timo Sirainen};
ae9691f7ef36d5272d72c90fa51393dfea5dd126Timo Sirainen
ae9691f7ef36d5272d72c90fa51393dfea5dd126Timo Sirainenstatic void o_stream_metawrap_call_callback(struct metawrap_ostream *mstream)
ae9691f7ef36d5272d72c90fa51393dfea5dd126Timo Sirainen{
ae9691f7ef36d5272d72c90fa51393dfea5dd126Timo Sirainen void (*write_callback)(void *) = mstream->write_callback;
ae9691f7ef36d5272d72c90fa51393dfea5dd126Timo Sirainen
2eccb2637d0153bb7f9ad39a70f254cece74342cTimo Sirainen if (write_callback != NULL) {
86bdb644d147a73df85abce4325254d694217a5fTimo Sirainen mstream->write_callback = NULL;
ae9691f7ef36d5272d72c90fa51393dfea5dd126Timo Sirainen write_callback(mstream->context);
ae9691f7ef36d5272d72c90fa51393dfea5dd126Timo Sirainen }
ae9691f7ef36d5272d72c90fa51393dfea5dd126Timo Sirainen}
ae9691f7ef36d5272d72c90fa51393dfea5dd126Timo Sirainen
ae9691f7ef36d5272d72c90fa51393dfea5dd126Timo Sirainenstatic ssize_t
ae9691f7ef36d5272d72c90fa51393dfea5dd126Timo Siraineno_stream_metawrap_sendv(struct ostream_private *stream,
ae9691f7ef36d5272d72c90fa51393dfea5dd126Timo Sirainen const struct const_iovec *iov, unsigned int iov_count)
ae9691f7ef36d5272d72c90fa51393dfea5dd126Timo Sirainen{
ae9691f7ef36d5272d72c90fa51393dfea5dd126Timo Sirainen struct metawrap_ostream *mstream = (struct metawrap_ostream *)stream;
4e8e7a93628b4ed60aaaa47c6f72c1433f21e81dTimo Sirainen ssize_t ret;
2d6c6f1d06d6d2e7b2ab0d46f7decdcf1cc80cd6Timo Sirainen
2d6c6f1d06d6d2e7b2ab0d46f7decdcf1cc80cd6Timo Sirainen o_stream_metawrap_call_callback(mstream);
86bdb644d147a73df85abce4325254d694217a5fTimo Sirainen if ((ret = o_stream_sendv(stream->parent, iov, iov_count)) < 0)
86bdb644d147a73df85abce4325254d694217a5fTimo Sirainen o_stream_copy_error_from_parent(stream);
ae9691f7ef36d5272d72c90fa51393dfea5dd126Timo Sirainen return ret;
ae9691f7ef36d5272d72c90fa51393dfea5dd126Timo Sirainen}
ae9691f7ef36d5272d72c90fa51393dfea5dd126Timo Sirainen
ae9691f7ef36d5272d72c90fa51393dfea5dd126Timo Sirainenstatic off_t
ae9691f7ef36d5272d72c90fa51393dfea5dd126Timo Siraineno_stream_metawrap_send_istream(struct ostream_private *_outstream,
ae9691f7ef36d5272d72c90fa51393dfea5dd126Timo Sirainen struct istream *instream)
ae9691f7ef36d5272d72c90fa51393dfea5dd126Timo Sirainen{
ae9691f7ef36d5272d72c90fa51393dfea5dd126Timo Sirainen struct metawrap_ostream *outstream =
ae9691f7ef36d5272d72c90fa51393dfea5dd126Timo Sirainen (struct metawrap_ostream *)_outstream;
ae9691f7ef36d5272d72c90fa51393dfea5dd126Timo Sirainen off_t ret;
ae9691f7ef36d5272d72c90fa51393dfea5dd126Timo Sirainen
ae9691f7ef36d5272d72c90fa51393dfea5dd126Timo Sirainen o_stream_metawrap_call_callback(outstream);
ae9691f7ef36d5272d72c90fa51393dfea5dd126Timo Sirainen if ((ret = o_stream_send_istream(_outstream->parent, instream)) < 0)
ae9691f7ef36d5272d72c90fa51393dfea5dd126Timo Sirainen o_stream_copy_error_from_parent(stream);
2eccb2637d0153bb7f9ad39a70f254cece74342cTimo Sirainen return ret;
2eccb2637d0153bb7f9ad39a70f254cece74342cTimo Sirainen}
2eccb2637d0153bb7f9ad39a70f254cece74342cTimo Sirainen
2eccb2637d0153bb7f9ad39a70f254cece74342cTimo Sirainenstruct ostream *
ae9691f7ef36d5272d72c90fa51393dfea5dd126Timo Siraineno_stream_create_metawrap(struct ostream *output,
ae9691f7ef36d5272d72c90fa51393dfea5dd126Timo Sirainen void (*write_callback)(void *), void *context)
ae9691f7ef36d5272d72c90fa51393dfea5dd126Timo Sirainen{
ae9691f7ef36d5272d72c90fa51393dfea5dd126Timo Sirainen struct metawrap_ostream *mstream;
ae9691f7ef36d5272d72c90fa51393dfea5dd126Timo Sirainen
ae9691f7ef36d5272d72c90fa51393dfea5dd126Timo Sirainen mstream = i_new(struct metawrap_ostream, 1);
ae9691f7ef36d5272d72c90fa51393dfea5dd126Timo Sirainen mstream->ostream.sendv = o_stream_metawrap_sendv;
ae9691f7ef36d5272d72c90fa51393dfea5dd126Timo Sirainen mstream->ostream.send_istream = o_stream_metawrap_send_istream;
ae9691f7ef36d5272d72c90fa51393dfea5dd126Timo Sirainen mstream->write_callback = write_callback;
ae9691f7ef36d5272d72c90fa51393dfea5dd126Timo Sirainen mstream->context = context;
ae9691f7ef36d5272d72c90fa51393dfea5dd126Timo Sirainen
ae9691f7ef36d5272d72c90fa51393dfea5dd126Timo Sirainen return o_stream_create(&mstream->ostream, output,
ae9691f7ef36d5272d72c90fa51393dfea5dd126Timo Sirainen o_stream_get_fd(output));
ae9691f7ef36d5272d72c90fa51393dfea5dd126Timo Sirainen}
ae9691f7ef36d5272d72c90fa51393dfea5dd126Timo Sirainen