annotate src/plugins/zlib/istream-zlib.c @ 4891:6ab2712f1a93 HEAD

Only imap binary was actually working.
author Timo Sirainen <tss@iki.fi>
date Sun, 10 Dec 2006 14:35:02 +0200
parents 55df57c028d4
children 81394e71f92a
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
rev   line source
3800
68e7519ebd90 Added zlib plugin
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
1 /* Copyright (C) 2005 Timo Sirainen */
68e7519ebd90 Added zlib plugin
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
2
68e7519ebd90 Added zlib plugin
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
3 #include "lib.h"
68e7519ebd90 Added zlib plugin
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
4 #include "istream-internal.h"
68e7519ebd90 Added zlib plugin
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
5 #include "istream-zlib.h"
68e7519ebd90 Added zlib plugin
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
6
68e7519ebd90 Added zlib plugin
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
7 #include <zlib.h>
68e7519ebd90 Added zlib plugin
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
8
68e7519ebd90 Added zlib plugin
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
9 /* Default maximum buffer size. Seeking backwards is very expensive, so keep
68e7519ebd90 Added zlib plugin
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
10 this pretty large */
68e7519ebd90 Added zlib plugin
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
11 #define DEFAULT_MAX_BUFFER_SIZE (1024*1024)
68e7519ebd90 Added zlib plugin
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
12
68e7519ebd90 Added zlib plugin
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
13 #define I_STREAM_MIN_SIZE 4096
68e7519ebd90 Added zlib plugin
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
14
68e7519ebd90 Added zlib plugin
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
15 struct zlib_istream {
68e7519ebd90 Added zlib plugin
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
16 struct _istream istream;
68e7519ebd90 Added zlib plugin
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
17
68e7519ebd90 Added zlib plugin
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
18 size_t max_buffer_size;
68e7519ebd90 Added zlib plugin
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
19
68e7519ebd90 Added zlib plugin
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
20 int fd;
68e7519ebd90 Added zlib plugin
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
21 gzFile *file;
68e7519ebd90 Added zlib plugin
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
22 uoff_t cached_size;
68e7519ebd90 Added zlib plugin
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
23 uoff_t seek_offset;
68e7519ebd90 Added zlib plugin
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
24
68e7519ebd90 Added zlib plugin
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
25 unsigned int marked:1;
68e7519ebd90 Added zlib plugin
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
26 };
68e7519ebd90 Added zlib plugin
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
27
68e7519ebd90 Added zlib plugin
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
28 static void _close(struct _iostream *stream)
68e7519ebd90 Added zlib plugin
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
29 {
68e7519ebd90 Added zlib plugin
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
30 struct zlib_istream *zstream = (struct zlib_istream *)stream;
68e7519ebd90 Added zlib plugin
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
31
68e7519ebd90 Added zlib plugin
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
32 if (zstream->file != NULL) {
68e7519ebd90 Added zlib plugin
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
33 gzclose(zstream->file);
68e7519ebd90 Added zlib plugin
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
34 zstream->file = NULL;
68e7519ebd90 Added zlib plugin
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
35 }
68e7519ebd90 Added zlib plugin
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
36 }
68e7519ebd90 Added zlib plugin
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
37
68e7519ebd90 Added zlib plugin
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
38 static void _destroy(struct _iostream *stream __attr_unused__)
68e7519ebd90 Added zlib plugin
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
39 {
68e7519ebd90 Added zlib plugin
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
40 struct _istream *_stream = (struct _istream *) stream;
68e7519ebd90 Added zlib plugin
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
41
68e7519ebd90 Added zlib plugin
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
42 p_free(_stream->iostream.pool, _stream->w_buffer);
68e7519ebd90 Added zlib plugin
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
43 }
68e7519ebd90 Added zlib plugin
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
44
68e7519ebd90 Added zlib plugin
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
45 static void _set_max_buffer_size(struct _iostream *stream, size_t max_size)
68e7519ebd90 Added zlib plugin
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
46 {
68e7519ebd90 Added zlib plugin
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
47 struct zlib_istream *zstream = (struct zlib_istream *)stream;
68e7519ebd90 Added zlib plugin
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
48
68e7519ebd90 Added zlib plugin
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
49 zstream->max_buffer_size = max_size;
68e7519ebd90 Added zlib plugin
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
50 }
68e7519ebd90 Added zlib plugin
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
51
68e7519ebd90 Added zlib plugin
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
52 static void i_stream_grow_buffer(struct _istream *stream, size_t bytes)
68e7519ebd90 Added zlib plugin
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
53 {
68e7519ebd90 Added zlib plugin
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
54 struct zlib_istream *zstream = (struct zlib_istream *)stream;
68e7519ebd90 Added zlib plugin
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
55 size_t old_size;
68e7519ebd90 Added zlib plugin
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
56
68e7519ebd90 Added zlib plugin
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
57 old_size = stream->buffer_size;
68e7519ebd90 Added zlib plugin
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
58
68e7519ebd90 Added zlib plugin
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
59 stream->buffer_size = stream->pos + bytes;
68e7519ebd90 Added zlib plugin
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
60 if (stream->buffer_size <= I_STREAM_MIN_SIZE)
68e7519ebd90 Added zlib plugin
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
61 stream->buffer_size = I_STREAM_MIN_SIZE;
68e7519ebd90 Added zlib plugin
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
62 else {
68e7519ebd90 Added zlib plugin
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
63 stream->buffer_size =
68e7519ebd90 Added zlib plugin
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
64 pool_get_exp_grown_size(stream->iostream.pool,
68e7519ebd90 Added zlib plugin
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
65 old_size, stream->buffer_size);
68e7519ebd90 Added zlib plugin
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
66 }
68e7519ebd90 Added zlib plugin
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
67
68e7519ebd90 Added zlib plugin
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
68 if (zstream->max_buffer_size > 0 &&
68e7519ebd90 Added zlib plugin
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
69 stream->buffer_size > zstream->max_buffer_size)
68e7519ebd90 Added zlib plugin
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
70 stream->buffer_size = zstream->max_buffer_size;
68e7519ebd90 Added zlib plugin
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
71
68e7519ebd90 Added zlib plugin
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
72 stream->buffer = stream->w_buffer =
68e7519ebd90 Added zlib plugin
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
73 p_realloc(stream->iostream.pool, stream->w_buffer,
68e7519ebd90 Added zlib plugin
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
74 old_size, stream->buffer_size);
68e7519ebd90 Added zlib plugin
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
75 }
68e7519ebd90 Added zlib plugin
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
76
68e7519ebd90 Added zlib plugin
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
77 static void i_stream_compress(struct _istream *stream)
68e7519ebd90 Added zlib plugin
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
78 {
68e7519ebd90 Added zlib plugin
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
79 memmove(stream->w_buffer, stream->w_buffer + stream->skip,
68e7519ebd90 Added zlib plugin
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
80 stream->pos - stream->skip);
68e7519ebd90 Added zlib plugin
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
81 stream->pos -= stream->skip;
68e7519ebd90 Added zlib plugin
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
82
68e7519ebd90 Added zlib plugin
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
83 stream->skip = 0;
68e7519ebd90 Added zlib plugin
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
84 }
68e7519ebd90 Added zlib plugin
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
85
68e7519ebd90 Added zlib plugin
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
86 static ssize_t _read(struct _istream *stream)
68e7519ebd90 Added zlib plugin
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
87 {
68e7519ebd90 Added zlib plugin
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
88 struct zlib_istream *zstream = (struct zlib_istream *)stream;
68e7519ebd90 Added zlib plugin
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
89 size_t size;
68e7519ebd90 Added zlib plugin
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
90 int ret;
68e7519ebd90 Added zlib plugin
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
91
68e7519ebd90 Added zlib plugin
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
92 if (stream->istream.closed)
68e7519ebd90 Added zlib plugin
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
93 return -1;
68e7519ebd90 Added zlib plugin
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
94
68e7519ebd90 Added zlib plugin
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
95 stream->istream.stream_errno = 0;
68e7519ebd90 Added zlib plugin
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
96
68e7519ebd90 Added zlib plugin
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
97 if (stream->pos == stream->buffer_size) {
68e7519ebd90 Added zlib plugin
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
98 if (!zstream->marked && stream->skip > 0) {
68e7519ebd90 Added zlib plugin
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
99 /* don't try to keep anything cached if we don't
68e7519ebd90 Added zlib plugin
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
100 have a seek mark. */
68e7519ebd90 Added zlib plugin
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
101 i_stream_compress(stream);
68e7519ebd90 Added zlib plugin
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
102 }
68e7519ebd90 Added zlib plugin
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
103
68e7519ebd90 Added zlib plugin
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
104 if (zstream->max_buffer_size == 0 ||
68e7519ebd90 Added zlib plugin
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
105 stream->buffer_size < zstream->max_buffer_size) {
68e7519ebd90 Added zlib plugin
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
106 /* buffer is full - grow it */
68e7519ebd90 Added zlib plugin
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
107 i_stream_grow_buffer(stream, I_STREAM_MIN_SIZE);
68e7519ebd90 Added zlib plugin
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
108 }
68e7519ebd90 Added zlib plugin
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
109
68e7519ebd90 Added zlib plugin
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
110 if (stream->pos == stream->buffer_size) {
68e7519ebd90 Added zlib plugin
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
111 if (stream->skip > 0) {
68e7519ebd90 Added zlib plugin
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
112 /* lose our buffer cache */
68e7519ebd90 Added zlib plugin
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
113 i_stream_compress(stream);
68e7519ebd90 Added zlib plugin
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
114 }
68e7519ebd90 Added zlib plugin
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
115
68e7519ebd90 Added zlib plugin
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
116 if (stream->pos == stream->buffer_size)
68e7519ebd90 Added zlib plugin
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
117 return -2; /* buffer full */
68e7519ebd90 Added zlib plugin
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
118 }
68e7519ebd90 Added zlib plugin
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
119 }
68e7519ebd90 Added zlib plugin
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
120
68e7519ebd90 Added zlib plugin
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
121 size = stream->buffer_size - stream->pos;
68e7519ebd90 Added zlib plugin
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
122
68e7519ebd90 Added zlib plugin
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
123 ret = -1;
68e7519ebd90 Added zlib plugin
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
124
68e7519ebd90 Added zlib plugin
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
125 i_assert(zstream->seek_offset == stream->istream.v_offset +
68e7519ebd90 Added zlib plugin
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
126 (stream->pos - stream->skip));
68e7519ebd90 Added zlib plugin
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
127 ret = gzread(zstream->file, stream->w_buffer + stream->pos, size);
68e7519ebd90 Added zlib plugin
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
128 if (ret == 0) {
68e7519ebd90 Added zlib plugin
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
129 /* EOF */
68e7519ebd90 Added zlib plugin
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
130 stream->istream.eof = TRUE;
68e7519ebd90 Added zlib plugin
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
131 return -1;
68e7519ebd90 Added zlib plugin
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
132 }
68e7519ebd90 Added zlib plugin
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
133
68e7519ebd90 Added zlib plugin
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
134 if (ret < 0) {
68e7519ebd90 Added zlib plugin
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
135 if (errno == EINTR || errno == EAGAIN)
68e7519ebd90 Added zlib plugin
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
136 ret = 0;
68e7519ebd90 Added zlib plugin
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
137 else {
68e7519ebd90 Added zlib plugin
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
138 stream->istream.eof = TRUE;
68e7519ebd90 Added zlib plugin
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
139 stream->istream.stream_errno = errno;
68e7519ebd90 Added zlib plugin
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
140 return -1;
68e7519ebd90 Added zlib plugin
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
141 }
68e7519ebd90 Added zlib plugin
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
142 }
68e7519ebd90 Added zlib plugin
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
143
68e7519ebd90 Added zlib plugin
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
144 zstream->seek_offset += ret;
68e7519ebd90 Added zlib plugin
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
145 stream->pos += ret;
68e7519ebd90 Added zlib plugin
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
146 i_assert(ret != 0);
68e7519ebd90 Added zlib plugin
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
147 return ret;
68e7519ebd90 Added zlib plugin
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
148 }
68e7519ebd90 Added zlib plugin
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
149
3863
55df57c028d4 Added "bool" type and changed all ints that were used as booleans to bool.
Timo Sirainen <tss@iki.fi>
parents: 3800
diff changeset
150 static void _seek(struct _istream *stream, uoff_t v_offset, bool mark)
3800
68e7519ebd90 Added zlib plugin
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
151 {
68e7519ebd90 Added zlib plugin
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
152 struct zlib_istream *zstream = (struct zlib_istream *) stream;
68e7519ebd90 Added zlib plugin
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
153 uoff_t start_offset = stream->istream.v_offset - stream->skip;
68e7519ebd90 Added zlib plugin
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
154
68e7519ebd90 Added zlib plugin
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
155 stream->istream.stream_errno = 0;
68e7519ebd90 Added zlib plugin
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
156
68e7519ebd90 Added zlib plugin
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
157 if (v_offset < start_offset) {
68e7519ebd90 Added zlib plugin
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
158 /* have to seek backwards */
68e7519ebd90 Added zlib plugin
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
159 gzseek(zstream->file, v_offset, SEEK_SET);
68e7519ebd90 Added zlib plugin
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
160 zstream->seek_offset = v_offset;
68e7519ebd90 Added zlib plugin
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
161
68e7519ebd90 Added zlib plugin
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
162 stream->skip = stream->pos = 0;
68e7519ebd90 Added zlib plugin
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
163 stream->istream.v_offset = v_offset;
68e7519ebd90 Added zlib plugin
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
164 } else if (v_offset <= start_offset + stream->pos) {
68e7519ebd90 Added zlib plugin
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
165 /* seeking backwards within what's already cached */
68e7519ebd90 Added zlib plugin
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
166 stream->skip = v_offset - start_offset;
68e7519ebd90 Added zlib plugin
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
167 stream->istream.v_offset = v_offset;
68e7519ebd90 Added zlib plugin
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
168 } else {
68e7519ebd90 Added zlib plugin
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
169 /* read and cache forward */
68e7519ebd90 Added zlib plugin
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
170 do {
68e7519ebd90 Added zlib plugin
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
171 size_t avail = stream->pos - stream->skip;
68e7519ebd90 Added zlib plugin
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
172 if (stream->istream.v_offset + avail >= v_offset) {
68e7519ebd90 Added zlib plugin
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
173 i_stream_skip(&stream->istream,
68e7519ebd90 Added zlib plugin
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
174 v_offset -
68e7519ebd90 Added zlib plugin
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
175 stream->istream.v_offset);
68e7519ebd90 Added zlib plugin
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
176 break;
68e7519ebd90 Added zlib plugin
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
177 }
68e7519ebd90 Added zlib plugin
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
178
68e7519ebd90 Added zlib plugin
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
179 i_stream_skip(&stream->istream, avail);
68e7519ebd90 Added zlib plugin
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
180 } while (_read(stream) >= 0);
68e7519ebd90 Added zlib plugin
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
181
68e7519ebd90 Added zlib plugin
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
182 if (stream->istream.v_offset != v_offset) {
68e7519ebd90 Added zlib plugin
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
183 /* some failure, we've broken it */
68e7519ebd90 Added zlib plugin
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
184 if (stream->istream.stream_errno != 0) {
68e7519ebd90 Added zlib plugin
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
185 i_error("zlib_istream.seek() failed: %s",
68e7519ebd90 Added zlib plugin
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
186 strerror(stream->istream.stream_errno));
68e7519ebd90 Added zlib plugin
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
187 i_stream_close(&stream->istream);
68e7519ebd90 Added zlib plugin
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
188 } else {
68e7519ebd90 Added zlib plugin
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
189 /* unexpected EOF. allow it since we may just
68e7519ebd90 Added zlib plugin
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
190 want to check if there's anything.. */
68e7519ebd90 Added zlib plugin
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
191 i_assert(stream->istream.eof);
68e7519ebd90 Added zlib plugin
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
192 }
68e7519ebd90 Added zlib plugin
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
193 }
68e7519ebd90 Added zlib plugin
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
194 }
68e7519ebd90 Added zlib plugin
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
195
68e7519ebd90 Added zlib plugin
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
196 if (mark) {
68e7519ebd90 Added zlib plugin
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
197 i_stream_compress(stream);
68e7519ebd90 Added zlib plugin
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
198 zstream->marked = TRUE;
68e7519ebd90 Added zlib plugin
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
199 }
68e7519ebd90 Added zlib plugin
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
200 }
68e7519ebd90 Added zlib plugin
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
201
3863
55df57c028d4 Added "bool" type and changed all ints that were used as booleans to bool.
Timo Sirainen <tss@iki.fi>
parents: 3800
diff changeset
202 static const struct stat *_stat(struct _istream *stream, bool exact)
3800
68e7519ebd90 Added zlib plugin
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
203 {
68e7519ebd90 Added zlib plugin
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
204 struct zlib_istream *zstream = (struct zlib_istream *) stream;
68e7519ebd90 Added zlib plugin
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
205 size_t size;
68e7519ebd90 Added zlib plugin
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
206
68e7519ebd90 Added zlib plugin
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
207 if (fstat(zstream->fd, &stream->statbuf) < 0) {
68e7519ebd90 Added zlib plugin
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
208 i_error("zlib_istream.fstat() failed: %m");
68e7519ebd90 Added zlib plugin
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
209 return NULL;
68e7519ebd90 Added zlib plugin
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
210 }
68e7519ebd90 Added zlib plugin
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
211
68e7519ebd90 Added zlib plugin
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
212 if (!exact)
68e7519ebd90 Added zlib plugin
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
213 return &stream->statbuf;
68e7519ebd90 Added zlib plugin
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
214
68e7519ebd90 Added zlib plugin
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
215 if (zstream->cached_size == (uoff_t)-1) {
68e7519ebd90 Added zlib plugin
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
216 uoff_t old_offset = stream->istream.v_offset;
68e7519ebd90 Added zlib plugin
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
217 do {
68e7519ebd90 Added zlib plugin
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
218 (void)i_stream_get_data(&stream->istream, &size);
68e7519ebd90 Added zlib plugin
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
219 i_stream_skip(&stream->istream, size);
68e7519ebd90 Added zlib plugin
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
220 } while (_read(stream) > 0);
68e7519ebd90 Added zlib plugin
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
221
68e7519ebd90 Added zlib plugin
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
222 zstream->cached_size = stream->istream.v_offset;
68e7519ebd90 Added zlib plugin
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
223 i_stream_seek(&stream->istream, old_offset);
68e7519ebd90 Added zlib plugin
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
224 }
68e7519ebd90 Added zlib plugin
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
225 stream->statbuf.st_size = zstream->cached_size;
68e7519ebd90 Added zlib plugin
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
226 return &stream->statbuf;
68e7519ebd90 Added zlib plugin
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
227 }
68e7519ebd90 Added zlib plugin
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
228
68e7519ebd90 Added zlib plugin
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
229 static void _sync(struct _istream *stream)
68e7519ebd90 Added zlib plugin
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
230 {
68e7519ebd90 Added zlib plugin
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
231 struct zlib_istream *zstream = (struct zlib_istream *) stream;
68e7519ebd90 Added zlib plugin
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
232
68e7519ebd90 Added zlib plugin
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
233 zstream->cached_size = (uoff_t)-1;
68e7519ebd90 Added zlib plugin
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
234 }
68e7519ebd90 Added zlib plugin
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
235
68e7519ebd90 Added zlib plugin
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
236 struct istream *i_stream_create_zlib(int fd, pool_t pool)
68e7519ebd90 Added zlib plugin
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
237 {
68e7519ebd90 Added zlib plugin
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
238 struct zlib_istream *zstream;
68e7519ebd90 Added zlib plugin
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
239
68e7519ebd90 Added zlib plugin
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
240 zstream = p_new(pool, struct zlib_istream, 1);
68e7519ebd90 Added zlib plugin
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
241 zstream->fd = fd;
68e7519ebd90 Added zlib plugin
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
242 zstream->file = gzdopen(fd, "r");
68e7519ebd90 Added zlib plugin
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
243 zstream->cached_size = (uoff_t)-1;
68e7519ebd90 Added zlib plugin
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
244 zstream->max_buffer_size = DEFAULT_MAX_BUFFER_SIZE;
68e7519ebd90 Added zlib plugin
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
245
68e7519ebd90 Added zlib plugin
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
246 zstream->istream.iostream.close = _close;
68e7519ebd90 Added zlib plugin
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
247 zstream->istream.iostream.destroy = _destroy;
68e7519ebd90 Added zlib plugin
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
248 zstream->istream.iostream.set_max_buffer_size = _set_max_buffer_size;
68e7519ebd90 Added zlib plugin
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
249
68e7519ebd90 Added zlib plugin
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
250 zstream->istream.read = _read;
68e7519ebd90 Added zlib plugin
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
251 zstream->istream.seek = _seek;
68e7519ebd90 Added zlib plugin
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
252 zstream->istream.stat = _stat;
68e7519ebd90 Added zlib plugin
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
253 zstream->istream.sync = _sync;
68e7519ebd90 Added zlib plugin
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
254
68e7519ebd90 Added zlib plugin
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
255 zstream->istream.istream.seekable = TRUE;
68e7519ebd90 Added zlib plugin
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
256 return _i_stream_create(&zstream->istream, pool, fd, 0);
68e7519ebd90 Added zlib plugin
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
257 }