istream-concat.c revision 1c6f6f5bef70f16546b3bc8f4cd5f93f373e82a2
c25356d5978632df6203437e1953bcb29e0c736fTimo Sirainen/* Copyright (c) 2007-2013 Dovecot authors, see the included COPYING file */
7fd51f7b0b4d990ec3cfef4e60ee685bf9fb32deTimo Sirainenstatic void i_stream_concat_close(struct iostream_private *stream,
eb64c3586d854cddd693f0b811d897399076a441Timo Sirainen struct concat_istream *cstream = (struct concat_istream *)stream;
eb64c3586d854cddd693f0b811d897399076a441Timo Sirainen unsigned int i;
eb64c3586d854cddd693f0b811d897399076a441Timo Sirainenstatic void i_stream_concat_destroy(struct iostream_private *stream)
eb64c3586d854cddd693f0b811d897399076a441Timo Sirainen struct concat_istream *cstream = (struct concat_istream *)stream;
32e1554df9abca74fef0af2ba2e4c37e90a06cd0Timo Sirainen unsigned int i;
16db188cfddce117500a161302f17ae691b4500eTimo Siraineni_stream_concat_set_max_buffer_size(struct iostream_private *stream,
296dca49e4fe6046e0328c67ef1cf4b8077dec9cTimo Sirainen struct concat_istream *cstream = (struct concat_istream *)stream;
e8490a52a1bc71bc53034e68f464435684ad810fTimo Sirainen unsigned int i;
e8490a52a1bc71bc53034e68f464435684ad810fTimo Sirainen i_stream_set_max_buffer_size(cstream->input[i], max_size);
e8490a52a1bc71bc53034e68f464435684ad810fTimo Sirainenstatic void i_stream_concat_read_next(struct concat_istream *cstream)
e8490a52a1bc71bc53034e68f464435684ad810fTimo Sirainen const unsigned char *data;
af3f857bb3166ed99595e11a9d18e5b5cc670e1aTimo Sirainen data = i_stream_get_data(cstream->cur_input, &data_size);
af3f857bb3166ed99595e11a9d18e5b5cc670e1aTimo Sirainen cstream->cur_input = cstream->input[cstream->cur_idx];
af3f857bb3166ed99595e11a9d18e5b5cc670e1aTimo Sirainen if (cstream->prev_stream_left > 0 || cstream->istream.pos == 0) {
c58906589cafc32df4c04ffbef933baadd3f2276Timo Sirainen cstream->istream.pos - cstream->istream.skip);
c396c5cdd510d09aa35875ccfd643c5c21ed1f89Timo Sirainen /* we already verified that the data size is less than the
a64adf62fa33f2463a86f990217b0c9078531a40Timo Sirainen maximum buffer size */
0dffa25d211be541ee3c953b23566a1a990789dfTimo Sirainen if (!i_stream_try_alloc(&cstream->istream, data_size, &size))
092018b35bb1dc5bd61848a38189fe6ac8f791ddTimo Sirainen memcpy(cstream->istream.w_buffer, data, data_size);
90804278df6586cceaf1b1b07a44713c01694048Timo Sirainenstatic ssize_t i_stream_concat_read(struct istream_private *stream)
90804278df6586cceaf1b1b07a44713c01694048Timo Sirainen struct concat_istream *cstream = (struct concat_istream *)stream;
90804278df6586cceaf1b1b07a44713c01694048Timo Sirainen const unsigned char *data;
90804278df6586cceaf1b1b07a44713c01694048Timo Sirainen size_t size, data_size, cur_data_pos, new_pos, bytes_skipped;
2615df45a8027948a474abe5e817b34b0499c171Timo Sirainen bytes_skipped = stream->skip - cstream->prev_skip;
2615df45a8027948a474abe5e817b34b0499c171Timo Sirainen /* no need to worry about buffers, skip everything */
c8cf8a605e0ddea7cb36fe04551aeca5090e684bTimo Sirainen } else if (bytes_skipped < cstream->prev_stream_left) {
c8cf8a605e0ddea7cb36fe04551aeca5090e684bTimo Sirainen /* we're still skipping inside buffer */
2615df45a8027948a474abe5e817b34b0499c171Timo Sirainen /* done with the buffer */
9b706b345064ce8e8a657f54633f009a101298eaTimo Sirainen i_stream_skip(cstream->cur_input, bytes_skipped);
e8490a52a1bc71bc53034e68f464435684ad810fTimo Sirainen i_assert(stream->pos >= stream->skip + cstream->prev_stream_left);
c0a87e5f3316a57e6f915882fa1951d0fbb74a61Timo Sirainen cur_data_pos = stream->pos - (stream->skip + cstream->prev_stream_left);
9b706b345064ce8e8a657f54633f009a101298eaTimo Sirainen data = i_stream_get_data(cstream->cur_input, &data_size);
288d6ef592719f2be3cad9f034e9be05f9839785Timo Sirainen /* need to read more */
9b706b345064ce8e8a657f54633f009a101298eaTimo Sirainen if (ret == -1 && cstream->cur_input->stream_errno != 0) {
9b706b345064ce8e8a657f54633f009a101298eaTimo Sirainen /* we either read something or we're at EOF */
a988c3fd9251806e38931a011aaa4006dd081cbdTimo Sirainen last_stream = cstream->input[cstream->cur_idx+1] == NULL;
957d09e495c33ad1180f82152e5e87e6b51ab04bTimo Sirainen stream->istream.eof = cstream->cur_input->eof && last_stream;
957d09e495c33ad1180f82152e5e87e6b51ab04bTimo Sirainen data = i_stream_get_data(cstream->cur_input, &data_size);
2615df45a8027948a474abe5e817b34b0499c171Timo Sirainen /* we can point directly to the current stream's buffers */
14b551180cb4ac7acac8b048d8d6d7278541d1f6Timo Sirainen /* nothing new read */
return ret;
if (*v_offset == 0) {
return UINT_MAX;
unsigned int count;