istream-zlib.c revision 9511a40d933181045343110c8101b75887062aae
2454dfa32c93c20a8522c6ed42fe057baaac9f9aStephan Bosch/* Copyright (c) 2005-2007 Dovecot authors, see the included COPYING file */
e28fa207d1a097fa6e4a867f74ee0761472ef1ceTimo Sirainen/* Default maximum buffer size. Seeking backwards is very expensive, so keep
37847ec8eaec9ad55c9df10ae109efe7b37ac573Timo Sirainen this pretty large */
a27e065f1a1f91c7fbdf7c2ea1c387441af0cbb3Timo Sirainenstatic void i_stream_zlib_close(struct iostream_private *stream)
dc5606fb66d30a659459446b6ca1a8b4f1146052Timo Sirainen struct zlib_istream *zstream = (struct zlib_istream *)stream;
697ff56bf3cdc9e7989ea2a70accf866b14b64d1Timo Sirainenstatic void i_stream_zlib_destroy(struct iostream_private *stream ATTR_UNUSED)
697ff56bf3cdc9e7989ea2a70accf866b14b64d1Timo Sirainen struct istream_private *_stream = (struct istream_private *)stream;
4ee00532a265bdfb38539d811fcd12d51210ac35Timo Sirainenstatic ssize_t i_stream_zlib_read(struct istream_private *stream)
697ff56bf3cdc9e7989ea2a70accf866b14b64d1Timo Sirainen struct zlib_istream *zstream = (struct zlib_istream *)stream;
8a0ad174adb1eb5108511b90e97f4e5f9089b0eeTimo Sirainen /* don't try to keep anything cached if we don't
a27e065f1a1f91c7fbdf7c2ea1c387441af0cbb3Timo Sirainen have a seek mark. */
a27e065f1a1f91c7fbdf7c2ea1c387441af0cbb3Timo Sirainen stream->buffer_size < stream->max_buffer_size) {
a27e065f1a1f91c7fbdf7c2ea1c387441af0cbb3Timo Sirainen /* buffer is full - grow it */
a27e065f1a1f91c7fbdf7c2ea1c387441af0cbb3Timo Sirainen i_stream_grow_buffer(stream, I_STREAM_MIN_SIZE);
a27e065f1a1f91c7fbdf7c2ea1c387441af0cbb3Timo Sirainen /* lose our buffer cache */
a27e065f1a1f91c7fbdf7c2ea1c387441af0cbb3Timo Sirainen i_assert(zstream->seek_offset == stream->istream.v_offset +
a27e065f1a1f91c7fbdf7c2ea1c387441af0cbb3Timo Sirainen ret = gzread(zstream->file, stream->w_buffer + stream->pos,
a27e065f1a1f91c7fbdf7c2ea1c387441af0cbb3Timo Sirainen } while (ret < 0 && errno == EINTR && stream->istream.blocking);
ac2defed599a97c4a71a9e90ba185929dfe59226Josef 'Jeff' Sipeki_stream_zlib_seek(struct istream_private *stream, uoff_t v_offset, bool mark)
a27e065f1a1f91c7fbdf7c2ea1c387441af0cbb3Timo Sirainen struct zlib_istream *zstream = (struct zlib_istream *) stream;
db8b0a3f74a20528d66a3c4be7df920e5c4554c2Timo Sirainen uoff_t start_offset = stream->istream.v_offset - stream->skip;
2615df45a8027948a474abe5e817b34b0499c171Timo Sirainen /* have to seek backwards */
ac2defed599a97c4a71a9e90ba185929dfe59226Josef 'Jeff' Sipek gzseek(zstream->file, v_offset, SEEK_SET);
ac2defed599a97c4a71a9e90ba185929dfe59226Josef 'Jeff' Sipek } else if (v_offset <= start_offset + stream->pos) {
63e207529879438e9f4412d97cdc34bdc82a3702Timo Sirainen /* seeking backwards within what's already cached */
ac2defed599a97c4a71a9e90ba185929dfe59226Josef 'Jeff' Sipek /* read and cache forward */
2649b237dd4690575e75a30b2bf3b39ebd37b835Timo Sirainen if (stream->istream.v_offset + avail >= v_offset) {
2615df45a8027948a474abe5e817b34b0499c171Timo Sirainen /* some failure, we've broken it */
2615df45a8027948a474abe5e817b34b0499c171Timo Sirainen /* unexpected EOF. allow it since we may just
2a6dcd984104fed84bed8795ccdfabb20e41ce52Timo Sirainen want to check if there's anything.. */
2615df45a8027948a474abe5e817b34b0499c171Timo Sirainenstatic const struct stat *
2615df45a8027948a474abe5e817b34b0499c171Timo Siraineni_stream_zlib_stat(struct istream_private *stream, bool exact)
2615df45a8027948a474abe5e817b34b0499c171Timo Sirainen struct zlib_istream *zstream = (struct zlib_istream *) stream;
49c48631cfd07017d5f93d83713fffe4f13730c4Timo Sirainen if (fstat(zstream->fd, &stream->statbuf) < 0) {
1728ff34ee03de825ad3aeed67d19f8ae140ee2eTimo Sirainen (void)i_stream_get_data(&stream->istream, &size);
2615df45a8027948a474abe5e817b34b0499c171Timo Sirainen zstream->cached_size = stream->istream.v_offset;
2615df45a8027948a474abe5e817b34b0499c171Timo Sirainen stream->statbuf.st_size = zstream->cached_size;
f0d09be40bd0c4423873128ae2f88a4020075dc4Timo Sirainenstatic void i_stream_zlib_sync(struct istream_private *stream)
1c1cecd3dfaf71b0c9499b044023e631841e88aaTimo Sirainen struct zlib_istream *zstream = (struct zlib_istream *) stream;
e5acc283bf030b0b5c79ca4e52d315c516a299faPascal Volk zstream->istream.iostream.close = i_stream_zlib_close;
e5acc283bf030b0b5c79ca4e52d315c516a299faPascal Volk zstream->istream.iostream.destroy = i_stream_zlib_destroy;
7920a47321690c932ffd4d286cd16b4048d22d41Timo Sirainen zstream->istream.max_buffer_size = DEFAULT_MAX_BUFFER_SIZE;
db8b0a3f74a20528d66a3c4be7df920e5c4554c2Timo Sirainen /* if it's a file, set the flags properly */
2615df45a8027948a474abe5e817b34b0499c171Timo Sirainen if (fstat(fd, &st) == 0 && S_ISREG(st.st_mode)) {