istream-tee.c revision 74f810327aca91b3375d3fc963bce8076785b1cb
02c335c23bf5fa225a467c19f2c063fb0dc7b8c3Timo Sirainen/* Copyright (c) 2006-2007 Dovecot authors, see the included COPYING file */
e248fe370c4047cee921a91b48edc37944ab0526Timo Sirainenstatic void tee_streams_update_buffer(struct tee_istream *tee)
e248fe370c4047cee921a91b48edc37944ab0526Timo Sirainen struct tee_child_istream *tstream = tee->children;
9f627b360ed38fdc54cb02ec5e67246c3f0d5b0fTimo Sirainen const unsigned char *data;
36b072d84a9076c3c483bf710444a716e987ccc3Stephan Bosch for (; tstream != NULL; tstream = tstream->next) {
36b072d84a9076c3c483bf710444a716e987ccc3Stephan Bosch tstream->istream.skip = tstream->istream.pos = 0;
36b072d84a9076c3c483bf710444a716e987ccc3Stephan Bosch old_used = tstream->istream.pos - tstream->istream.skip;
36b072d84a9076c3c483bf710444a716e987ccc3Stephan Bosch tstream->istream.skip = tstream->istream.istream.v_offset -
36b072d84a9076c3c483bf710444a716e987ccc3Stephan Bosch i_assert(tstream->istream.skip + old_used <= size);
36b072d84a9076c3c483bf710444a716e987ccc3Stephan Bosch tstream->istream.pos = tstream->istream.skip + old_used;
04eb0abcf8f8b0c014499b5c5bae89484553613fStephan Boschstatic void tee_streams_skip(struct tee_istream *tee)
04eb0abcf8f8b0c014499b5c5bae89484553613fStephan Bosch struct tee_child_istream *tstream = tee->children;
36b072d84a9076c3c483bf710444a716e987ccc3Stephan Bosch for (; tstream != NULL; tstream = tstream->next) {
36b072d84a9076c3c483bf710444a716e987ccc3Stephan Boschstatic void i_stream_tee_close(struct iostream_private *stream)
9f627b360ed38fdc54cb02ec5e67246c3f0d5b0fTimo Sirainen struct tee_child_istream *tstream = (struct tee_child_istream *)stream;
e248fe370c4047cee921a91b48edc37944ab0526Timo Sirainenstatic void i_stream_tee_destroy(struct iostream_private *stream)
e248fe370c4047cee921a91b48edc37944ab0526Timo Sirainen struct tee_child_istream *tstream = (struct tee_child_istream *)stream;
e248fe370c4047cee921a91b48edc37944ab0526Timo Sirainen if (tstream->istream.istream.v_offset > tee->max_read_offset)
660b99a7059824676b2b8d6f79b8e15d47df25a2Timo Sirainen tee->max_read_offset = tstream->istream.istream.v_offset;
e248fe370c4047cee921a91b48edc37944ab0526Timo Sirainen for (p = &tee->children; *p != NULL; p = &(*p)->next) {
9f627b360ed38fdc54cb02ec5e67246c3f0d5b0fTimo Sirainen i_assert(tee->input->v_offset <= tee->max_read_offset);
e248fe370c4047cee921a91b48edc37944ab0526Timo Siraineni_stream_tee_set_max_buffer_size(struct iostream_private *stream,
ce1a6c9b82117d253df9acd77e54ac84dd8a247eTimo Sirainen struct tee_child_istream *tstream = (struct tee_child_istream *)stream;
ce1a6c9b82117d253df9acd77e54ac84dd8a247eTimo Sirainen i_stream_set_max_buffer_size(tstream->tee->input, max_size);
ce1a6c9b82117d253df9acd77e54ac84dd8a247eTimo Sirainenstatic ssize_t i_stream_tee_read(struct istream_private *stream)
ce1a6c9b82117d253df9acd77e54ac84dd8a247eTimo Sirainen struct tee_child_istream *tstream = (struct tee_child_istream *)stream;
ce1a6c9b82117d253df9acd77e54ac84dd8a247eTimo Sirainen const unsigned char *data;
ce1a6c9b82117d253df9acd77e54ac84dd8a247eTimo Sirainen (tstream->istream.pos - tstream->istream.skip);
ce1a6c9b82117d253df9acd77e54ac84dd8a247eTimo Sirainen i_assert(last_high_offset <= input->v_offset + size);
ce1a6c9b82117d253df9acd77e54ac84dd8a247eTimo Sirainen if (last_high_offset == input->v_offset + size) {
ce1a6c9b82117d253df9acd77e54ac84dd8a247eTimo Sirainen /* someone else is holding the data,
ce1a6c9b82117d253df9acd77e54ac84dd8a247eTimo Sirainen wait for it */
e248fe370c4047cee921a91b48edc37944ab0526Timo Siraineni_stream_tee_seek(struct istream_private *stream ATTR_UNUSED,
e248fe370c4047cee921a91b48edc37944ab0526Timo Sirainen uoff_t v_offset ATTR_UNUSED, bool mark ATTR_UNUSED)
36b072d84a9076c3c483bf710444a716e987ccc3Stephan Bosch i_panic("tee-istream: seeking unsupported currently");
36b072d84a9076c3c483bf710444a716e987ccc3Stephan Boschstatic const struct stat *
e248fe370c4047cee921a91b48edc37944ab0526Timo Siraineni_stream_tee_stat(struct istream_private *stream, bool exact)
e248fe370c4047cee921a91b48edc37944ab0526Timo Sirainen struct tee_child_istream *tstream = (struct tee_child_istream *)stream;
e248fe370c4047cee921a91b48edc37944ab0526Timo Sirainen return i_stream_stat(tstream->tee->input, exact);
d694a52bce62c52080c3f87a56dcf77030fd2712Timo Sirainenstatic void i_stream_tee_sync(struct istream_private *stream)
009217abb57a24a4076092e8e4e165545747839eStephan Bosch struct tee_child_istream *tstream = (struct tee_child_istream *)stream;
009217abb57a24a4076092e8e4e165545747839eStephan Bosch (void)i_stream_get_data(tstream->tee->input, &size);
e248fe370c4047cee921a91b48edc37944ab0526Timo Sirainen i_panic("tee-istream: i_stream_sync() called "
e248fe370c4047cee921a91b48edc37944ab0526Timo Sirainen "with data still buffered");
c93aca832ee532010ead91b85fa9f614132e1be2Stephan Boschstruct tee_istream *tee_i_stream_create(struct istream *input)
ab281fc992907b6cf6c730f672dc3aa4c6685015Timo Sirainenstruct istream *tee_i_stream_create_child(struct tee_istream *tee)
1bf5c6c20f3d51f13d3240cfb46e471074c86276Timo Sirainen tstream->istream.iostream.close = i_stream_tee_close;
1bf5c6c20f3d51f13d3240cfb46e471074c86276Timo Sirainen tstream->istream.iostream.destroy = i_stream_tee_destroy;